feat: Add spawner util
+ Added spawner utility + Bumped to v0.1.4
This commit is contained in:
parent
33913122fd
commit
dcb55661ac
6 changed files with 501 additions and 2 deletions
|
@ -15,3 +15,4 @@ A set of utilities for [Jecs](https://github.com/ukendio/jecs)
|
|||
- [replicator](/lib/replicator.luau) - Keep track of all entities with the passed components and calculate differences
|
||||
- [ref](/lib/ref.luau) - Reference entities by key
|
||||
- [command_buffer](/lib/command_buffer.luau) - Buffer commands to prevent iterator invalidation
|
||||
- [spawner](/lib/spawner.luau) - Spawn entities with required components
|
||||
|
|
|
@ -3,18 +3,26 @@
|
|||
local jecs = require("@jecs")
|
||||
|
||||
local WORLD = require("./world")
|
||||
|
||||
local collect = require("./collect")
|
||||
export type collect_signal_like<T...> = collect.signal_like<any, T...>
|
||||
export type collect_verbose_signal_like<D, T...> = collect.signal_like<D, T...>
|
||||
|
||||
local command_buffer = require("./command_buffer")
|
||||
export type command_buffer = command_buffer.command_buffer
|
||||
|
||||
local handle = require("./handle")
|
||||
export type handle = handle.handle
|
||||
|
||||
local ref = require("./ref")
|
||||
|
||||
local replicator = require("./replicator")
|
||||
export type replicator = replicator.replicator
|
||||
export type changes = replicator.changes
|
||||
|
||||
local spawner = require("./spawner")
|
||||
export type spawner<T...> = spawner.spawner<T...>
|
||||
|
||||
--- Set the world for all utilities.
|
||||
--- Should be called once per context before any utility is used.
|
||||
--- @param world jecs.World
|
||||
|
@ -30,4 +38,5 @@ return {
|
|||
replicator = replicator,
|
||||
ref = ref,
|
||||
command_buffer = command_buffer,
|
||||
spawner = spawner,
|
||||
}
|
||||
|
|
49
lib/spawner.luau
Normal file
49
lib/spawner.luau
Normal file
|
@ -0,0 +1,49 @@
|
|||
--!strict
|
||||
local spawner_type = require("./spawner_type")
|
||||
local WORLD = require("./world").get
|
||||
local handle = require("./handle")
|
||||
|
||||
export type spawner<T...> = spawner_type.spawner<T...>
|
||||
|
||||
--- Creates an entity spawner.
|
||||
--- ```luau
|
||||
--- local spawner = jecs_utils.spawner(components.part, components.velocity, components.position)
|
||||
--- for _ = 1, 1000 do
|
||||
--- spawner.spawn(part_template:Clone(), Vector3.zero, Vector3.zero)
|
||||
--- end
|
||||
--- ```
|
||||
--- @param ... T... -- Components to use.
|
||||
--- @return spawner<T...>
|
||||
local function spawner(...)
|
||||
local components = { ... }
|
||||
local world = WORLD()
|
||||
|
||||
local function spawn(...)
|
||||
local passed = { ... }
|
||||
local entity = world:entity()
|
||||
|
||||
for idx, component in components do
|
||||
world:set(entity, component, passed[idx])
|
||||
end
|
||||
|
||||
return entity
|
||||
end
|
||||
|
||||
local function spawn_with_handle(...)
|
||||
local passed = { ... }
|
||||
local entity = handle(world:entity())
|
||||
|
||||
for idx, component in components do
|
||||
entity:set(component, passed[idx])
|
||||
end
|
||||
|
||||
return entity
|
||||
end
|
||||
|
||||
return {
|
||||
spawn = spawn,
|
||||
spawn_with_handle = spawn_with_handle,
|
||||
}
|
||||
end
|
||||
|
||||
return (spawner :: any) :: spawner_type.create_spawner
|
391
lib/spawner_type.luau
Normal file
391
lib/spawner_type.luau
Normal file
|
@ -0,0 +1,391 @@
|
|||
--!strict
|
||||
local jecs = require("@jecs")
|
||||
type entity<T = nil> = jecs.Entity<T>
|
||||
type id<T = nil> = jecs.Id<T>
|
||||
|
||||
local handle = require("./handle")
|
||||
|
||||
export type spawner<T...> = {
|
||||
--- Creates an entity with the given components.
|
||||
--- @param ... T...
|
||||
--- @return entity
|
||||
spawn: (T...) -> entity,
|
||||
--- Creates an entity with the given components and returns a handle to it.
|
||||
--- @param ... T...
|
||||
--- @return handle
|
||||
spawn_with_handle: (T...) -> handle.handle,
|
||||
}
|
||||
|
||||
-- Very beautiful type incoming!
|
||||
-- Sadly this has to be done, components are of different types than their values (`entity<T>` vs `T`)
|
||||
export type create_spawner =
|
||||
(<A>(id<A>) -> spawner<A>)
|
||||
& (<A, B>(id<A>, id<B>) -> spawner<A, B>)
|
||||
& (<A, B, C>(id<A>, id<B>, id<C>) -> spawner<A, B, C>)
|
||||
& (<A, B, C, D>(id<A>, id<B>, id<C>, id<D>) -> spawner<A, B, C, D>)
|
||||
& (<A, B, C, D, E>(id<A>, id<B>, id<C>, id<D>, id<E>) -> spawner<A, B, C, D, E>)
|
||||
& (<A, B, C, D, E, F>(id<A>, id<B>, id<C>, id<D>, id<E>, id<F>) -> spawner<A, B, C, D, E, F>)
|
||||
& (<A, B, C, D, E, F, G>(id<A>, id<B>, id<C>, id<D>, id<E>, id<F>, id<G>) -> spawner<A, B, C, D, E, F, G>)
|
||||
& (<A, B, C, D, E, F, G, H>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>
|
||||
) -> spawner<A, B, C, D, E, F, G, H>)
|
||||
& (<A, B, C, D, E, F, G, H, I>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>,
|
||||
id<U>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>,
|
||||
id<U>,
|
||||
id<V>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>,
|
||||
id<U>,
|
||||
id<V>,
|
||||
id<W>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>,
|
||||
id<U>,
|
||||
id<V>,
|
||||
id<W>,
|
||||
id<X>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>,
|
||||
id<U>,
|
||||
id<V>,
|
||||
id<W>,
|
||||
id<X>,
|
||||
id<Y>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y>)
|
||||
& (<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z>(
|
||||
id<A>,
|
||||
id<B>,
|
||||
id<C>,
|
||||
id<D>,
|
||||
id<E>,
|
||||
id<F>,
|
||||
id<G>,
|
||||
id<H>,
|
||||
id<I>,
|
||||
id<J>,
|
||||
id<K>,
|
||||
id<L>,
|
||||
id<M>,
|
||||
id<N>,
|
||||
id<O>,
|
||||
id<P>,
|
||||
id<Q>,
|
||||
id<R>,
|
||||
id<S>,
|
||||
id<T>,
|
||||
id<U>,
|
||||
id<V>,
|
||||
id<W>,
|
||||
id<X>,
|
||||
id<Y>,
|
||||
id<Z>
|
||||
) -> spawner<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z>)
|
||||
|
||||
return {}
|
|
@ -1,14 +1,17 @@
|
|||
--!strict
|
||||
-- stylua: ignore start
|
||||
local jecs = require("../jecs")
|
||||
local jecs = require("@jecs")
|
||||
local jecs_utils = require("@jecs_utils")
|
||||
local testkit = require("@testkit")
|
||||
|
||||
type entity<T = nil> = jecs.Entity<T>
|
||||
|
||||
local collect = jecs_utils.collect
|
||||
local handle = jecs_utils.handle
|
||||
local replicator = jecs_utils.replicator
|
||||
local ref = jecs_utils.ref
|
||||
local command_buffer = jecs_utils.command_buffer
|
||||
local spawner = jecs_utils.spawner
|
||||
|
||||
local signal = require("./signal")
|
||||
|
||||
|
@ -233,5 +236,51 @@ TEST("jecs_utils.command_buffer", function()
|
|||
end
|
||||
end)
|
||||
|
||||
TEST("jecs_utils.spawner()", function()
|
||||
do CASE "spawn"
|
||||
local world = jecs.World.new()
|
||||
jecs_utils.initialize(world)
|
||||
|
||||
local c1: entity<number> = world:component()
|
||||
local c2: entity<string> = world:component()
|
||||
local c3: entity<{}> = world:component()
|
||||
|
||||
local t1 = world:entity()
|
||||
|
||||
local entity_spawner = spawner(c1, c2, c3, t1)
|
||||
|
||||
local tbl = {}
|
||||
|
||||
local idx = entity_spawner.spawn(1234, "abcdef", tbl)
|
||||
CHECK(world:contains(idx))
|
||||
CHECK(world:get(idx, c1) == 1234)
|
||||
CHECK(world:get(idx, c2) == "abcdef")
|
||||
CHECK(world:get(idx, c3) == tbl)
|
||||
CHECK(world:has(idx, t1))
|
||||
end
|
||||
|
||||
do CASE "spawn_with_handle"
|
||||
local world = jecs.World.new()
|
||||
jecs_utils.initialize(world)
|
||||
|
||||
local c1: entity<number> = world:component()
|
||||
local c2: entity<string> = world:component()
|
||||
local c3: entity<{}> = world:component()
|
||||
|
||||
local t1 = world:entity()
|
||||
|
||||
local entity_spawner = spawner(c1, c2, c3, t1)
|
||||
|
||||
local tbl = {}
|
||||
|
||||
local ent = entity_spawner.spawn_with_handle(1234, "abcdef", tbl)
|
||||
CHECK(world:contains(ent:id()))
|
||||
CHECK(ent:get(c1) == 1234)
|
||||
CHECK(ent:get(c2) == "abcdef")
|
||||
CHECK(ent:get(c3) == tbl)
|
||||
CHECK(ent:has(t1))
|
||||
end
|
||||
end)
|
||||
|
||||
FINISH()
|
||||
-- stylua: ignore end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "mark-marks/jecs-utils"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
registry = "https://github.com/UpliftGames/wally-index"
|
||||
realm = "shared"
|
||||
license = "MIT"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue