Difference between revisions of "NodeSpace.h"

From Organic Design wiki
m
m
Line 132: Line 132:
 
//  ie. a function would have to set THEN to change, so why not change loop directly itself?
 
//  ie. a function would have to set THEN to change, so why not change loop directly itself?
 
void nodeReduce() {
 
void nodeReduce() {
node loop = nodeTraverse(this,nodeLOOP);
+
if (this = nodeGetValue(loop = nodeTraverse(this,nodeLOOP),nodeNULL)) { // Get current loop item if exists
if (this = nodeGetValue(loop,nodeNULL)) { // Get current loop item if exists
 
 
nodeSetValue(loop,nodeNULL,nodeGetValue(this,nodeNEXT)); // Rotate loop
 
nodeSetValue(loop,nodeNULL,nodeGetValue(this,nodeNEXT)); // Rotate loop
 
nodeGetValue(this,nodeCODE)?((code*)*nodeState(this,nodeNULL))():nodeReduce(); // Exec or reduce item
 
nodeGetValue(this,nodeCODE)?((code*)*nodeState(this,nodeNULL))():nodeReduce(); // Exec or reduce item
 
}
 
}
 
}
 
}

Revision as of 05:02, 4 August 2006

// This article and all its includes are licenced under LGPL // GPL: http://www.gnu.org/copyleft/lesser.html // SRC: http://www.organicdesign.co.nz/nodeSpace.c

typedef int node; // node: a type for referring to nodes typedef void (code)(); // code: a type for executing functions from pointer

// Reserved nodes used by nodal reduction process (tmp) // - doesn't matter that these node indexes conflict with 128 ascii nodes // because these will not currently need anything stored in them

  1. define nodeROOT 0
  2. define nodeNULL 0
  3. define nodeFALSE 0
  4. define nodeLOOP 1
  5. define nodeTRUE 1
  6. define nodeNEXT 2
  7. define nodePREV 3
  8. define nodeCODE 4

// Runtime nodes node this; // this: the current node, like cwd node nodeNETWORK; node nodeDESKTOP; node nodeSERVER; node nodeCLIENTS; node nodeSTREAMINFO;

// Prototypes node nodeTraverse(node subject,node key); node nodeGetValue(node subject,node key); node nodeSetValue(node subject,node key,node value); node nodeInsertKey(node subject,node key); node nodeRemoveKey(node subject,node key); node nodeLoopInsert(node subject,node insert); node nodeLoopRemove(node subject); void **nodeGetState(node subject,node key); int nodeInit(); void nodeExit(); void nodeReduce();


// - use array-of-node path? node nodeTraverse(node subject,node key) { return listTraverse((item)subject,(item)key); }

// set nodal value of node/path // - allows null key node nodeGetValue(node subject,node key) { return listGetValue(key?listTraverse((item)subject,(item)key):(item)subject); }

node nodeSetValue(node subject,node key,node value) { // todo: onChange return listSetValue(key?listTraverse((item)subject,(item)key):(item)subject, (item)value); }

// Returns a newly created node node nodeInsert() { return (node)listInsert(); }

// Returns newly created node // - this is just traverse() but with an event raised node nodeInsertKey(node subject,node key) { // todo: onInstall node i = nodeTraverse(subject,key); return i; }

// Returns the node that was removed node nodeRemoveKey(node subject,node key) { // todo: onRemove node i = nodeTraverse(subject,key); // todo: delete return i; }

// Returns the inserted node as the new loop pointer // - this allows it to act as a stack if nodeLOOP (current-loop-node) is updated with returned node // - either can be nodeNULL on entry (for new loop and/or new node) node nodeLoopInsert(node subject,node insert) { if (insert == nodeNULL) insert = nodeInsert(); if (subject == nodeNULL) subject = insert; node next = nodeGetValue(subject,nodeNEXT); nodeSetValue(insert,nodeNEXT,next); nodeSetValue(subject,nodeNEXT,insert); nodeSetValue(insert,nodePREV,subject); return nodeSetValue(next,nodePREV,insert); }

// Returns the new loop pointer so nodeLOOP can be removed and updated node nodeLoopRemove(node subject) { node prev = nodeGetValue(subject,nodePREV); node next = nodeGetValue(subject,nodeNEXT); nodeSetValue(next,nodePREV,prev); return nodeSetValue(prev,nodeNEXT,next); }

void **nodeState(node subject,node key) { return hash(itob(key?(int)listTraverse((item)subject,(item)key):(int)subject,nssBuf)); }


// Clean up all the mess and exit void nodeExit() { logAdd("Gracefully exiting."); interfaceExit(); serverExit(); listExit(); exit(EXIT_SUCCESS); }


// Set up initial nodal structure // - todo: this structure should be built at runtime from deserialised string description int nodeInit() { nodeNETWORK = nodeLoopInsert(nodeNULL,nodeNULL); nodeDESKTOP = nodeLoopInsert(nodeNETWORK,nodeNULL); nodeSERVER = nodeLoopInsert(nodeNULL,nodeNULL); nodeCLIENTS = nodeLoopInsert(nodeSERVER,nodeNULL); nodeSTREAMINFO = nodeInsert(); nodeSetValue(nodeROOT,nodeLOOP,nodeNETWORK); nodeSetValue(nodeNETWORK,nodeLOOP,nodeSERVER); nodeSetValue(nodeDESKTOP,nodeCODE,nodeTRUE); nodeSetValue(nodeSERVER,nodeCODE,nodeTRUE); return EXIT_SUCCESS; }

// Moves "this" to current loop item if exists then rotates loop and executes or reduces the item // - THEN may not be needed since by default things should stay the same // ie. a function would have to set THEN to change, so why not change loop directly itself? void nodeReduce() { if (this = nodeGetValue(loop = nodeTraverse(this,nodeLOOP),nodeNULL)) { // Get current loop item if exists nodeSetValue(loop,nodeNULL,nodeGetValue(this,nodeNEXT)); // Rotate loop nodeGetValue(this,nodeCODE)?((code*)*nodeState(this,nodeNULL))():nodeReduce(); // Exec or reduce item } }