Making in-game events function

Hello everybody, I’m currently working on a game that will fire specific events (function) at a specific time. It’s pretty hard to explain so maybe Ill do it by showing the code concept.

for _, event in pairs(events) do
      local taskCoro = coroutine.create(event)
      coroutine.resume(taskCoro)
end

I hope now you know what I want to do.
Problem is, I need to have a way to stop executing all these functions.

StopEvents.Event:Connect(function()
      -- Running events will be saved
      for _, event in pairs(running_event) do
            somehow_stop_executing(event)
      end
end)

So to summarize events needs to be fired in something like coroutine (because a few may be run at once) and there needs to be a way to stop it from executing.
Events won’t be hard-coded so if I would do it by BindableEvents and Scripts I would need to use Instance.new(), etc.

Thank you for your time!

Use promises they have the ability to be cancelled.

Like this tween example:

local function tween(obj, tweenInfo, props)
	return Promise.new(function(resolve, reject, onCancel)
		local tween = TweenService:Create(obj, tweenInfo, props)
			
		-- Register a callback to be called if the Promise is cancelled.
		onCancel(function()
			tween:Cancel()
		end) 
			
		tween.Completed:Connect(resolve)
		tween:Play()
	end)
end

-- Begin tweening immediately
local promise = tween(workspace.Part, TweenInfo.new(2), { Transparency = 0.5 }):andThen(function()
	print("This is never printed.")
end):catch(function()
	print("This is never printed.")
end):finally(function()
	print("But this *is* printed!")
end)
wait(1)
promise:cancel() -- Cancel the Promise, which cancels the tween.

Instead of a tween have it be your event and such.

1 Like

Ill check this out and let you know if it will do a trick!
Thanks!

Well, there is a problem.

local Promise = require(game.ServerStorage.Promise)

local function event_executor()
	return Promise.new(function(resolve, reject, onCancel)
			onCancel(function()
				print('cancelling')
			end)
			
			print('a')
			wait(2)
			print('b')
			wait(2)
			print('c')
	end)
end


local promise = event_executor()

wait(2)
promise:cancel()
print("Cancelled!")

Output:

  20:44:51.842  a  -  Server - Script2:9
  20:44:55.009  b  -  Server - Script2:11
  20:44:55.159  cancelling  -  Server - Script2:6
  20:44:55.159  Cancelled!  -  Server - Script2:22
  20:44:57.020  c  -  Server - Script2:13

As you can see it does not stop.

So if you want to disconnect a listener then you have to define the listener then use :Disconnect() which will remove the running thread and stop the event from happening.

So do you have any idea how to implement that?

local connection
connection = StopEvents.Event:Connect(function()
for _, event in pairs(running_event) do
            connection:Disconnect()
      end
end)

This would not stop executing of any event. In above example “event” is a

print('a')
wait(2)
print('b')
wait(2)
print('c')

and you can see I wanted to stop it after 2 seconds, so c should not be printed.

You need to look at the examples provided in the documentation especially with chaining here is how it could be done.

Output:

  10:32:30.450  A  -  Server - Script:8
  10:32:32.452  B  -  Server - Script:11
  10:32:32.452  Cancelled!  -  Server - Script:22
local Promise = require(script.Promise)

local sleep = Promise.promisify(wait)

local function event_executor()
	return Promise.resolve():andThen(function()
		
		print("A")
	end):doneCall(sleep,2):andThen(function()

		print("B")
	end):doneCall(sleep,2):andThen(function()

		print("C")
	end)
end

local promise = event_executor()

wait(2)
promise:cancel()
print("Cancelled!")

The problem with this is “events” are not hard-coded. They are just functions (let’s call it X, you don’t know what X is)

x(args) -- You just run it.