I’m working on an ambitious new project and I’ve run into an issue. Server => Client communication. A significant amount of data must be transferred from the server to the client to keep the client updated on what’s going on.
My hypothesis for this was to detect when the players’ data table was modified, then run some checks and set some hard values in the players’ directory that the player could read. Now maybe hard values aren’t the way to go, but I believe it’s the most efficient for my application.
This is the current code I have. It successfully detects changes with the surface values of the players’ data table. Meaning if I made a change to a deep table, this callback would never fire. I know I can use recursion to accomplish this. I just need someone smarter than me to help me.
Personally, I would suggest using a method to explicitly tell you the data has changed, but if you want to do it using metatables something like the following should work.
local function listenToDeepChanges(t, onChange)
local mt = {
__index = t,
__newindex = function (self, k, v)
if type(v) == "table" then
rawset(t, k, listenToDeepChanges(v, onChange))
else
rawset(t, k, v)
end
onChange(t, k, v)
end
}
for k, v in pairs(t) do
if type(v) == "table" then
t[k] = listenToDeepChanges(v, onChange)
end
end
return setmetatable({}, mt)
end
All you need to do then is call
local playerDataListening = listenToDeepChanges(playerData, function (updatedTable, key, newValue)
-- Do something here
end)
When faced with this type of problem I have opted to making an explicit function call when a data change occurs, like @ComplexGeometry mentioned above me.
If this approach is taken, to reduce code duplication, the data being changed should be encapsulated in a function/object that owns the data.