*/}}
Browse Source

node branch masking

YimingWu 1 year ago
parent
commit
b6f381f768
7 changed files with 169 additions and 132 deletions
  1. 16 5
      la_interface.h
  2. 1 1
      la_kernel.c
  3. 1 1
      la_resource.c
  4. 16 2
      la_util.h
  5. 122 93
      resources/la_nodes_basic.c
  6. 1 1
      resources/la_templates.c
  7. 12 29
      resources/la_tns_drivers.c

+ 16 - 5
la_interface.h

@@ -257,7 +257,6 @@ NEED_STRUCTURE(laNodeCategory);
 STRUCTURE(laRackPageCollection){
     laRackPage* CurrentPage;
     laListHandle Pages;
-    laListHandle Eval;
     int NeedEval,NeedRebuild;
 };
 
@@ -1357,6 +1356,10 @@ void la_RegisterInputMapperOperators();
 #define LA_DAG_FLAG_TEMP 1
 #define LA_DAG_FLAG_PERM 2
 
+
+int laRebuildPageEval(laRackPage* rp);
+int laRunPage(laRackPage* rp, uint64_t mask);
+
 void laMappingRequestRebuild();
 void laMappingRequestEval();
 int la_RebuildInputMapping();
@@ -1389,11 +1392,14 @@ void latouched_NodeInSocket(void* unused, int hint);
 #define LA_SRC_AND_PARENT(socket) \
     ((socket)->Source && (socket)->Source->Parent)
 
-#define LA_VISIT_NODE(node) \
-    {int result=node->Type->Visit(node,l); if(result!=LA_DAG_FLAG_PERM) return LA_DAG_FLAG_ERR;}
+#define LA_VISIT_NODE(node,vi) \
+    {if(node){int result=node->Type->Visit(node,vi); if(result!=LA_DAG_FLAG_PERM) return LA_DAG_FLAG_ERR;} }
 
-#define LA_GUARD_THIS_NODE(n) \
-    {if(n->Base.Eval==LA_DAG_FLAG_PERM) return LA_DAG_FLAG_PERM; if(n->Base.Eval==LA_DAG_FLAG_TEMP) return LA_DAG_FLAG_ERR; n->Base.Eval=LA_DAG_FLAG_TEMP; }
+#define LA_GUARD_THIS_NODE(n,vi) \
+    {uint64_t br=vi->Branch; if((n->Base.Branch&br)==br) return LA_DAG_FLAG_PERM; if((n->Base.BranchTemp&br)==br) return LA_DAG_FLAG_ERR; n->Base.BranchTemp|=br; }
+
+#define LA_ADD_THIS_NODE(n,vi) \
+    {uint64_t br=vi->Branch; if(!n->Base.Branch){ lstAppendPointer(vi->l,n); } n->Base.Branch|=br; n->Base.BranchTemp&=(~br); }
 
 extern laBaseNodeType LA_IDN_KEYBOARD;
 extern laBaseNodeType LA_IDN_MOUSE;
@@ -1454,6 +1460,8 @@ STRUCTURE(laRackPage){
     laListItem Item;
     laSafeString* Name;
     laListHandle Racks;
+    laListHandle Eval;
+    laListHandle AlwaysBranchers;
     int RackType;
 };
 #define LA_RACK_TYPE_INPUT (1<<0)
@@ -1505,6 +1513,9 @@ STRUCTURE(laSwitchNode){
     laNodeInSocket* SwitchIn;
     real TempVal;
     int Switch;
+    int MaxUsed;
+    laRackPage* Page;
+    uint64_t BranchSW;
 };
 STRUCTURE(laCombineNode){
     laBaseNode Base;

+ 1 - 1
la_kernel.c

@@ -5129,7 +5129,7 @@ int la_UpdateUiListRecursive(laUiList *uil, int U, int L, int R, int B, int Fast
                     SubB = la_UpdateUiListRecursive(ui->Page,
                         ui->TB + (ui->State == LA_UI_ACTIVE ? 0 : LA_RH)+(NoDecal?0:bt->TM), ui->TL+(NoDecal?0:bt->LM), ui->TR-(NoDecal?0:bt->RM)-scrollw, B, Fast, ParentPanel);
                     ui->TB = (ui->Page->HeightCoeff > 0 ? ui->TU + ui->Page->HeightCoeff * LA_RH :
-                            (ui->Page->HeightCoeff < 0 ? B + (ui->Page->HeightCoeff+1) * LA_RH : SubB)) + (NoDecal?0:bt->TM);
+                            (ui->Page->HeightCoeff < 0 ? B + (ui->Page->HeightCoeff+1) * LA_RH + (_PB+_PT) : SubB)) + (NoDecal?0:bt->BM);
                     int subh = ui->TB-ui->TU-LA_RH-bt->TM-bt->BM;
                     if((ui->Page->TR>ui->TR-(NoDecal?0:bt->RM) && (!ui->Page->ScrollerShownH)) ||
                         (ui->Page->TR<=ui->TR-(NoDecal?0:bt->RM)  && ui->Page->ScrollerShownH)){

+ 1 - 1
la_resource.c

@@ -212,7 +212,7 @@ void la_RegisterMainThemes(){
         bt = laDesignBoxedTheme(t, "Socket",&_LA_THEME_SOCKET,
             0.1, 0.65, 0.7, 0.8, 0.1, 0.95, 1, 1, 1, 1, 1, 1, 1, 1);
         bt = laDesignBoxedTheme(t, "Collection Group",&_LA_THEME_COLLECTION_GROUP,
-            0.25, 0.35, 0.8, 0.7, 0.1, 0.3, 1, 1, 0, 0, 1, 1, 1, 1);
+            0.25, 0.35, 0.4, 0.7, 0.1, 0.45, 1, 1, 0, 0, 1, 1, 1, 1);
         bt = laDesignBoxedTheme(t, "Collection Item",&_LA_THEME_COLLECTION_ITEM,
             0.25, 0.35, 0.8, 0.7, 0.1, 0.3, 1, 1, 0, 0, 1, 1, 1, 1);
         bt = laDesignBoxedTheme(t, "3D Viewer",&_LA_THEME_3D_VIEW,

+ 16 - 2
la_util.h

@@ -393,10 +393,21 @@ STRUCTURE(laTranslationMatch) {
 	char * Target;
 	char * Replacement;
 };
+
+NEED_STRUCTURE(laRackPage);
+
+STRUCTURE(laNodeVisitInfo){
+    laListHandle* l;
+    laListHandle* br;
+    uint64_t Branch;
+    int NextBranch;
+    laRackPage* Page;
+};
+
 NEED_STRUCTURE(laBaseNode);
 typedef void (*laBaseNodeInitF)(laBaseNode*, int NoCreate);
 typedef void (*laBaseNodeDestroyF)(laBaseNode*);
-typedef int (*laBaseNodeVisitF)(laBaseNode*, laListHandle*);
+typedef int (*laBaseNodeVisitF)(laBaseNode*, laNodeVisitInfo*);
 typedef int (*laBaseNodeEvalF)(laBaseNode*);
 
 STRUCTURE(laBaseNodeType){
@@ -416,7 +427,10 @@ STRUCTURE(laBaseNode){
     laSafeString* Name;
     laBaseNodeType* Type;
     laNodeRack* InRack;
-    int Gap; int Eval; int InitDone;
+    int Gap; int InitDone;
+	uint64_t EvalMagic;
+	uint64_t Branch;
+	uint64_t BranchTemp;
 };
 
 

+ 122 - 93
resources/la_nodes_basic.c

@@ -77,7 +77,7 @@ void IDN_ControllerDestroy(laInputControllerNode* n){
     for(int i=0;i<8;i++){ laDestroyOutSocket(n->Sockets[i].Out); }
     strSafeDestroy(&n->Base.Name);
 }
-int IDN_ControllerVisit(laInputControllerNode* n, laListHandle* l){
+int IDN_ControllerVisit(laInputControllerNode* n, laNodeVisitInfo* vi){
     laController* c=la_FindControllerWithID(n->UserID);
     if(!c){ for(int i=0;i<8;i++){ laInputControllerNodeSocket* ns=&n->Sockets[i]; LA_IDN_CONTROLLER_RESET_SOCKET(ns); } return LA_DAG_FLAG_PERM; }
     else{
@@ -95,8 +95,7 @@ int IDN_ControllerVisit(laInputControllerNode* n, laListHandle* l){
             ns->Offset=p->Offset;
         }
     }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_ControllerEval(laInputControllerNode* n){
@@ -152,11 +151,10 @@ void IDN_InputVisualizeDestroy(laInputVisualizerNode* n){
     laDestroyInSocket(n->In);
     strSafeDestroy(&n->Base.Name);
 }
-int IDN_InputVisualizeVisit(laInputVisualizerNode* n, laListHandle* l){
-    n->Base.Eval=LA_DAG_FLAG_TEMP;
-    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent;LA_VISIT_NODE(sn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_InputVisualizeVisit(laInputVisualizerNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent;LA_VISIT_NODE(sn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_InputVisualizerEval(laInputVisualizerNode* n){
@@ -199,11 +197,10 @@ void IDN_SplitDestroy(laSplitNode* n){
     laDestroyInSocket(n->In); strSafeDestroy(&n->Base.Name);
     for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
 }
-int IDN_SplitVisit(laSplitNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent; LA_VISIT_NODE(sn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_SplitVisit(laSplitNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* sn=n->In->Source->Parent; LA_VISIT_NODE(sn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_SplitEval(laSplitNode* n){
@@ -250,19 +247,29 @@ void IDN_SwitchDestroy(laSwitchNode* n){
     laDestroyInSocket(n->SwitchIn); laDestroyOutSocket(n->Out); strSafeDestroy(&n->Base.Name);
     for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
 }
-int IDN_SwitchVisit(laSwitchNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
+int IDN_SwitchVisit(laSwitchNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi); n->MaxUsed=0; n->Page=vi->Page;
+    for(int i=0;i<8;i++){ if(n->In[i].In->Source){ n->MaxUsed=i+2; } }
+    uint64_t OrigBranch=vi->Branch; int NextBranch=vi->NextBranch;
+    vi->NextBranch+=n->MaxUsed; n->BranchSW=(1<<(NextBranch-1));
+    if(OrigBranch==1){ lstAppendPointer(vi->br,n); }
     for(int i=0;i<8;i++){
-        if(n->In[i].In->Source){ laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn); }
+        if(n->In[i].In->Source){
+            vi->Branch=OrigBranch|(1<<(NextBranch+i));
+            laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn,vi);
+        }
     }
-    laBaseNode* sw=n->SwitchIn->Source?n->SwitchIn->Source->Parent:0; if(sw){ LA_VISIT_NODE(sw); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+    vi->Branch=OrigBranch|n->BranchSW;
+    laBaseNode* sw=n->SwitchIn->Source?n->SwitchIn->Source->Parent:0; if(sw){ LA_VISIT_NODE(sw,vi); }
+    vi->Branch=OrigBranch;
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_SwitchEval(laSwitchNode* n){
     int sw=n->Switch;
-    if(n->SwitchIn->Source){ laNodeOutSocket* os=n->SwitchIn->Source; int* id; real* fd;
+    if(n->SwitchIn->Source){
+        laRunPage(n->Page,n->BranchSW);
+        laNodeOutSocket* os=n->SwitchIn->Source; int* id; real* fd;
         switch(os->DataType){
         case LA_PROP_ARRAY|LA_PROP_ENUM:
             id=os->Data; for(int i=0;i<os->ArrLen;i++){ if(id[i]){sw=i; break;} } break;
@@ -273,6 +280,7 @@ int IDN_SwitchEval(laSwitchNode* n){
         default: sw=0; break;
         }
     }
+    laRunPage(n->Page,(n->BranchSW<<(sw+1)));
     TNS_CLAMP(sw,0,7);
     laSwitchNodeInSocket *is=&n->In[sw];
     if(is->In->Source){ n->Out->Data=is->In->Source->Data; n->Out->DataType=is->In->Source->DataType; n->Out->ArrLen=is->In->Source->ArrLen; }
@@ -313,11 +321,10 @@ void IDN_CombineDestroy(laCombineNode* n){
     laDestroyOutSocket(n->Out);laDestroyOutSocket(n->OutInt);laDestroyOutSocket(n->OutEnum); strSafeDestroy(&n->Base.Name);
     for(int i=0;i<8;i++){ laDestroyInSocket(n->In[i].In); }
 }
-int IDN_CombineVisit(laCombineNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    for(int i=0;i<8;i++){ if(LA_SRC_AND_PARENT(n->In[i].In)){ laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn); } }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_CombineVisit(laCombineNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    for(int i=0;i<8;i++){ if(LA_SRC_AND_PARENT(n->In[i].In)){ laBaseNode* sn=n->In[i].In->Source->Parent; LA_VISIT_NODE(sn,vi); } }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_CombineEval(laCombineNode* n){
@@ -365,10 +372,9 @@ void IDN_ValuesDestroy(laValuesNode* n){
     strSafeDestroy(&n->Base.Name);
     for(int i=0;i<8;i++){ laDestroyOutSocket(n->Out[i].Out); }
 }
-int IDN_ValuesVisit(laValuesNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_ValuesVisit(laValuesNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_ValuesEval(laValuesNode* n){
@@ -413,12 +419,11 @@ void IDN_MatrixDestroy(laMatrixNode* n){
     strSafeDestroy(&n->Base.Name);
     laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out);
 }
-int IDN_MatrixVisit(laMatrixNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_MatrixVisit(laMatrixNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_MatrixEval(laMatrixNode* n){
@@ -461,12 +466,11 @@ void IDN_MathInit(laMathNode* n, int NoCreate){
 void IDN_MathDestroy(laMathNode* n){
     strSafeDestroy(&n->Base.Name); laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out); laDestroyOutSocket(n->OutInt);
 }
-int IDN_MathVisit(laMathNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_MathVisit(laMathNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 #define LA_GET_SRC_AS_FLOAT(var, socket) \
@@ -541,15 +545,14 @@ void IDN_MapperDestroy(laMapperNode* n){
     laDestroyInSocket(n->InMin); laDestroyInSocket(n->InMax); laDestroyInSocket(n->OutMin); laDestroyInSocket(n->OutMax);
     laValueMapperDestroy(n->Mapper);
 }
-int IDN_MapperVisit(laMapperNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InMin)){ laBaseNode* bn=n->InMin->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InMax)){ laBaseNode* bn=n->InMax->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->OutMin)){ laBaseNode* bn=n->OutMin->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->OutMax)){ laBaseNode* bn=n->OutMax->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_MapperVisit(laMapperNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InMin)){ laBaseNode* bn=n->InMin->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InMax)){ laBaseNode* bn=n->InMax->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->OutMin)){ laBaseNode* bn=n->OutMin->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->OutMax)){ laBaseNode* bn=n->OutMax->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_MapperEval(laMapperNode* n){
@@ -592,11 +595,11 @@ void IDN_RandomInit(laRandomNode* n, int NoCreate){
 void IDN_RandomDestroy(laRandomNode* n){
     strSafeDestroy(&n->Base.Name); laDestroyOutSocket(n->Out); laDestroyInSocket(n->InMin); laDestroyInSocket(n->InMax);
 }
-int IDN_RandomVisit(laRandomNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->InMin)){ laBaseNode* bn=n->InMin->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InMax)){ laBaseNode* bn=n->InMax->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
+int IDN_RandomVisit(laRandomNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->InMin)){ laBaseNode* bn=n->InMin->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InMax)){ laBaseNode* bn=n->InMax->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_RandomEval(laRandomNode* n){
@@ -629,12 +632,11 @@ void IDN_VectorMathInit(laVectorMathNode* n, int NoCreate){
 void IDN_VectorMathDestroy(laVectorMathNode* n){
     strSafeDestroy(&n->Base.Name); laDestroyInSocket(n->InL); laDestroyInSocket(n->InR); laDestroyOutSocket(n->Out);
 }
-int IDN_VectorMathVisit(laVectorMathNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_VectorMathVisit(laVectorMathNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InR)){ laBaseNode* bn=n->InR->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 #define LA_GET_SRC_AS_FLOAT_THINGS(var, socket, maxlen) \
@@ -684,8 +686,10 @@ void IDN_CommentInit(laCommentNode* n, int NoCreate){
 void IDN_CommentDestroy(laCommentNode* n){
     strSafeDestroy(&n->Base.Name); strSafeDestroy(&n->Content); 
 }
-int IDN_CommentVisit(laCommentNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n); n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
+int IDN_CommentVisit(laCommentNode* n, laNodeVisitInfo* vi){
+    //LA_GUARD_THIS_NODE(n,vi); 
+    //LA_ADD_THIS_NODE(n,vi);
+    // No need to evaluate comments I guess?
     return LA_DAG_FLAG_PERM;
 }
 int IDN_CommentEval(laCommentNode* n){ return 1; }
@@ -713,11 +717,10 @@ void IDN_RGB2OKHSLDestroy(laRGB2OKHSLNode* n){
     strSafeDestroy(&n->Base.Name);
     laDestroyInSocket(n->In); laDestroyOutSocket(n->OutH); laDestroyOutSocket(n->OutS); laDestroyOutSocket(n->OutL);
 }
-int IDN_RGB2OKHSLVisit(laRGB2OKHSLNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_RGB2OKHSLVisit(laRGB2OKHSLNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->In)){ laBaseNode* bn=n->In->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_RGB2OKHSLEval(laRGB2OKHSLNode* n){
@@ -757,13 +760,12 @@ void IDN_OKHSL2RGBDestroy(laOKHSL2RGBNode* n){
     strSafeDestroy(&n->Base.Name);
     laDestroyInSocket(n->InH); laDestroyInSocket(n->InS); laDestroyInSocket(n->InL); laDestroyOutSocket(n->Out);
 }
-int IDN_OKHSL2RGBVisit(laOKHSL2RGBNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->InH)){ laBaseNode* bn=n->InH->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InS)){ laBaseNode* bn=n->InS->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_OKHSL2RGBVisit(laOKHSL2RGBNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->InH)){ laBaseNode* bn=n->InH->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InS)){ laBaseNode* bn=n->InS->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->InL)){ laBaseNode* bn=n->InL->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_OKHSL2RGBEval(laOKHSL2RGBNode* n){
@@ -1286,33 +1288,60 @@ typedef laMathNode laSmallMathNode;
     MAIN.tNodeOut=laCreateOutSocket(0,"TOUT",0);
 }
 
-
-
 void laMappingRequestRebuild(){ MAIN.InputMapping->NeedRebuild=1; }
 void laMappingRequestEval(){ MAIN.InputMapping->NeedEval=1; }
 
-int la_RunInputMapping(){
-    MAIN.InputMapping->NeedEval = 0;
-    for(laListItemPointer*lip=MAIN.InputMapping->Eval.pFirst;lip;lip=lip->pNext){
-        laBaseNode* n=lip->p; if(!n->InitDone){ n->Type->Init(n,1); n->InitDone=1; } n->Type->Eval(n);
-    }
-    return 1;
-}
-int la_RebuildInputMapping(){
-    MAIN.InputMapping->NeedRebuild = 0;
-    while(lstPopPointer(&MAIN.InputMapping->Eval));
-    laListHandle pending={0}; laRackPage* rp=MAIN.InputMapping->CurrentPage; if(!rp)return LA_DAG_FLAG_PERM;
+int __DEBUG_PAGE_EVAL__=1;
+
+int laRebuildPageEval(laRackPage* rp){
+    if(!rp)return LA_DAG_FLAG_PERM;
+    while(lstPopPointer(&rp->Eval)); while(lstPopPointer(&rp->AlwaysBranchers));
+    laListHandle pending={0}; 
     for(laNodeRack* ir=rp->Racks.pFirst;ir;ir=ir->Item.pNext){
-        for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ if(!bn->InitDone){ bn->Type->Init(bn,1); bn->InitDone=1; } lstAppendPointer(&pending,bn); bn->Eval=0; }
+        for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ if(!bn->InitDone){ bn->Type->Init(bn,1); bn->InitDone=1; }
+            lstAppendPointer(&pending,bn); bn->Branch=0; bn->BranchTemp=0;
+        }
     }
-    laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
+    laBaseNode*n; int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
+    laNodeVisitInfo vi;
+    vi.Branch=1; vi.NextBranch=2; vi.l=&rp->Eval; vi.br=&rp->AlwaysBranchers; vi.Page=rp;
     for(laListItemPointer*lip=pending.pFirst;lip;lip=NextLip){ n=lip->p; NextLip=lip->pNext;
-        if(n->Eval&LA_DAG_FLAG_PERM) continue;
-        result=n->Type->Visit(n,&MAIN.InputMapping->Eval); if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&pending)); break; }
+        if(n->Branch & 1) continue;
+        result=n->Type->Visit(n,&vi); if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&pending)); break; }
     }
-    if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&MAIN.InputMapping->Eval)); return LA_DAG_FLAG_ERR; }
+    if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&rp->Eval)); while(lstPopPointer(&rp->AlwaysBranchers)); return LA_DAG_FLAG_ERR; }
     return LA_DAG_FLAG_PERM;
 }
+int laRunPage(laRackPage* rp, uint64_t mask){
+    static uint64_t magic=3;
+    if(!rp || (!rp->Eval.pFirst && !rp->AlwaysBranchers.pFirst)) return 0;
+    if(__DEBUG_PAGE_EVAL__ && mask==1){ printf("Page eval %s\n",rp->Name->Ptr); }
+    if(mask==1){
+        for(laListItemPointer*lip=rp->AlwaysBranchers.pFirst;lip;lip=lip->pNext){
+            laBaseNode* n=lip->p; if(!n->InitDone){ n->Type->Init(n,1); n->InitDone=1; }
+            if(n->EvalMagic==magic) continue; if(__DEBUG_PAGE_EVAL__){ printf("  AB %.6x\n",n); }
+            n->EvalMagic=magic; n->Type->Eval(n);
+        }
+    }
+    for(laListItemPointer*lip=rp->Eval.pFirst;lip;lip=lip->pNext){
+        laBaseNode* n=lip->p; if(!n->InitDone){ n->Type->Init(n,1); n->InitDone=1; }
+        if((!(n->Branch&mask)) || (mask==1&&n->Branch!=1) || n->EvalMagic==magic) continue;
+        if(__DEBUG_PAGE_EVAL__){ printf("  NN %d %s %.6x\n",mask,n->Type->Name,n); }
+        n->EvalMagic=magic; n->Type->Eval(n);
+    }
+    if(__DEBUG_PAGE_EVAL__ && mask==1){ printf("End\n"); }
+    if(mask==1){ magic++; }
+    return 1;
+}
+
+int la_RunInputMapping(){
+    MAIN.InputMapping->NeedEval = 0;
+    return laRunPage(MAIN.InputMapping->CurrentPage, 1);
+}
+int la_RebuildInputMapping(){
+    MAIN.InputMapping->NeedRebuild = 0;
+    return laRebuildPageEval(MAIN.InputMapping->CurrentPage);
+}
 
 //==================================================================================================
 

+ 1 - 1
resources/la_templates.c

@@ -1539,7 +1539,7 @@ void laui_InputMapper(laUiList *uil, laPropPack *This, laPropPack *Extra, laColu
         laShowItemFull(uil,cr,0,"la.input_mapping.pages",LA_WIDGET_COLLECTION_SELECTOR,0,0,0);
     }laEndCondition(uil,b2);
     
-    laShowItemFull(uil,c,0,"la.input_mapping.current_page",LA_WIDGET_COLLECTION_SINGLE,0,laui_RackPage,0)->Flags|=LA_UI_FLAGS_NO_DECAL;;
+    laShowItemFull(uil,c,0,"la.input_mapping.current_page",LA_WIDGET_COLLECTION_SINGLE,0,laui_RackPage,0)->Flags|=LA_UI_FLAGS_NO_DECAL;
 }
 void lauidetached_Drivers(laPanel* p){
     la_MakeDetachedProp(p, "la.drivers.current_page", "page");

+ 12 - 29
resources/la_tns_drivers.c

@@ -34,10 +34,9 @@ void IDN_TransformInit(tnsTransformNode* n, int NoCreate){
 void IDN_TransformDestroy(tnsTransformNode* n){
     laDestroyInSocket(n->Mat); strSafeDestroy(&n->Base.Name);
 }
-int IDN_TransformVisit(tnsTransformNode* n, laListHandle* l){
-    if(LA_SRC_AND_PARENT(n->Mat)){ laBaseNode*bn=n->Mat->Source->Parent; LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM;
-    lstAppendPointer(l, n);
+int IDN_TransformVisit(tnsTransformNode* n, laNodeVisitInfo* vi){
+    if(LA_SRC_AND_PARENT(n->Mat)){ laBaseNode*bn=n->Mat->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_TransformEval(tnsTransformNode* n){
@@ -75,13 +74,13 @@ void IDN_MakeTransformDestroy(tnsMakeTransformNode* n){
     laDestroyInSocket(n->Rot); laDestroyInSocket(n->Angle);
     laDestroyInSocket(n->Sca);
 }
-int IDN_MakeTransformVisit(tnsMakeTransformNode* n, laListHandle* l){
-    LA_GUARD_THIS_NODE(n);
-    if(LA_SRC_AND_PARENT(n->Loc)){ laBaseNode*bn=n->Loc->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->Rot)){ laBaseNode*bn=n->Rot->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->Sca)){ laBaseNode*bn=n->Sca->Source->Parent; LA_VISIT_NODE(bn); }
-    if(LA_SRC_AND_PARENT(n->Angle)){ laBaseNode*bn=n->Angle->Source->Parent;  LA_VISIT_NODE(bn); }
-    n->Base.Eval=LA_DAG_FLAG_PERM; lstAppendPointer(l, n);
+int IDN_MakeTransformVisit(tnsMakeTransformNode* n, laNodeVisitInfo* vi){
+    LA_GUARD_THIS_NODE(n,vi);
+    if(LA_SRC_AND_PARENT(n->Loc)){ laBaseNode*bn=n->Loc->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->Rot)){ laBaseNode*bn=n->Rot->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->Sca)){ laBaseNode*bn=n->Sca->Source->Parent; LA_VISIT_NODE(bn,vi); }
+    if(LA_SRC_AND_PARENT(n->Angle)){ laBaseNode*bn=n->Angle->Source->Parent;  LA_VISIT_NODE(bn,vi); }
+    LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
 }
 int IDN_MakeTransformEval(tnsMakeTransformNode* n){
@@ -190,25 +189,9 @@ void laDriverRequestEval(){ MAIN.Drivers->NeedEval=1; }
 
 int la_RunDrivers(){
     MAIN.Drivers->NeedEval = 0;
-    for(laListItemPointer*lip=MAIN.Drivers->Eval.pFirst;lip;lip=lip->pNext){
-        laBaseNode* n=lip->p; if(!n->InitDone){ n->Type->Init(n,1); n->InitDone=1; } n->Type->Eval(n);
-    }
-    return 1;
+    return laRunPage(MAIN.Drivers->CurrentPage, 1);
 }
 int la_RebuildDriverEval(){
     MAIN.Drivers->NeedRebuild = 0;
-    while(lstPopPointer(&MAIN.Drivers->Eval));
-    laListHandle pending={0};
-    for(laRackPage* dp=MAIN.Drivers->Pages.pFirst;dp;dp=dp->Item.pNext){
-        for(laNodeRack* ir=dp->Racks.pFirst;ir;ir=ir->Item.pNext){
-            for(laBaseNode*bn=ir->Nodes.pFirst;bn;bn=bn->Item.pNext){ if(!bn->InitDone){ bn->Type->Init(bn,1); bn->InitDone=1; } lstAppendPointer(&pending,bn); bn->Eval=0; }
-        }
-    }
-    laBaseNode*n;int result=LA_DAG_FLAG_PERM; laListItemPointer*NextLip;
-    for(laListItemPointer*lip=pending.pFirst;lip;lip=NextLip){ n=lip->p; NextLip=lip->pNext;
-        if(n->Eval&LA_DAG_FLAG_PERM) continue;
-        result=n->Type->Visit(n,&MAIN.Drivers->Eval); if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&pending)); break; }
-    }
-    if(result==LA_DAG_FLAG_ERR){ while(lstPopPointer(&MAIN.Drivers->Eval)); return LA_DAG_FLAG_ERR; }
-    return LA_DAG_FLAG_PERM;
+    return laRebuildPageEval(MAIN.Drivers->CurrentPage);
 }