Detect a value when it has been changed in a table OOP

Hi, I’m currently making a FSM using OOP. I want to detect changes in the table but I currently have no idea how to do so. Here’s my code:

local FSM = {}

FSM.__index = FSM

local config = {
	init = "idle",
	states = {
		["Slide"]  = {from = {"sprint", "idle"}, to = "slide"},
		["Sprint"] = {from = {"idle"}, to = "sprint"},
	},
}

function FSM:Init()
	local self = setmetatable(config, FSM)
	
	self.currState = self.init

	return self
end

function FSM:Transition(state)
    -- irrelevant code, all it does is change the state
end

return FSM

I have tried using self.__newindex but that doesn’t seem to work. Also have tried to create an empty table or proxy table and but that would break my module because it doesnt return the FSM.__index = FSM (I think).
Any help is appreciated

1 Like

Return a proxy table whose __index and __newindex are functions that return the value normally from the actual table, and set the value normally into the actual table. Then you can modify them to your heart’s content, like firing a signal when variables are read or written, throwing errors when invalid members are accessed, etc.

2 Likes

Thanks, worked beautifully, turned out I was setting the wrong table to the metatable. I will be posting the code here for anyone else having the same issues.

function FSM:Init()
	local self = setmetatable(config, FSM)
	
	self.currState = self.init

	local mt = setmetatable(FSM, {
		__index = function(tbl, key)
			return self[key]
		end,
		__newindex = function(tbl, key, val)
			print(key, val)
			self[key] = val
			return self[key]
		end,
	})

	return mt
end

I still don’t get why its setmetatable(FSM, ... instead of setmetatable(self, ... though… With that being aside thank you very much for your reply

1 Like