3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
33 #include "serverobject.h"
37 static void stackDump(lua_State *L, std::ostream &o)
40 int top = lua_gettop(L);
41 for (i = 1; i <= top; i++) { /* repeat for each level */
42 int t = lua_type(L, i);
45 case LUA_TSTRING: /* strings */
46 o<<"\""<<lua_tostring(L, i)<<"\"";
49 case LUA_TBOOLEAN: /* booleans */
50 o<<(lua_toboolean(L, i) ? "true" : "false");
53 case LUA_TNUMBER: /* numbers */ {
55 snprintf(buf, 10, "%g", lua_tonumber(L, i));
59 default: /* other values */
60 o<<lua_typename(L, t);
69 static void realitycheck(lua_State *L)
71 int top = lua_gettop(L);
73 dstream<<"Stack is over 30:"<<std::endl;
74 stackDump(L, dstream);
75 script_error(L, "Stack is over 30 (reality check)");
79 // Register new object prototype
80 // register_entity(name, prototype)
81 static int l_register_entity(lua_State *L)
83 const char *name = luaL_checkstring(L, 1);
84 luaL_checktype(L, 2, LUA_TTABLE);
85 infostream<<"register_entity: "<<name<<std::endl;
87 // Get minetest.registered_entities
88 lua_getglobal(L, "minetest");
89 lua_getfield(L, -1, "registered_entities");
90 luaL_checktype(L, -1, LUA_TTABLE);
91 int registered_entities = lua_gettop(L);
92 lua_pushvalue(L, 2); // Object = param 2 -> stack top
93 // registered_entities[name] = object
94 lua_setfield(L, registered_entities, name);
96 // Get registered object to top of stack
99 // Set __index to point to itself
100 lua_pushvalue(L, -1);
101 lua_setfield(L, -2, "__index");
103 // Set metatable.__index = metatable
104 luaL_getmetatable(L, "minetest.entity");
105 lua_pushvalue(L, -1); // duplicate metatable
106 lua_setfield(L, -2, "__index");
107 // Set object metatable
108 lua_setmetatable(L, -2);
110 return 0; /* number of results */
114 static int l_new_entity(lua_State *L)
117 setmetatable(o, self)
122 luaL_checktype(L, -1, LUA_TTABLE);
123 luaL_getmetatable(L, "minetest.entity");
124 lua_pushvalue(L, -1); // duplicate metatable
125 lua_setfield(L, -2, "__index");
126 lua_setmetatable(L, -2);
132 static const struct luaL_Reg minetest_f [] = {
133 {"register_entity", l_register_entity},
134 //{"new_entity", l_new_entity},
138 static int l_entity_set_deleted(lua_State *L)
143 static const struct luaL_Reg minetest_entity_m [] = {
144 {"set_deleted", l_entity_set_deleted},
151 ServerActiveObject *m_object;
153 static const char className[];
154 static const luaL_reg methods[];
156 static ObjectRef *checkobject(lua_State *L, int narg)
158 luaL_checktype(L, narg, LUA_TUSERDATA);
159 void *ud = luaL_checkudata(L, narg, className);
160 if(!ud) luaL_typerror(L, narg, className);
161 return *(ObjectRef**)ud; // unbox pointer
164 // Exported functions
166 static int l_remove(lua_State *L)
168 ObjectRef *o = checkobject(L, 1);
169 ServerActiveObject *co = o->m_object;
170 if(co == NULL) return 0;
171 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
172 co->m_removed = true;
176 static int gc_object(lua_State *L) {
177 //ObjectRef *o = checkobject(L, 1);
178 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
179 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
185 ObjectRef(ServerActiveObject *object):
188 infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
194 infostream<<"ObjectRef destructing for id="<<m_object->getId()<<std::endl;
196 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;
199 // Creates an ObjectRef and leaves it on top of stack
200 // Not callable from Lua; all references are created on the C side.
201 static void create(lua_State *L, ServerActiveObject *object)
203 ObjectRef *o = new ObjectRef(object);
204 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
205 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
206 luaL_getmetatable(L, className);
207 lua_setmetatable(L, -2);
210 static void set_null(lua_State *L)
212 ObjectRef *o = checkobject(L, -1);
213 ServerActiveObject *co = o->m_object;
219 static void Register(lua_State *L)
222 int methodtable = lua_gettop(L);
223 luaL_newmetatable(L, className);
224 int metatable = lua_gettop(L);
226 lua_pushliteral(L, "__metatable");
227 lua_pushvalue(L, methodtable);
228 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
230 lua_pushliteral(L, "__index");
231 lua_pushvalue(L, methodtable);
232 lua_settable(L, metatable);
234 lua_pushliteral(L, "__gc");
235 lua_pushcfunction(L, gc_object);
236 lua_settable(L, metatable);
238 lua_pop(L, 1); // drop metatable
240 luaL_openlib(L, 0, methods, 0); // fill methodtable
241 lua_pop(L, 1); // drop methodtable
243 // Cannot be created from Lua
244 //lua_register(L, className, create_object);
248 const char ObjectRef::className[] = "ObjectRef";
250 #define method(class, name) {#name, class::l_##name}
252 const luaL_reg ObjectRef::methods[] = {
253 method(ObjectRef, remove),
257 void scriptapi_export(lua_State *L, Server *server)
260 assert(lua_checkstack(L, 20));
261 infostream<<"scriptapi_export"<<std::endl;
263 // Register global functions in table minetest
265 luaL_register(L, NULL, minetest_f);
266 lua_setglobal(L, "minetest");
268 // Get the main minetest table
269 lua_getglobal(L, "minetest");
271 // Add registered_entities table in minetest
273 lua_setfield(L, -2, "registered_entities");
275 // Add object_refs table in minetest
277 lua_setfield(L, -2, "object_refs");
279 // Add luaentities table in minetest
281 lua_setfield(L, -2, "luaentities");
283 // Load and run some base Lua stuff
284 /*script_load(L, (porting::path_data + DIR_DELIM + "scripts"
285 + DIR_DELIM + "base.lua").c_str());*/
287 // Create entity reference metatable
288 luaL_newmetatable(L, "minetest.entity_reference");
291 // Create entity prototype
292 luaL_newmetatable(L, "minetest.entity");
293 // metatable.__index = metatable
294 lua_pushvalue(L, -1); // Duplicate metatable
295 lua_setfield(L, -2, "__index");
296 // Put functions in metatable
297 luaL_register(L, NULL, minetest_entity_m);
298 // Put other stuff in metatable
300 // Entity C reference
301 ObjectRef::Register(L);
304 // Dump stack top with the dump2 function
305 static void dump2(lua_State *L, const char *name)
307 // Dump object (debug)
308 lua_getglobal(L, "dump2");
309 luaL_checktype(L, -1, LUA_TFUNCTION);
310 lua_pushvalue(L, -2); // Get previous stack top as first parameter
311 lua_pushstring(L, name);
312 if(lua_pcall(L, 2, 0, 0))
313 script_error(L, "error: %s\n", lua_tostring(L, -1));
316 void scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
317 const char *init_state)
320 assert(lua_checkstack(L, 20));
321 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
322 <<name<<"\""<<std::endl;
324 int initial_top = lua_gettop(L);
326 // Create object as a dummy string (TODO: Create properly)
328 // Get minetest.registered_entities[name]
329 lua_getglobal(L, "minetest");
330 lua_getfield(L, -1, "registered_entities");
331 luaL_checktype(L, -1, LUA_TTABLE);
332 lua_pushstring(L, name);
334 // Should be a table, which we will use as a prototype
335 luaL_checktype(L, -1, LUA_TTABLE);
336 int prototype_table = lua_gettop(L);
337 //dump2(L, "prototype_table");
339 // Create entity object
341 int object = lua_gettop(L);
343 // Set object metatable
344 lua_pushvalue(L, prototype_table);
345 lua_setmetatable(L, -2);
347 /*// Set prototype_table.__index = prototype_table
348 lua_pushvalue(L, prototype_table); // Copy to top of stack
349 lua_pushvalue(L, -1); // duplicate prototype_table
350 lua_setfield(L, -2, "__index");*/
352 /*lua_pushstring(L, "debug from C");
353 lua_setfield(L, -2, "on_step");*/
355 // Get minetest.luaentities table
356 lua_getglobal(L, "minetest");
357 lua_getfield(L, -1, "luaentities");
358 luaL_checktype(L, -1, LUA_TTABLE);
359 int luaentities = lua_gettop(L);
361 // luaentities[id] = object
362 lua_pushnumber(L, id); // Push id
363 lua_pushvalue(L, object); // Copy object to top of stack
364 lua_settable(L, luaentities);
366 lua_settop(L, initial_top); // Reset stack
369 void scriptapi_luaentity_rm(lua_State *L, u16 id)
372 assert(lua_checkstack(L, 20));
373 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
375 // Get minetest.luaentities table
376 lua_getglobal(L, "minetest");
377 lua_getfield(L, -1, "luaentities");
378 luaL_checktype(L, -1, LUA_TTABLE);
379 int objectstable = lua_gettop(L);
381 /*// Get luaentities[id]
382 lua_pushnumber(L, cobj->getId()); // Push id
383 lua_gettable(L, objectstable);
384 // Object is at stack top
385 lua_pop(L, 1); // pop object*/
387 // Set luaentities[id] = nil
388 lua_pushnumber(L, id); // Push id
390 lua_settable(L, objectstable);
392 lua_pop(L, 2); // pop luaentities, minetest
395 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
398 assert(lua_checkstack(L, 20));
399 infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
401 // Get minetest.luaentities[i]
402 lua_getglobal(L, "minetest");
403 lua_getfield(L, -1, "luaentities");
404 luaL_checktype(L, -1, LUA_TTABLE);
405 lua_pushnumber(L, id);
407 int object = lua_gettop(L);
408 // State: object is at top of stack
409 /*dump2(L, "entity");
410 lua_getmetatable(L, -1);
411 dump2(L, "getmetatable(entity)");
412 lua_getfield(L, -1, "__index");
413 dump2(L, "getmetatable(entity).__index");
417 lua_getfield(L, -1, "on_step");
418 luaL_checktype(L, -1, LUA_TFUNCTION);
419 lua_pushvalue(L, object); // self
420 lua_pushnumber(L, dtime); // dtime
421 // Call with 2 arguments, 0 results
422 if(lua_pcall(L, 2, 0, 0))
423 script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));
425 lua_pop(L, 1); // pop object
426 lua_pop(L, 2); // pop luaentities, minetest
429 std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
432 assert(lua_checkstack(L, 20));
433 infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
438 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
441 assert(lua_checkstack(L, 20));
442 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
444 // Create object on stack
445 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
446 int object = lua_gettop(L);
448 // Get minetest.object_refs table
449 lua_getglobal(L, "minetest");
450 lua_getfield(L, -1, "object_refs");
451 luaL_checktype(L, -1, LUA_TTABLE);
452 int objectstable = lua_gettop(L);
454 // object_refs[id] = object
455 lua_pushnumber(L, cobj->getId()); // Push id
456 lua_pushvalue(L, object); // Copy object to top of stack
457 lua_settable(L, objectstable);
459 // pop object_refs, minetest and the object
463 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
466 assert(lua_checkstack(L, 20));
467 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
469 // Get minetest.object_refs table
470 lua_getglobal(L, "minetest");
471 lua_getfield(L, -1, "object_refs");
472 luaL_checktype(L, -1, LUA_TTABLE);
473 int objectstable = lua_gettop(L);
475 // Get object_refs[id]
476 lua_pushnumber(L, cobj->getId()); // Push id
477 lua_gettable(L, objectstable);
478 // Set object reference to NULL
479 ObjectRef::set_null(L);
480 lua_pop(L, 1); // pop object
482 // Set object_refs[id] = nil
483 lua_pushnumber(L, cobj->getId()); // Push id
485 lua_settable(L, objectstable);
487 // pop object_refs, minetest