TenshiRuntimeState TenshiRuntimeInit(void) { TenshiRuntimeState ret; ret = (TenshiRuntimeState)(malloc(sizeof(struct _TenshiRuntimeState))); if (!ret) return NULL; ret->L = luaL_newstate(); if (!ret->L) { TenshiRuntimeDeinit(ret); return NULL; } // Load libraries TenshiRuntime_openlibs(ret->L); // Load actor library. This is special because it loads into the global // scope and not into a specific module. tenshi_open_actor(ret->L); // Load mailbox library. Similar thing. tenshi_open_mbox(ret->L); // Load get_device implementation. tenshi_open_get_device(ret->L); // Load install_trap_global implementation. tenshi_open_trap_global(ret->L); // Set up actor scheduler lua_pushcfunction(ret->L, ActorSchedulerInit); if (lua_pcall(ret->L, 0, 0, 0) != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Set up preemption trick threading_setup(ret->L); // Store ourselves into the registry lua_pushstring(ret->L, RIDX_RUNTIMESTATE); lua_pushlightuserdata(ret->L, ret); lua_settable(ret->L, LUA_REGISTRYINDEX); return ret; }
int main(int argc, char **argv) { printf("Hello world!\n"); TenshiRuntimeState s = TenshiRuntimeInit(); printf("Allocated state: %p\n", s); TenshiRegisterCFunctions(s, testprogram_runtimeentries); const char studentcode[] = "sensor = get_device('stestsensor')\n" "actuator = get_device('atestactuator')\n" "sensor_sampled = triggers.sampled(sensor)\n" "\n" "while true do\n" " local val = sensor_sampled:recv()\n" " print('sensor is ' .. tostring(val))\n" " actuator:send({val})\n" "end"; TenshiActorState a; int ret = LoadStudentcode(s, studentcode, strlen(studentcode), &a); printf("LoadStudentcode: %d, TenshiActorState: %p\n", ret, a); ret = ActorSetRunnable(a, 1); printf("ActorSetRunnable: %d\n", ret); int i = 0; while (i < 100) { printf("-----> Sent into sensor: %d\n", i); global_sensor_data = i; ret = TenshiFlagSensor(s, hax_dev_sensor); printf("TenshiFlagSensor: %d\n", ret); ret = TenshiRunQuanta(s); printf("Ran quanta %d, ret = %d\n", i, ret); i++; } TenshiRuntimeDeinit(s); printf("Done!\n"); return 0; }
TenshiRuntimeState TenshiRuntimeInit(void) { TenshiRuntimeState ret; ret = (TenshiRuntimeState)(malloc(sizeof(struct _TenshiRuntimeState))); if (!ret) return NULL; ret->L = luaL_newstate(); if (!ret->L) { TenshiRuntimeDeinit(ret); return NULL; } // Register checkxip function on ARM #ifdef __arm__ lua_setcheckxip(ret->L, lua_arm_checkxip); #endif // Load libraries TenshiRuntime_openlibs_phase1(ret->L); lua_gc(ret->L, LUA_GCCOLLECT, 0); // Load actor library. This is special because it loads into the global // scope and not into a specific module. tenshi_open_actor(ret->L); // Load mailbox library. Similar thing. tenshi_open_mbox(ret->L); // Load get_device implementation. tenshi_open_get_device(ret->L); // Load install_trap_global implementation. tenshi_open_trap_global(ret->L); TenshiRuntime_openlibs_phase2(ret->L); // Set up actor scheduler lua_pushcfunction(ret->L, ActorSchedulerInit); if (lua_pcall(ret->L, 0, 0, 0) != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Set up preemption trick threading_setup(ret->L); // Store ourselves into the registry lua_pushstring(ret->L, RIDX_RUNTIMESTATE); lua_pushlightuserdata(ret->L, ret); lua_settable(ret->L, LUA_REGISTRYINDEX); // Load the code for the actor that handles reading sensor updates and // updating sensor mailboxes ret->sensor_actor = ActorCreate(ret); if (!ret->sensor_actor) { TenshiRuntimeDeinit(ret); return NULL; } int ret_ = luaL_loadbuffer(ret->sensor_actor->L, sensor_actor_lc, sizeof(sensor_actor_lc), "sensor_actor.lua"); if (ret_ != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Load the code for the actor that handles reading actuator mailboxes and // updating actuators. ret->actuator_actor = ActorCreate(ret); if (!ret->actuator_actor) { TenshiRuntimeDeinit(ret); return NULL; } ret_ = luaL_loadbuffer(ret->actuator_actor->L, actuator_actor_lc, sizeof(actuator_actor_lc), "actuator_actor.lua"); if (ret_ != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Construct the RIDX_CHANGED_SENSORS table lua_pushstring(ret->L, RIDX_CHANGED_SENSORS); lua_newtable(ret->L); lua_settable(ret->L, LUA_REGISTRYINDEX); // Initialize RIDX_SENSORDEVMAP as a table with weak values that will be // used to map lightuserdata to Lua objects lua_pushstring(ret->L, RIDX_SENSORDEVMAP); lua_newtable(ret->L); lua_pushstring(ret->L, "__mode"); lua_pushstring(ret->L, "v"); lua_settable(ret->L, -3); lua_pushvalue(ret->L, -1); lua_setmetatable(ret->L, -2); lua_settable(ret->L, LUA_REGISTRYINDEX); lua_gc(ret->L, LUA_GCCOLLECT, 0); return ret; }