Ejemplo n.º 1
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;
  }

  // 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;
}
Ejemplo n.º 2
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;
}