diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-23 08:35:40 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-23 08:35:40 +0200 |
| commit | 17ca8b54fdc0aa2df875fc7b80def4dd56959d7f (patch) | |
| tree | 38cf24c341cd4165ccf58aac16eaea0725bb11ec /src | |
| parent | d468b693d79ddb416c45669e5ca8400cbdc34e85 (diff) | |
| download | lanes-17ca8b54fdc0aa2df875fc7b80def4dd56959d7f.tar.gz lanes-17ca8b54fdc0aa2df875fc7b80def4dd56959d7f.tar.bz2 lanes-17ca8b54fdc0aa2df875fc7b80def4dd56959d7f.zip | |
on_state_create receives a string argument, "lane" or "keeper"
Diffstat (limited to 'src')
| -rw-r--r-- | src/state.cpp | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/src/state.cpp b/src/state.cpp index 0175449..83b9e85 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
| @@ -207,22 +207,24 @@ static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) | |||
| 207 | 207 | ||
| 208 | // ################################################################################################# | 208 | // ################################################################################################# |
| 209 | 209 | ||
| 210 | static constexpr char const* kOnStateCreate{ "on_state_create" }; | ||
| 211 | |||
| 210 | void InitializeOnStateCreate(Universe* U_, lua_State* L_) | 212 | void InitializeOnStateCreate(Universe* U_, lua_State* L_) |
| 211 | { | 213 | { |
| 212 | STACK_CHECK_START_REL(L_, 1); // L_: settings | 214 | STACK_CHECK_START_REL(L_, 1); // L_: settings |
| 213 | if (luaG_getfield(L_, -1, "on_state_create") != LuaType::NIL) { // L_: settings on_state_create|nil | 215 | if (luaG_getfield(L_, -1, kOnStateCreate) != LuaType::NIL) { // L_: settings on_state_create|nil |
| 214 | // store C function pointer in an internal variable | 216 | // store C function pointer in an internal variable |
| 215 | U_->onStateCreateFunc = lua_tocfunction(L_, -1); // L_: settings on_state_create | 217 | U_->onStateCreateFunc = lua_tocfunction(L_, -1); // L_: settings on_state_create |
| 216 | if (U_->onStateCreateFunc != nullptr) { | 218 | if (U_->onStateCreateFunc != nullptr) { |
| 217 | // make sure the function doesn't have upvalues | 219 | // make sure the function doesn't have upvalues |
| 218 | char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? | 220 | char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? |
| 219 | if (_upname != nullptr) { // should be "" for C functions with upvalues if any | 221 | if (_upname != nullptr) { // should be "" for C functions with upvalues if any |
| 220 | raise_luaL_error(L_, "on_state_create shouldn't have upvalues"); | 222 | raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate); |
| 221 | } | 223 | } |
| 222 | // remove this C function from the config table so that it doesn't cause problems | 224 | // remove this C function from the config table so that it doesn't cause problems |
| 223 | // when we transfer the config table in newly created Lua states | 225 | // when we transfer the config table in newly created Lua states |
| 224 | lua_pushnil(L_); // L_: settings on_state_create nil | 226 | lua_pushnil(L_); // L_: settings on_state_create nil |
| 225 | lua_setfield(L_, -3, "on_state_create"); // L_: settings on_state_create | 227 | lua_setfield(L_, -3, kOnStateCreate); // L_: settings on_state_create |
| 226 | } else { | 228 | } else { |
| 227 | // optim: store marker saying we have such a function in the config table | 229 | // optim: store marker saying we have such a function in the config table |
| 228 | U_->onStateCreateFunc = reinterpret_cast<lua_CFunction>(InitializeOnStateCreate); | 230 | U_->onStateCreateFunc = reinterpret_cast<lua_CFunction>(InitializeOnStateCreate); |
| @@ -265,31 +267,35 @@ lua_State* create_state([[maybe_unused]] Universe* U_, lua_State* from_) | |||
| 265 | 267 | ||
| 266 | void CallOnStateCreate(Universe* U_, lua_State* L_, lua_State* from_, LookupMode mode_) | 268 | void CallOnStateCreate(Universe* U_, lua_State* L_, lua_State* from_, LookupMode mode_) |
| 267 | { | 269 | { |
| 268 | if (U_->onStateCreateFunc != nullptr) { | 270 | if (U_->onStateCreateFunc == nullptr) { |
| 269 | STACK_CHECK_START_REL(L_, 0); | 271 | return; |
| 270 | DEBUGSPEW_CODE(DebugSpew(U_) << "calling on_state_create()" << std::endl); | 272 | } |
| 271 | if (U_->onStateCreateFunc != reinterpret_cast<lua_CFunction>(InitializeOnStateCreate)) { | 273 | |
| 272 | // C function: recreate a closure in the new state, bypassing the lookup scheme | 274 | STACK_CHECK_START_REL(L_, 0); |
| 273 | lua_pushcfunction(L_, U_->onStateCreateFunc); // on_state_create() | 275 | DEBUGSPEW_CODE(DebugSpew(U_) << "calling on_state_create()" << std::endl); |
| 274 | } else { // Lua function located in the config table, copied when we opened "lanes.core" | 276 | if (U_->onStateCreateFunc != reinterpret_cast<lua_CFunction>(InitializeOnStateCreate)) { |
| 275 | if (mode_ != LookupMode::LaneBody) { | 277 | // C function: recreate a closure in the new state, bypassing the lookup scheme |
| 276 | // if attempting to call in a keeper state, do nothing because the function doesn't exist there | 278 | lua_pushcfunction(L_, U_->onStateCreateFunc); // on_state_create() |
| 277 | // this doesn't count as an error though | 279 | } else { // Lua function located in the config table, copied when we opened "lanes.core" |
| 278 | STACK_CHECK(L_, 0); | 280 | if (mode_ != LookupMode::LaneBody) { |
| 279 | return; | 281 | // if attempting to call in a keeper state, do nothing because the function doesn't exist there |
| 280 | } | 282 | // this doesn't count as an error though |
| 281 | kConfigRegKey.pushValue(L_); // L_: {} | 283 | STACK_CHECK(L_, 0); |
| 282 | STACK_CHECK(L_, 1); | 284 | return; |
| 283 | std::ignore = luaG_getfield(L_, -1, "on_state_create"); // L_: {} on_state_create() | ||
| 284 | lua_remove(L_, -2); // L_: on_state_create() | ||
| 285 | } | 285 | } |
| 286 | kConfigRegKey.pushValue(L_); // L_: {} | ||
| 286 | STACK_CHECK(L_, 1); | 287 | STACK_CHECK(L_, 1); |
| 287 | // capture error and raise it in caller state | 288 | std::ignore = luaG_getfield(L_, -1, kOnStateCreate); // L_: {} on_state_create() |
| 288 | if (lua_pcall(L_, 0, 0, 0) != LUA_OK) { | 289 | lua_remove(L_, -2); // L_: on_state_create() |
| 289 | raise_luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L_, -1) ? lua_tostring(L_, -1) : lua_typename(L_, lua_type(L_, -1))); | ||
| 290 | } | ||
| 291 | STACK_CHECK(L_, 0); | ||
| 292 | } | 290 | } |
| 291 | STACK_CHECK(L_, 1); | ||
| 292 | // capture error and raise it in caller state | ||
| 293 | std::string_view const _stateType{ mode_ == LookupMode::LaneBody ? "lane" : "keeper" }; | ||
| 294 | std::ignore = lua_pushstringview(L_, _stateType); // L_: on_state_create() "<type>" | ||
| 295 | if (lua_pcall(L_, 1, 0, 0) != LUA_OK) { | ||
| 296 | raise_luaL_error(from_, "%s failed: \"%s\"", kOnStateCreate, lua_isstring(L_, -1) ? lua_tostring(L_, -1) : lua_typename(L_, lua_type(L_, -1))); | ||
| 297 | } | ||
| 298 | STACK_CHECK(L_, 0); | ||
| 293 | } | 299 | } |
| 294 | 300 | ||
| 295 | // ################################################################################################# | 301 | // ################################################################################################# |
