mirror of
https://github.com/CompeyDev/rusty-luau.git
synced 2024-12-12 04:40:40 +00:00
chore(Future): include await system and fallible futures
This commit is contained in:
parent
b5ba4d9e38
commit
6f02130e51
1 changed files with 38 additions and 8 deletions
|
@ -4,6 +4,12 @@ local mod = require("../mod")
|
|||
local Signal = mod.signal
|
||||
type Signal<T...> = mod.Signal<T...>
|
||||
|
||||
local result = require("result")
|
||||
local Result = result.Result
|
||||
export type Result<T, E> = result.Result<T, E>
|
||||
local Ok = result.Ok
|
||||
local Err = result.Err
|
||||
|
||||
local Future = {}
|
||||
export type Status = "initialized" | "running" | "cancelled" | "done"
|
||||
export type Future<T> = typeof(Future) & {
|
||||
|
@ -11,19 +17,14 @@ export type Future<T> = typeof(Future) & {
|
|||
_ret: T,
|
||||
_thread: thread,
|
||||
_spawnEvt: Signal<()>,
|
||||
_retEvt: Signal<T, Status>,
|
||||
_retEvt: Signal<T | Result<T, string>, Status>,
|
||||
_status: Status,
|
||||
}
|
||||
|
||||
function Future.new<T>(fn: (...any) -> T, args: { any })
|
||||
local function _constructor<T>(fn: (Signal<()>, Signal<T, Status>) -> (), args: { any })
|
||||
return setmetatable(
|
||||
{
|
||||
_thread = coroutine.create(function(spawnEvt: Signal<()>, retEvt: Signal<T, Status>)
|
||||
spawnEvt:Fire()
|
||||
|
||||
local ret = fn(table.unpack(args))
|
||||
retEvt:Fire(ret, "done")
|
||||
end),
|
||||
_thread = coroutine.create(fn),
|
||||
|
||||
_spawnEvt = Signal.new(),
|
||||
_retEvt = Signal.new(),
|
||||
|
@ -35,6 +36,25 @@ function Future.new<T>(fn: (...any) -> T, args: { any })
|
|||
)
|
||||
end
|
||||
|
||||
function Future.new<T>(fn: (...any) -> T, args: { any })
|
||||
return _constructor(function(spawnEvt: Signal<()>, retEvt: Signal<T, Status>)
|
||||
spawnEvt:Fire()
|
||||
|
||||
local ret = fn(table.unpack(args))
|
||||
retEvt:Fire(ret, "done")
|
||||
end, args)
|
||||
end
|
||||
|
||||
function Future.try<T>(fn: (...any) -> T, args: { any })
|
||||
return _constructor(function(spawnEvt: Signal<()>, retEvt: Signal<Result<T, string>, Status>)
|
||||
spawnEvt:Fire()
|
||||
|
||||
local ok, ret = pcall(fn, table.unpack(args))
|
||||
local result: Result<T, string> = if ok then Ok(ret) else Err(ret)
|
||||
retEvt:Fire(result, "done")
|
||||
end, args)
|
||||
end
|
||||
|
||||
function Future.poll<T>(self: Future<T>): (Status, T)
|
||||
if self._status == "initialized" then
|
||||
self._retEvt:Connect(function(firedRet, status: Status)
|
||||
|
@ -68,3 +88,13 @@ function Future.cancel<T>(self: Future<T>)
|
|||
self._retEvt:Fire(nil :: any, "cancelled")
|
||||
self._status = "cancelled"
|
||||
end
|
||||
|
||||
function Future.await<T>(self: Future<T>): T
|
||||
while true do
|
||||
local status: Status, ret: T = self:poll()
|
||||
|
||||
if status == "done" then
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue