Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add uuid to ObjectRefs for tracking objects between loads #5012

Open
orwell96 opened this issue Jan 8, 2017 · 14 comments · May be fixed by #14135
Open

Add uuid to ObjectRefs for tracking objects between loads #5012

orwell96 opened this issue Jan 8, 2017 · 14 comments · May be fixed by #14135
Labels
Concept approved Approved by a core dev: PRs welcomed! Feature request Issues that request the addition or enhancement of a feature @ Script API

Comments

@orwell96
Copy link
Contributor

orwell96 commented Jan 8, 2017

I have an ObjectRef and want to get it's Active Object ID.
Getting the active object ID of objects is hard, there seems to be only one way:

  1. have a reliably unique value in the object's Luaentity
  2. iterate minetest.luaentities and look for exactly that value
  3. retrieve the Active Object ID associated to it.

There should be an API call for ObjectRefs "object:get_id()" to get its ActiveObjectID.

Reason why I need this:
I want to check if certain entities are still loaded from a globalstep, by storing their ActiveObjectID in a table and looking if the ObjectRef still resides in minetest.object_refs

BTW, a reliable method to check if a stored ObjectRef is still loaded/associated to an SAO is to call object:getyaw(). If it returns nil, it is not.

@stujones11
Copy link
Contributor

stujones11 commented Jan 8, 2017

It is actually possible to iterate though minetest.luaentities and compare the objectRefs directly so step 1 is not strictly necessary, however, this would be a very useful feature.

@orwell96
Copy link
Contributor Author

orwell96 commented Jan 8, 2017

I don't know if comparing the ObjectRefs directly will work. Lua can only compare pointers, and if both are different, they will not match.

@stujones11
Copy link
Contributor

Lua can only compare pointers, and if both are different, they will not match.

You may well be right there, I don't know enough about the inner workings to comment but code like this has worked seemingly reliably for me in the past.

local function get_object_id(object)
	for id, entity in pairs(minetest.luaentities) do
		if entity.object == object then
			return id
		end
	end
end

@orwell96
Copy link
Contributor Author

orwell96 commented Jan 8, 2017

OK, when experience proved it...
Still not good.

@stujones11
Copy link
Contributor

Still not good.

I totally agree, this is a much needed feature for more advanced uses of SAOs that needs to be implemented in a proper way.

@paramat paramat added the Request / Suggestion The issue makes a suggestion for something that should be done but isn't a new feature. label Jan 12, 2017
@sorcerykid
Copy link
Contributor

sorcerykid commented Jan 27, 2017

I second this request. I'm taking a stab at using Lua entities for ambient sounds, and it would really help to have access to the active object IDs so that I could track when they are loaded and unloaded in the environment, similar to the implementation that orwell96 is suggesting above.

This should be an extremely easy change to the API since server active objects already have a getId( ) method in the parent class. Something like this in l_object.cpp perhaps?


// get_id(self)
int ObjectRef::l_get_id(lua_State *L)
{
        NO_MAP_LOCK_REQUIRED;
        ObjectRef *ref = checkobject(L, 1);
        ServerActiveObject *co = getluaobject(ref);
        if (co == NULL) return 0;
        // Do it
        lua_pushinteger(L, co->getId());
        return 1;
}

@rubenwardy rubenwardy added @ Script API Feature ✨ PRs that add or enhance a feature labels Apr 3, 2018
@rubenwardy
Copy link
Member

rubenwardy commented Apr 3, 2018

Is the object ID allocated when the object is loaded? If so, there's the possibility of IDs being reused which could cause obscure bugs

@nerzhul
Copy link
Member

nerzhul commented Apr 3, 2018

@rubenwardy little chance to be re-used as it's incremented on each entity and it's a u64
exposing get_id sounds reasonable

@rubenwardy rubenwardy changed the title Modding API: Make Active Object ID directly accessible from ObjectRef Add uuid to ObjectRefs for tracking objects between loads Feb 29, 2020
@paramat paramat added Feature request Issues that request the addition or enhancement of a feature and removed Feature ✨ PRs that add or enhance a feature Request / Suggestion The issue makes a suggestion for something that should be done but isn't a new feature. labels Mar 1, 2020
@paramat
Copy link
Contributor

paramat commented Mar 1, 2020

Old issue, is this supported by any core devs? I assume yes from the comments but please add the label if you do.

@sorcerykid
Copy link
Contributor

Relevant IRC discussion from yesterday:

http://irc.minetest.net/minetest-dev/2020-02-29

@rubenwardy
Copy link
Member

I support this and I think sfan5 does too

@sfan5 sfan5 added the Concept approved Approved by a core dev: PRs welcomed! label Mar 1, 2020
@fluxionary
Copy link
Contributor

I want to check if certain entities are still loaded from a globalstep, by storing their ActiveObjectID in a table and looking if the ObjectRef still resides in minetest.object_refs
little chance to be re-used as it's incremented on each entity and it's a u64

aren't object IDs u16? they currently do get re-used; object_ids are not unique over time, only at any given moment. it's possible that the id points to a different object when you do a check.

u16 getFreeId() const
{
// try to reuse id's as late as possible
static thread_local u16 last_used_id = 0;
u16 startid = last_used_id;
while (!isFreeId(++last_used_id)) {
if (last_used_id == startid)
return 0;
}
return last_used_id;
}
bool isFreeId(u16 id) const
{
return id != 0 && m_active_objects.find(id) == m_active_objects.end();
}
std::unordered_map<u16, T *> m_active_objects;

or has this become a proposal to increase the size of the id? i notice the title of the issue has changed, though the reasoning for that might have been on IRC...

BTW, a reliable method to check if a stored ObjectRef is still loaded/associated to an SAO is to call object:getyaw(). If it returns nil, it is not.

this works currently, but i thought this was discouraged?

minetest/doc/lua_api.txt

Lines 6943 to 6952 in f680d10

When you receive an `ObjectRef` as a callback argument or from another API
function, it is possible to store the reference somewhere and keep it around.
It will keep functioning until the object is unloaded or removed.
However, doing this is **NOT** recommended as there is (intentionally) no method
to test if a previously acquired `ObjectRef` is still valid.
Instead, `ObjectRefs` should be "let go" of as soon as control is returned from
Lua back to the engine.
Doing so is much less error-prone and you will never need to wonder if the
object you are working with still exists.

@sfan5
Copy link
Member

sfan5 commented Oct 15, 2022

#11050 btw

@sfence sfence linked a pull request Dec 20, 2023 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Concept approved Approved by a core dev: PRs welcomed! Feature request Issues that request the addition or enhancement of a feature @ Script API
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants