💾 Archived View for republic.circumlunar.space › users › korruptor › blog › 2022-12-20-EmbeddingWren… captured on 2024-06-16 at 12:21:39. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
It's Xmas time, which, amongst other things, means I have no guilt about working on the side project for a few days...
So I'm back on the EH500!
The last time I picked this up was in the Summer, so I decided to finish embedding Wren and get the rest of the "console" exposed to script.
When I last discussed this, I posted an example where I loaded a class of static methods and ticked those. I've changed tack since then in two fundamental ways.
First, a class of static methods is limited in what it can operate on (static members), so now I instantiate the class and adjust my call handles appropriately:
{ wrenEnsureSlots(s_pWrenVM, 1); wrenSetSlotHandle(s_pWrenVM, 0, s_pWH_LevelMode_ClassHandle); // // Call new() // wrenCall(s_pWrenVM, s_pWH_New); wrenReleaseHandle(s_pWrenVM, s_pWH_LevelMode_ClassHandle); s_pWH_LevelMode_ClassHandle = NULL; if (wrenGetSlotCount(s_pWrenVM) == 0) { LOG_ERROR("-- Interpreter error, calling LevelMode->new"); Framework_Guru(SCRIPT_ERROR); } s_pWH_LevelMode_ClassHandle = wrenGetSlotHandle(s_pWrenVM, 0); }
The instantiated class is free to create other objects, hold a list of things to tick, etc. which was what I needed all along.
Secondly, in the Summer, the platform API -- the foreign methods that map to console "registers" and functions in C-land -- was on disk, in its own module, that others could import. I didn't like this. So I've stolen a trick from the Wren implementation in Tic80; it's trivial to store the API in a string, in C code, and load it into VM as the first thing that's parsed, before I do any of the above.
static char const* s_sPlatformAPI = "\n\ class EH {\n\ construct new() {}\n\ foreign static GetFrameCount()\n\ foreign static GetGameDeltaSeconds()\n\ ... static TO_RADIANS { 0.0174532925 }\n\ static TO_DEGREES { 57.295779514 }\n\ static PI { 3.1415926535 }\n\ static SCREEN_WIDTH { 384 }\n\ static SCREEN_HEIGHT { 216 }\n\ static SCREEN_HALF_WIDTH { 192 }\n\ static SCREEN_HALF_HEIGHT { 108 }\n\ \ }\n"
This has the effect of adding a class full of static methods into module "main", making them accessible anywhere via an import:
import "main" for EH
From the scripting perspective, this makes no difference, but it removes the need for a source file on disk that could go missing or get out of sync with the EH500.
https://tdi.online/images/eh500_xmas.mp4
Bar palette manipulation, I have everything in the EH500 exposed to Wren. It's been quick to implement -- little more than a day -- and easy enough to test. The slot system is clean, simple and fits my needs perfectly.
It's taken me a while to grok the error messages from the interpreter, but that's no different than any other language... I just need to use it in anger.
Next steps: