@@ -43,7 +43,7 @@ lua_State *LuaState::getState() const {
4343
4444#ifndef LAPI_LUAJIT
4545
46- // Binds lua librares with the lua state
46+ // Binds lua libraries with the lua state
4747void LuaState::bindLibraries (Array libs) {
4848 for (int i = 0 ; i < libs.size (); i++) {
4949 String lib = ((String)libs[i]).to_lower ();
@@ -85,7 +85,7 @@ void LuaState::bindLibraries(Array libs) {
8585
8686#else
8787
88- // Binds lua librares with the lua state
88+ // Binds lua libraries with the lua state
8989void LuaState::bindLibraries (Array libs) {
9090 for (int i = 0 ; i < libs.size (); i++) {
9191 String lib = ((String)libs[i]).to_lower ();
@@ -141,10 +141,52 @@ void LuaState::setHook(Callable hook, int mask, int count) {
141141 lua_sethook (L, luaHook, mask, count);
142142}
143143
144+ void LuaState::indexForReading (String name) {
145+ #ifndef LAPI_GDEXTENSION
146+ Vector<String> strs = name.split (" ." );
147+ #else
148+ PackedStringArray strs = name.split (" ." );
149+ #endif
150+ for (String str : strs) {
151+ if (lua_type (L, -1 ) != LUA_TTABLE) {
152+ lua_pop (L, 1 );
153+ lua_pushnil (L);
154+ break ;
155+ }
156+ lua_getfield (L, -1 , str.ascii ().get_data ());
157+ lua_remove (L, -2 );
158+ }
159+ }
160+
161+ String LuaState::indexForWriting (String name) {
162+ #ifndef LAPI_GDEXTENSION
163+ Vector<String> strs = name.split (" ." );
164+ #else
165+ PackedStringArray strs = name.split (" ." );
166+ #endif
167+ String last = strs[strs.size () - 1 ];
168+ strs.remove_at (strs.size () - 1 );
169+ for (String str : strs) {
170+ if (lua_type (L, -1 ) != LUA_TTABLE) {
171+ lua_pop (L, 1 );
172+ lua_pushnil (L);
173+ break ;
174+ }
175+ lua_getfield (L, -1 , str.ascii ().get_data ());
176+ lua_remove (L, -2 );
177+ }
178+ return last;
179+ }
180+
144181// Returns true if a lua function exists with the given name
145182bool LuaState::luaFunctionExists (String functionName) {
183+ #ifndef LAPI_LUAJIT
184+ lua_pushglobaltable (L);
185+ #else
186+ lua_pushvalue (L, LUA_GLOBALSINDEX);
187+ #endif
188+ indexForReading (functionName);
146189 // LuaJIT does not return a type here
147- lua_getglobal (L, functionName.ascii ().get_data ());
148190 int type = lua_type (L, -1 );
149191 lua_pop (L, 1 );
150192 return type == LUA_TFUNCTION;
@@ -157,20 +199,52 @@ Variant LuaState::getVar(int index) const {
157199
158200// Pull a global variant from Lua to GDScript
159201Variant LuaState::pullVariant (String name) {
160- lua_getglobal (L, name.ascii ().get_data ());
202+ #ifndef LAPI_LUAJIT
203+ lua_pushglobaltable (L);
204+ #else
205+ lua_pushvalue (L, LUA_GLOBALSINDEX);
206+ #endif
207+ indexForReading (name);
208+ Variant val = getVar (-1 );
209+ lua_pop (L, 1 );
210+ return val;
211+ }
212+ Variant LuaState::getRegistryValue (String name) {
213+ lua_pushvalue (L, LUA_REGISTRYINDEX);
214+ indexForReading (name);
161215 Variant val = getVar (-1 );
162216 lua_pop (L, 1 );
163217 return val;
164218}
165219
220+ Ref<LuaError> LuaState::setRegistryValue (String name, Variant var) {
221+ lua_pushvalue (L, LUA_REGISTRYINDEX);
222+ String field = indexForWriting (name);
223+ if (lua_isnil (L, -1 )) {
224+ lua_pop (L, 1 );
225+ return LuaError::newError (" cannot index nil with string" , LuaError::ERR_RUNTIME); // Make it look natural.
226+ }
227+ Ref<LuaError> err = pushVariant (var);
228+ if (err.is_null ()) {
229+ lua_setfield (L, -2 , field.ascii ().get_data ());
230+ lua_pop (L, 1 );
231+ return nullptr ;
232+ }
233+ lua_pop (L, 1 );
234+ return err;
235+ }
236+
166237// call a Lua function from GDScript
167238Variant LuaState::callFunction (String functionName, Array args) {
168239 // push the error handler on to the stack
169240 lua_pushcfunction (L, luaErrorHandler);
170241
171- // put global function name on stack
172- lua_getglobal (L, functionName.ascii ().get_data ());
173-
242+ #ifndef LAPI_LUAJIT
243+ lua_pushglobaltable (L);
244+ #else
245+ lua_pushvalue (L, LUA_GLOBALSINDEX);
246+ #endif
247+ indexForReading (functionName);
174248 // push args
175249 for (int i = 0 ; i < args.size (); ++i) {
176250 pushVariant (args[i]);
@@ -193,11 +267,23 @@ Ref<LuaError> LuaState::pushVariant(Variant var) const {
193267
194268// Call pushVariant() and set it to a global name
195269Ref<LuaError> LuaState::pushGlobalVariant (String name, Variant var) {
270+ #ifndef LAPI_LUAJIT
271+ lua_pushglobaltable (L);
272+ #else
273+ lua_pushvalue (L, LUA_GLOBALSINDEX);
274+ #endif
275+ String field = indexForWriting (name);
276+ if (lua_isnil (L, -1 )) {
277+ lua_pop (L, 1 );
278+ return LuaError::newError (" cannot index nil with string" , LuaError::ERR_RUNTIME); // Make it look natural.
279+ }
196280 Ref<LuaError> err = pushVariant (var);
197281 if (err.is_null ()) {
198- lua_setglobal (L, name.ascii ().get_data ());
282+ lua_setfield (L, -2 , field.ascii ().get_data ());
283+ lua_pop (L, 1 );
199284 return nullptr ;
200285 }
286+ lua_pop (L, 1 );
201287 return err;
202288}
203289
@@ -332,7 +418,7 @@ Ref<LuaError> LuaState::pushVariant(lua_State *state, Variant var) {
332418 break ;
333419 }
334420
335- // If the type being pushed is a lua error, Raise a error
421+ // If the type being pushed is a lua error, Raise an error
336422#ifndef LAPI_GDEXTENSION
337423 if (Ref<LuaError> err = Object::cast_to<LuaError>(var.operator Object *()); !err.is_null ()) {
338424#else
0 commit comments