Flag
A lock for the threads of one program: whoever asks first gets it first.
RunAsync(work) holds the flag while work runs and lets go when it returns or errors, so it is the safe way in. PickupAsync hands you a FlagHolder to release yourself, or nil once the timeout passes. Make one with Flag.new().
Example
--!strict
-- Two purchases that wait in the middle of an update take turns on one Flag, first come first served.
local Flag = require("@shotsystem/Flag")
local Promise = require("@shotsystem/Promise")
local TimeService = require("@shotsystem/TimeService")
local wallet = { Coins = 100 }
local flag = Flag.new()
-- reads the coins, waits (as a save would), then writes them back
local function buy(item : string, price : number)
flag:RunAsync(function()
local coins = wallet.Coins
TimeService:WaitAsync(0.05)
wallet.Coins = coins - price
print(item, "bought, coins left:", wallet.Coins)
end)
end
local apple = Promise.Spawn(buy, "Apple", 30)
local pear = Promise.Spawn(buy, "Pear", 20)
print("while they run:", tostring(flag), flag.Taken)
Promise.AllAsync({ apple, pear })
print("coins:", wallet.Coins, tostring(flag), flag.Taken)
-- RunAsync gives back what the work returns, and lets go even when the work errors
print("result:", flag:RunAsync(function() return wallet.Coins, "coins" end))
print("error:", pcall(function()
flag:RunAsync(function() error("no stock", 0) end)
end))
print("taken after the error:", flag.Taken)while they run: Flag(taken) true Apple bought, coins left: 70 Pear bought, coins left: 50 coins: 50 Flag(free) false result: 50 coins error: false no stock taken after the error: false
Constructors
| Name | Arguments | Returns | Description |
|---|---|---|---|
| Flag.new | () | Flag |
Properties
| Name | Type | Default | Description |
|---|---|---|---|
| Taken | boolean | Whether a thread holds the flag now; false again after Release, and after RunAsync's work returns or errors. |
Methods
| Name | Arguments | Returns | Description |
|---|---|---|---|
| PickupAsync yields | (timeout: number?) | FlagHolder? | Waits its turn, in arrival order, for the flag and gives the FlagHolder, or nil once the timeout passes. |
| RunAsync yields | (work: () -> ...any) | ...any | Waits for the flag, runs work() holding it and gives back all its results; the flag is released even when work errors. |
