mirror of
https://github.com/CompeyDev/rusty-luau.git
synced 2024-12-12 04:40:40 +00:00
feat: include initial Future
impl
This commit is contained in:
parent
38704d18af
commit
01229741f6
4 changed files with 104 additions and 0 deletions
76
lib/future.luau
Normal file
76
lib/future.luau
Normal file
|
@ -0,0 +1,76 @@
|
|||
local task = require("@lune/task")
|
||||
|
||||
local mod = require("../mod")
|
||||
local Signal = mod.signal
|
||||
type Signal<T...> = mod.Signal<T...>
|
||||
|
||||
local option = require("option")
|
||||
type Option<T> = option.Option<T>
|
||||
local Some = option.Some
|
||||
local None = option.None
|
||||
|
||||
local Future = {}
|
||||
export type Status = "initialized" | "running" | "cancelled" | "done"
|
||||
export type Future<T> = typeof(Future) & {
|
||||
_fn: (set: (value: T) -> ()) -> T,
|
||||
_ret: T?,
|
||||
_thread: thread,
|
||||
_spawnEvt: Signal<()>,
|
||||
_retEvt: Signal<T, Status>,
|
||||
_status: Status,
|
||||
}
|
||||
|
||||
function Future.new<T>(fn: (...any) -> T, 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),
|
||||
|
||||
_spawnEvt = Signal.new(),
|
||||
_retEvt = Signal.new(),
|
||||
_status = "initialized",
|
||||
} :: Future<T>,
|
||||
{
|
||||
__index = Future,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
function Future.poll<T>(self: Future<T>): (Status, Option<T>)
|
||||
if self._status == "initialized" then
|
||||
self._retEvt:Connect(function(firedRet, status: Status)
|
||||
self._status = status
|
||||
self._ret = firedRet
|
||||
|
||||
-- Cleanup
|
||||
coroutine.yield(self._thread)
|
||||
coroutine.close(self._thread)
|
||||
|
||||
self._spawnEvt:DisconnectAll()
|
||||
self._retEvt:DisconnectAll()
|
||||
end)
|
||||
|
||||
self._spawnEvt:Connect(function()
|
||||
self._status = "running"
|
||||
end)
|
||||
|
||||
coroutine.resume(self._thread, self._spawnEvt, self._retEvt)
|
||||
end
|
||||
|
||||
if self._status == "running" then
|
||||
-- Just wait a bit more for the signal to fire
|
||||
task.wait(0.01)
|
||||
end
|
||||
|
||||
local retOpt = if self._ret == nil then None() else Some(self._ret)
|
||||
return self._status, retOpt
|
||||
end
|
||||
|
||||
function Future.cancel<T>(self: Future<T>)
|
||||
self._retEvt:Fire(nil :: any, "cancelled")
|
||||
self._status = "cancelled"
|
||||
end
|
14
mod.luau
Normal file
14
mod.luau
Normal file
|
@ -0,0 +1,14 @@
|
|||
local luau = require("@lune/luau")
|
||||
local fs = require("@lune/fs")
|
||||
|
||||
local SIGNAL_PATH = "Packages/_Index/ffrostflame_luausignal@0.2.4/luausignal/src/init.luau"
|
||||
local _signal = require(SIGNAL_PATH)
|
||||
export type Signal<T...> = _signal.luauSignal<T...>
|
||||
local signal: {
|
||||
new: <T...>() -> Signal<T...>,
|
||||
} =
|
||||
luau.load('local task = require("@lune/task")\n' .. fs.readFile(SIGNAL_PATH))()
|
||||
|
||||
return {
|
||||
signal = signal,
|
||||
}
|
13
wally.lock
Normal file
13
wally.lock
Normal file
|
@ -0,0 +1,13 @@
|
|||
# This file is automatically @generated by Wally.
|
||||
# It is not intended for manual editing.
|
||||
registry = "test"
|
||||
|
||||
[[package]]
|
||||
name = "compeydev/rusty-luau"
|
||||
version = "0.1.0"
|
||||
dependencies = [["luausignal", "ffrostflame/luausignal@0.2.4"]]
|
||||
|
||||
[[package]]
|
||||
name = "ffrostflame/luausignal"
|
||||
version = "0.2.4"
|
||||
dependencies = []
|
|
@ -8,3 +8,4 @@ exclude = ["tests/**", "examples/**", "**"]
|
|||
include = ["lib/**", "LICENSE.md", "README.md", "wally.toml"]
|
||||
|
||||
[dependencies]
|
||||
luausignal = "ffrostflame/luausignal@0.2.4"
|
Loading…
Reference in a new issue