*/}}
Browse Source

Raw prop improvements and save along support

YimingWu 2 months ago
parent
commit
be52dc03c7
7 changed files with 220 additions and 250 deletions
  1. 196 187
      la_data.c
  2. 19 21
      la_data.h
  3. 0 3
      la_interface.h
  4. 1 1
      la_kernel.c
  5. 2 10
      resources/la_operators.c
  6. 1 27
      resources/la_properties.c
  7. 1 1
      resources/la_templates.c

+ 196 - 187
la_data.c

@@ -23,6 +23,7 @@ extern LA MAIN;
 const char* LA_UDF_EXTENSION_STRINGS[]={
     "LA_UDF_EXTENSION_FLOAT32",
     "LA_UDF_EXTENSION_RAW",
+    "LA_UDF_EXTENSION_QUICK_SEEK",
     "",
 };
 
@@ -2509,15 +2510,18 @@ void la_ReadBuffer(laUDF *udf, u64bit Size, void *Result){
 }
 void* la_ReadRaw(laUDF *udf, int* _sz){
     int _size = la_ReadInt(udf);
-    if (_size){
-        void* data=calloc(1,_size);
-        la_ReadBuffer(udf, _size, data);
-        if(_sz) *_sz=_size;
-        return data;
-    } return 0;
+    if(_sz){
+        if (_size){
+            void* data=calloc(1,_size);
+            la_ReadBuffer(udf, _size, data);
+            if(_sz) *_sz=_size;
+            return data;
+        } return 0;
+    }else{
+        la_Seek(udf, la_Tell(udf)+_size); return 0;
+    }
 }
 
-
 void la_WriteSingleProperty(laUDF *udf, void *FromInstance, laProp *p){
     la_WriteString(udf, p->Identifier);
 }
@@ -2745,9 +2749,13 @@ void la_WriteEnumProp(laUDF *udf, laPropPack *pp){
 }
 void la_ReadRawProp(laUDF *udf, laPropPack *pp){
     la_ReadShort(udf);//mark
-    int _size=0;
-    void* data=la_ReadRaw(udf,&_size);
-    if (pp) laSetRaw(pp, data, _size); free(data);
+    if (pp) {
+        int _size=0;
+        void* data=la_ReadRaw(udf,&_size);
+        laSetRaw(pp, data, _size); free(data);
+    }else{
+        la_ReadRaw(udf,0);
+    }
 }
 void la_WriteRawProp(laUDF *udf, laPropPack *pp){
     laProp *p = pp->LastPs->p;
@@ -2950,57 +2958,6 @@ void la_AddPostReadNode(void *Instance, laContainerPostReadFunc Func){
     upr->Instance = Instance;
     upr->Func = Func;
 }
-laUDFContentNode *la_AppendUDFContentNode(laUDFContentInstance *Parent, laPropPack *ForMe, u64bit FileSeek){
-    char FullPath[256]={0};
-    laUDFContentNode *ucn = CreateNew(laUDFContentNode);
-    FullPath[0] = 0;
-
-    laProp *p = ForMe->LastPs->p;
-
-    strSafeSet(&ucn->Identifier, p->Identifier);
-    sprintf(FullPath, "%s.%s", Parent->Parent->FullPath->Ptr, p->Identifier);
-    strSafeSet(&ucn->FullPath, FullPath);
-    ucn->PP.Go = &ucn->FakePS;
-    ucn->PP.LastPs = &ucn->FakePS;
-    ucn->FakePS.p = p;
-    ucn->FakePS.Type = U'.';
-    ucn->PP.RawThis = &Parent->Parent->PP;
-    ucn->Parent = Parent;
-    ucn->FileSeek = FileSeek;
-
-    lstAppendItem(&Parent->Children, ucn);
-
-    return ucn;
-}
-laUDFContentInstance *la_AppendUDFContentInstance(laUDFContentNode *Parent, u64bit FileSeek){
-    laUDFContentInstance *uci = CreateNew(laUDFContentInstance);
-
-    uci->FileSeek = FileSeek;
-    uci->Parent = Parent;
-    strSafePrint(&uci->Identifier,"Instance at seek 0x%0x", FileSeek);
-
-    lstAppendItem(&Parent->Instances, uci);
-
-    return uci;
-}
-void la_DestroyUDFContentNodeTreeRecursive(laUDFContentNode *ucn, int FreeRoot){
-    laUDFContentNode *ucni, *NextUCNI;
-    laUDFContentInstance *ucii, *NextUCII;
-    for (ucii = ucn->Instances.pFirst; ucii; ucii = NextUCII){
-        NextUCII = ucii->Item.pNext;
-        for (ucni = ucii->Children.pFirst; ucni; ucni = NextUCNI){
-            NextUCNI = ucni->Item.pNext;
-            strSafeDestroy(&ucii->Identifier);
-            lstRemoveItem(&ucii->Children, ucni);
-            la_DestroyUDFContentNodeTreeRecursive(ucni, 1);
-        }
-        lstRemoveItem(&ucn->Instances, ucii);
-        FreeMem(ucii);
-    }
-    strSafeDestroy(&ucn->Identifier);
-    strSafeDestroy(&ucn->FullPath);
-    if (FreeRoot) FreeMem(ucn);
-}
 
 void *la_GetReadDBInstNUID(char *ReferReadNUID){
     if (!ReferReadNUID) return 0;
@@ -3058,7 +3015,7 @@ void la_LoadAdditionalRegistries(){
         laManagedUDF* m;
         logPrint("[INFO] Loading additional resource: %s\n",r->Path->Ptr);
         laUDF* udf = laOpenUDF(r->Path->Ptr, 1, 0, &m);
-        if (udf){ laExtractUDF(udf, m, LA_UDF_MODE_OVERWRITE, 0); laCloseUDF(udf); }else{ logPrint("[WARN] Can't open resource: %s\n",r->Path->Ptr); }
+        if (udf){ laExtractUDF(udf, m, LA_UDF_MODE_OVERWRITE); laCloseUDF(udf); }else{ logPrint("[WARN] Can't open resource: %s\n",r->Path->Ptr); }
     }
 }
 
@@ -3176,13 +3133,16 @@ int la_ExtractFakeProp(laUDF *udf){
             }
         }
         break;
+    case LA_PROP_RAW:
+        la_ReadRawProp(udf, 0);
+        break;
     default:
         ReadState = ReadState;
         break;
     }
     return 0;
 }
-int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentInst, int Mode, laUDFContentNode *Parent){
+int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentInst, int Mode){
     laPropStep SubPS = {0};
     laPropPack SubPP = {0};
     char buf[LA_RAW_CSTR_MAX_LEN] = {0};
@@ -3199,7 +3159,6 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
     int VariableNodeSize;
     char NodeType[128]={0};
     int EStatus = 0;
-    laUDFContentInstance *uci;
     real ReadF;
     int ReadI;
     int IsExceptionNode = 0;
@@ -3212,13 +3171,11 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
 
         SubMode = la_ReadShort(udf);
         if (SubMode == LA_UDF_SHARE_RESOURCE){
-            if (!Parent){
-                la_ReadString(udf, buf);
-                laSetActiveInstance(p, pp->LastPs->UseInstance, la_FindSharedResouce(buf));
-            }
+            la_ReadString(udf, buf);
+            laSetActiveInstance(p, pp->LastPs->UseInstance, la_FindSharedResouce(buf));
         }elif (SubMode == LA_UDF_REFER){
             Instance = la_ReadPointer(udf);
-            if (Instance && !Parent && p->Offset>=0){
+            if (Instance && p->Offset>=0){
                 if (p->OffsetIsPointer) la_AddPtrSyncCommand(Instance, ParentInst, 0, p);
                 else la_AddDataInst(Instance, 0, ((BYTE *)pp->LastPs->UseInstance + p->Offset));
             }
@@ -3226,7 +3183,7 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
             char NUID[32]={0};
             NUID[0] = 0;
             la_ReadString(udf, NUID);
-            if (NUID[0] && !Parent){
+            if (NUID[0]){
                 la_AddPtrSyncCommand(0, ParentInst, NUID, p);
             }
         }elif (SubMode == LA_UDF_COLLECTION){
@@ -3244,7 +3201,6 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                 laPropIterator PI = {0};
 
                 ItemType = la_ReadShort(udf);
-                if (Parent) uci = la_AppendUDFContentInstance(Parent, la_Tell(udf));
 
                 Instance = laGetInstance(p, pp->LastPs->UseInstance, &PI);
 
@@ -3252,7 +3208,7 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
 
                 if (ItemType == LA_UDF_HYPER_ITEM){
                     if (p->SubProp->Hyper == 2){
-                        if (!Parent && !IsExceptionNode) la_ReadHyperData(udf, Instance);
+                        if (!IsExceptionNode) la_ReadHyperData(udf, Instance);
                         else la_ReadHyperData(udf, 0);
                         if(mUDF) memAssignRef(Instance, &((laMemNodeHyper*)memGetHead(Instance, 0))->FromFile, mUDF);
                         memMarkClean(Instance);
@@ -3260,16 +3216,16 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                     if(Mode==LA_UDF_MODE_APPEND){ lstAppendPointer(&MAIN.RenewHyper2s,Instance); }
                 }
 
-                if (!Parent && p->SubProp->PostRead) la_AddPostReadNode(Instance, p->SubProp->PostRead);
+                if (p->SubProp->PostRead) la_AddPostReadNode(Instance, p->SubProp->PostRead);
 
                 ReadInstance = la_ReadPointer(udf);
                 ReadState = la_ReadInt(udf);
 
-                if (!Parent) ThisDBInst=Instance;
+                ThisDBInst=Instance;
 
                 PropNumPerItem = la_ReadShort(udf);
                 for (j = 0; j < PropNumPerItem; j++){
-                    int result; laUDFContentNode *ucn;
+                    int result;
                     la_ReadString(udf, buf);
                     subp = la_PropLookup(&p->SubProp->Props, buf);
                     SubPP.RawThis = pp;
@@ -3277,17 +3233,12 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                     SubPS.UseInstance = Instance;
                     if ((!subp) ||subp->UDFIgnore){la_ExtractFakeProp(udf); continue;}
                     if (subp&&!subp->SubProp){ subp->SubProp = la_ContainerLookup(((laSubProp *)subp)->TargetID); }
-                    if (subp&& Parent && subp->PropertyType == LA_PROP_SUB){
-                        if (!subp->UDFIsRefer && !IsExceptionNode){
-                            ucn = la_AppendUDFContentNode(uci, &SubPP, la_Tell(udf));
-                            result = la_ExtractProp(udf, mUDF, &SubPP, ThisDBInst, Mode, ucn);
-                        }else{ result = la_ExtractFakeProp(udf);}
-                    }else{
-                        result = (IsExceptionNode||!subp) ? result = la_ExtractFakeProp(udf) : la_ExtractProp(udf, mUDF, &SubPP, ThisDBInst, Mode, Parent);
-                    }
+                    
+                    result = (IsExceptionNode||!subp) ? result = la_ExtractFakeProp(udf) : la_ExtractProp(udf, mUDF, &SubPP, ThisDBInst, Mode);
+                    
                     EStatus = result ? result : EStatus;
                 }
-                if (!Parent && p->SubProp->PostReadIm) p->SubProp->PostReadIm(Instance);
+                if (p->SubProp->PostReadIm) p->SubProp->PostReadIm(Instance);
             }else{
                 if(Mode==LA_UDF_MODE_APPEND && p->UDFIsSingle){
                     logPrint("[Note] Mode is APPEND but property '%s' only allows one instance, will overwrite.\n", p->Identifier);
@@ -3302,8 +3253,6 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
 
                     ItemType = la_ReadShort(udf);
 
-                    if (Parent) uci = la_AppendUDFContentInstance(Parent, la_Tell(udf));
-
                     if(p->UDFReadProgress){ laShowProgress((real)i/NumItems,-1); } //printf("add pc %s\n",pc->Identifier);
 
                     if(pc==LA_PC_SOCKET_OUT || pc==LA_PC_SOCKET_IN){ laGraphRequestRebuild(); }
@@ -3312,7 +3261,7 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                     if (udf){
                         int IsItem=((laSubProp*)p)->ListHandleOffset?1:0;
                         RealSize = RealSize ? RealSize : p->SubProp->NodeSize;
-                        if (!Parent && !IsExceptionNode){
+                        if (!IsExceptionNode){
                             if (p->UDFIsSingle && (pp->EndInstance=laGetActiveInstanceStrict(pp->LastPs->p,pp->LastPs->UseInstance))){ 
                                 Instance = pp->EndInstance; la_ResetInstance(Instance, pc, IsItem); replaced=1;
                             }
@@ -3340,14 +3289,14 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                             else la_ReadHyperData(udf, 0);
                             if(Mode==LA_UDF_MODE_APPEND){ lstAppendPointer(&MAIN.RenewHyper2s,Instance); }
                         }
-                        if (!Parent && !IsExceptionNode){
+                        if (!IsExceptionNode){
                             if (pc->PostRead) la_AddPostReadNode(Instance, pc->PostRead);
                         }
 
                         ReadInstance = la_ReadPointer(udf);
                         ReadState = la_ReadInt(udf);
 
-                        if (!Parent && !IsExceptionNode && !replaced){
+                        if (!IsExceptionNode && !replaced){
                             la_AddDataInst(ReadInstance, pc->Hyper == 2 ? ((laMemNodeHyper *)memGetHead(Instance,0))->NUID.String : 0, Instance);
                         }
                         ThisDBInst = Instance;
@@ -3359,23 +3308,18 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
                             subp = la_PropLookup(&pc->Props, buf);
                             if ((!subp) || subp->UDFIgnore) la_ExtractFakeProp(udf);
                             else{
-                                int result; laUDFContentNode *ucn;
+                                int result;
                                 ThisSeek = la_Tell(udf);
                                 SubPP.RawThis = pp; SubPS.p = subp; SubPS.UseInstance = Instance;
                                 la_EnsureSubTarget(subp, 0);
-                                if (Parent && subp->PropertyType == LA_PROP_SUB && subp->SubProp){
-                                    if (!subp->UDFIsRefer && !IsExceptionNode){
-                                        ucn = la_AppendUDFContentNode(uci, &SubPP, ThisSeek);
-                                        result = la_ExtractProp(udf, mUDF, &SubPP, ThisDBInst, Mode, ucn);
-                                    }else{ result = la_ExtractFakeProp(udf); }
-                                }else{
-                                    result = IsExceptionNode ? la_ExtractFakeProp(udf) : la_ExtractProp(udf, mUDF, &SubPP, ThisDBInst, Mode, Parent);
-                                }
+                                
+                                result = IsExceptionNode ? la_ExtractFakeProp(udf) : la_ExtractProp(udf, mUDF, &SubPP, ThisDBInst, Mode);
+                                
                                 EStatus = result ? result : EStatus;
                             }
                         }
 
-                        if (!Parent && !IsExceptionNode && !replaced){
+                        if (!IsExceptionNode && !replaced){
                             if (pc->PostReadIm) pc->PostReadIm(Instance);
                             if (pp->LastPs->UseInstance){
                                 if (!p->UDFIsSingle){
@@ -3398,30 +3342,18 @@ int la_ExtractProp(laUDF *udf, laManagedUDF* mUDF, laPropPack *pp, void *ParentI
         break;
     case LA_PROP_INT:
     case LA_PROP_ARRAY | LA_PROP_INT:
-        ReadI = la_ReadIntProp(udf, Parent ? 0 : pp);
-        if (Parent && p->Tag & LA_AS_IDENTIFIER){
-            sprintf(buf, "%d", ReadI); strSafeSet(&((laUDFContentInstance *)Parent->Instances.pLast)->Identifier, buf);
-        }
+        ReadI = la_ReadIntProp(udf, pp);
         break;
     case LA_PROP_FLOAT:
     case LA_PROP_ARRAY | LA_PROP_FLOAT:
-        ReadF = la_ReadFloatProp(udf, Parent ? 0 : pp);
-        if (Parent && p->Tag & LA_AS_IDENTIFIER){
-            sprintf(buf, "%lf", ReadF); strSafeSet(&((laUDFContentInstance *)Parent->Instances.pLast)->Identifier, buf);
-        }
+        ReadF = la_ReadFloatProp(udf, pp);
         break;
     case LA_PROP_STRING:
-        if (Parent && p->Tag & LA_AS_IDENTIFIER){
-            la_ReadStringPropAsIdentifier(udf, buf); strSafeSet(&((laUDFContentInstance *)Parent->Instances.pLast)->Identifier, buf);
-        }else{
-            la_ReadStringProp(udf, Parent ? 0 : pp);
-        }
+        la_ReadStringProp(udf, pp);
         break;
     case LA_PROP_ENUM:
     case LA_PROP_ARRAY | LA_PROP_ENUM:
-        la_ReadEnumProp(udf, Parent ? 0 : pp, buf);
-        if (Parent && p->Tag & LA_AS_IDENTIFIER){
-            strSafeSet(&((laUDFContentInstance *)Parent->Instances.pLast)->Identifier, buf); }
+        la_ReadEnumProp(udf, pp, buf);
         break;
     case LA_PROP_RAW:
         la_ReadRawProp(udf, pp);
@@ -3442,6 +3374,31 @@ int la_RematchPointers(int Mode){
     while(inst=lstPopPointer(&MAIN.RenewHyper2s)){ laMemNodeHyper* h=memGetHead(inst,0);memMakeHyperData(h);memAssignRef(h,&h->FromFile,0);  }
 }
 
+
+int la_WriteHyperRecords(laUDF *udf){
+    int i = 0;
+    u64bit CountSeek = la_Tell(udf);
+    u64bit EndSeek;
+    laUDFHyperRecordItem *hri;
+    laMemNodeHyper* h;
+    la_WriteLong(udf, 0);
+    while (hri = lstPopItem(&udf->HyperRecords)){
+        h=memGetHead(hri->HyperUserMem, 0);
+        la_WriteString(udf, h->NUID.String);
+        if(hri->pc) la_WriteString(udf, hri->pc->Identifier); else la_WriteString(udf, "");
+        la_WritePointer(udf, hri->Seek);
+        i++; memFree(hri);
+    }
+    EndSeek = la_Tell(udf);
+    la_Seek(udf, CountSeek); la_WriteLong(udf, i); la_Seek(udf, EndSeek);
+
+    return i;
+}
+int la_WritePropQuickSeek(laUDF *udf){
+    for(laUDFPropSegment* ps=udf->PropsToOperate.pFirst;ps;ps=ps->Item.pNext){
+        la_WriteString(udf,SSTR(ps->Path)); la_WriteLong(udf,ps->WriteQuickSeek);
+    }
+}
 int laPackUDF(laUDF *udf, int UseInstanceList, int DoBackup){
     laUDFPropSegment *ps;
     short NumSegments = 0;
@@ -3481,39 +3438,51 @@ int laPackUDF(laUDF *udf, int UseInstanceList, int DoBackup){
 
     udf->CurrentH2Instance=udf->H2Instances.pFirst;
 
-    while (ps = lstPopItem(&udf->PropsToOperate)){
+    for(laUDFPropSegment* ps=udf->PropsToOperate.pFirst;ps;ps=ps->Item.pNext){
         printf("    %-15s\n", ps->Path ? ps->Path->Ptr : ps->PPP->LastPs->p->Identifier);
+        ps->WriteQuickSeek = la_Tell(udf);
         la_WriteProp(udf, ps->PPP ? ps->PPP : &ps->PP, ps->PPP ? 1 : 0, UseInstanceList);
-        la_FreePropStepCache(ps->PP.Go);
-        strSafeDestroy(&ps->Path);
-        FreeMem(ps);
     }
     logPrint("[ALL DONE]\n\n");
 
     nuidActualSeek = la_Tell(udf);
 
+    la_WritePropQuickSeek(udf);
     la_WriteHyperRecords(udf);
 
     u64bit ActualSize=la_Tell(udf);
 
-    la_Seek(udf, RefPos);
-    la_WriteLong(udf, udf->TotalRefs);
-
-    la_Seek(udf, nuidSeekRef);
-    la_WritePointer(udf, nuidActualSeek);
-
-    la_Seek(udf, SizeAndExt);
-    la_WritePointer(udf, (ActualSize&(0x0000ffffffffffff))<<16);
+    la_Seek(udf, RefPos); la_WriteLong(udf, udf->TotalRefs);
+    la_Seek(udf, nuidSeekRef); la_WritePointer(udf, nuidActualSeek);
+    la_Seek(udf, SizeAndExt); la_WritePointer(udf, ((ActualSize&(0x0000ffffffffffff))<<16)|LA_UDF_EXTENSIONS_ENABLED);
 
     udf->Modified = 0;
 
+    while(ps = lstPopItem(&udf->PropsToOperate)){
+        la_FreePropStepCache(ps->PP.Go);
+        strSafeDestroy(&ps->Path);
+        FreeMem(ps);
+    }
+
     laCloseUDF(udf);
 
     laHideProgress();
 
     return 1;
 }
-int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode, laListHandle *Parent){
+
+void laExtractProp(laUDF *udf, char* Path){
+    laUDFPropSegment *ps = CreateNew(laUDFPropSegment);
+    strSafeSet(&ps->Path, Path);
+}
+int la_PropIsSelected(laUDF* udf, char* Path){
+    if(!udf->PropsToOperate.pFirst) return 1;
+    for(laUDFPropSegment* ps=udf->PropsToOperate.pFirst;ps;ps=ps->Item.pNext){
+        if(strSame(SSTR(ps->Path),Path)) return 1;
+    }
+    return 0;
+}
+int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode){
     char Identifier[9] = {0};
     char buf[1024]={0};
     short Version, NumSegments;
@@ -3524,7 +3493,6 @@ int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode, laListHandle *Parent)
     int EStatus = 0;
     u64bit SeekRef;
     int IsPart;
-    laUDFContentNode *ucni = Parent;
 
     ma_device_stop(&MAIN.Audio->AudioDevice);
     if(MAIN.InitArgs.HasAudio) laSpinLock(&MAIN.Audio->AudioStatusLock);
@@ -3535,7 +3503,7 @@ int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode, laListHandle *Parent)
 
     // file size verification and extension switches.
     u64bit verification=la_ReadPointer(udf);
-    u64bit FileSize=verification>>16; int Extensions=verification&0xffff;
+    u64bit FileSize=verification>>16; int Extensions=verification&LA_UDF_ALL_EXTENSIONS;
     if(FileSize && FileSize<la_FileSize(udf)){ logPrintNew("UDF verification failed for %s\n", udf->FileName->Ptr); return 0; }
 
     /*udf->TotalRefs = */ la_ReadLong(udf);
@@ -3543,58 +3511,81 @@ int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode, laListHandle *Parent)
     la_ReadLong(udf); //seek mark
     SeekRef = la_ReadPointer(udf);
 
-    logPrintNew("Extracting UDF %s:\n", udf->FileName->Ptr);
+    logPrintNew("Extracting UDF [0x%x] %s:\n", udf->Extensions, udf->FileName->Ptr);
 
     //MAIN.NextPendingPointer = 0;
     //MAIN.PendingPointers = CreateNewBuffer(laUDFPointerRecord, udf->TotalRefs);
 
     //SubPP.LastPs = &SubP;
 
-    if (!udf->PropsToOperate.pFirst){ //Extract All
-        for (i = 0; i < NumSegments; i++){
-            laUDFContentNode *ucn;
-            laUDFContentInstance *uci;
-            void *dbi = 0;
-            int result;
-            int LastOffset;
-            la_ReadString(udf, buf);
-            LastOffset = strlen(buf) - 1;
-            buf[LastOffset] = buf[LastOffset] == U'.' ? 0 : buf[LastOffset];
-            logPrint("    Prop Segment \"%s\" ...\n", buf);
-            la_GetPropFromPath(&SubPP, 0, buf, 0);
-            la_StepPropPack(&SubPP);
-            if (Parent){
-                ucni = CreateNew(laUDFContentNode);
-                la_GetPropFromPath(&ucni->PP, 0, buf, 0);
-                la_StepPropPack(&ucni->PP);
-                strSafeSet(&ucni->FullPath, buf);
-                strSafeSet(&ucni->Identifier, buf);
-                ucni->FileSeek = la_Tell(udf);
-                lstAppendItem(Parent, ucni);
-            }
-            dbi = SubPP.EndInstance; //la_GetWriteDBInst(SubPP.EndInstance);
-            result = (SubPP.LastPs&&SubPP.LastPs->p)?
-                la_ExtractProp(udf, mUDF, &SubPP, dbi, Mode, ucni):
-                la_ExtractFakeProp(udf);
-            EStatus = result ? result : EStatus;
-            laNotifyUsersPP(&SubPP);
-            logPrint("    [Done]\n", buf);
-            la_FreePropStepCache(SubPP.Go);
-            SubPP.Go = 0;
-        }
+    for (i = 0; i < NumSegments; i++){
+        void *dbi = 0;
+        int result, LastOffset, selected=0;
+        la_ReadString(udf, buf);
+        LastOffset = strlen(buf) - 1;
+        buf[LastOffset] = buf[LastOffset] == U'.' ? 0 : buf[LastOffset];
+        logPrint("    Prop Segment \"%s\" ...", buf);
+        selected = la_PropIsSelected(udf, buf);
+        la_GetPropFromPath(&SubPP, 0, buf, 0);
+        la_StepPropPack(&SubPP);
+        dbi = SubPP.EndInstance; //la_GetWriteDBInst(SubPP.EndInstance);
+        result = (SubPP.LastPs&&SubPP.LastPs->p&&selected)?
+            la_ExtractProp(udf, mUDF, &SubPP, dbi, Mode):
+            la_ExtractFakeProp(udf);
+        EStatus = result ? result : EStatus;
+        //if(SubPP.LastPs->p->PropertyType!=LA_PROP_RAW){
+        //    laNotifyUsersPP(&SubPP);
+        //}
+        logPrint(" [Done]\n", buf);
+        la_FreePropStepCache(SubPP.Go);
+        SubPP.Go = 0;
     }
 
     la_RematchPointers(Mode);
-
+    
     laHideProgress();
-
+    
     MAIN.IsReadingUDF = 0;
 
+    laUDFPropSegment* ps; while (ps = lstPopItem(&udf->PropsToOperate)){ strSafeDestroy(&ps->Path); FreeMem(ps); }
+
     if(MAIN.InitArgs.HasAudio) laSpinUnlock(&MAIN.Audio->AudioStatusLock);
 
     return EStatus;
 }
 
+int laExtractQuickRaw(FILE* fp, char* path, uint8_t** buf, size_t* size){
+    laUDF _udf={0},*udf=&_udf; udf->DiskFile = fp;
+    char str[128];
+    char Identifier[32];
+    la_Seek(udf,0);
+    la_ReadBuffer(udf, sizeof(LA_UDF_IDENTIFIER) - 1, Identifier);
+    u64bit verification=la_ReadPointer(udf);
+    u64bit FileSize=verification>>16; int Extensions=verification&LA_UDF_ALL_EXTENSIONS;
+    if(FileSize && FileSize<la_FileSize(udf)){ return 0; }
+    if(!(Extensions & LA_UDF_EXTENSION_QUICK_SEEK)){ return 0; }
+
+    /*udf->TotalRefs = */ la_ReadLong(udf);
+    short NumSegments = la_ReadShort(udf);
+    la_ReadLong(udf); //seek mark
+    off_t SeekRef = la_ReadPointer(udf);
+
+    la_Seek(udf,SeekRef);
+
+    for(int i=0;i<NumSegments;i++){
+        la_ReadString(udf,str);
+        int Seek = la_ReadLong(udf);
+        if(strSame(str,path)){
+            la_Seek(udf,Seek);
+            la_ReadString(udf, str); // prop name
+            la_ReadShort(udf);// raw mark
+            void* data=la_ReadRaw(udf,size);
+            *buf=data; if(data){ return 1; }
+            break;
+        }
+    }
+    return 0;
+}
 
 laManagedUDF* la_FindManagedUDF(char* FileName){
     for(laManagedUDF* m=MAIN.ManagedUDFs.pFirst;m;m=m->Item.pNext){
@@ -3617,16 +3608,28 @@ void la_MakeDummyManagedUDF(){
         MAIN.DummyManageUDFSingleForce=memAcquire(sizeof(laManagedUDF)); strSafeSet(&MAIN.DummyManageUDFSingleForce->BaseName, "< Force >");
     }
 }
-void laSaveProp(char* path){
+laManagedSaveProp* laSaveProp(char* path){
     if(!path || !path[0]) return; laManagedSaveProp* msp=0;
     for(laManagedSaveProp* m=MAIN.ManagedSaveProps.pFirst;m;m=m->Item.pNext){
         if(!strcmp(m->Path->Ptr,path)){ msp=m; break; }
     }
     if(!msp){ msp=memAcquireSimple(sizeof(laManagedSaveProp)); lstAppendItem(&MAIN.ManagedSaveProps, msp); }
     strSafeSet(&msp->Path, path);
+    return msp;
+}
+void laSaveAlongside(laManagedSaveProp* parent, char* path){
+    if(!path || !path[0] || !parent) return; laManagedSaveProp* msp=0;
+    for(laManagedSaveProp* m=parent->SaveAlongside.pFirst;m;m=m->Item.pNext){
+        if(!strcmp(m->Path->Ptr,path)){ msp=m; break; }
+    }
+    if(!msp){ msp=memAcquireSimple(sizeof(laManagedSaveProp)); lstAppendItem(&parent->SaveAlongside, msp); }
+    strSafeSet(&msp->Path, path);
 }
 void laClearSaveProp(){
-    laManagedSaveProp* m; while(m=lstPopItem(&MAIN.ManagedSaveProps)) { strSafeDestroy(&m->Path); memFree(m); }
+    laManagedSaveProp* m; while(m=lstPopItem(&MAIN.ManagedSaveProps)) {
+        laManagedSaveProp* ma; while(ma=lstPopItem(&m->SaveAlongside)){ strSafeDestroy(&ma->Path); memFree(ma); }
+        strSafeDestroy(&m->Path); memFree(m);
+    }
 }
 
 int la_ScanForModifiedRecursive(laPropPack* pp, int ReturnIfAnyMod, int ReturnIfAnyEmpty, int* rempty, int RegisterToUDF){
@@ -3673,7 +3676,12 @@ int laRegisterModifications(int ReturnIfAnyMod, int ReturnIfAnyEmpty, int* rempt
             result|=la_ScanForModifiedRecursive(&PP, ReturnIfAnyMod, ReturnIfAnyEmpty, rempty, RegisterToUDF);
             for(laManagedUDF* m=MAIN.ManagedUDFs.pFirst;m;m=m->Item.pNext){
                 if(!m->udf)continue;
-                if(m->udf->HasInstances){ laWriteProp(m->udf,msp->Path->Ptr); m->udf->HasInstances=0; }
+                if(m->udf->HasInstances){ laWriteProp(m->udf,SSTR(msp->Path));
+                    for(laManagedSaveProp* am=msp->SaveAlongside.pFirst;am;am=am->Item.pNext){
+                        laWriteProp(m->udf,SSTR(am->Path));
+                    }
+                    m->udf->HasInstances=0;
+                }
             }
             if((ReturnIfAnyMod||ReturnIfAnyEmpty)&&result)return result;
             la_FreePropStepCache(PP.Go);
@@ -3717,26 +3725,15 @@ void la_ReadOwnHyperItems(laUDF *udf, laUDFRegistry* r){
         } else {logPrint("Duplicated Resource: %s | %s\n",uid.String,name);}
     }
 }
-int la_WriteHyperRecords(laUDF *udf){
-    int i = 0;
-    u64bit CountSeek = la_Tell(udf);
-    u64bit EndSeek;
-    laUDFHyperRecordItem *hri;
-    laMemNodeHyper* h;
-    la_WriteLong(udf, 0);
-    while (hri = lstPopItem(&udf->HyperRecords)){
-        h=memGetHead(hri->HyperUserMem, 0);
-        la_WriteString(udf, h->NUID.String);
-        if(hri->pc) la_WriteString(udf, hri->pc->Identifier); else la_WriteString(udf, "");
-        la_WritePointer(udf, hri->Seek);
-        i++; memFree(hri);
+int la_ReadPropQuickSeek(laUDF *udf){
+    char* buf[128];
+    for(int i=0;i<udf->NumSegmets;i++){
+        laUDFPropQuickSeek *qs = memAcquireSimple(sizeof(laUDFPropQuickSeek));
+        la_ReadString(udf,buf); strSafeSet(&qs->Path,buf);
+        qs->QuickSeek = la_ReadLong(udf);
+        lstAppendItem(&udf->QuickSeeks,qs);
+        logPrint("    QuickSeek 0x%x %s\n",qs->QuickSeek,SSTR(qs->Path));
     }
-    EndSeek = la_Tell(udf);
-    la_Seek(udf, CountSeek);
-    la_WriteLong(udf, i);
-    la_Seek(udf, EndSeek);
-
-    return i;
 }
 
 laUDF *laOpenUDF(char *FileName, int ReadToMemory, laUDFRegistry* ReadRegistryRef, laManagedUDF** UseManaged){
@@ -3764,6 +3761,13 @@ laUDF *laOpenUDF(char *FileName, int ReadToMemory, laUDFRegistry* ReadRegistryRe
     }
 
     extensions = la_ReadPointer(udf);
+    udf->Extensions = extensions & LA_UDF_ALL_EXTENSIONS;
+    if((udf->Extensions | LA_UDF_EXTENSIONS_ENABLED)!=LA_UDF_EXTENSIONS_ENABLED){
+        logPrint("Unsupported UDF extension 0x%x (0x%x enabled), it's probably saved with a newer version of the program.\n",
+            udf->Extensions,LA_UDF_EXTENSIONS_ENABLED);
+        laCloseUDF(udf);
+        return 0;
+    }
 
     udf->TotalRefs = la_ReadLong(udf);   //total refs
     udf->NumSegmets = la_ReadShort(udf); //num segments
@@ -3772,6 +3776,9 @@ laUDF *laOpenUDF(char *FileName, int ReadToMemory, laUDFRegistry* ReadRegistryRe
     la_Seek(udf, SeekRef);
 
     if(ReadRegistryRef){
+        if(udf->Extensions & LA_UDF_EXTENSION_QUICK_SEEK){
+            la_ReadPropQuickSeek(udf);
+        }
         la_ReadOwnHyperItems(udf, ReadRegistryRef);
     }
 
@@ -3785,11 +3792,13 @@ void laCloseUDF(laUDF *udf){
     laUDFOwnHyperItem *ohi;
     laUDFHyperRecordItem *hri;
     laUDFPropSegment *ps;
+    laUDFPropQuickSeek *qs;
 
     if (udf->DiskFile){ fclose(udf->DiskFile); udf->DiskFile=0; };
 
     while (lstPopPointer(&udf->OwnHyperItems));
     while (lstPopPointer(&udf->HyperRecords));
+    while (qs = lstPopItem(&udf->QuickSeeks)){ strSafeDestroy(&qs->Path); memFree(qs); }
 
     if(udf->CurrentH2Instance){ logPrint("[WARN] udf->CurrentH2Instance!=0 after UDF packing.\n"); udf->CurrentH2Instance=0; }
 

+ 19 - 21
la_data.h

@@ -438,11 +438,17 @@ STRUCTURE(laPtrSyncCommand){
     laUID ReadNUID;
 };
 
+STRUCTURE(laUDFPropQuickSeek){
+    laListItem Item;
+    laSafeString *Path;
+    off_t QuickSeek;
+};
 STRUCTURE(laUDFPropSegment){
     laListItem Item;
     laPropPack *PPP;
     laPropPack PP;
     laSafeString *Path;
+    off_t WriteQuickSeek;
 };
 STRUCTURE(laUDFH2Instance){
     laListItem Item;
@@ -451,6 +457,7 @@ STRUCTURE(laUDFH2Instance){
 };
 STRUCTURE(laUDF){
     int Opened;
+    int Extensions;
     FILE *DiskFile;
     laSafeString *FileName;
 
@@ -458,6 +465,7 @@ STRUCTURE(laUDF){
     laUDFH2Instance* CurrentH2Instance;
     
     laListHandle PropsToOperate;
+    laListHandle QuickSeeks;
     //laListHandle  PointerSync;
     //laListHandle  PointerRecording;
     short NumSegmets;
@@ -505,24 +513,7 @@ STRUCTURE(laManagedUDF){
 STRUCTURE(laManagedSaveProp){
     laListItem Item;
     laSafeString* Path;
-};
-NEED_STRUCTURE(laUDFContentInstance);
-STRUCTURE(laUDFContentNode){
-    laListItem Item;
-    laListHandle Instances;
-    laSafeString *Identifier;
-    laSafeString *FullPath;
-    unsigned long FileSeek;
-    laPropPack PP;
-    laPropStep FakePS;
-    laUDFContentInstance *Parent;
-};
-STRUCTURE(laUDFContentInstance){
-    laListItem Item;
-    laSafeString *Identifier;
-    u64bit FileSeek;
-    laUDFContentNode *Parent;
-    laListHandle Children;
+    laListHandle SaveAlongside;
 };
 
 
@@ -722,8 +713,11 @@ STRUCTURE(laActionRetarget){
 
 #define LA_UDF_EXTENSION_FLOAT32 (1<<0)
 #define LA_UDF_EXTENSION_RAW (1<<1)
+#define LA_UDF_EXTENSION_QUICK_SEEK (1<<2)
+
+#define LA_UDF_EXTENSIONS_ENABLED (LA_UDF_EXTENSION_RAW|LA_UDF_EXTENSION_QUICK_SEEK)
 
-#define LA_UDF_EXTENSION_BITS (LA_UDF_EXTENSION_RAW)
+#define LA_UDF_ALL_EXTENSIONS 0xffff
 
 #define LA_UDF_MARK_TIMESTAMP 3
 
@@ -985,14 +979,18 @@ int laWriteProp(laUDF *udf, char *Path);
 int laWritePropP(laUDF *udf, laPropPack *pp);
 int laPackUDF(laUDF *udf, int UseInstanceList, int DoBackup);
 
-void laSaveProp(char* path);
+laManagedSaveProp* laSaveProp(char* path);
+void laSaveAlongside(laManagedSaveProp* parent, char* path);
 void laClearSaveProp();
 
 int laRegisterModifications(int ReturnIfAnyMod, int ReturnIfAnyEmpty, int* rempty, int RegisterToUDF);
 
 laUDF *laOpenUDF(char *FileName, int ReadToMemory, laUDFRegistry* ReadRegistryRef, laManagedUDF** UseManaged);
 void laCloseUDF(laUDF *udf);
-int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode, laListHandle *Parent);
+void laExtractProp(laUDF *udf, char* Path);
+int laExtractUDF(laUDF *udf, laManagedUDF* mUDF, int Mode);
+
+int laExtractQuickRaw(FILE* fp, char* path, uint8_t** buf, size_t* size);
 
 int laLoadHyperResources(char* uid_search);
 

+ 0 - 3
la_interface.h

@@ -580,8 +580,6 @@ STRUCTURE(LA){
 
     //laThemeColor *ConditionStackColors[6];
 
-    laUDFContentNode TEST_Link;
-
     laListHandle MediaFiles;
 
     int GraphNeedsRebuild; // current mechanism only allows global.
@@ -2179,7 +2177,6 @@ STRUCTURE(laFileBrowser){
 
 STRUCTURE(laUDFPreviewExtra){
     laUDF *UDF;
-    laListHandle ContentNodes;
     int Opened;
     int Append;
 };

+ 1 - 1
la_kernel.c

@@ -1387,7 +1387,7 @@ void laEnsureUserPreferences(){
     laClearUDFRegistries();
     while(MAIN.ResourceFolders.pFirst){ laRemoveResourceFolder(MAIN.ResourceFolders.pFirst); }
     while(MAIN.InputMapping->InputMappings.pFirst){ laRemoveInputMapping(MAIN.InputMapping->InputMappings.pFirst); }
-    laExtractUDF(udf,0,LA_UDF_MODE_OVERWRITE,0);
+    laExtractUDF(udf,0,LA_UDF_MODE_OVERWRITE);
     laCloseUDF(udf);
     la_RemoveDuplicatedScreenConf();
     la_RemoveDuplicatedControllers();

+ 2 - 10
resources/la_operators.c

@@ -531,15 +531,8 @@ int OPMOD_FileBrowserConfirm(laOperator *a, laEvent *e){
     return LA_RUNNING;
 }
 
-void la_DestroyUDFContentNodeTreeRecursive(laUDFContentNode* ucn, int FreeRoot);
 void OPEXT_UDFOperation(laOperator *a, laEvent *e){
     laUDFPreviewExtra *upe = a->CustomData;
-    laUDFContentNode *ucni, *NextUCNI;
-    for (ucni = upe->ContentNodes.pFirst; ucni; ucni = NextUCNI){
-        NextUCNI = ucni->Item.pNext;
-        la_FreePropStepCache(ucni->PP.Go);
-        la_DestroyUDFContentNodeTreeRecursive(ucni, 1);
-    }
     memFree(upe);
 }
 int OPINV_UDFRead(laOperator *a, laEvent *e){
@@ -558,7 +551,7 @@ int OPMOD_UDFRead(laOperator *a, laEvent *e){
             if (upe->UDF){
                 laFreeNewerDifferences();
                 laFreeOlderDifferences(1);
-                laExtractUDF(upe->UDF, m, upe->Append?LA_UDF_MODE_APPEND:LA_UDF_MODE_OVERWRITE, 0);
+                laExtractUDF(upe->UDF, m, upe->Append?LA_UDF_MODE_APPEND:LA_UDF_MODE_OVERWRITE);
                 laCloseUDF(upe->UDF);
                 laRecordEverythingAndPush(); laNotifyUsers("la.differences");
                 return LA_FINISHED;
@@ -2296,8 +2289,7 @@ void la_RegisterBuiltinOperators(){
     at = laCreateOperatorType("LA_udf_read", "Read", "Read a UDF file", 0, 0, OPEXT_UDFOperation, OPINV_UDFRead, OPMOD_UDFRead, U'📑', LA_ACTUATOR_SYSTEM);
     pc = laDefineOperatorProps(at, 0);
     at->UiDefine = laui_LinkerPanel;
-    laAddSubGroup(pc, "root_nodes", "UDF Nodes", "List Of All Linkable/Appendable Nodes In The File", "udf_content_node",0, 0, laui_LinkerSelectionProp, -1, 0, 0, 0, 0, 0, 0, offsetof(laUDFPreviewExtra, ContentNodes), 0);
-
+    
     at = laCreateOperatorType("LA_udf_save_instance", "Save Instance", "Save a instance as a UDF block", 0, 0, OPEXT_UDFOperation, OPINV_UDFSaveInstance, OPMOD_UDFSaveInstance, U'📑', LA_ACTUATOR_SYSTEM);
 
     at = laCreateOperatorType("LA_managed_save", "Save as", "Save managed data blocks", 0, 0, OPEXT_ManagedSave, OPINV_ManagedSave, OPMOD_ManagedSave, U'🖫', LA_ACTUATOR_SYSTEM);

+ 1 - 27
resources/la_properties.c

@@ -459,15 +459,6 @@ void laget_MainIdentifier(laUDF *udf, char *result, char** here){
 void laget_UDFFilePath(laUDF *udf, char *result, char** here){
     *here=udf->FileName->Ptr;
 }
-void laget_UDFContentNodeFullPath(laUDFContentNode *ucn, char *result, char** here){
-    if (ucn->FullPath && ucn->FullPath->Ptr) *here=ucn->FullPath->Ptr;
-}
-void laget_UDFContentNodeIdentifier(laUDFContentNode *ucn, char *result, char** here){
-    if (ucn->Identifier && ucn->Identifier->Ptr) *here=ucn->Identifier->Ptr;
-}
-void laget_UDFContentInstanceIdentifier(laUDFContentInstance *uci, char *result, char** here){
-    if (uci->Identifier && uci->Identifier->Ptr) *here=uci->Identifier->Ptr;
-}
 
 void lapost_PropPack(laPropPack *pp);
 void laget_ConditionNodePropPath(laUiConditionNode *ucn, char *result, char** here){
@@ -1573,8 +1564,7 @@ void la_RegisterInternalProps(){
             laAddSubGroup(p,"filtered_signals","Filtered Signals","Filtered custom signals","la_custom_signal",0,0,laui_IdentifierOnly,-1,laget_FirstFilteredCustomSignal,0,lagetnext_FilteredSignal,0,0,0,0,LA_UDF_IGNORE);
             
             laAddStringProperty(p, "identifier", "Identifier", "Identifier", 0,0,0,0,0,0,0,laget_MainIdentifier, 0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
-            laAddSubGroup(p, "test_ucn", "TEST UCN", "---", "udf_content_node",0,0,0,offsetof(LA, TEST_Link), 0,0,0,0,0,0,0,0);
-            
+  
             ep=laAddEnumProperty(p, "detached_view_switch", "View Detached", "Use detached view on panels", LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(LA, DetachedViewSwitch),0,0,0,0,0,0,0,0,0,LA_UDF_IGNORE);
             laAddEnumItemAs(ep, "LINKED", "Linked", "View is linked to global current states", 0, U'🔗');
             laAddEnumItemAs(ep, "DETACHED", "Detached", "View is detached from global states and is pinned to panel", 1, U'📌');
@@ -1664,22 +1654,6 @@ void la_RegisterInternalProps(){
             laAddEnumItemAs(ep, "CLEAN", "Clean", "File data is untouched", 0,0);
             ep->ElementBytes=2;
         }
-
-        p = laAddPropertyContainer("udf_content_node", "UDF Content Node", "Type Structure For Previewing,Selecting,Linking UDF Contnet", U'🖹', 0,0,0,0,0);{
-            laAddStringProperty(p, "full_path", "Full Path", "Full Path", 0,0,0,0,0,0,0,laget_UDFContentNodeFullPath, 0,0,LA_READ_ONLY);
-            laAddStringProperty(p, "identifier", "Identifier", "Self Identifier", 0,0,0,0,0,0,0,laget_UDFContentNodeIdentifier, 0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
-            laAddIntProperty(p, "file_seek", "File Seek", "Prop Beginner's Location In The File", 0,0,0,0,0,0,0,0,offsetof(laUDFContentNode, FileSeek), 0,0,0,0,0,0,0,0,0,0,LA_READ_ONLY);
-            laAddSubGroup(p, "instances", "Instances", "Instance Nodes (Only SubProps)", "udf_content_instance",0,0,0,-1, 0,0,0,0,0,0,offsetof(laUDFContentNode, Instances), 0);
-            laAddSubGroup(p, "parent", "Parent", "Parent Instance Node", "udf_content_node",0,0,0,offsetof(laUDFContentNode, Parent), 0,0,0,0,0,0,0,LA_UDF_REFER);
-            laAddSubGroup(p, "pc", "Prop Container", "This Property Container", "property_package",0,0,0,offsetof(laUDFContentNode, PP), 0,0,0,0,0,0,0,LA_UDF_LOCAL | LA_UDF_REFER);
-        }
-
-        p = laAddPropertyContainer("udf_content_instance", "UDF Content Instance", "Instance/FileSeek Storage For Previewing,Selecting,Linking UDF Contnet", U'🖹', 0,0,0,0,0);{
-            laAddStringProperty(p, "identifier", "Identifier", "Self Identifier", 0,0,0,0,0,0,0,laget_UDFContentInstanceIdentifier, 0,0,LA_READ_ONLY);
-            laAddIntProperty(p, "file_seek", "File Seek", "Instance's Location In The File", 0,0,0,0,0,0,0,0,offsetof(laUDFContentInstance, FileSeek), 0,0,0,0,0,0,0,0,0,0,LA_AS_IDENTIFIER|LA_READ_ONLY);
-            laAddSubGroup(p, "children", "Children", "Child Properties (Only SubProps)", "udf_content_node",0,0,0,-1, 0,0,0,0,0,0,offsetof(laUDFContentInstance, Children), 0);
-            laAddSubGroup(p, "parent", "Parent", "Parent Property Node", "udf_content_node",0,0,0,offsetof(laUDFContentInstance, Parent), 0,0,0,0,0,0,0,LA_UDF_REFER);
-        }
         
         p = laAddPropertyContainer("managed_prop", "Managed Property", "Managed property for detecting changes for saving files", 0,0,sizeof(laManagedSaveProp), 0,0,0);{
             laAddStringProperty(p, "path", "Path", "Property path", 0,0,0,0,1, offsetof(laManagedSaveProp, Path), 0,0,0,0,LA_READ_ONLY);

+ 1 - 1
resources/la_templates.c

@@ -1462,7 +1462,7 @@ void laui_About(laUiList *uil, laPropPack *Base, laPropPack *OperatorInst, laCol
             laShowLabel(gu, gc, "UDF Extensions:", 0, 0)->Flags|=LA_TEXT_MONO;
             laShowLabel(gu, gc, "🗸LA_UDF_BASICS", 0, 0)->Flags|=LA_TEXT_MONO;
             for(int i=0;i<64;i++){
-                if(!LA_UDF_EXTENSION_STRINGS[i][0]) break; int gray=!((1<<i)&LA_UDF_EXTENSION_BITS);
+                if(!LA_UDF_EXTENSION_STRINGS[i][0]) break; int gray=!((1<<i)&LA_UDF_EXTENSIONS_ENABLED);
                 sprintf(buf,"%s%s",gray?"  ":"🗸",LA_UDF_EXTENSION_STRINGS[i]);
                 laUiItem* ext=laShowLabel(gu, gc, buf, 0, 0); ext->Flags|=LA_TEXT_MONO;
                 if(gray){ ext->Flags|=LA_UI_FLAGS_DISABLED; }