*/}}
浏览代码

segmented raw get

YimingWu 7 月之前
父节点
当前提交
699a3e53c7
共有 4 个文件被更改,包括 59 次插入11 次删除
  1. 42 7
      la_data.c
  2. 6 2
      la_data.h
  3. 1 0
      la_interface.h
  4. 10 2
      la_kernel.c

+ 42 - 7
la_data.c

@@ -1154,6 +1154,9 @@ laProp *laAddRawProperty(laPropContainer *Container, const char *Identifier, con
     la_AssignPropertyGeneralSub(p);
     return p;
 }
+void laRawPropertyExtraFunctions(laProp* p, laRawMultiGetF MultiGet, laRawMultiCanGetF CanMultiGet){
+    laRawProp *rp=p; rp->RawMultiCanGet=CanMultiGet; rp->RawMultiGet=MultiGet;
+}
 
 
 //void laPropertySignal(laProp* p, int Throw, int Catch) {
@@ -2042,7 +2045,15 @@ void* laGetRaw(laPropPack *pp, int* r_size, int* return_is_a_copy){
         return data;
     } return 0;
 }
-int laSetRaw(laPropPack *pp, void* data, int _size){
+int laGetMultiRaw(laPropPack* pp, int* r_chunks, int* r_sizes, void** pointers){
+    if (pp->LastPs->p->PropertyType == LA_PROP_RAW){
+        laRawProp* rp=pp->LastPs->p; if(!rp->RawMultiGet){ return 0; }
+        rp->RawMultiGet(pp->LastPs->UseInstance,r_chunks,r_sizes,pointers);
+        if(*r_chunks>0){ return 1; } return 0;
+    }
+    return 0;
+}
+int laSetRaw(laPropPack *pp, void* data, uint32_t _size){
     if (pp->LastPs->p->PropertyType == LA_PROP_RAW){ laRawProp* rp=pp->LastPs->p;
         if(rp->RawSet){ rp->RawSet(pp->LastPs->UseInstance, data, _size); return 1; }
         if(rp->Base.OffsetIsPointer){ void** target=(((char*)pp->LastPs->UseInstance)+rp->Base.Offset); if(*target) free(*target);
@@ -2088,6 +2099,10 @@ int laGetFloatRange(laPropPack *pp, real *min, real *max){
     return 0;
 }
 
+int laCanGetMultiRaw(laProp *p,void* inst){
+    laRawProp *rp = p; if (p->PropertyType == LA_PROP_RAW){
+        if (rp->RawMultiGet && (!rp->RawMultiCanGet || rp->RawMultiCanGet(inst))) return 1; } return 0;
+}
 int laCanGetState(laProp *sub){ laSubProp *sp = sub; if (sub->PropertyType == LA_PROP_SUB){ if (sp->GetState) return 1; } return 0; }
 int laCanGetTheme(laProp *sub){ laSubProp *sp = sub; if (sub->PropertyType == LA_PROP_SUB){ if (sp->GetTheme) return 1; } return 0; }
 int laCanGetGap(laProp *sub){ laSubProp *sp = sub; if (sub->PropertyType == LA_PROP_SUB){ if (sp->GetGap) return 1; } return 0; }
@@ -2415,6 +2430,9 @@ void la_WriteOnlyMBString(laUDF *udf, char *String){
 void la_WriteInt(laUDF *udf, int Data){
     fwrite(&Data, sizeof(int), 1, udf->DiskFile);
 }
+void la_WriteUInt(laUDF *udf, uint32_t Data){
+    fwrite(&Data, sizeof(uint32_t), 1, udf->DiskFile);
+}
 void la_WriteUByte(laUDF *udf, unsigned char Data){
     fwrite(&Data, sizeof(unsigned char), 1, udf->DiskFile);
 }
@@ -2452,6 +2470,12 @@ int la_ReadInt(laUDF *udf){
     else{ memcpy(&result, udf->FileContent + udf->Seek, sizeof(int)); udf->Seek += sizeof(int); }
     return result;
 }
+uint32_t la_ReadUInt(laUDF *udf){
+    uint32_t result;
+    if(!udf->FileContent){ fread(&result, sizeof(uint32_t), 1, udf->DiskFile); }
+    else{ memcpy(&result, udf->FileContent + udf->Seek, sizeof(uint32_t)); udf->Seek += sizeof(uint32_t); }
+    return result;
+}
 u64bit la_ReadLong(laUDF *udf){
     u64bit result;
     if(!udf->FileContent){ fread(&result, sizeof(u64bit), 1, udf->DiskFile); }
@@ -2508,8 +2532,8 @@ void la_ReadBuffer(laUDF *udf, u64bit Size, void *Result){
     if(!udf->FileContent){ fread(Result, Size, 1, udf->DiskFile); }
     else{ memcpy(Result, udf->FileContent + udf->Seek, Size); udf->Seek += Size; }
 }
-void* la_ReadRaw(laUDF *udf, int* _sz){
-    int _size = la_ReadInt(udf);
+void* la_ReadRaw(laUDF *udf, uint32_t* _sz){
+    uint32_t _size = la_ReadUInt(udf);
     if(_sz){
         if (_size){
             void* data=calloc(1,_size);
@@ -2750,7 +2774,7 @@ void la_WriteEnumProp(laUDF *udf, laPropPack *pp){
 void la_ReadRawProp(laUDF *udf, laPropPack *pp){
     la_ReadShort(udf);//mark
     if (pp) {
-        int _size=0;
+        uint32_t _size=0;
         void* data=la_ReadRaw(udf,&_size);
         laSetRaw(pp, data, _size); free(data);
     }else{
@@ -2759,11 +2783,22 @@ void la_ReadRawProp(laUDF *udf, laPropPack *pp){
 }
 void la_WriteRawProp(laUDF *udf, laPropPack *pp){
     laProp *p = pp->LastPs->p;
-    void* data; int _size=0, IsCopy=0;
-    data=laGetRaw(pp, &_size, &IsCopy);
     la_WriteShort(udf, LA_UDF_RAW_MARK);
+    if(laCanGetMultiRaw(p,pp->LastPs->UseInstance)){
+        int chunks=0; uint32_t sizes[128]={0}; void* pointers[128]={0};
+        uint32_t totalsize=0;
+        if(laGetMultiRaw(pp,&chunks,sizes,pointers)){ TNS_CLAMP(chunks,1,128);
+            for(int i=0;i<chunks;i++){ totalsize+=sizes[i]; } la_WriteUInt(udf,totalsize);
+            if(totalsize){
+                for(int i=0;i<chunks;i++){ if(sizes[i] && pointers[i]){ la_WriteSized(udf,pointers[i],sizes[i]); free(pointers[i]); } }
+            }
+        }
+        return;
+    }
+    void* data; uint32_t _size=0, IsCopy=0;
+    data=laGetRaw(pp, &_size, &IsCopy);
     if(!data){ _size=0; }
-    la_WriteInt(udf,_size);
+    la_WriteUInt(udf,_size);
     if(_size){ la_WriteSized(udf,data,_size); }
     if(IsCopy && data){ free(data); }
 }

+ 6 - 2
la_data.h

@@ -81,8 +81,10 @@ typedef void *(*laSubUIThemeF)(void* parent, void* inst); // return a theme, MAI
 typedef int (*laSubUIGapF)(void* parent, void* inst);
 typedef void (*laSubUICategoryF)(void* parent, void* inst, char *copy_result, char** direct_result);
 typedef void* (*laRawGetF)(void *, int* r_size, int* return_is_a_copy);
+typedef void (*laRawMultiGetF)(void *, int* r_chunks, uint32_t* r_sizes, void** pointers); // max 128 chunks
+typedef int (*laRawMultiCanGetF)(void *);
 typedef int (*laRawGetSizeF)(void *);
-typedef void (*laRawSetF)(void *, void* data, int copy_size);
+typedef void (*laRawSetF)(void *, void* data, uint32_t copy_size);
 
 typedef void (*laContainerPostReadFunc)(void *);
 typedef laPropContainer* (*laGetNodeTypeFunc)(void *);
@@ -372,6 +374,7 @@ STRUCTURE(laOperatorProp){
 STRUCTURE(laRawProp){
     laProp Base;
     laRawGetF RawGet;
+    laRawMultiGetF RawMultiGet; laRawMultiCanGetF RawMultiCanGet;
     laRawSetF RawSet;
     laRawGetSizeF RawGetSize;
 };
@@ -842,7 +845,7 @@ int laActuateProp(laPropPack *This, laPropPack *RunPP, laOperator *OptionalFrom,
 int laGetIntRange(laPropPack *pp, int *min, int *max);
 int laGetFloatRange(laPropPack *pp, real *min, real *max);
 void* laGetRaw(laPropPack *pp, int* r_size, int* return_is_a_copy);
-int laSetRaw(laPropPack *pp, void* data, int _size);
+int laSetRaw(laPropPack *pp, void* data, uint32_t _size);
 
 int laTryGetInstanceIdentifier(void* Instance, laPropContainer* pc, char* identifier, char** here);
 
@@ -927,6 +930,7 @@ laProp *laAddOperatorProperty(laPropContainer *Container, const char *Identifier
                               const char *OperatorID, uint32_t IconID, laWidget* DefaultWidget);
 
 laProp *laAddRawProperty(laPropContainer *Container, const char *Identifier, const char *Name, const char *Description, int OffsetSize, laRawGetSizeF GetSize, laRawGetF RawGet, laRawSetF RawSet, u64bit Tag);
+void laRawPropertyExtraFunctions(laProp* p, laRawMultiGetF MultiGet, laRawMultiCanGetF CanMultiGet);
 
 //void laPropertySignal(laProp* p, int Throw, int Catch);
 

+ 1 - 0
la_interface.h

@@ -500,6 +500,7 @@ STRUCTURE(LA){
     const char* MenuProgramName;
 
     SYSLOCK MemLock;
+    SYSLOCK OpsLock;
     laHash256 GlobalMemPool;
     int ByteCount;
     int TotalByteCount;

+ 10 - 2
la_kernel.c

@@ -779,12 +779,13 @@ int la_GetDPI(HWND win){
 #define PROGRESSW (LA_RH*15)
 
 void laShowProgress(real p1, real p2){
+    laSpinLock(&MAIN.OpsLock);
     laBoxedTheme *bt = _LA_THEME_TAB; real* fg=laThemeColor(bt,LA_BT_TEXT); real* bg=laThemeColor(bt,LA_BT_NORMAL);
     if(!MAIN.Progress.Called){
         laRecordTime(&MAIN.Progress.TimeCalled); MAIN.Progress.Called=1;
     }else{
         laTimeRecorder tm; laRecordTime(&tm);
-        real t=laTimeElapsedSecondsf(&tm,&MAIN.Progress.TimeCalled); if(t<0.1) return;
+        real t=laTimeElapsedSecondsf(&tm,&MAIN.Progress.TimeCalled); if(t<0.1){ laSpinUnlock(&MAIN.OpsLock); return; }
         memcpy(&MAIN.Progress.TimeCalled,&tm,sizeof(laTimeRecorder));
         if(!MAIN.Progress.Shown){
              int ww=PROGRESSW+LA_RH*2;
@@ -834,10 +835,12 @@ void laShowProgress(real p1, real p2){
     MSG msg;
     while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){ TranslateMessage(&msg); DispatchMessage(&msg); };
 #endif
+    laSpinUnlock(&MAIN.OpsLock);
 }
 void laHideProgress(){
+    laSpinLock(&MAIN.OpsLock);
     if(!MAIN.Progress.Shown){
-        MAIN.Progress.Called=0; return;
+        MAIN.Progress.Called=0; laSpinUnlock(&MAIN.OpsLock); return;
     }
     laTimeRecorder tm; laRecordTime(&tm);
     real t=laTimeElapsedSecondsf(&tm,&MAIN.Progress.TimeCalled);
@@ -850,6 +853,7 @@ void laHideProgress(){
     ShowWindow(MAIN.Progress.w,SW_HIDE);
     if(MAIN.CurrentWindow) UpdateWindow(MAIN.CurrentWindow->win);
 #endif
+    laSpinUnlock(&MAIN.OpsLock);
 }
 
 //=======================
@@ -935,6 +939,7 @@ int laGetReadyWith(laInitArguments* ia){
 #endif
 
     laSpinInit(&MAIN.MemLock);
+    laSpinInit(&MAIN.OpsLock);
 
     memcpy(&MAIN.InitArgs,ia,sizeof(laInitArguments));
     if(MAIN.InitArgs.GLMajor>4||MAIN.InitArgs.GLMajor<1){ MAIN.InitArgs.GLMajor=3; }
@@ -1374,6 +1379,9 @@ void laShutoff(int SavePrefereces){
     hshFree(&MAIN.DBInstMemLeft);
     memNoLonger();
 
+    laSpinDestroy(&MAIN.MemLock);
+    laSpinDestroy(&MAIN.OpsLock);
+
 #ifdef LA_WITH_LUAJIT
     lua_close(MAIN.L);
 #endif