I’m working on a signal system with intended behavior and API matching that of the traditional BindableEvent
(while adding some typechecking support and borrowing performance enhancements from Stravant’s GoodSignal).
In this structure, the signal’s “Event” object and the “Connection” objects created from it should not expose the parent “Signal” object, but both objects will internally need to know what that parent object is in order to properly perform their logic.
To manage this, I’ve been storing references to the parent Signal in weak tables indexed by the Event and Connection objects. This has worked fine for Connections, but I’m running into problems with the Event and Signal relationship. I can’t seem to figure out how to get both objects to reference each other and still get garbage-collected once they’re out of scope.
In researching the problem a bit, I found the following pattern to achieve a solution, and while it does work in standard Lua 5.1 (with the Luau features removed), it does not work in Luau. How can this be modified to allow the references to be correctly cleaned up?
--Build a weak table to hold the objects
local link_table = setmetatable({}, {__mode = "kv"})
do
--Create two elements and associate them with one another via the "link_table"
local element_1 = {}
local element_2 = {}
link_table[element_1] = element_2
link_table[element_2] = element_1
end
--At this point, the only references to either "element_1" or "element_2" are in the weak "link_table"
while task.wait() do --Yield to engine to allow for garbage collection to occur.
local count = 0
for _ in pairs(link_table) do
count += 1
end
print(count, link_table) --Always prints 2, table still has both elements in it.
end