--[[-- Core Module - Async - An extention of task and token to allow a single require to register and run async functions. @core Async @alias Async @usage -- To use Async you must register the allowed functions when the file is loaded, often this will just be giving access to -- some functions within a module if you expect that at part may be blocked by in game permissions or a custom system you have made -- you may also want to register functions that you want to have a time delay, such as waiting 2 seconds before printing a message -- When player.admin is called (either command or gui element event) by a player who isnt admin then it will error -- here we register the function to promote the player so that it will run async and outside the player scope local promote_player = Async.register(function(player) player.admin = true end) -- This will allow us to bypass the error by running one tick later outside of any player scope Async(promote_player,game.player) -- Here we make an sync function that we want to have a delay, note the delay is not defined here local print_message = Async.register(function(player,message) player.print(message) end) -- We can then call the async function with a delay using the wait function Async.wait(60, print_message, game.player, 'One second has passed!') ]] local Task = require 'utils.task' --- @dep utils.task local Token = require 'utils.token' --- @dep utils.token local Async = {} local internal_run = Token.register(function(params) local func = Token.get(params.token) return func(unpack(params.params)) end) --[[-- Register a new async function, must called when the file is loaded @function register @tparam function callback the function that can be called as an async function @treturn string the uid of the async function which can be passed to Async.run and Async.wait @usage-- Registering a function to set the admin state of a player local set_admin = Async.register(function(player, state) if player.valid then player.admin = state end end) @usage-- Registering a function to print to a player local print_to_player = Async.register(function(player, message) if player.valid then player.print(message) end end) ]] Async.register = Token.register --[[-- Runs an async function, you may supply any number of arguments as required by that function @tparam string token the token of the async function you want to run @tparam[opt] any ... the other params that you want to pass to your function @usage-- Make a player admin regardless of if you are admin Async.run(set_admin, player, true) ]] function Async.run(token,...) Task.queue_task(internal_run, { token = token, params = {...} }) end --[[-- Runs an async function after the given number of ticks, you may supply any number of arguments as required by that function @tparam number ticks the number of ticks that you want the function to run after @tparam string token the token of the async function you want to run @tparam[opt] any ... the other params that you want to pass to your function @usage-- Print a message to a player after 5 seconds Async.wait(300, print_to_player, 'Hello, World!') ]] function Async.wait(ticks,token,...) Task.set_timeout_in_ticks(ticks, internal_run, { token = token, params = {...} }) end return setmetatable(Async,{ __call = function(self,...) self.run(...) end })