*/}}
Browse Source

Undo clean up, mesh undo seems all working

improved list difference
Yiming Wu 2 years ago
parent
commit
438b68a5df

+ 22 - 16
source/lagui/la_data.c

@@ -721,7 +721,9 @@ laProp *la_CreateProperty(laPropContainer *Container, int Type, const char *Iden
 
     return p;
 }
-
+void la_ClearDetachedProp(laPanel* p){
+    laProp *np; while(np=lstPopItem(&p->PropLinkContainer->Props)){ free(np->Identifier); memFree(np); }
+}
 laProp *la_MakeDetachedProp(laPanel* p, const char *From, const char *Rename){
     laIntProp *ip;
     laFloatProp *fp;
@@ -3712,18 +3714,19 @@ void laPushDifferences(char* Description, u64bit hint){
 }
 
 void la_FreeInstance(void* inst, laPropContainer* pc, int no_free);
-void la_FreeDBInst(laDBInst* dbi, int no_freeinst);
-void la_FreeDBProp(laDBProp* dbp){
-    printf("free dbp %s %x\n",dbp->p->Identifier,dbp);
+void la_FreeDBInst(laDBInst* dbi, int no_freeinst, int cleanup_only, int SkipInstances);
+void la_FreeDBProp(laDBProp* dbp, int cleanup_only, int SkipInstances){
+    //printf("free dbp %s %x\n",dbp->p->Identifier,dbp);
     if(dbp->p->PropertyType==LA_PROP_SUB){
-        if((((laSubProp*)dbp->p)->ListHandleOffset||dbp->p->UDFNoCreate||dbp->p->UDFIsSingle)&&(!dbp->p->UDFIsRefer)){
+        if((((laSubProp*)dbp->p)->ListHandleOffset||dbp->p->UDFNoCreate||dbp->p->UDFIsSingle)&&(!dbp->p->UDFIsRefer)&&(!SkipInstances)){
             laDBSubProp* dsp=dbp; laDBInst* si;
             //printf("fdbp %s %x %x %x\n",dbp->p->Identifier,dsp->Instances.pFirst,dsp->Instances.pLast,((laListItem*)dsp->Instances.pFirst)->pNext);
-            while(si=lstPopItem(&dsp->Instances)){ la_FreeDBInst(si,dbp->p->UDFNoCreate||(!dbp->p->OffsetIsPointer)); }
+            while(si=lstPopItem(&dsp->Instances)){ la_FreeDBInst(si,dbp->p->UDFNoCreate||(!dbp->p->OffsetIsPointer),cleanup_only,SkipInstances); }
         } // prevent freeing the data;
     }elif(dbp->p->PropertyType==LA_PROP_STRING && ((laStringProp*)dbp->p)->IsSafeString){
         strSafeSet(&dbp->Data,0);
     }elif(dbp->p->PropertyType==LA_PROP_RAW){
+        printf("raw dbp %s\n",dbp->p->Identifier);
         free(dbp->Data);
     }else{
         //printf("-data- %x\n",dbp->Data);
@@ -3731,23 +3734,24 @@ void la_FreeDBProp(laDBProp* dbp){
     }
     memFree(dbp);
 }
-void la_FreeDBInst(laDBInst* dbi, int no_freeinst){
+void la_FreeDBInst(laDBInst* dbi, int no_freeinst, int cleanup_only, int SkipInstances){
     laListHandle* l=hsh65536DoHashLongPtr(MAIN.DBInstLink,dbi->OriginalInstance); lstRemoveItem(l, &dbi->Item2);
-    printf("free dbi %s %x\n", dbi->pc->Identifier,dbi);
-    laDBProp* dbp; while(dbp=lstPopItem(&dbi->Props)){ la_FreeDBProp(dbp); }
-    if(dbi->OriginalInstance) la_FreeInstance(dbi->OriginalInstance, dbi->pc, no_freeinst);
+    //printf("free dbi %s %x\n", dbi->pc->Identifier,dbi);
+    laDBProp* dbp; while(dbp=lstPopItem(&dbi->Props)){ la_FreeDBProp(dbp, cleanup_only,SkipInstances); }
+    if(dbi->OriginalInstance && (!cleanup_only)) la_FreeInstance(dbi->OriginalInstance, dbi->pc, no_freeinst);
     memFree(dbi);
 }
 void la_FreeDiffCommand(laDiffCommand* dc, laDiff* d, int FromLeft){
-    printf("freedc %s\n",dc->p->Identifier);
+    //printf("freedc %s\n",dc->p->Identifier);
     if(dc->p->PropertyType==LA_PROP_SUB && (((laSubProp*)dc->p)->ListHandleOffset||dc->p->UDFNoCreate||dc->p->UDFIsSingle) && (!dc->p->UDFIsRefer)){
         laDiffCommandInst* dci; laDiffCommandSub* dcs=dc;
-        while(dci=lstPopItem(&dcs->AddedInst)){ if(!FromLeft) la_FreeDBInst(dci->DBInst,(dc->p->UDFNoCreate||(!dc->p->OffsetIsPointer))); memFree(dci); }
+        while(dci=lstPopItem(&dcs->AddedInst)){ if(!FromLeft) la_FreeDBInst(dci->DBInst,(dc->p->UDFNoCreate||(!dc->p->OffsetIsPointer)),0,0); memFree(dci); }
         while(dci=lstPopItem(&dcs->MovedInst)){ memFree(dci); }
-        while(dci=lstPopItem(&dcs->RemovedInst)){ if(FromLeft) la_FreeDBInst(dci->DBInst,(dc->p->UDFNoCreate||(!dc->p->OffsetIsPointer))); memFree(dci); }
+        while(dci=lstPopItem(&dcs->RemovedInst)){ if(FromLeft) la_FreeDBInst(dci->DBInst,(dc->p->UDFNoCreate||(!dc->p->OffsetIsPointer)),0,1); memFree(dci); }
     }elif(dc->p->PropertyType==LA_PROP_STRING && ((laStringProp*)dc->p)->IsSafeString){
         strSafeSet(&dc->Data,0);
     }elif(dc->p->PropertyType==LA_PROP_RAW){
+        printf("raw %s\n",dc->p->Identifier);
         free(dc->Data);
     }
     memFree(dc);
@@ -3784,11 +3788,11 @@ void la_FreeOlderDifferences(int KeepHowMany){
 }
 void la_FreeAllDifferences(){
     la_FreeNewerDifferences();
-    la_FreeOlderDifferences(1); //XXX 0 seems to have problems
+    la_FreeOlderDifferences(1);
 }
 void la_NoLongerRecordUndo(){
     la_FreeAllDifferences();
-    laDBProp*dbp; while(dbp=lstPopItem(&MAIN.RootDBInst.Props)){ la_FreeDBProp(dbp); }
+    laDBProp*dbp; while(dbp=lstPopItem(&MAIN.RootDBInst.Props)){ la_FreeDBProp(dbp,1,0); }
     laDBRecordedProp* p; while(p=lstPopItem(&MAIN.DBRecordedProps)){ strSafeDestroy(&p->OriginalPath); memFree(p); }
     hshFree(&MAIN.DBInstLink);
 }
@@ -3990,6 +3994,8 @@ int la_GenerateListDifferences(laDBInst* dbi, laDBSubProp* dbp, laPropPack* pp,
         if(!dbi->Item.pPrev){dbp->Instances.pFirst=dbi;}
         if(!dbi->Item.pNext){dbp->Instances.pLast=dbi;}
     }
+
+    if(!New.pFirst){ dbp->Instances.pFirst=dbp->Instances.pLast=0; }
     
     for(laDiffTemp* lip=NewDeleted.pFirst;lip;lip=lip->Item.pNext){
         laDBInst* dbi=lip->p; lstAppendItem(&dc->RemovedInst, la_NewDiffCommandInst(dbi, lip->tPrev, lip->tNext));printf("deleted %x %x\n", dbi, dbi->OriginalInstance);
@@ -4140,7 +4146,7 @@ void la_FreeInstance(void* inst, laPropContainer* pc, int no_free){
     //if(p->PropertyType!=LA_PROP_SUB) return;
     //if(!p->SubProp || ((laSubProp*)p)->TargetID) p->SubProp=la_ContainerLookup(((laSubProp*)p)->TargetID);
     //laPropContainer* pc=p->SubProp; if(((laSubProp*)p)->GetType) pc=((laSubProp*)p)->GetType(inst);
-    printf("freeinst %s %x\n",pc->Name,inst);
+    //printf("freeinst %s %x\n",pc->Name,inst);
     if(pc->BeforeFree) pc->BeforeFree(inst);
     laPropStep SubPS = {0}; laPropPack SubPP = {0}; laPropIterator pi={0}; SubPP.LastPs=&SubPS; 
     for(laProp* p=pc->Props.pFirst;p;p=p->Item.pNext){

+ 1 - 0
source/lagui/la_data.h

@@ -750,6 +750,7 @@ NEED_STRUCTURE(laWidget);
 
 laProp *la_CreateProperty(laPropContainer *Container, int Type, const char *Identifier, const char *Name, const char *Description,
                           const char *Prefix, const char *Unit, laWidget* DefaultWidget, u64bit Tag);
+void la_ClearDetachedProp(laPanel* p);
 laProp *la_MakeDetachedProp(laPanel* p, const char *From, const char *Rename);
 laProp *laAddIntProperty(laPropContainer *Container, const char *Identifier, const char *Name, const char *Description, laWidget* DefaultWidget,
                          const char *Prefix, const char *Unit, int Max, int Min, int Step, int DefVal, const int *DefArr,

+ 1 - 1
source/lagui/la_interface.h

@@ -1560,7 +1560,7 @@ laPanel *laDesignPropPanel(char *Title, int X, int Y, int W, int H,
 laPanel *laDesignOperatorPanel(char *Title, int X, int Y, int W, int H, int MaxW, int MaxH, int MinW, int MinH, int SnapL, int SnapR, int SnapT, int SnapB,
                                laUiDefineFunc Define, laPropPack *This, laPropPack *OperatorProps);
 void laDeferedDestroyPanel(laPanel *p);
-void laDestroySinglePanel(laPanel *p);
+void laDestroySinglePanel(laPanel *p, int immediate);
 void laEnsurePanelInBound(laPanel *p,laUiList* uil);
 int laEnclosePanelContent(laPanel *p, laUiList *uil);
 laPanel *laEnableIdlePanel(laPanel *Attachment, laOperator *a, laPropPack *OperatorProps, laUiDefineFunc ReplaceUiDefine, laPropPack *This,

+ 12 - 16
source/lagui/la_kernel.c

@@ -132,9 +132,7 @@ void la_DestroyWindow(laWindow *wnd){
 
     strSafeDestroy(&wnd->Title);
 
-    while (p = lstPopItem(&wnd->Panels)){
-        laDestroySinglePanel(p);
-    }
+    while (p = lstPopItem(&wnd->Panels)){ laDestroySinglePanel(p,1); }
     while (l = lstPopItem(&wnd->Layouts)){
         laDestroyBlocksRecursive(l->FirstBlock);
         strSafeDestroy(&l->ID);
@@ -1614,7 +1612,7 @@ void la_WindowDefDraw(laWindow *w, laBoxedTheme *bt){
         if (!p->AnimationMode){
             lstRemoveItem(&w->FadingPanels, p);
             p->AnimationMode = LA_PANEL_ANIMATION_DESTROY;
-            laDeferredDestroyPanel(p);
+            laDeferredDestroyPanel(p, 0);
         }else
             la_PanelDrawToWindow(p, w);
     }
@@ -1797,9 +1795,7 @@ void laDestroyBlocksRecursive(laBlock *Root){
         laDestroyBlocksRecursive(Root->B1);
         laDestroyBlocksRecursive(Root->B2);
     }else{
-        while (p = lstPopItem(&Root->Panels)){
-            laDestroySinglePanel(p);
-        }
+        while (p = lstPopItem(&Root->Panels)){ laDestroySinglePanel(p, 1); }
     }
     memFree(Root);
 }
@@ -2156,7 +2152,7 @@ laPanel *laDesignOperatorPanel(char *Title, int X, int Y, int W, int H, int MaxW
     return p;
 }
 
-void laDeferredDestroyPanel(laPanel *p){
+void laDeferredDestroyPanel(laPanel *p, int immediate){
     laPanel *ip;
     tnsDelete2DOffscreen(p->OffScr);
     p->OffScr = 0;
@@ -2178,15 +2174,16 @@ void laDeferredDestroyPanel(laPanel *p){
 
     for (ip = p->SubPanels.pFirst; ip; ip = ip->Item.pNext){
         //lstRemoveItem(&p->SubPanels, ip);
-        laDestroySinglePanel(ip);
+        laDestroySinglePanel(ip, immediate);
         laNotifyUsers("la.windows.panels");
     }
 
+    la_ClearDetachedProp(p);
     memFree(p->PropLinkContainer); memFree(p->PropLinkFakeProp);
 
     la_ReturnPanelNode(p);
 }
-void laDestroySinglePanel(laPanel *p){
+void laDestroySinglePanel(laPanel *p, int immediate){
     la_SetPropMathcerContext(p);
 
     if (p->PropLinkPP.LastPs&&p->PropLinkPP.LastPs->p->SubProp->Props.pFirst){
@@ -2213,8 +2210,8 @@ void laDestroySinglePanel(laPanel *p){
         la_StopUiOperatorService(p);
     }
 
-    if (!p->AnimationMode){
-        laDeferredDestroyPanel(p);
+    if ((!p->AnimationMode) || immediate){
+        laDeferredDestroyPanel(p, immediate);
     }else{
         p->LaterDestroy = 1;
     }
@@ -5548,7 +5545,7 @@ void *la_DestroyOperator(laOperator **a, laListHandle *Operators, int OnlyThisOn
     if (laNonFixedPanelExists((*a)->OperatorPanel)){
         la_SetPropMathcerContext((*a)->OperatorPanel);
         MAIN.CurrentPanel = (*a)->OperatorPanel;
-        laDestroySinglePanel((*a)->OperatorPanel);
+        laDestroySinglePanel((*a)->OperatorPanel,0);
     }
     if ((*a)->CreatedThis) FreeMem((*a)->CreatedThis);
 
@@ -6151,9 +6148,7 @@ int la_HandleSingleEvent(laEvent *e, laListHandle *Operators){
         if (a->State & LA_BLOCK){ Result = a->Type->Modal(a, e); }
 
         //la_PrintOperatorStack();
-
-        if(Result == LA_OPERATOR_CALLS_SHUTOFF){ return 0; }
-
+        
         if (a->Type->ExtraMark & LA_EXTRA_TO_PANEL){
             laLocalToWindow(a, a->ToPanel, &e->x, &e->y);
             e->Localized = 0;
@@ -6185,6 +6180,7 @@ int la_HandleSingleEvent(laEvent *e, laListHandle *Operators){
         if (Result & LA_FINISH || Result == LA_CANCEL || (a->StopNow && a->Using == 0)){
             if (a->Type->Exit) a->Type->Exit(a, Result);
             la_DestroyOperator(&a, Operators, 0);
+            if(Result == LA_OPERATOR_CALLS_SHUTOFF){ return 0; }
         }
 
         a = NextA;

+ 7 - 1
source/lagui/la_tns_kernel.c

@@ -1545,6 +1545,11 @@ void tnsDeleteBuiltinShaders(){
 void tnsQuit(){
     tnsQuitFontManager();
 
+    tnsObject*o; 
+    while(o=lstPopItem(&T->World.AllObjects)){ tnsDestroyObject(o); }
+    while(o=lstPopItem(&T->World.RootObjects)){ tnsDestroyRootObject(o); }
+    memFreeRemainingLeftNodes();
+
     tnsDeleteBuiltinShaders();
 
     tnsOffscreen* off; while(off=T->Offscreens.pFirst){ tnsDelete2DOffscreen(off); }
@@ -3480,7 +3485,8 @@ void tnsDestroyObject(tnsObject *o){
     lstRemoveItem(&T->World.AllObjects, o);
 
     if(o->Type==TNS_OBJECT_MESH){ tnsMeshObject* mo=o;
-        if(mo->v) arrFree(&mo->v, &mo->maxv); if(mo->e) arrFree(&mo->e, &mo->maxe); if(mo->f) arrFree(&mo->f, &mo->maxf);
+        if(mo->v) arrFree(&mo->v, &mo->maxv); if(mo->e) arrFree(&mo->e, &mo->maxe);
+        if(mo->f){ for(int i=0;i<mo->totf;i++){ free(mo->f[i].loop); } arrFree(&mo->f, &mo->maxf); }
         mo->totv=mo->tote=mo->totf=0;
         tnsInvalidateMeshBatch(o);
     }

+ 7 - 7
source/lagui/resources/la_operators.c

@@ -940,7 +940,7 @@ int OPCHK_BlockHasMorePanels(laPropPack *This, laStringSplitor *Instructions){
 int OPINV_BlockClosePanel(laOperator *a, laEvent *e){
     laPanel*p = a->This?a->This->LastPs->UseInstance:0;
     if(p && p->Mode == LA_PANEL_FLOATING_TOP){
-        laDestroySinglePanel(p);
+        laDestroySinglePanel(p,0);
         return LA_FINISHED;
     }
 
@@ -965,7 +965,7 @@ int OPMOD_BlockClosePanel(laOperator *a, laEvent *e){
         if (!b) b = laDetectBlockRecursive(l->FirstBlock, e->x, e->y);
         if (!b) return LA_CANCELED;
         if (a->ConfirmData->Mode == LA_CONFIRM_OK){
-            laDestroySinglePanel(b->CurrentPanel);
+            laDestroySinglePanel(b->CurrentPanel,1);
             la_RecalcBlockRecursive(b, b->X, b->Y, b->W, b->H);
         }
         return LA_FINISHED;
@@ -1596,13 +1596,13 @@ int OPMOD_MenuPanel(laOperator *a, laEvent *e){
 
     if(p->CloseWhenMovedOut && (!IsClose || (!IsIn && e->Type==LA_TIME_IDLE) || e->Type==LA_L_MOUSE_DOWN||e->Type==LA_R_MOUSE_DOWN)){ 
         la_StopUiOperatorService(p);
-        laDestroySinglePanel(p);
+        laDestroySinglePanel(p,0);
         return LA_FINISHED_PASS;
     }
     if (e->Type == LA_ESCAPE_DOWN || (e->Type == LA_L_MOUSE_DOWN && !IsIn)){
         laConfirmInt(a, 1, LA_CONFIRM_DATA);
         la_StopUiOperatorService(p);
-        laDestroySinglePanel(p);
+        laDestroySinglePanel(p,0);
         return LA_FINISHED_PASS;
     }
 
@@ -1660,7 +1660,7 @@ int OPMOD_MenuPanel(laOperator *a, laEvent *e){
     if (a->ConfirmData){
         laConfirmInt(a, a->ConfirmData->IData, a->ConfirmData->Mode);
         la_StopUiOperatorService(p);
-        laDestroySinglePanel(p);
+        laDestroySinglePanel(p,0);
         return LA_FINISHED_PASS;
     }
 
@@ -1679,7 +1679,7 @@ int OPMOD_ModalPanel(laOperator *a, laEvent *e){
     if (e->Type == LA_KEY_DOWN && e->key==LA_KEY_ESCAPE){
         laConfirmInt(a, 0, LA_CONFIRM_CANCEL);
         la_StopUiOperatorService(p);
-        laDestroySinglePanel(p);
+        laDestroySinglePanel(p,0);
         return LA_FINISHED_PASS;
     }
 
@@ -1689,7 +1689,7 @@ int OPMOD_ModalPanel(laOperator *a, laEvent *e){
              return LA_RUNNING_PASS;
         }
         la_StopUiOperatorService(p);
-        laDestroySinglePanel(p);
+        laDestroySinglePanel(p,0);
         return LA_FINISHED_PASS;
     }
 

+ 2 - 1
source/lagui/resources/la_properties.c

@@ -711,13 +711,14 @@ void* tnsget_MeshObjectFaceRaw(tnsMeshObject* o, int* r_size, int* r_is_copy){
     return arr; 
 }
 void tnsset_MeshObjectFaceRaw(tnsMeshObject* o, int* data, int s){
-    if(!data) return; int totf=data[0]; int i=1;
     if(o->f){
         for(int fi=0;fi<o->totf;fi++){
             if(o->f[fi].loop){ free(o->f[fi].loop); o->f[fi].loop=0; }
         }
         arrFree(&o->f, &o->maxf); o->totf=0; 
     }
+    if(!data) return;
+    int totf=data[0]; int i=1;
     o->f=calloc(1,sizeof(tnsFace)*totf); o->maxf=o->totf=totf;
     for(int fi=0;fi<totf;fi++){
         tnsFace*f=&o->f[fi];

+ 1 - 1
source/lagui/resources/la_widgets_viewers.c

@@ -538,7 +538,7 @@ void la_3DViewDestroy(laUiItem *ui){
     tnsDelete2DOffscreen(e->OffScr);
     tnsDelete2DOffscreen(e->OffScrShadow);
     
-    //XXX: cause breaks tnsDestroyObject(e->ViewingCamera);
+    tnsDestroyObject(e->ViewingCamera);
 
     memFree(e);
 }