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 | // ################################################################################################# |