Skip to content

Commit a0dce51

Browse files
committed
Move script_run_callbacks to Lua
1 parent 96f753a commit a0dce51

File tree

2 files changed

+57
-84
lines changed

2 files changed

+57
-84
lines changed

builtin/misc_register.lua

+39
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,45 @@ minetest.register_item(":", {
314314
groups = {not_in_creative_inventory=1},
315315
})
316316

317+
318+
function minetest.run_callbacks(callbacks, mode, ...)
319+
assert(type(callbacks) == "table")
320+
local cb_len = #callbacks
321+
if cb_len == 0 then
322+
if mode == 2 or mode == 3 then
323+
return true
324+
elseif mode == 4 or mode == 5 then
325+
return false
326+
end
327+
end
328+
local ret = nil
329+
for i = 1, cb_len do
330+
local cb_ret = callbacks[i](...)
331+
332+
if mode == 0 and i == 1 then
333+
ret = cb_ret
334+
elseif mode == 1 and i == cb_len then
335+
ret = cb_ret
336+
elseif mode == 2 then
337+
if not cb_ret or i == 1 then
338+
ret = cb_ret
339+
end
340+
elseif mode == 3 then
341+
if cb_ret then
342+
return cb_ret
343+
end
344+
ret = cb_ret
345+
elseif mode == 4 then
346+
if (cb_ret and not ret) or i == 1 then
347+
ret = cb_ret
348+
end
349+
elseif mode == 5 and cb_ret then
350+
return cb_ret
351+
end
352+
end
353+
return ret
354+
end
355+
317356
--
318357
-- Callback registration
319358
--

src/script/common/c_internal.cpp

+18-84
Original file line numberDiff line numberDiff line change
@@ -66,101 +66,35 @@ void script_error(lua_State *L)
6666
// Then push nargs arguments.
6767
// Then call this function, which
6868
// - runs the callbacks
69-
// - removes the table and arguments from the lua stack
70-
// - pushes the return value, computed depending on mode
69+
// - replaces the table and arguments with the return value,
70+
// computed depending on mode
7171
void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
7272
{
73-
// Insert the return value into the lua stack, below the table
7473
assert(lua_gettop(L) >= nargs + 1);
7574

76-
lua_pushnil(L);
77-
int rv = lua_gettop(L) - nargs - 1;
78-
lua_insert(L, rv);
79-
80-
// Insert error handler after return value
75+
// Insert error handler
8176
lua_pushcfunction(L, script_error_handler);
82-
int errorhandler = rv + 1;
77+
int errorhandler = lua_gettop(L) - nargs - 1;
8378
lua_insert(L, errorhandler);
8479

85-
// Stack now looks like this:
86-
// ... <return value = nil> <error handler> <table> <arg#1> <arg#2> ... <arg#n>
87-
88-
int table = errorhandler + 1;
89-
int arg = table + 1;
90-
91-
luaL_checktype(L, table, LUA_TTABLE);
92-
93-
// Foreach
94-
lua_pushnil(L);
95-
bool first_loop = true;
96-
while(lua_next(L, table) != 0){
97-
// key at index -2 and value at index -1
98-
luaL_checktype(L, -1, LUA_TFUNCTION);
99-
// Call function
100-
for(int i = 0; i < nargs; i++)
101-
lua_pushvalue(L, arg+i);
102-
if(lua_pcall(L, nargs, 1, errorhandler))
103-
script_error(L);
104-
105-
// Move return value to designated space in stack
106-
// Or pop it
107-
if(first_loop){
108-
// Result of first callback is always moved
109-
lua_replace(L, rv);
110-
first_loop = false;
111-
} else {
112-
// Otherwise, what happens depends on the mode
113-
if(mode == RUN_CALLBACKS_MODE_FIRST)
114-
lua_pop(L, 1);
115-
else if(mode == RUN_CALLBACKS_MODE_LAST)
116-
lua_replace(L, rv);
117-
else if(mode == RUN_CALLBACKS_MODE_AND ||
118-
mode == RUN_CALLBACKS_MODE_AND_SC){
119-
if((bool)lua_toboolean(L, rv) == true &&
120-
(bool)lua_toboolean(L, -1) == false)
121-
lua_replace(L, rv);
122-
else
123-
lua_pop(L, 1);
124-
}
125-
else if(mode == RUN_CALLBACKS_MODE_OR ||
126-
mode == RUN_CALLBACKS_MODE_OR_SC){
127-
if((bool)lua_toboolean(L, rv) == false &&
128-
(bool)lua_toboolean(L, -1) == true)
129-
lua_replace(L, rv);
130-
else
131-
lua_pop(L, 1);
132-
}
133-
else
134-
assert(0);
135-
}
80+
// Insert minetest.run_callbacks between error handler and table
81+
lua_getglobal(L, "minetest");
82+
lua_getfield(L, -1, "run_callbacks");
83+
lua_remove(L, -2);
84+
lua_insert(L, errorhandler + 1);
13685

137-
// Handle short circuit modes
138-
if(mode == RUN_CALLBACKS_MODE_AND_SC &&
139-
(bool)lua_toboolean(L, rv) == false)
140-
break;
141-
else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
142-
(bool)lua_toboolean(L, rv) == true)
143-
break;
86+
// Insert mode after table
87+
lua_pushnumber(L, (int) mode);
88+
lua_insert(L, errorhandler + 3);
14489

145-
// value removed, keep key for next iteration
146-
}
147-
148-
// Remove stuff from stack, leaving only the return value
149-
lua_settop(L, rv);
90+
// Stack now looks like this:
91+
// ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>
15092

151-
// Fix return value in case no callbacks were called
152-
if(first_loop){
153-
if(mode == RUN_CALLBACKS_MODE_AND ||
154-
mode == RUN_CALLBACKS_MODE_AND_SC){
155-
lua_pop(L, 1);
156-
lua_pushboolean(L, true);
157-
}
158-
else if(mode == RUN_CALLBACKS_MODE_OR ||
159-
mode == RUN_CALLBACKS_MODE_OR_SC){
160-
lua_pop(L, 1);
161-
lua_pushboolean(L, false);
162-
}
93+
if (lua_pcall(L, nargs + 2, 1, errorhandler)) {
94+
script_error(L);
16395
}
96+
97+
lua_remove(L, -2); // Remove error handler
16498
}
16599

166100

0 commit comments

Comments
 (0)