aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-23 08:35:40 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-23 08:35:40 +0200
commit17ca8b54fdc0aa2df875fc7b80def4dd56959d7f (patch)
tree38cf24c341cd4165ccf58aac16eaea0725bb11ec /src
parentd468b693d79ddb416c45669e5ca8400cbdc34e85 (diff)
downloadlanes-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.cpp56
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
210static constexpr char const* kOnStateCreate{ "on_state_create" };
211
210void InitializeOnStateCreate(Universe* U_, lua_State* L_) 212void 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
266void CallOnStateCreate(Universe* U_, lua_State* L_, lua_State* from_, LookupMode mode_) 268void 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// #################################################################################################