Moved more polyfill code into the engine proper
This commit is contained in:
@@ -22,8 +22,9 @@
|
||||
<ClCompile Include="source\main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="assets\scripts\children_test.toy" />
|
||||
<None Include="assets\scripts\entity.toy" />
|
||||
<None Include="assets\scripts\frames.toy" />
|
||||
<None Include="assets\scripts\frames_test.toy" />
|
||||
<None Include="assets\scripts\init.toy" />
|
||||
<None Include="assets\scripts\scene.toy" />
|
||||
<None Include="assets\scripts\tilemap\layer-background.toy" />
|
||||
|
||||
30
assets/scripts/children_test.toy
Normal file
30
assets/scripts/children_test.toy
Normal file
@@ -0,0 +1,30 @@
|
||||
import node;
|
||||
|
||||
//util to generate and init a child node of a given parent
|
||||
fn makeChild(parent: opaque, fname: string) {
|
||||
var child: opaque = loadNode(fname);
|
||||
parent.pushNode(child);
|
||||
child.initNode();
|
||||
return child;
|
||||
}
|
||||
|
||||
fn onInit(node: opaque) {
|
||||
for (var i = 0; i < 20; i++) {
|
||||
node.makeChild("scripts:/tilemap/tile.toy");
|
||||
}
|
||||
|
||||
node.freeChildNode(10);
|
||||
var n = node.getChildNode(10);
|
||||
|
||||
for (var i = 0; i < 20; i++) {
|
||||
//this would originally prune tombstones...
|
||||
node.makeChild("scripts:/tilemap/tile.toy");
|
||||
}
|
||||
|
||||
print node.getChildNodeCount();
|
||||
|
||||
var m = node.getChildNode(10);
|
||||
|
||||
print n;
|
||||
print m;
|
||||
}
|
||||
@@ -28,4 +28,4 @@ mapInputEventToKeyUp("character_right", "right"); //event, keysym
|
||||
initWindow("Airport Game", 1080, 720, false);
|
||||
|
||||
//kick off the logic of the scene graph
|
||||
loadRootNode("scripts:/scene.toy");
|
||||
loadRootNode("scripts:/children_test.toy");
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
import standard;
|
||||
import node;
|
||||
|
||||
var childCounter: int = 0;
|
||||
|
||||
//TODO: reference these from a global source (root?)
|
||||
var tileWidth: int const = 64;
|
||||
var tileHeight: int const = 64;
|
||||
@@ -23,9 +21,6 @@ fn makeChildSprite(parent: opaque, spriteName: string) {
|
||||
|
||||
child.loadTexture("sprites:/" + spriteName);
|
||||
|
||||
//BUGFIX
|
||||
childCounter++;
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
import standard;
|
||||
import node;
|
||||
|
||||
var childCounter: int = 0;
|
||||
|
||||
//TODO: reference these from a global source (root?)
|
||||
var tileWidth: int const = 64;
|
||||
var tileHeight: int const = 64;
|
||||
@@ -23,9 +21,6 @@ fn makeChildSprite(parent: opaque, spriteName: string) {
|
||||
|
||||
child.loadTexture("sprites:/" + spriteName);
|
||||
|
||||
//BUGFIX
|
||||
childCounter++;
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
import standard;
|
||||
import node;
|
||||
|
||||
//TODO: get child count
|
||||
var childCounter: int = 0;
|
||||
|
||||
var camX: float = 0;
|
||||
var camY: float = 0;
|
||||
|
||||
@@ -33,7 +30,6 @@ fn makeChild(parent: opaque, fname: string) {
|
||||
fn loadLayer(node: opaque, layerName: string) {
|
||||
//load the given layer as a child
|
||||
var layerNode = node.makeChild("scripts:/tilemap/" + layerName);
|
||||
childCounter++;
|
||||
}
|
||||
|
||||
var stepCounter = 0;
|
||||
@@ -49,7 +45,7 @@ fn onDraw(node: opaque) {
|
||||
stepCounter = 0;
|
||||
|
||||
//iterate over each layer, passing in the screen dimensions
|
||||
for (var c = 0; c < childCounter; c++) {
|
||||
for (var c = 0; c < node.getChildNodeCount(); c++) {
|
||||
node.getChildNode(c).callNodeFn("drawLayer", camX, camY, screenWidth, screenHeight, c * 4.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ void Box_initEngineNode(Box_EngineNode* node, Toy_Interpreter* interpreter, cons
|
||||
node->children = NULL;
|
||||
node->capacity = 0;
|
||||
node->count = 0;
|
||||
node->childCount = 0;
|
||||
node->texture = NULL;
|
||||
node->rect = ((SDL_Rect) { 0, 0, 0, 0 });
|
||||
node->frames = 0;
|
||||
@@ -40,7 +41,7 @@ void Box_initEngineNode(Box_EngineNode* node, Toy_Interpreter* interpreter, cons
|
||||
}
|
||||
|
||||
void Box_pushEngineNode(Box_EngineNode* node, Box_EngineNode* child) {
|
||||
//push to the array (prune tombstones when expanding/copying)
|
||||
//push to the array
|
||||
if (node->count + 1 > node->capacity) {
|
||||
int oldCapacity = node->capacity;
|
||||
|
||||
@@ -48,25 +49,14 @@ void Box_pushEngineNode(Box_EngineNode* node, Box_EngineNode* child) {
|
||||
node->children = TOY_GROW_ARRAY(Box_EngineNode*, node->children, oldCapacity, node->capacity);
|
||||
}
|
||||
|
||||
//prune tombstones (experimental)
|
||||
int counter = 0;
|
||||
for (int i = 0; i < node->capacity; i++) {
|
||||
if (i >= node->count) {
|
||||
node->count = counter;
|
||||
break;
|
||||
}
|
||||
|
||||
//move down
|
||||
if (node->children[i] != NULL) {
|
||||
node->children[counter++] = node->children[i];
|
||||
}
|
||||
}
|
||||
|
||||
//assign
|
||||
node->children[node->count++] = child;
|
||||
|
||||
//reverse-assign
|
||||
child->parent = node;
|
||||
|
||||
//count
|
||||
node->childCount++;
|
||||
}
|
||||
|
||||
void Box_freeEngineNode(Box_EngineNode* node) {
|
||||
@@ -95,6 +85,28 @@ void Box_freeEngineNode(Box_EngineNode* node) {
|
||||
TOY_FREE(Box_EngineNode, node);
|
||||
}
|
||||
|
||||
Box_EngineNode* Box_getChildEngineNode(Box_EngineNode* node, int index) {
|
||||
if (index < 0 || index > node->count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node->children[index];
|
||||
}
|
||||
|
||||
void Box_freeChildEngineNode(Box_EngineNode* node, int index) {
|
||||
//get the child node
|
||||
Box_EngineNode* childNode = node->children[index];
|
||||
|
||||
//free the node
|
||||
if (childNode != NULL) {
|
||||
Box_callRecursiveEngineNode(childNode, &engine.interpreter, "onFree", NULL);
|
||||
Box_freeEngineNode(childNode);
|
||||
node->childCount--;
|
||||
}
|
||||
|
||||
node->children[index] = NULL;
|
||||
}
|
||||
|
||||
Toy_Literal Box_callEngineNodeLiteral(Box_EngineNode* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
|
||||
Toy_Literal ret = TOY_TO_NULL_LITERAL;
|
||||
|
||||
@@ -188,6 +200,10 @@ void Box_callRecursiveEngineNode(Box_EngineNode* node, Toy_Interpreter* interpre
|
||||
Toy_freeLiteral(key);
|
||||
}
|
||||
|
||||
int Box_getChildCountEngineNode(Box_EngineNode* node) {
|
||||
return node->childCount;
|
||||
}
|
||||
|
||||
int Box_loadTextureEngineNode(Box_EngineNode* node, const char* fname) {
|
||||
SDL_Surface* surface = IMG_Load(fname);
|
||||
|
||||
@@ -223,28 +239,28 @@ void Box_setRectEngineNode(Box_EngineNode* node, SDL_Rect rect) {
|
||||
node->rect = rect;
|
||||
}
|
||||
|
||||
BOX_API SDL_Rect Box_getRectEngineNode(Box_EngineNode* node) {
|
||||
SDL_Rect Box_getRectEngineNode(Box_EngineNode* node) {
|
||||
return node->rect;
|
||||
}
|
||||
|
||||
BOX_API void Box_setFramesEngineNode(Box_EngineNode* node, int frames) {
|
||||
void Box_setFramesEngineNode(Box_EngineNode* node, int frames) {
|
||||
node->frames = frames;
|
||||
node->currentFrame = 0; //just in case
|
||||
}
|
||||
|
||||
BOX_API int Box_getFramesEngineNode(Box_EngineNode* node) {
|
||||
int Box_getFramesEngineNode(Box_EngineNode* node) {
|
||||
return node->frames;
|
||||
}
|
||||
|
||||
BOX_API void Box_setCurrentFrameEngineNode(Box_EngineNode* node, int currentFrame) {
|
||||
void Box_setCurrentFrameEngineNode(Box_EngineNode* node, int currentFrame) {
|
||||
node->currentFrame = currentFrame;
|
||||
}
|
||||
|
||||
BOX_API int Box_getCurrentFrameEngineNode(Box_EngineNode* node) {
|
||||
int Box_getCurrentFrameEngineNode(Box_EngineNode* node) {
|
||||
return node->currentFrame;
|
||||
}
|
||||
|
||||
BOX_API void Box_incrementCurrentFrame(Box_EngineNode* node) {
|
||||
void Box_incrementCurrentFrame(Box_EngineNode* node) {
|
||||
node->currentFrame++;
|
||||
if (node->currentFrame >= node->frames) {
|
||||
node->currentFrame = 0;
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef struct Box_private_engineNode {
|
||||
Box_EngineNode** children;
|
||||
int capacity;
|
||||
int count; //includes tombstones
|
||||
int childCount;
|
||||
|
||||
//rendering-specific features
|
||||
SDL_Texture* texture;
|
||||
@@ -41,6 +42,9 @@ BOX_API void Box_initEngineNode(Box_EngineNode* node, Toy_Interpreter* interpret
|
||||
BOX_API void Box_pushEngineNode(Box_EngineNode* node, Box_EngineNode* child); //push to the array (prune tombstones when expanding/copying)
|
||||
BOX_API void Box_freeEngineNode(Box_EngineNode* node); //free this node and all children
|
||||
|
||||
BOX_API Box_EngineNode* Box_getChildEngineNode(Box_EngineNode* node, int index);
|
||||
BOX_API void Box_freeChildEngineNode(Box_EngineNode* node, int index);
|
||||
|
||||
BOX_API Toy_Literal Box_callEngineNodeLiteral(Box_EngineNode* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
|
||||
BOX_API Toy_Literal Box_callEngineNode(Box_EngineNode* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and only this node, if it exists
|
||||
|
||||
@@ -48,6 +52,8 @@ BOX_API Toy_Literal Box_callEngineNode(Box_EngineNode* node, Toy_Interpreter* in
|
||||
BOX_API void Box_callRecursiveEngineNodeLiteral(Box_EngineNode* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
|
||||
BOX_API void Box_callRecursiveEngineNode(Box_EngineNode* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and all children, if it exists
|
||||
|
||||
BOX_API int Box_getChildCountEngineNode(Box_EngineNode* node);
|
||||
|
||||
BOX_API int Box_loadTextureEngineNode(Box_EngineNode* node, const char* fname);
|
||||
BOX_API void Box_freeTextureEngineNode(Box_EngineNode* node);
|
||||
|
||||
|
||||
@@ -191,12 +191,19 @@ static int nativeGetChildNode(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
|
||||
return -1;
|
||||
}
|
||||
|
||||
Box_EngineNode* childNode = parentNode->children[intIndex];
|
||||
Toy_Literal child = TOY_TO_OPAQUE_LITERAL(childNode, childNode->tag);
|
||||
Box_EngineNode* childNode = Box_getChildEngineNode(parentNode, intIndex);
|
||||
Toy_Literal child;
|
||||
|
||||
if (childNode == NULL) {
|
||||
child = TOY_TO_NULL_LITERAL;
|
||||
}
|
||||
else {
|
||||
child = TOY_TO_OPAQUE_LITERAL(childNode, childNode->tag);
|
||||
}
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, child);
|
||||
|
||||
//no return value
|
||||
//cleanup
|
||||
Toy_freeLiteral(parent);
|
||||
Toy_freeLiteral(child);
|
||||
Toy_freeLiteral(index);
|
||||
@@ -210,46 +217,37 @@ static int nativeFreeChildNode(Toy_Interpreter* interpreter, Toy_LiteralArray* a
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal index = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal node = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal indexLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal nodeIdn = node; //annoying
|
||||
if (TOY_IS_IDENTIFIER(node) && Toy_parseIdentifierToValue(interpreter, &node)) {
|
||||
Toy_freeLiteral(nodeIdn);
|
||||
Toy_Literal nodeLiteralIdn = nodeLiteral; //annoying
|
||||
if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
|
||||
Toy_freeLiteral(nodeLiteralIdn);
|
||||
}
|
||||
|
||||
//check argument types
|
||||
if (!TOY_IS_OPAQUE(node) || !TOY_IS_INTEGER(index)) {
|
||||
if (!TOY_IS_OPAQUE(nodeLiteral) || !TOY_IS_INTEGER(indexLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to freeChildNode\n");
|
||||
Toy_freeLiteral(node);
|
||||
Toy_freeLiteral(nodeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Box_EngineNode* parentNode = TOY_AS_OPAQUE(node);
|
||||
int idx = TOY_AS_INTEGER(index);
|
||||
Box_EngineNode* node = TOY_AS_OPAQUE(nodeLiteral);
|
||||
int idx = TOY_AS_INTEGER(indexLiteral);
|
||||
|
||||
//check bounds
|
||||
if (idx < 0 || idx >= parentNode->count) {
|
||||
if (idx < 0 || idx >= node->count) {
|
||||
interpreter->errorOutput("Node index out of bounds in freeChildNode\n");
|
||||
Toy_freeLiteral(node);
|
||||
Toy_freeLiteral(index);
|
||||
Toy_freeLiteral(nodeLiteral);
|
||||
Toy_freeLiteral(indexLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the child node
|
||||
Box_EngineNode* childNode = parentNode->children[idx];
|
||||
|
||||
//free the node
|
||||
if (childNode != NULL) {
|
||||
Box_callRecursiveEngineNode(childNode, &engine.interpreter, "onFree", NULL);
|
||||
Box_freeEngineNode(childNode);
|
||||
}
|
||||
|
||||
parentNode->children[idx] = NULL;
|
||||
Box_freeChildEngineNode(node, idx);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(node);
|
||||
Toy_freeLiteral(index);
|
||||
Toy_freeLiteral(nodeLiteral);
|
||||
Toy_freeLiteral(indexLiteral);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -291,6 +289,40 @@ static int nativeGetParentNode(Toy_Interpreter* interpreter, Toy_LiteralArray* a
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeGetChildNodeCount(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//checks
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments passed to getChildNodeCount\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal nodeLiteralIdn = nodeLiteral;
|
||||
if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) {
|
||||
Toy_freeLiteral(nodeLiteralIdn);
|
||||
}
|
||||
|
||||
if (!TOY_IS_OPAQUE(nodeLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to getChildNodeCount\n");
|
||||
Toy_freeLiteral(nodeLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the count
|
||||
Box_EngineNode* node = TOY_AS_OPAQUE(nodeLiteral);
|
||||
int childCount = Box_getChildCountEngineNode(node);
|
||||
Toy_Literal childCountLiteral = TOY_TO_INTEGER_LITERAL(childCount);
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, childCountLiteral);
|
||||
|
||||
//no return value
|
||||
Toy_freeLiteral(nodeLiteral);
|
||||
Toy_freeLiteral(childCountLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeLoadTexture(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments passed to loadTexture\n");
|
||||
@@ -797,6 +829,7 @@ int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter
|
||||
{"getChildNode", nativeGetChildNode},
|
||||
{"freeChildNode", nativeFreeChildNode},
|
||||
{"getParentNode", nativeGetParentNode},
|
||||
{"getChildNodeCount", nativeGetChildNodeCount},
|
||||
{"loadTexture", nativeLoadTexture},
|
||||
{"freeTexture", nativeFreeTexture},
|
||||
{"setNodeRect", nativeSetNodeRect},
|
||||
@@ -808,8 +841,8 @@ int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter
|
||||
{"incrementCurrentNodeFrame", nativeIncrementCurrentNodeFrame},
|
||||
{"drawNode", nativeDrawNode},
|
||||
{"callNodeFn", nativeCallNodeFn},
|
||||
|
||||
//TODO: get rect, get node var, create empty node, get child count, get root node
|
||||
|
||||
//TODO: get rect, get node var, create empty node, get root node
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user