Triggering replication of custom objects with __newindex?

So, I’m trying to clean up some code and replicate whenever a value changes. Right now I have replication working, but it serializes the entire object instead of just the deltas. Adding code to each updater function would technically work but would be cumbersome to maintain, so I was hoping to find a general solution to this problem by using __newindex to trigger replication of only properties that are being changed. I’d rather not use polling because that seems too… juvenile.

Here is a simplification of what I already have:

Car = {}
Car.__index = Car

function Car.new()
	local newcar = {}
	setmetatable(newcar, Car)
	newcar.value = 1
	return newcar
end

a = Car.new()
a.value = 2 -- an arbitrary function gets called when a property is changed in the table
print(a.value)

Is there an elegant way trigger a function on property set without impeding the property from being set?

1 Like

I believe you basically have to create a proxy table that acts as a middleman between the actual data and whatever is interfacing with it

Like @Crazyman32 said:

local function makeObject()
	local t = {}
	local mt = {}
	setmetatable(t, mt)

	local prop = {}

	function mt.__index(self, index)
		print("GET", index)
		return prop[index]
	end

	function mt.__newindex(self, index, value)
		print("SET", index, value)
		prop[index] = value
	end

	return t
end

local obj = makeObject()

obj.a = 1 --> SET a 1
print(obj.a) --> GET a
--> 1
1 Like

Is there a way to combine this with the conventions in this tutorial?

e.g.

Car = {}
Car.__index = Car
function Car.new(position, driver, model)
    local newcar = {}
    setmetatable(newcar, Car)
    newcar.Position = position
    newcar.Driver = driver
    newcar.Model = model
    return newcar
end
function Car:Boost()
    self.Speed = self.Speed + 5
end

Or is it a one-or-the-other kind of deal?

I’m not familiar enough with metatables to see a solution.

I think I’ve got it:

Car = {}
function Car.new(position, driver, model)
    local t = {Speed = 0}
	local mt = {}
	local proxy = {}
	setmetatable(t, mt)
	function mt.__index(self, index)
		return Car[index] or proxy[index]
	end

	function mt.__newindex(self, index, value)
		proxy[index] = value
	end
	
    return t
end
function Car:Boost()
    self.Speed = self.Speed + 5
end

a = Car.new()
a:Boost()
print(a.Speed)

instead of setting the __index of Car to itself, then setting the mt of the object to Car.

1 Like