@@ -66,101 +66,35 @@ void script_error(lua_State *L)
66
66
// Then push nargs arguments.
67
67
// Then call this function, which
68
68
// - 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
71
71
void script_run_callbacks (lua_State *L, int nargs, RunCallbacksMode mode)
72
72
{
73
- // Insert the return value into the lua stack, below the table
74
73
assert (lua_gettop (L) >= nargs + 1 );
75
74
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
81
76
lua_pushcfunction (L, script_error_handler);
82
- int errorhandler = rv + 1 ;
77
+ int errorhandler = lua_gettop (L) - nargs - 1 ;
83
78
lua_insert (L, errorhandler);
84
79
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 );
136
85
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 );
144
89
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>
150
92
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);
163
95
}
96
+
97
+ lua_remove (L, -2 ); // Remove error handler
164
98
}
165
99
166
100
0 commit comments