// examples/embed.c -- add scripting to a C program with calog, in ~40 lines. // // The entire embedding surface is calog.h: create a runtime, register a native C // function the host provides, open a script context on an engine, fire-and-forget a // script, and calogPump on the host thread to service the script's calls back into // the host. Swap calogJsEngine for calogLuaEngine / calogSquirrelEngine to change // languages -- nothing else changes. #define _POSIX_C_SOURCE 200809L #include "calog.h" #include #include // A host-provided native, callable from any embedded engine. Runs on the host thread // (this one), during calogPump -- so it can touch host state without locking. static int32_t hostLog(CalogValueT *args, int32_t argCount, CalogValueT *result, void *userData) { (void)userData; calogValueNil(result); if (argCount != 1 || args[0].type != calogStringE) { return calogFail(result, calogErrArgE, "hostLog expects one string"); } printf("[host] %s\n", args[0].as.s.bytes); return calogOkE; } int main(void) { CalogT *calog; CalogContextT *ctx; struct timespec tick = { 0, 1000000 }; // 1 ms int i; calog = calogCreate(); calogRegister(calog, "hostLog", hostLog, NULL); ctx = calogContextOpen(calog, &calogJsEngine); calogContextEval(ctx, "hostLog('hello from JavaScript, ' + (6 * 7))"); // A real host pumps calog inside its own main loop; here we tick briefly so the // fire-and-forget script gets to run and call hostLog on this thread. for (i = 0; i < 50; i++) { calogPump(calog); nanosleep(&tick, NULL); } calogContextClose(ctx); calogDestroy(calog); return 0; }