Keyboard event-based input is working for keydown and keyup
This commit is contained in:
@@ -1,20 +1,27 @@
|
|||||||
import engine;
|
import engine;
|
||||||
//import input;
|
import input;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
//input settings, mapping SDL2's virtual keys to event names
|
//input settings, mapping SDL2's virtual keys to event names
|
||||||
mapInputEventToKey("character_up", "w", 0); //event, keysym, keymod
|
mapInputEventToKeyDown("character_up", "w"); //event, keysym
|
||||||
mapInputEventToKey("character_left", "a", 0); //event, keysym, keymod
|
mapInputEventToKeyDown("character_left", "a"); //event, keysym
|
||||||
mapInputEventToKey("character_down", "s", 0); //event, keysym, keymod
|
mapInputEventToKeyDown("character_down", "s"); //event, keysym
|
||||||
mapInputEventToKey("character_right", "d", 0); //event, keysym, keymod
|
mapInputEventToKeyDown("character_right", "d"); //event, keysym
|
||||||
|
|
||||||
mapInputEventToSpecial("character_up", "arrow_up"); //event, special
|
mapInputEventToKeyUp("character_up", "w"); //event, keysym
|
||||||
mapInputEventToSpecial("character_left", "arrow_left"); //event, special
|
mapInputEventToKeyUp("character_left", "a"); //event, keysym
|
||||||
mapInputEventToSpecial("character_down", "arrow_down"); //event, special
|
mapInputEventToKeyUp("character_down", "s"); //event, keysym
|
||||||
mapInputEventToSpecial("character_right", "arrow_right"); //event, special
|
mapInputEventToKeyUp("character_right", "d"); //event, keysym
|
||||||
|
|
||||||
mapInputEventToKey("character_jump", " ", 0); //event, keysym, keymod
|
mapInputEventToKeyDown("character_up", "up"); //event, keysym
|
||||||
*/
|
mapInputEventToKeyDown("character_left", "left"); //event, keysym
|
||||||
|
mapInputEventToKeyDown("character_down", "down"); //event, keysym
|
||||||
|
mapInputEventToKeyDown("character_right", "right"); //event, keysym
|
||||||
|
|
||||||
|
mapInputEventToKeyUp("character_up", "up"); //event, keysym
|
||||||
|
mapInputEventToKeyUp("character_left", "left"); //event, keysym
|
||||||
|
mapInputEventToKeyUp("character_down", "down"); //event, keysym
|
||||||
|
mapInputEventToKeyUp("character_right", "right"); //event, keysym
|
||||||
|
|
||||||
//this function must always be called, or the engine won't run
|
//this function must always be called, or the engine won't run
|
||||||
initWindow("Airport Game", 800, 600, false);
|
initWindow("Airport Game", 800, 600, false);
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
import node;
|
import node;
|
||||||
|
|
||||||
|
//constants
|
||||||
|
var SPEED: int const = 10;
|
||||||
|
|
||||||
//variables
|
//variables
|
||||||
var parent: opaque = null;
|
var parent: opaque = null;
|
||||||
var x: int = 50;
|
var x: int = 50;
|
||||||
var y: int = 50;
|
var y: int = 50;
|
||||||
|
|
||||||
|
var xspeed: int = 0;
|
||||||
|
var yspeed: int = 0;
|
||||||
|
|
||||||
//accessors
|
//accessors
|
||||||
fn getX(node: opaque) {
|
fn getX(node: opaque) {
|
||||||
print "Called getX";
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,8 +31,53 @@ fn onInit(node: opaque) {
|
|||||||
print "accessed parent";
|
print "accessed parent";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn onKeyDown(node: opaque, event: string) {
|
||||||
|
if (event == "character_up") {
|
||||||
|
yspeed -= SPEED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == "character_down") {
|
||||||
|
yspeed += SPEED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == "character_left") {
|
||||||
|
xspeed -= SPEED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == "character_right") {
|
||||||
|
xspeed += SPEED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn onKeyUp(node: opaque, event: string) {
|
||||||
|
if (event == "character_up" && yspeed < 0) {
|
||||||
|
yspeed = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == "character_down" && yspeed > 0) {
|
||||||
|
yspeed = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == "character_left" && xspeed < 0) {
|
||||||
|
xspeed = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == "character_right" && xspeed > 0) {
|
||||||
|
xspeed = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn onStep(node: opaque) {
|
fn onStep(node: opaque) {
|
||||||
print "render.toy:onStep()";
|
x += xspeed;
|
||||||
|
y += yspeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn onFree(node: opaque) {
|
fn onFree(node: opaque) {
|
||||||
@@ -37,7 +87,7 @@ fn onFree(node: opaque) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn onDraw(node: opaque) {
|
fn onDraw(node: opaque) {
|
||||||
print "render.toy:onDraw() called";
|
// print "render.toy:onDraw() called";
|
||||||
|
|
||||||
var px = parent.callNode("getX");
|
var px = parent.callNode("getX");
|
||||||
var py = parent.callNode("getY");
|
var py = parent.callNode("getY");
|
||||||
|
|||||||
111
core/engine.c
111
core/engine.c
@@ -11,6 +11,8 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
#include "literal_array.h"
|
||||||
|
#include "literal_dictionary.h"
|
||||||
|
|
||||||
#include "console_colors.h"
|
#include "console_colors.h"
|
||||||
|
|
||||||
@@ -40,6 +42,12 @@ void initEngine() {
|
|||||||
fatalError("Failed to initialize SDL2");
|
fatalError("Failed to initialize SDL2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//init events
|
||||||
|
initLiteralArray(&engine.keyDownEvents);
|
||||||
|
initLiteralDictionary(&engine.symKeyDownEvents);
|
||||||
|
initLiteralArray(&engine.keyUpEvents);
|
||||||
|
initLiteralDictionary(&engine.symKeyUpEvents);
|
||||||
|
|
||||||
//init Toy
|
//init Toy
|
||||||
initInterpreter(&engine.interpreter);
|
initInterpreter(&engine.interpreter);
|
||||||
injectNativeHook(&engine.interpreter, "engine", hookEngine);
|
injectNativeHook(&engine.interpreter, "engine", hookEngine);
|
||||||
@@ -56,13 +64,9 @@ void initEngine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void freeEngine() {
|
void freeEngine() {
|
||||||
SDL_DestroyRenderer(engine.renderer);
|
|
||||||
SDL_DestroyWindow(engine.window);
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
//clear existing root node
|
//clear existing root node
|
||||||
if (engine.rootNode != NULL) {
|
if (engine.rootNode != NULL) {
|
||||||
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onFree");
|
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
|
||||||
|
|
||||||
freeEngineNode(engine.rootNode);
|
freeEngineNode(engine.rootNode);
|
||||||
|
|
||||||
@@ -71,14 +75,31 @@ void freeEngine() {
|
|||||||
|
|
||||||
freeInterpreter(&engine.interpreter);
|
freeInterpreter(&engine.interpreter);
|
||||||
|
|
||||||
|
//free events
|
||||||
|
freeLiteralArray(&engine.keyDownEvents);
|
||||||
|
freeLiteralDictionary(&engine.symKeyDownEvents);
|
||||||
|
freeLiteralArray(&engine.keyUpEvents);
|
||||||
|
freeLiteralDictionary(&engine.symKeyUpEvents);
|
||||||
|
|
||||||
|
//free SDL
|
||||||
|
SDL_DestroyRenderer(engine.renderer);
|
||||||
|
SDL_DestroyWindow(engine.window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
engine.renderer = NULL;
|
engine.renderer = NULL;
|
||||||
engine.window = NULL;
|
engine.window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void execStep() {
|
static void execEvents() {
|
||||||
//call onStep
|
//clear event lists
|
||||||
if (engine.rootNode != NULL) {
|
if (engine.keyDownEvents.count > 0) {
|
||||||
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onStep");
|
freeLiteralArray(&engine.keyDownEvents);
|
||||||
|
//NOTE: this is likely memory intensive - a more bespoke linked list designed for this task would be better
|
||||||
|
//NOTE: alternatively - manual memory-wipes, skipping the free step could be better
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyUpEvents.count > 0) {
|
||||||
|
freeLiteralArray(&engine.keyUpEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
//poll events
|
//poll events
|
||||||
@@ -103,8 +124,65 @@ static void execStep() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//TODO: input
|
//input
|
||||||
|
case SDL_KEYDOWN: {
|
||||||
|
//determine the given keycode
|
||||||
|
Literal keycodeLiteral = TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
|
||||||
|
if (!existsLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral)) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//get the event name
|
||||||
|
Literal eventLiteral = getLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral);
|
||||||
|
|
||||||
|
//push to the event list
|
||||||
|
pushLiteralArray(&engine.keyDownEvents, eventLiteral);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_KEYUP: {
|
||||||
|
//determine the given keycode
|
||||||
|
Literal keycodeLiteral = TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
|
||||||
|
if (!existsLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the event name
|
||||||
|
Literal eventLiteral = getLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral);
|
||||||
|
|
||||||
|
//push to the event list
|
||||||
|
pushLiteralArray(&engine.keyUpEvents, eventLiteral);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//callbacks
|
||||||
|
if (engine.rootNode != NULL) {
|
||||||
|
//key down events
|
||||||
|
for (int i = 0; i < engine.keyDownEvents.count; i++) {
|
||||||
|
LiteralArray args;
|
||||||
|
initLiteralArray(&args);
|
||||||
|
pushLiteralArray(&args, engine.keyDownEvents.literals[i]);
|
||||||
|
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onKeyDown", &args);
|
||||||
|
freeLiteralArray(&args);
|
||||||
|
}
|
||||||
|
|
||||||
|
//key up events
|
||||||
|
for (int i = 0; i < engine.keyUpEvents.count; i++) {
|
||||||
|
LiteralArray args;
|
||||||
|
initLiteralArray(&args);
|
||||||
|
pushLiteralArray(&args, engine.keyUpEvents.literals[i]);
|
||||||
|
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onKeyUp", &args);
|
||||||
|
freeLiteralArray(&args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void execStep() {
|
||||||
|
if (engine.rootNode != NULL) {
|
||||||
|
//steps
|
||||||
|
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onStep", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,18 +198,11 @@ void execEngine() {
|
|||||||
struct timeval delta = { .tv_sec = 0, .tv_usec = 1000 * 1000 / 60 }; //60 frames per second
|
struct timeval delta = { .tv_sec = 0, .tv_usec = 1000 * 1000 / 60 }; //60 frames per second
|
||||||
|
|
||||||
while (engine.running) {
|
while (engine.running) {
|
||||||
|
execEvents();
|
||||||
|
|
||||||
//calc the time passed
|
//calc the time passed
|
||||||
gettimeofday(&engine.realTime, NULL);
|
gettimeofday(&engine.realTime, NULL);
|
||||||
|
|
||||||
// printf("real time: %ld.%ld sim time: %ld.%ld + (delta: %ld.%ld)\n",
|
|
||||||
// engine.realTime.tv_sec,
|
|
||||||
// engine.realTime.tv_usec,
|
|
||||||
// engine.simTime.tv_sec,
|
|
||||||
// engine.simTime.tv_usec,
|
|
||||||
// delta.tv_sec,
|
|
||||||
// delta.tv_usec
|
|
||||||
// );
|
|
||||||
|
|
||||||
//if not enough time has passed
|
//if not enough time has passed
|
||||||
if (timercmp(&engine.simTime, &engine.realTime, <)) {
|
if (timercmp(&engine.simTime, &engine.realTime, <)) {
|
||||||
//while not enough time has passed
|
//while not enough time has passed
|
||||||
@@ -151,7 +222,7 @@ void execEngine() {
|
|||||||
SDL_SetRenderDrawColor(engine.renderer, 0, 0, 0, 255); //NOTE: This line can be disabled later
|
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
|
SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later
|
||||||
|
|
||||||
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onDraw");
|
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onDraw", NULL);
|
||||||
|
|
||||||
SDL_RenderPresent(engine.renderer);
|
SDL_RenderPresent(engine.renderer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include "engine_node.h"
|
#include "engine_node.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
|
#include "literal_array.h"
|
||||||
|
#include "literal_dictionary.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@@ -24,6 +27,13 @@ typedef struct _engine {
|
|||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
int screenWidth;
|
int screenWidth;
|
||||||
int screenHeight;
|
int screenHeight;
|
||||||
|
|
||||||
|
//input syms mapped to events
|
||||||
|
LiteralArray keyDownEvents; //list of events that occurred this frame
|
||||||
|
LiteralDictionary symKeyDownEvents; //keysym -> event names
|
||||||
|
|
||||||
|
LiteralArray keyUpEvents; //list of events that occurred this frame
|
||||||
|
LiteralDictionary symKeyUpEvents; //keysym -> event names
|
||||||
} Engine;
|
} Engine;
|
||||||
|
|
||||||
//extern singleton
|
//extern singleton
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ void freeEngineNode(EngineNode* node) {
|
|||||||
node->freeMemory(node);
|
node->freeMemory(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key) {
|
Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key, LiteralArray* args) {
|
||||||
Literal ret = TO_NULL_LITERAL;
|
Literal ret = TO_NULL_LITERAL;
|
||||||
|
|
||||||
//if this fn exists
|
//if this fn exists
|
||||||
@@ -116,6 +116,12 @@ Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Litera
|
|||||||
|
|
||||||
pushLiteralArray(&arguments, n);
|
pushLiteralArray(&arguments, n);
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
for (int i = 0; i < args->count; i++) {
|
||||||
|
pushLiteralArray(&arguments, args->literals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callLiteralFn(interpreter, fn, &arguments, &returns);
|
callLiteralFn(interpreter, fn, &arguments, &returns);
|
||||||
|
|
||||||
ret = popLiteralArray(&returns);
|
ret = popLiteralArray(&returns);
|
||||||
@@ -130,18 +136,18 @@ Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Litera
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName) {
|
Literal callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName, LiteralArray* args) {
|
||||||
//call "fnName" on this node, and all children, if it exists
|
//call "fnName" on this node, and all children, if it exists
|
||||||
Literal key = TO_IDENTIFIER_LITERAL(copyString(fnName, strlen(fnName)), strlen(fnName));
|
Literal key = TO_IDENTIFIER_LITERAL(copyString(fnName, strlen(fnName)), strlen(fnName));
|
||||||
|
|
||||||
Literal ret = callEngineNodeLiteral(node, interpreter, key);
|
Literal ret = callEngineNodeLiteral(node, interpreter, key, args);
|
||||||
|
|
||||||
freeLiteral(key);
|
freeLiteral(key);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key) {
|
void callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key, LiteralArray* args) {
|
||||||
//if this fn exists
|
//if this fn exists
|
||||||
if (existsLiteralDictionary(node->functions, key)) {
|
if (existsLiteralDictionary(node->functions, key)) {
|
||||||
Literal fn = getLiteralDictionary(node->functions, key);
|
Literal fn = getLiteralDictionary(node->functions, key);
|
||||||
@@ -152,6 +158,13 @@ void callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter,
|
|||||||
initLiteralArray(&arguments);
|
initLiteralArray(&arguments);
|
||||||
initLiteralArray(&returns);
|
initLiteralArray(&returns);
|
||||||
|
|
||||||
|
//feed the arguments in backwards!
|
||||||
|
if (args) {
|
||||||
|
for (int i = args->count -1; i >= 0; i--) {
|
||||||
|
pushLiteralArray(&arguments, args->literals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pushLiteralArray(&arguments, n);
|
pushLiteralArray(&arguments, n);
|
||||||
|
|
||||||
callLiteralFn(interpreter, fn, &arguments, &returns);
|
callLiteralFn(interpreter, fn, &arguments, &returns);
|
||||||
@@ -166,16 +179,16 @@ void callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter,
|
|||||||
//recurse to the (non-tombstone) children
|
//recurse to the (non-tombstone) children
|
||||||
for (int i = 0; i < node->count; i++) {
|
for (int i = 0; i < node->count; i++) {
|
||||||
if (node->children[i] != NULL) {
|
if (node->children[i] != NULL) {
|
||||||
callRecursiveEngineNodeLiteral(node->children[i], interpreter, key);
|
callRecursiveEngineNodeLiteral(node->children[i], interpreter, key, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void callRecursiveEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName) {
|
void callRecursiveEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName, LiteralArray* args) {
|
||||||
//call "fnName" on this node, and all children, if it exists
|
//call "fnName" on this node, and all children, if it exists
|
||||||
Literal key = TO_IDENTIFIER_LITERAL(copyString(fnName, strlen(fnName)), strlen(fnName));
|
Literal key = TO_IDENTIFIER_LITERAL(copyString(fnName, strlen(fnName)), strlen(fnName));
|
||||||
|
|
||||||
callRecursiveEngineNodeLiteral(node, interpreter, key);
|
callRecursiveEngineNodeLiteral(node, interpreter, key, args);
|
||||||
|
|
||||||
freeLiteral(key);
|
freeLiteral(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,11 +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 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
|
CORE_API void freeEngineNode(EngineNode* node); //free and tombstone this node
|
||||||
|
|
||||||
CORE_API Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key);
|
CORE_API Literal callEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key, LiteralArray* args);
|
||||||
CORE_API Literal callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName); //call "fnName" on this node, and only this node, if it exists
|
CORE_API Literal callEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName, LiteralArray* args); //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 callRecursiveEngineNodeLiteral(EngineNode* node, Interpreter* interpreter, Literal key, LiteralArray* args);
|
||||||
CORE_API void callRecursiveEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName); //call "fnName" on this node, and all children, if it exists
|
CORE_API void callRecursiveEngineNode(EngineNode* node, Interpreter* interpreter, char* fnName, LiteralArray* args); //call "fnName" on this node, and all children, if it exists
|
||||||
|
|
||||||
CORE_API int loadTextureEngineNode(EngineNode* node, char* fname);
|
CORE_API int loadTextureEngineNode(EngineNode* node, char* fname);
|
||||||
CORE_API void freeTextureEngineNode(EngineNode* node);
|
CORE_API void freeTextureEngineNode(EngineNode* node);
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ static int nativeLoadRootNode(Interpreter* interpreter, LiteralArray* arguments)
|
|||||||
|
|
||||||
//clear existing root node
|
//clear existing root node
|
||||||
if (engine.rootNode != NULL) {
|
if (engine.rootNode != NULL) {
|
||||||
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onFree");
|
callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
|
||||||
|
|
||||||
freeEngineNode(engine.rootNode);
|
freeEngineNode(engine.rootNode);
|
||||||
FREE(EngineNode, engine.rootNode);
|
FREE(EngineNode, engine.rootNode);
|
||||||
@@ -137,7 +137,7 @@ static int nativeLoadRootNode(Interpreter* interpreter, LiteralArray* arguments)
|
|||||||
initEngineNode(engine.rootNode, &inner, tb, size);
|
initEngineNode(engine.rootNode, &inner, tb, size);
|
||||||
|
|
||||||
//init the new node (and ONLY this node)
|
//init the new node (and ONLY this node)
|
||||||
callEngineNode(engine.rootNode, &engine.interpreter, "onInit");
|
callEngineNode(engine.rootNode, &engine.interpreter, "onInit", NULL);
|
||||||
|
|
||||||
//cleanup
|
//cleanup
|
||||||
freeLiteralArray(&inner.stack);
|
freeLiteralArray(&inner.stack);
|
||||||
|
|||||||
@@ -2,7 +2,68 @@
|
|||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
//TODO: native input calls
|
#include "engine.h"
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
static int nativeMapInputEventToKey(Interpreter* interpreter, LiteralArray* arguments, LiteralDictionary* symKeyEventsPtr, char* fnName) {
|
||||||
|
//checks
|
||||||
|
if (arguments->count != 2) {
|
||||||
|
interpreter->errorOutput("Incorrect number of arguments passed to ");
|
||||||
|
interpreter->errorOutput(fnName);
|
||||||
|
interpreter->errorOutput("\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal symLiteral = popLiteralArray(arguments);
|
||||||
|
Literal evtLiteral = popLiteralArray(arguments);
|
||||||
|
|
||||||
|
Literal evtLiteralIdn = evtLiteral;
|
||||||
|
if (IS_IDENTIFIER(evtLiteral) && parseIdentifierToValue(interpreter, &evtLiteral)) {
|
||||||
|
freeLiteral(evtLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal symLiteralIdn = symLiteral;
|
||||||
|
if (IS_IDENTIFIER(symLiteral) && parseIdentifierToValue(interpreter, &symLiteral)) {
|
||||||
|
freeLiteral(symLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_STRING(symLiteral) || !IS_STRING(evtLiteral)) {
|
||||||
|
interpreter->errorOutput("Incorrect type of arguments passed to mapInputEventToKey\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//use the keycode for faster lookups
|
||||||
|
SDL_Keycode keycode = SDL_GetKeyFromName( AS_STRING(symLiteral) );
|
||||||
|
|
||||||
|
if (keycode == SDLK_UNKNOWN) {
|
||||||
|
interpreter->errorOutput("Unknown key found: ");
|
||||||
|
interpreter->errorOutput(SDL_GetError());
|
||||||
|
interpreter->errorOutput("\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal keycodeLiteral = TO_INTEGER_LITERAL( (int)keycode );
|
||||||
|
|
||||||
|
//save the sym-event pair
|
||||||
|
setLiteralDictionary(symKeyEventsPtr, keycodeLiteral, evtLiteral); //I could possibly map multiple events to one sym
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
freeLiteral(symLiteral);
|
||||||
|
freeLiteral(evtLiteral);
|
||||||
|
freeLiteral(keycodeLiteral);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//dry wrappers
|
||||||
|
static int nativeMapInputEventToKeyDown(Interpreter* interpreter, LiteralArray* arguments) {
|
||||||
|
return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyDownEvents, "mapInputEventToKeyDown");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nativeMapInputEventToKeyUp(Interpreter* interpreter, LiteralArray* arguments) {
|
||||||
|
return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyUpEvents, "mapInputEventToKeyUp");
|
||||||
|
}
|
||||||
|
|
||||||
//call the hook
|
//call the hook
|
||||||
typedef struct Natives {
|
typedef struct Natives {
|
||||||
@@ -13,9 +74,9 @@ typedef struct Natives {
|
|||||||
int hookInput(Interpreter* interpreter, Literal identifier, Literal alias) {
|
int hookInput(Interpreter* interpreter, Literal identifier, Literal alias) {
|
||||||
//build the natives list
|
//build the natives list
|
||||||
Natives natives[] = {
|
Natives natives[] = {
|
||||||
// {"mapInputEventToKey", nativeMapInputEventToKey},
|
{"mapInputEventToKeyDown", nativeMapInputEventToKeyDown},
|
||||||
|
{"mapInputEventToKeyUp", nativeMapInputEventToKeyUp},
|
||||||
// {"mapInputEventToMouse", nativeMapInputEventToMouse},
|
// {"mapInputEventToMouse", nativeMapInputEventToMouse},
|
||||||
// {"mapInputEventToSpecial", nativeMapInputEventToSpecial},
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static int nativeInitNode(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
EngineNode* engineNode = AS_OPAQUE(node);
|
EngineNode* engineNode = AS_OPAQUE(node);
|
||||||
|
|
||||||
//init the new node (and ONLY this node)
|
//init the new node (and ONLY this node)
|
||||||
callEngineNode(engineNode, &engine.interpreter, "onInit");
|
callEngineNode(engineNode, &engine.interpreter, "onInit", NULL);
|
||||||
|
|
||||||
//cleanup
|
//cleanup
|
||||||
freeLiteral(node);
|
freeLiteral(node);
|
||||||
@@ -140,7 +140,7 @@ static int nativeFreeChildNode(Interpreter* interpreter, LiteralArray* arguments
|
|||||||
|
|
||||||
//free the node
|
//free the node
|
||||||
if (childNode != NULL) {
|
if (childNode != NULL) {
|
||||||
callRecursiveEngineNode(childNode, &engine.interpreter, "onFree");
|
callRecursiveEngineNode(childNode, &engine.interpreter, "onFree", NULL);
|
||||||
freeEngineNode(childNode);
|
freeEngineNode(childNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,7 +563,7 @@ static int nativeCallNode(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
Literal fnNameIdentifier = TO_IDENTIFIER_LITERAL(copyString(strptr, strlen(strptr)), strlen(strptr));
|
Literal fnNameIdentifier = TO_IDENTIFIER_LITERAL(copyString(strptr, strlen(strptr)), strlen(strptr));
|
||||||
|
|
||||||
//call the function
|
//call the function
|
||||||
Literal result = callEngineNodeLiteral(AS_OPAQUE(nodeLiteral), interpreter, fnNameIdentifier);
|
Literal result = callEngineNodeLiteral(AS_OPAQUE(nodeLiteral), interpreter, fnNameIdentifier, NULL);
|
||||||
|
|
||||||
pushLiteralArray(&interpreter->stack, result);
|
pushLiteralArray(&interpreter->stack, result);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user