diff --git a/crates/sapphire-jecs/lib/collect.luau b/crates/sapphire-jecs/lib/collect.luau new file mode 100644 index 0000000..5f00be6 --- /dev/null +++ b/crates/sapphire-jecs/lib/collect.luau @@ -0,0 +1,72 @@ +--!strict + +--[[ +original author by @memorycode +taken from https://github.com/Ukendio/jecs/blob/main/demo/src/ReplicatedStorage/std/collect.luau if there were any changes made there + +MIT License + +Copyright (c) 2024 Michael + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--]] + +--- What signals passed to `collect()` should be able to be coerced into +export type signal = { Connect: (self: signal, (T...) -> ()) -> any, [any]: any } + +--- Collects all arguments fired through the given signal, and drains the collection on iteration.\ +--- Expects signals to have a `Connect` ***method***. +--- ```luau +--- local sig = collect(some_signal) +--- +--- -- Imagine this as an ECS scheduler loop +--- while task.wait() do +--- for index, arg1 in sig do -- arg1, arg2, etc +--- print(arg1) +--- end +--- end +--- ``` +--- @param event signal +--- @return () -> (number, T...), () -> () -- iterator and disconnector +local function collect(event: signal): (() -> (number, T...), () -> ()) + local storage = {} + local mt = {} + local iter = function() + local n = #storage + return function(): (number?, T...) + if n <= 0 then + mt.__iter = nil + return nil + end + + n -= 1 + return n + 1, unpack(table.remove(storage, 1) :: any) + end + end + + local disconnect = event:Connect(function(...) + table.insert(storage, { ... }) + mt.__iter = iter :: any + end) + + setmetatable(storage, mt) + return storage :: any, disconnect +end + +return collect diff --git a/crates/sapphire-jecs/lib/init.luau b/crates/sapphire-jecs/lib/init.luau index 9779fd0..e61ca88 100644 --- a/crates/sapphire-jecs/lib/init.luau +++ b/crates/sapphire-jecs/lib/init.luau @@ -25,6 +25,8 @@ export type handle = handle.handle local _ref = require(script.ref) local ref = _ref.ref local ref_on_created = _ref.on_created +local collect = require(script.collect) +export type collect_signal = collect.signal local spawner_type = require(script.spawner_type) local SapphireJecs = {} @@ -131,6 +133,7 @@ end SapphireJecs.ref = ref SapphireJecs.on_created = ref_on_created +SapphireJecs.collect = collect --- Creates a new entity and returns its id. --- @return entity diff --git a/crates/sapphire-jecs/wally.toml b/crates/sapphire-jecs/wally.toml index fc36e8d..74125e3 100644 --- a/crates/sapphire-jecs/wally.toml +++ b/crates/sapphire-jecs/wally.toml @@ -1,6 +1,6 @@ [package] name = "mark-marks/sapphire-jecs" -version = "0.1.4" +version = "0.1.5" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" license = "MIT"