mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-05 18:41:05 +00:00
Add persistent unique identifiers for objects (#14135)
This commit is contained in:
parent
e0f8243629
commit
4f42b4308c
20 changed files with 257 additions and 19 deletions
|
@ -406,17 +406,13 @@ 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.(*)
|
||||
* 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.
|
||||
* (*) 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
|
||||
* since we lose control over the ref and the contained pointer.
|
||||
* using ::set_null() and removed from the core.object_refs and
|
||||
* core.object_by_guids tables.
|
||||
*/
|
||||
|
||||
void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
@ -434,8 +430,20 @@ void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
|
|||
|
||||
// object_refs[id] = object
|
||||
lua_pushinteger(L, cobj->getId()); // Push id
|
||||
lua_pushvalue(L, object); // Copy object to top of stack
|
||||
lua_pushvalue(L, object);
|
||||
lua_settable(L, objectstable);
|
||||
|
||||
// Get core.objects_by_guid table
|
||||
lua_getglobal(L, "core");
|
||||
lua_getfield(L, -1, "objects_by_guid");
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
objectstable = lua_gettop(L);
|
||||
|
||||
// objects_by_guid[guid] = object
|
||||
auto guid = cobj->getGUID();
|
||||
assert(!guid.empty());
|
||||
lua_pushvalue(L, object);
|
||||
lua_setfield(L, objectstable, guid.c_str());
|
||||
}
|
||||
|
||||
void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
|
||||
|
@ -445,6 +453,8 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
|
|||
|
||||
// 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);
|
||||
|
@ -460,6 +470,15 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
|
|||
lua_pushinteger(L, cobj->getId()); // Push id
|
||||
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_pushnil(L);
|
||||
lua_setfield(L, objectstable, cobj->getGUID().c_str());
|
||||
}
|
||||
|
||||
void ScriptApiBase::objectrefGetOrCreate(lua_State *L, ServerActiveObject *cobj)
|
||||
|
|
|
@ -119,6 +119,20 @@ int ObjectRef::l_is_valid(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// get_guid()
|
||||
int ObjectRef::l_get_guid(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
|
||||
ServerActiveObject *sao = getobject(ref);
|
||||
if (sao == nullptr)
|
||||
return 0;
|
||||
|
||||
std::string guid = sao->getGUID();
|
||||
lua_pushlstring(L, guid.c_str(), guid.size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_pos(self)
|
||||
int ObjectRef::l_get_pos(lua_State *L)
|
||||
{
|
||||
|
@ -2838,6 +2852,7 @@ luaL_Reg ObjectRef::methods[] = {
|
|||
// ServerActiveObject
|
||||
luamethod(ObjectRef, remove),
|
||||
luamethod(ObjectRef, is_valid),
|
||||
luamethod(ObjectRef, get_guid),
|
||||
luamethod_aliased(ObjectRef, get_pos, getpos),
|
||||
luamethod_aliased(ObjectRef, set_pos, setpos),
|
||||
luamethod(ObjectRef, add_pos),
|
||||
|
|
|
@ -61,6 +61,9 @@ private:
|
|||
// is_valid(self)
|
||||
static int l_is_valid(lua_State *L);
|
||||
|
||||
// get_guid()
|
||||
static int l_get_guid(lua_State *L);
|
||||
|
||||
// get_pos(self)
|
||||
static int l_get_pos(lua_State *L);
|
||||
|
||||
|
|
|
@ -62,6 +62,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");
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue