aboutsummaryrefslogtreecommitdiff
path: root/src/state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.cpp')
-rw-r--r--src/state.cpp71
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
45static constexpr std::string_view kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes!
46
47// #################################################################################################
48// ################################################################################################# 44// #################################################################################################
49namespace { 45namespace {
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