diff --git a/Toy b/Toy index 632ed7c..cceefa6 160000 --- a/Toy +++ b/Toy @@ -1 +1 @@ -Subproject commit 632ed7c089c13e75263658abb06b3e3b10247c06 +Subproject commit cceefa63756b1b7ec41e482c7df1035f87b4643a diff --git a/assets/scripts/render.toy b/assets/scripts/render.toy index 47a58ff..0b59176 100644 --- a/assets/scripts/render.toy +++ b/assets/scripts/render.toy @@ -1,18 +1,54 @@ -import engine; import node; +//variables +var parent: opaque = null; +var x: int = 50; +var y: int = 50; + +//accessors +fn getX() { + print "Called getX"; + return x; +} + +fn getY() { + return y; +} + +//lifecycle functions fn onInit(node: opaque) { - node.loadTextureEngineNode("assets/sprites/character.png"); + print "render.toy:onInit() called"; + + node.loadTexture("assets/sprites/character.png"); + print "loaded texture"; + + parent = node.getNodeParent(); + print "accessed parent"; } fn onStep(node: opaque) { - // + print "render.toy:onStep()"; } fn onFree(node: opaque) { - node.freeTextureEngineNode(); + print "render.toy:onFree() called"; + + node.freeTexture(); } fn onDraw(node: opaque) { - node.drawEngineNode(50, 50, 100, 100); -} \ No newline at end of file + //print "render.toy:onDraw() called"; + + var px = parent.callNode("getX"); + var py = parent.callNode("getY"); + + if (px == null) { + px = 0; + } + + if (py == null) { + py = 0; + } + + node.drawNode(x + px, y + py, 100, 100); +} diff --git a/assets/scripts/root.toy b/assets/scripts/root.toy index 4b35eba..028a078 100644 --- a/assets/scripts/root.toy +++ b/assets/scripts/root.toy @@ -2,14 +2,10 @@ import engine; import node; -fn _makeChild(parent: opaque, fname: string, init: bool) { +fn _makeChild(parent: opaque, fname: string) { var child: opaque = loadNode(fname); - - if (init) { - child.initNode(); - } - parent.pushNode(child); + child.initNode(); } //root node can load the whole scene, and essentially act as the scene object @@ -17,16 +13,17 @@ fn onInit(node: opaque) { print "root.toy:onInit() called"; //make a child - node.makeChild("assets/scripts/child.toy", true); //indicate whether to call "init" on the new node or not - node.makeChild("assets/scripts/child.toy", false); - node.makeChild("assets/scripts/child.toy", false); +// node.makeChild("assets/scripts/child.toy"); +// node.makeChild("assets/scripts/child.toy"); + node.makeChild("assets/scripts/render.toy"); - //actually, grab that first node and free it - node.freeChildNode(0); //must be done from the parent node, so it's pointer can be nullified + print node; + print node.getNodeChild(0); - var r = loadNode("assets/scripts/render.toy"); + var o = node.getNodeChild(0); + print o.callNode("getX"); - node.pushNode(r); + print node.getNodeChild(0).callNode("getX"); } fn onStep(node: opaque) { diff --git a/core/engine.c b/core/engine.c index cef5ef7..9840425 100644 --- a/core/engine.c +++ b/core/engine.c @@ -62,7 +62,7 @@ void freeEngine() { //clear existing root node if (engine.rootNode != NULL) { - callEngineNode(engine.rootNode, &engine.interpreter, "onFree"); + callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onFree"); freeEngineNode(engine.rootNode); @@ -78,7 +78,7 @@ void freeEngine() { static void execStep() { //call onStep if (engine.rootNode != NULL) { - callEngineNode(engine.rootNode, &engine.interpreter, "onStep"); + callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onStep"); } //poll events @@ -151,7 +151,7 @@ void execEngine() { SDL_SetRenderDrawColor(engine.renderer, 0, 0, 0, 255); //NOTE: This line can be disabled later SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later - callEngineNode(engine.rootNode, &engine.interpreter, "onDraw"); + callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onDraw"); SDL_RenderPresent(engine.renderer); } diff --git a/core/engine_node.c b/core/engine_node.c index 95b6ea8..566e81f 100644 --- a/core/engine_node.c +++ b/core/engine_node.c @@ -101,7 +101,47 @@ void freeEngineNode(EngineNode* node) { node->freeMemory(node); } -static void callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key) { +Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key) { + Literal ret = TO_NULL_LITERAL; + + //if this fn exists + if (existsLiteralDictionary(node->functions, key)) { + Literal fn = getLiteralDictionary(node->functions, key); + Literal n = TO_OPAQUE_LITERAL(node, node->tag); + + LiteralArray arguments; + LiteralArray returns; + initLiteralArray(&arguments); + initLiteralArray(&returns); + + pushLiteralArray(&arguments, n); + + callLiteralFn(interpreter, fn, &arguments, &returns); + + ret = popLiteralArray(&returns); + + freeLiteralArray(&arguments); + freeLiteralArray(&returns); + + freeLiteral(n); + freeLiteral(fn); + } + + return ret; +} + +Literal callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName) { + //call "fnName" on this node, and all children, if it exists + Literal key = TO_IDENTIFIER_LITERAL(copyString(fnName, strlen(fnName)), strlen(fnName)); + + Literal ret = callEngineNodeLiteral(node, interpreter, key); + + freeLiteral(key); + + return ret; +} + +void callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key) { //if this fn exists if (existsLiteralDictionary(node->functions, key)) { Literal fn = getLiteralDictionary(node->functions, key); @@ -126,16 +166,16 @@ static void callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Li //recurse to the (non-tombstone) children for (int i = 0; i < node->count; i++) { if (node->children[i] != NULL) { - callEngineNodeLiteral(node->children[i], interpreter, key); + callRecursiveEngineNodeLiteral(node->children[i], interpreter, key); } } } -void callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName) { +void callRecursiveEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName) { //call "fnName" on this node, and all children, if it exists Literal key = TO_IDENTIFIER_LITERAL(copyString(fnName, strlen(fnName)), strlen(fnName)); - callEngineNodeLiteral(node, interpreter, key); + callRecursiveEngineNodeLiteral(node, interpreter, key); freeLiteral(key); } diff --git a/core/engine_node.h b/core/engine_node.h index c871e2a..708c69c 100644 --- a/core/engine_node.h +++ b/core/engine_node.h @@ -44,8 +44,11 @@ CORE_API void initEngineNode(EngineNode* node, Interpreter* interpreter, void* t CORE_API void pushEngineNode(EngineNode* node, EngineNode* child); //push to the array (prune tombstones when expanding/copying) CORE_API void freeEngineNode(EngineNode* node); //free and tombstone this node -//TODO: replace calling system with a better version -CORE_API void callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName); //call "fnName" on this node, and all children, if it exists +CORE_API Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key); +CORE_API Literal callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName); //call "fnName" on this node, and only this node, if it exists + +CORE_API void callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key); +CORE_API void callRecursiveEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName); //call "fnName" on this node, and all children, if it exists CORE_API int loadTextureEngineNode(EngineNode* node, char* fname); CORE_API void freeTextureEngineNode(EngineNode* node); diff --git a/core/lib_engine.c b/core/lib_engine.c index 4fa2b32..b1b7f05 100644 --- a/core/lib_engine.c +++ b/core/lib_engine.c @@ -98,7 +98,7 @@ static int nativeLoadRootNode(Interpreter* interpreter, LiteralArray* arguments) //clear existing root node if (engine.rootNode != NULL) { - callEngineNode(engine.rootNode, &engine.interpreter, "onFree"); + callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onFree"); freeEngineNode(engine.rootNode); FREE(EngineNode, engine.rootNode); @@ -136,7 +136,7 @@ static int nativeLoadRootNode(Interpreter* interpreter, LiteralArray* arguments) initEngineNode(engine.rootNode, &inner, tb, size); - //init the new node + //init the new node (and ONLY this node) callEngineNode(engine.rootNode, &engine.interpreter, "onInit"); //cleanup diff --git a/core/lib_node.c b/core/lib_node.c index abb88f8..978f6ec 100644 --- a/core/lib_node.c +++ b/core/lib_node.c @@ -95,7 +95,7 @@ static int nativeInitNode(Interpreter* interpreter, LiteralArray* arguments) { EngineNode* engineNode = AS_OPAQUE(node); - //init the new node + //init the new node (and ONLY this node) callEngineNode(engineNode, &engine.interpreter, "onInit"); //cleanup @@ -140,7 +140,7 @@ static int nativeFreeChildNode(Interpreter* interpreter, LiteralArray* arguments //free the node if (childNode != NULL) { - callEngineNode(childNode, &engine.interpreter, "onFree"); + callRecursiveEngineNode(childNode, &engine.interpreter, "onFree"); freeEngineNode(childNode); } @@ -276,7 +276,7 @@ static int nativeGetNodeParent(Interpreter* interpreter, LiteralArray* arguments return 1; } -static int nativeLoadTextureEngineNode(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeLoadTexture(Interpreter* interpreter, LiteralArray* arguments) { if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments passed to loadTextureEngineNode\n"); return -1; @@ -324,7 +324,7 @@ static int nativeLoadTextureEngineNode(Interpreter* interpreter, LiteralArray* a return 0; } -static int nativeFreeTextureEngineNode(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeFreeTexture(Interpreter* interpreter, LiteralArray* arguments) { if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments passed to freeTextureEngineNode\n"); return -1; @@ -357,7 +357,7 @@ static int nativeFreeTextureEngineNode(Interpreter* interpreter, LiteralArray* a return 0; } -static int nativeSetRectEngineNode(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeSetRect(Interpreter* interpreter, LiteralArray* arguments) { if (arguments->count != 5) { interpreter->errorOutput("Incorrect number of arguments passed to setRectEngineNode\n"); return -1; @@ -423,7 +423,7 @@ static int nativeSetRectEngineNode(Interpreter* interpreter, LiteralArray* argum //TODO: get x, y, w, h -static int nativeDrawEngineNode(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeDrawNode(Interpreter* interpreter, LiteralArray* arguments) { if (arguments->count != 3 && arguments->count != 5) { interpreter->errorOutput("Incorrect number of arguments passed to drawEngineNode\n"); return -1; @@ -532,6 +532,46 @@ static int nativeGetNodeTag(Interpreter* interpreter, LiteralArray* arguments) { return 1; } +static int nativeCallNode(Interpreter* interpreter, LiteralArray* arguments) { + //checks + if (arguments->count != 2) { + interpreter->errorOutput("Incorrect number of arguments passed to callEngineNode\n"); + return -1; + } + + Literal fnName = popLiteralArray(arguments); + Literal nodeLiteral = popLiteralArray(arguments); + + Literal nodeIdn = nodeLiteral; + if (IS_IDENTIFIER(nodeLiteral) && parseIdentifierToValue(interpreter, &nodeLiteral)) { + freeLiteral(nodeIdn); + } + + Literal fnNameIdn = fnName; + if (IS_IDENTIFIER(fnName) && parseIdentifierToValue(interpreter, &fnName)) { + freeLiteral(fnNameIdn); + } + + if (!IS_OPAQUE(nodeLiteral) || !IS_STRING(fnName)) { + interpreter->errorOutput("Incorrect argument type passed to callEngineNode\n"); + freeLiteral(nodeLiteral); + freeLiteral(fnName); + return -1; + } + + //call the function + Literal result = callEngineNodeLiteral(AS_OPAQUE(nodeLiteral), interpreter, fnName); + + // pushLiteralArray(&interpreter->stack, result); + + //cleanup + freeLiteral(nodeLiteral); + freeLiteral(fnName); + freeLiteral(result); + + return 1; +} + //call the hook typedef struct Natives { char* name; @@ -547,10 +587,11 @@ int hookNode(Interpreter* interpreter, Literal identifier, Literal alias) { {"_pushNode", nativePushNode}, {"_getNodeChild", nativeGetNodeChild}, {"_getNodeParent", nativeGetNodeParent}, - {"_loadTextureEngineNode", nativeLoadTextureEngineNode}, - {"_freeTextureEngineNode", nativeFreeTextureEngineNode}, - {"_setRectEngineNode", nativeSetRectEngineNode}, - {"_drawEngineNode", nativeDrawEngineNode}, + {"_loadTexture", nativeLoadTexture}, + {"_freeTexture", nativeFreeTexture}, + {"_setRect", nativeSetRect}, + {"_drawNode", nativeDrawNode}, + {"_callNode", nativeCallNode}, // {"getNodeTag", nativeGetNodeTag}, //not needed if there's only one node type {NULL, NULL}, };