Question

I'm writing a game engine and I'd like to use Io for scripting. The engine is written in pure C99, not C++. I've successfully bound Io to some of the game's C functions, and it works well.
However, I'd like to call Io methods in the C game loop. Essentially, I'd like to load a script (probably with IoState_doFile_()) containing something along the lines of

Game init := method(...)
Game keypress := method(key, ...)
// and update, render, etc

Then, in the C game loop, I'd like to call those functions, some of which I need to pass arguments to. Unfortunately, Io's documentation is good but incredibly sparse. I've dug through the IoVM code a bit and have found nothing useful (I'm probably not digging hard enough). What's the best way to do this? Something like

sprintf(buf, "Game update(%u)", &deltaTime);
IoState_doCString_(buf);

seems rather hackish (assuming it even works; I haven't tried), not to mention probably really inefficient.

Was it helpful?

Solution

According to this mailing-list thread, it is possible to use IoObject_rawDoString_label_() and IoState_retain_() to compile a message from source and apply it with IoMessage_locals_performOn_().

Alternatively, the message can be constructed manually via IoMessage_newWithName_() and the IoMessage_setCachedArg_*() functions.

I did not find any documentation for this, but the list of relevant functions can be found in IoMessage.h.

The code that works for this particular case is

/* When you initialize everything */
renderMessage = IoObject_rawDoString_label_(IoState_lobby(state),
    IoState_symbolWithCString_(state, "message(Game render())"),
    IoState_symbolWithCString_(state, "[Game render]"));
IoState_retain_(state, renderMessage);

/* In the game loop's render function */
IoMessage_locals_performOn_(renderMessage, IoState_lobby(state), IoState_lobby(state));

For messages that you need to pass arguments to, you need this instead:

/* When you initialize everything */
updateMessage = IoMessage_newWithName_(state, IoState_symbolWithCString_(state, "update"));
IoState_retain_(state, updateMessage);

/* In the game loop's update function */
IoMessage_setCachedArg_toInt_(updateMessage, 0, deltaTime);
IoMessage_locals_performOn_(updateMessage, IoState_lobby(state),
    IoObject_getSlot_(IoState_lobby(state), IoState_symbolWithCString_(state, "Game")));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top