What’s the difference between Signal class and Methods?
The point is that you can attach a callback function to an “action” which will run when said action happens.
Directly
local TestModule = {}
TestModule.__index = TestModule
function TestModule.new()
local self = setmetatable({},TestModule)
self._listeners = {}
return self
end
-- this allows us to pass a function that will run on "test"
function TestModule:ListenForTest(func)
table.insert(self._listeners,func)
end
----------------------------------------------------------------
-- at this point we can fire the test listener whenever we want
function TestModule:Test(a,b,c)
-- do whatever we want
-- fire the listeners
for _,listener in ipairs (self._listeners) do
task.spawn(function()
listener(a,b,c)
end)
end
end
return TestModule
Other Code:
local TestModule = require(TestModule)
local new_test = TestModule.new()
new_test:ListenForTest(function(a,b,c)
-- this will fire when "Test" runs
print(a,b,c)
end)
new_test:Test()
Signal
The Signal Class is just a way to abstract the same code from above
local Signal = require(Signal)
local TestModule = {}
TestModule.__index = TestModule
function TestModule.new()
local self = setmetatable({},TestModule)
self.TestChanged = Signal.new()
return self
end
function TestModule:DoSomething()
-- change some stuff
self.TestChanged:Fire(thing_that_changed)
end
Other Code:
local TestModule = require(TestModule)
local new_test = TestModule.new()
new_test.TestChanged:Connect(function(test_that_changed)
print(test_that_changed)
end)
new_test:DoSomething()
Signals don’t need to be used exclusively in objects
If I’m calling the change why do I need a Signal? I already know I am changing something.
This is the real question you are asking. The answer is to decouple your code.
The point of of Event-Driven-Programming is you can write code based on “Events” and that code is completely unrelated to the code that “fires” the event.
Example:
-
You want to give a player a sword when a player joins, you can use game.Players.PlayerAdded:Connect(func)
-
Your code “Sword giving code” is completely unrelated to the code that handles a player joining (that’s all backend roblox code)
-
Now you have your “sword giver” decoupled from roblox’s code
The more decoupled your code is, the easier it is find a particular set of code, the easier it is to make changes in your code, and the easier it is to find bugs in your code.
Because of that most games (and other applications) use event driven programming in order to react to changes without coupling code between systems.
You don’t need to go out looking for places to use a Signals, but if you ever see yourself needing to know when state changes (because another system changed) it. You can consider Signals.
I leave you with the Game Programming Patterns book,
Specifically these pages:
Architecture (this page talks about decoupling)
Observer Pattern (a more primitive verison of events, but it’s the same idea)
The rest of the book is also a gold mine especially if you plan on making a big game with a lot of programmers.