Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Timing listeners using BindableEvents won't fire?

Asked by
compUcomp 417 Moderation Voter
4 years ago

I have this BindableEvent named "AddListener". It's parented to my timing script, which listens for these events and triggers the callback given when the time specified is reached. The signature is AddListener:Fire(id, triggerTime, cb). The first parameter is an identifier for the listener so I can remove it later if needed, kind of like with ContextActionService:BindAction. The second parameter is the number of minutes after midnight when the third parameter, the callback, should be executed. This is the timing script:

local listeners = {}
local AddListener = Instance.new("BindableEvent")
AddListener.Event:Connect(function (id, triggerTime, cb)
    listeners[id] = {
        ["triggerTime"] = triggerTime, 
        ["cb"] = cb
    }
end)
AddListener.Parent = script
local RemoveListener = Instance.new("BindableEvent")
RemoveListener.Event:Connect(function (id)
    listeners[id] = nil
end)
RemoveListener.Parent = script
min = 0
minRate = 60 -- how many times faster than a minute irl

while true do
    game.Lighting:SetMinutesAfterMidnight(min)
    local actualTime = wait(60 / minRate) / (60 / minRate) -- corrects for lag
    for i, v in pairs(listeners) do
        if v.triggerTime > min and v.triggerTime < min + actualTime then
            v.cb()
            print("executed timing listener with id " .. i) -- doesn't print
        end
    end
    min = min + actualTime
end

This is the listener, from another script:

local sss = game:GetService("ServerScriptService")
local addListener = sss.TimingScript:FindFirstChild("AddListener") or sss.TimingScript:WaitForChild("AddListener")
addListener:Fire("test", 60, function ()
    print("hello world!") -- doesn't print
end)

Both of these are server scripts. No errors are thrown, but neither of the print statements are ran.

1 answer

Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

If you want, you can use _G to make a global variable.

local listeners = {}

local AddListener = Instance.new("BindableEvent")
AddListener.Event:Connect(function(id, triggerTime, cb)
    listeners[id] = {
        ["triggerTime"] = triggerTime, 
        ["cb"] = cb
    }
    cb() -- Take you sure you called your function.
end)

local RemoveListener = Instance.new("BindableEvent")
RemoveListener.Event:Connect(function (id)
    listeners[id] = nil
end)

_G.GlobalVariables = {Added = AddListener, Remove = RemoveListener}

You can wait this variable with this function who return the Global Variable when is created with the other script. It's my personal method and other scripters use that.

local GlobalVariables = (function()
    repeat
        wait()
        if _G.GlobalVariables ~= nil then
            return _G.GlobalVariables 
        end
    until _G.GlobalVariables
end)()

GlobalVariables.Added:Fire("test", 60, function()
    print("hello world!")
end)

You don't have to assign a parent to your BindableEvent, he exist yet.

To any question post it on the commentaries!!

0
_G is slow because it doesn't know where the variable is and has to make a lot of checks which is slow, use module scripts or value objects if you really want a `global variable` royaltoe 5144 — 4y
0
I don't know but I use it everywhere and "Mad Games" has used this feature on each of its scripts. I think it's a good method. Personally I use module script when I want create a more complicate systeme and not just for a BindableEvent lol.. But indeed when you don't know what do you doing it's easily broken. NiniBlackJackQc 1562 — 4y
1
Thanks! I don't know what changed, but using _G works. compUcomp 417 — 4y
Ad

Answer this question