Open appgurueu opened 6 months ago
Would it be possible to handle this via the Lua garbage collector? Similar to Weak Tables in Lua, just make it nil when it does no longer exist.
Would it be possible to handle this via the Lua garbage collector? Similar to Weak Tables in Lua, just make it nil when it does no longer exist.
Unfortunately I don't think that's possible without modifying Lua. With weak tables, you effectively mark the parent, telling Lua that children can still be garbage-collected (if there are no remaining "strong" references to them).
I'm not aware of any mechanism that would allow you to mark a userdatum (or a table for that matter) itself as collectable. (I also searched the reference manual and couldn't find anything that would be helpful here.)
(And even if such a mechanism existed, we couldn't rely on the GC actually collecting the userdatum in a timely manner, and for the remaining duration of its life, it would still be invalid.)
The only thing remaining here is whether to deprecate getters / setters on invalid objects. We probably don't want to deprecate getters since it is too much work for anyone involved, and they return nothing consistently. Setters may be deprecated in-code eventually, the docs already don't endorse this.
Object lifetime is managed by the engine. This means that the "rug can be pulled" from under a modder; an entity can become invalid from one server step to the next. Modders need to be careful to check this.
Getters will just return some kind of "invalid" value - sometimes even a valid value - while setters will just be no-ops. I believe this probably masks logic bugs.
I think the engine could help them here.
First and foremost, our docs should draw attention to the issue to make sure it isn't overlooked. This is relatively simple to do.
However, I don't think we should stop there. My suggestion:
is_valid
to provide an idiomatic way to check whether an objectref is valid; currently modders are inconsistently - and sometimes slightly wastefully - checkingobj:get_pos()
,obj:get_yaw()
etc.Ultimately, what we're doing here is implementing "optionals at home", where the default behavior is error-throwing unwrapping (which makes sense for our purposes).
Thoughts?