diff options
Diffstat (limited to 'src/state.cpp')
-rw-r--r-- | src/state.cpp | 71 |
1 files changed, 2 insertions, 69 deletions
diff --git a/src/state.cpp b/src/state.cpp index 1975148..0757203 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
@@ -41,10 +41,6 @@ THE SOFTWARE. | |||
41 | #include "universe.h" | 41 | #include "universe.h" |
42 | 42 | ||
43 | // ################################################################################################# | 43 | // ################################################################################################# |
44 | |||
45 | static constexpr std::string_view kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes! | ||
46 | |||
47 | // ################################################################################################# | ||
48 | // ################################################################################################# | 44 | // ################################################################################################# |
49 | namespace { | 45 | namespace { |
50 | // ############################################################################################# | 46 | // ############################################################################################# |
@@ -157,42 +153,6 @@ namespace state { | |||
157 | // ############################################################################################# | 153 | // ############################################################################################# |
158 | // ############################################################################################# | 154 | // ############################################################################################# |
159 | 155 | ||
160 | void CallOnStateCreate(Universe* const U_, lua_State* const L_, lua_State* const from_, LookupMode const mode_) | ||
161 | { | ||
162 | if (U_->onStateCreateFunc == nullptr) { | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | STACK_CHECK_START_REL(L_, 0); | ||
167 | DEBUGSPEW_CODE(DebugSpew(U_) << "calling on_state_create()" << std::endl); | ||
168 | if (U_->onStateCreateFunc != reinterpret_cast<lua_CFunction>(InitializeOnStateCreate)) { | ||
169 | // C function: recreate a closure in the new state, bypassing the lookup scheme | ||
170 | lua_pushcfunction(L_, U_->onStateCreateFunc); // on_state_create() | ||
171 | } else { // Lua function located in the config table, copied when we opened "lanes.core" | ||
172 | if (mode_ != LookupMode::LaneBody) { | ||
173 | // if attempting to call in a keeper state, do nothing because the function doesn't exist there | ||
174 | // this doesn't count as an error though | ||
175 | STACK_CHECK(L_, 0); | ||
176 | return; | ||
177 | } | ||
178 | kConfigRegKey.pushValue(L_); // L_: {} | ||
179 | STACK_CHECK(L_, 1); | ||
180 | LuaType const _funcType{ luaG_getfield(L_, -1, kOnStateCreate) }; // L_: {} on_state_create() | ||
181 | if (_funcType != LuaType::FUNCTION) { | ||
182 | raise_luaL_error(L_, "INTERNAL ERROR: %s is a %s, not a function", kOnStateCreate.data(), luaG_typename(L_, _funcType).data()); | ||
183 | } | ||
184 | lua_remove(L_, -2); // L_: on_state_create() | ||
185 | } | ||
186 | STACK_CHECK(L_, 1); | ||
187 | // capture error and raise it in caller state | ||
188 | std::string_view const _stateType{ mode_ == LookupMode::LaneBody ? "lane" : "keeper" }; | ||
189 | luaG_pushstring(L_, _stateType); // L_: on_state_create() "<type>" | ||
190 | if (lua_pcall(L_, 1, 0, 0) != LUA_OK) { | ||
191 | raise_luaL_error(from_, "%s failed: \"%s\"", kOnStateCreate.data(), lua_isstring(L_, -1) ? luaG_tostring(L_, -1).data() : luaG_typename(L_, -1).data()); | ||
192 | } | ||
193 | STACK_CHECK(L_, 0); | ||
194 | } | ||
195 | |||
196 | // ############################################################################################# | 156 | // ############################################################################################# |
197 | 157 | ||
198 | lua_State* CreateState([[maybe_unused]] Universe* const U_, lua_State* const from_, std::string_view const& hint_) | 158 | lua_State* CreateState([[maybe_unused]] Universe* const U_, lua_State* const from_, std::string_view const& hint_) |
@@ -219,33 +179,6 @@ namespace state { | |||
219 | 179 | ||
220 | // ############################################################################################# | 180 | // ############################################################################################# |
221 | 181 | ||
222 | void InitializeOnStateCreate(Universe* const U_, lua_State* const L_) | ||
223 | { | ||
224 | STACK_CHECK_START_REL(L_, 1); // L_: settings | ||
225 | if (luaG_getfield(L_, -1, kOnStateCreate) != LuaType::NIL) { // L_: settings on_state_create|nil | ||
226 | // store C function pointer in an internal variable | ||
227 | U_->onStateCreateFunc = lua_tocfunction(L_, -1); // L_: settings on_state_create | ||
228 | if (U_->onStateCreateFunc != nullptr) { | ||
229 | // make sure the function doesn't have upvalues | ||
230 | char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? | ||
231 | if (_upname != nullptr) { // should be "" for C functions with upvalues if any | ||
232 | raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate.data()); | ||
233 | } | ||
234 | // remove this C function from the config table so that it doesn't cause problems | ||
235 | // when we transfer the config table in newly created Lua states | ||
236 | lua_pushnil(L_); // L_: settings on_state_create nil | ||
237 | luaG_setfield(L_, -3, kOnStateCreate); // L_: settings on_state_create | ||
238 | } else { | ||
239 | // optim: store marker saying we have such a function in the config table | ||
240 | U_->onStateCreateFunc = reinterpret_cast<lua_CFunction>(InitializeOnStateCreate); | ||
241 | } | ||
242 | } | ||
243 | lua_pop(L_, 1); // L_: settings | ||
244 | STACK_CHECK(L_, 1); | ||
245 | } | ||
246 | |||
247 | // ############################################################################################# | ||
248 | |||
249 | /* | 182 | /* |
250 | * Like 'luaL_openlibs()' but allows the set of libraries be selected | 183 | * Like 'luaL_openlibs()' but allows the set of libraries be selected |
251 | * | 184 | * |
@@ -274,7 +207,7 @@ namespace state { | |||
274 | STACK_CHECK(_L, 0); | 207 | STACK_CHECK(_L, 0); |
275 | 208 | ||
276 | // neither libs (not even 'base') nor special init func: we are done | 209 | // neither libs (not even 'base') nor special init func: we are done |
277 | if (!libs_.has_value() && U_->onStateCreateFunc == nullptr) { | 210 | if (!libs_.has_value() && std::holds_alternative<std::nullptr_t>(U_->onStateCreateFunc)) { |
278 | DEBUGSPEW_CODE(DebugSpew(U_) << "luaG_newstate(nullptr)" << std::endl); | 211 | DEBUGSPEW_CODE(DebugSpew(U_) << "luaG_newstate(nullptr)" << std::endl); |
279 | return _L; | 212 | return _L; |
280 | } | 213 | } |
@@ -342,7 +275,7 @@ namespace state { | |||
342 | 275 | ||
343 | // call this after the base libraries are loaded and GC is restarted | 276 | // call this after the base libraries are loaded and GC is restarted |
344 | // will raise an error in from_ in case of problem | 277 | // will raise an error in from_ in case of problem |
345 | CallOnStateCreate(U_, _L, from_, LookupMode::LaneBody); | 278 | U_->callOnStateCreate(_L, from_, LookupMode::LaneBody); |
346 | 279 | ||
347 | STACK_CHECK(_L, 0); | 280 | STACK_CHECK(_L, 0); |
348 | // after all this, register everything we find in our name<->function database | 281 | // after all this, register everything we find in our name<->function database |