Skip to content

Commit

Permalink
Add core.obejcts_by_guid table, doc and test for it.
Browse files Browse the repository at this point in the history
  • Loading branch information
sfence committed Jan 22, 2024
1 parent 385116f commit 0337e3f
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 3 deletions.
1 change: 1 addition & 0 deletions builtin/game/features.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ core.features = {
wallmounted_rotate = true,
item_specific_pointabilities = true,
blocking_pointability_type = true,
have_guids = true,
}

function core.has_feature(arg)
Expand Down
4 changes: 4 additions & 0 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5302,6 +5302,8 @@ Utilities
item_specific_pointabilities = true,
-- Nodes `pointable` property can be `"blocking"` (5.9.0)
blocking_pointability_type = true,
-- objects have get_guid method and lua entities alse set_guid method (5.9.0)
have_guids = true,
}
```

Expand Down Expand Up @@ -7022,6 +7024,8 @@ Global tables
as they are only read when spawning.
* `minetest.object_refs`
* Map of object references, indexed by active object id
* `minetest.objects_by_guid`
* Map of object references, indexed by active object GUID
* `minetest.luaentities`
* Map of Lua entities, indexed by active object id
* `minetest.registered_abms`
Expand Down
2 changes: 2 additions & 0 deletions games/devtest/mods/unittests/entity.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,12 @@ local function test_entity_guid(_, pos)
obj:remove()
check_log({"on_deactivate(true)"})

assert(core.objects_by_guid["@UNITTEST"]==nil)
obj = core.add_entity(pos, "unittests:guid")
check_log({"on_activate(0)"})

assert(obj:get_guid()=="@UNITTEST")
assert(core.objects_by_guid["@UNITTEST"]~=nil)

obj:remove()
end
Expand Down
39 changes: 36 additions & 3 deletions src/script/cpp_api/s_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,12 @@ void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn)
/*
* How ObjectRefs are handled in Lua:
* When an active object is created, an ObjectRef is created on the Lua side
* and stored in core.object_refs[id].
* and stored in core.object_refs[id] and in core.objects_by_guids[[GUID].
* Methods that require an ObjectRef to a certain object retrieve it from that
* table instead of creating their own.(*)
* When an active object is removed, the existing ObjectRef is invalidated
* using ::set_null() and removed from the core.object_refs table.
* using ::set_null() and removed from the core.object_refs and
* core.object_by_guids tables.
* (*) An exception to this are NULL ObjectRefs and anonymous ObjectRefs
* for objects without ID.
* It's unclear what the latter are needed for and their use is problematic
Expand Down Expand Up @@ -431,13 +432,35 @@ void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
lua_settable(L, objectstable);
}

void ScriptApiBase::addObjectByGuid(ServerActiveObject *cobj)
{
SCRIPTAPI_PRECHECKHEADER
assert(getType() == ScriptingType::Server);

// Create object on stack
ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
int object = lua_gettop(L);

// Get core.objects_by_guid table
lua_getglobal(L, "core");
lua_getfield(L, -1, "objects_by_guid");
luaL_checktype(L, -1, LUA_TTABLE);
int objectstable = lua_gettop(L);

// objects_by_guid[GUID] = object
lua_pushstring(L, cobj->getGuid().c_str()); // Push GUID
lua_pushvalue(L, object); // Copy object to top of stack
lua_settable(L, objectstable);
}

void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
{
SCRIPTAPI_PRECHECKHEADER
assert(getType() == ScriptingType::Server);

// Get core.object_refs table
lua_getglobal(L, "core");
int core = lua_gettop(L);
lua_getfield(L, -1, "object_refs");
luaL_checktype(L, -1, LUA_TTABLE);
int objectstable = lua_gettop(L);
Expand All @@ -450,7 +473,17 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
lua_pop(L, 1); // pop object

// Set object_refs[id] = nil
lua_pushnumber(L, cobj->getId()); // Push id
lua_pushnumber(L, cobj->getId()); // Push GUID
lua_pushnil(L);
lua_settable(L, objectstable);

// Get core.objects_by_guid
lua_getfield(L, core, "objects_by_guid");
luaL_checktype(L, -1, LUA_TTABLE);
objectstable = lua_gettop(L);

// Set objects_by_guid[GUID] = nil
lua_pushstring(L, cobj->getGuid().c_str()); // Push GUID
lua_pushnil(L);
lua_settable(L, objectstable);
}
Expand Down
1 change: 1 addition & 0 deletions src/script/cpp_api/s_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class ScriptApiBase : protected LuaHelper {

/* object */
void addObjectReference(ServerActiveObject *cobj);
void addObjectByGuid(ServerActiveObject *cobj);
void removeObjectReference(ServerActiveObject *cobj);

ScriptingType getType() { return m_type; }
Expand Down
3 changes: 3 additions & 0 deletions src/script/scripting_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ ServerScripting::ServerScripting(Server* server):
lua_newtable(L);
lua_setfield(L, -2, "object_refs");

lua_newtable(L);
lua_setfield(L, -2, "objects_by_guid");

lua_newtable(L);
lua_setfield(L, -2, "luaentities");

Expand Down
2 changes: 2 additions & 0 deletions src/serverenvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,8 @@ u16 ServerEnvironment::addActiveObjectRaw(std::unique_ptr<ServerActiveObject> ob
m_script->addObjectReference(object);
// Post-initialize object
object->addedToEnvironment(dtime_s);
// After post-initialize, GUID is known
m_script->addObjectByGuid(object);

// Add static data to block
if (object->isStaticAllowed()) {
Expand Down

0 comments on commit 0337e3f

Please sign in to comment.