mirror of
https://github.com/Ukendio/jecs.git
synced 2025-08-04 03:09:18 +00:00
Support setting signal on cached Relation
Some checks are pending
Some checks are pending
This commit is contained in:
parent
4153a7cdfe
commit
add9ad3939
5 changed files with 64 additions and 85 deletions
26
jecs.luau
26
jecs.luau
|
@ -24,10 +24,10 @@ export type Archetype = {
|
||||||
|
|
||||||
export type QueryInner = {
|
export type QueryInner = {
|
||||||
compatible_archetypes: { Archetype },
|
compatible_archetypes: { Archetype },
|
||||||
ids: { i53 },
|
ids: { Id },
|
||||||
filter_with: { i53 },
|
filter_with: { Id },
|
||||||
filter_without: { i53 },
|
filter_without: { Id },
|
||||||
next: () -> (number, ...any),
|
next: () -> (Entity, ...any),
|
||||||
world: World,
|
world: World,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@ export type Query<T...> = typeof(setmetatable(
|
||||||
archetypes: (self: Query<T...>) -> { Archetype },
|
archetypes: (self: Query<T...>) -> { Archetype },
|
||||||
cached: (self: Query<T...>) -> Query<T...>,
|
cached: (self: Query<T...>) -> Query<T...>,
|
||||||
ids: { Id<any> },
|
ids: { Id<any> },
|
||||||
|
patch: (self: Query<T...>, fn: (T...) -> (T...)) -> (),
|
||||||
|
view: (self: Query<T...>) -> View<T...>,
|
||||||
-- world: World
|
-- world: World
|
||||||
},
|
},
|
||||||
{} :: {
|
{} :: {
|
||||||
|
@ -68,6 +70,12 @@ export type Observer = {
|
||||||
query: QueryInner,
|
query: QueryInner,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type observer = {
|
||||||
|
callback: (archetype: archetype) -> (),
|
||||||
|
query: query,
|
||||||
|
}
|
||||||
|
|
||||||
type archetype = {
|
type archetype = {
|
||||||
id: number,
|
id: number,
|
||||||
types: { i53 },
|
types: { i53 },
|
||||||
|
@ -504,7 +512,7 @@ local function ecs_pair_second(world: world, e: i53)
|
||||||
return ecs_get_alive(world, obj)
|
return ecs_get_alive(world, obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function query_match(query: QueryInner, archetype: archetype)
|
local function query_match(query: query, archetype: archetype)
|
||||||
local columns_map = archetype.columns_map
|
local columns_map = archetype.columns_map
|
||||||
local with = query.filter_with
|
local with = query.filter_with
|
||||||
|
|
||||||
|
@ -526,7 +534,7 @@ local function query_match(query: QueryInner, archetype: archetype)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function find_observers(world: world, event: i53, component: i53): { Observer }?
|
local function find_observers(world: world, event: i53, component: i53): { observer }?
|
||||||
local cache = world.observable[event]
|
local cache = world.observable[event]
|
||||||
if not cache then
|
if not cache then
|
||||||
return nil
|
return nil
|
||||||
|
@ -2615,7 +2623,7 @@ local function world_new()
|
||||||
table.insert(listeners, existing_hook)
|
table.insert(listeners, existing_hook)
|
||||||
end
|
end
|
||||||
|
|
||||||
local idr = world.component_index[component]
|
local idr = component_index[ECS_PAIR(component, EcsWildcard)] or component_index[component]
|
||||||
if idr then
|
if idr then
|
||||||
idr.on_add = on_add
|
idr.on_add = on_add
|
||||||
else
|
else
|
||||||
|
@ -2650,7 +2658,7 @@ local function world_new()
|
||||||
table.insert(listeners, existing_hook)
|
table.insert(listeners, existing_hook)
|
||||||
end
|
end
|
||||||
|
|
||||||
local idr = world.component_index[component]
|
local idr = component_index[ECS_PAIR(component, EcsWildcard)] or component_index[component]
|
||||||
if idr then
|
if idr then
|
||||||
idr.on_change = on_change
|
idr.on_change = on_change
|
||||||
else
|
else
|
||||||
|
@ -2681,7 +2689,7 @@ local function world_new()
|
||||||
table.insert(listeners, existing_hook)
|
table.insert(listeners, existing_hook)
|
||||||
end
|
end
|
||||||
|
|
||||||
local idr = world.component_index[component]
|
local idr = component_index[ECS_PAIR(component, EcsWildcard)] or component_index[component]
|
||||||
if idr then
|
if idr then
|
||||||
idr.on_remove = on_remove
|
idr.on_remove = on_remove
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@rbxts/jecs",
|
"name": "@rbxts/jecs",
|
||||||
"version": "0.9.0-rc.7",
|
"version": "0.9.0-rc.8",
|
||||||
"description": "Stupidly fast Entity Component System",
|
"description": "Stupidly fast Entity Component System",
|
||||||
"main": "jecs.luau",
|
"main": "jecs.luau",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -1064,40 +1064,77 @@ end)
|
||||||
|
|
||||||
TEST("world:added", function()
|
TEST("world:added", function()
|
||||||
local world = jecs.world()
|
local world = jecs.world()
|
||||||
|
|
||||||
do CASE "Should work even if set after the component has been used"
|
do CASE "Should work even if set after the component has been used"
|
||||||
local A = world:component()
|
local A = world:component()
|
||||||
|
|
||||||
world:set(world:entity(), A, 2)
|
world:set(world:entity(), A, 2)
|
||||||
local ran = false
|
local ran = false
|
||||||
world:added(A, function()
|
world:added(A, function()
|
||||||
ran = true
|
ran = true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local entity = world:entity()
|
local entity = world:entity()
|
||||||
world:set(entity, A, 3)
|
world:set(entity, A, 3)
|
||||||
|
CHECK(ran)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do CASE "Should work even if set after the pair has been used"
|
||||||
|
local A = world:component()
|
||||||
|
local B = world:component()
|
||||||
|
|
||||||
|
world:set(world:entity(), A, 2)
|
||||||
|
world:set(world:entity(), pair(A, B), 2)
|
||||||
|
|
||||||
|
world:added(A, function()
|
||||||
|
ran = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
local entity = world:entity()
|
||||||
|
world:set(entity, pair(A, B), 3)
|
||||||
|
CHECK(ran)
|
||||||
|
end
|
||||||
|
|
||||||
|
do CASE "Should allow setting signal after Relation has been used as a component"
|
||||||
|
local A = world:component()
|
||||||
|
local B = world:component()
|
||||||
|
|
||||||
|
world:add(world:entity(), A)
|
||||||
|
|
||||||
|
world:added(A, function()
|
||||||
|
ran = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
world:add(world:entity(), pair(A, B))
|
||||||
|
CHECK(ran)
|
||||||
|
end
|
||||||
|
|
||||||
|
do CASE "Should invoke signal for the Relation being set as a key despite a pair with Relation having been cached"
|
||||||
|
local A = world:component()
|
||||||
|
local B = world:component()
|
||||||
|
|
||||||
|
world:add(world:entity(), pair(A, B))
|
||||||
|
|
||||||
|
world:added(A, function()
|
||||||
|
ran = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
world:add(world:entity(), A)
|
||||||
|
|
||||||
CHECK(ran)
|
CHECK(ran)
|
||||||
end
|
end
|
||||||
|
|
||||||
do CASE "Should not override hook"
|
do CASE "Should not override hook"
|
||||||
local A = world:component()
|
local A = world:component()
|
||||||
|
|
||||||
local count = 1
|
local count = 1
|
||||||
local function counter()
|
local function counter()
|
||||||
count += 1
|
count += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
world:set(A, jecs.OnAdd, counter)
|
world:set(A, jecs.OnAdd, counter)
|
||||||
world:added(A, counter)
|
world:added(A, counter)
|
||||||
world:set(world:entity(), A, false)
|
world:set(world:entity(), A, false)
|
||||||
CHECK(count == (1 + 2))
|
CHECK(count == (1 + 2))
|
||||||
world:set(world:entity(), A, false)
|
world:set(world:entity(), A, false)
|
||||||
|
|
||||||
CHECK(count == (1 + (2 * 2)))
|
CHECK(count == (1 + (2 * 2)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
TEST("world:range()", function()
|
TEST("world:range()", function()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ukendio/jecs"
|
name = "ukendio/jecs"
|
||||||
version = "0.9.0-rc.7"
|
version = "0.9.0-rc.8"
|
||||||
registry = "https://github.com/UpliftGames/wally-index"
|
registry = "https://github.com/UpliftGames/wally-index"
|
||||||
realm = "shared"
|
realm = "shared"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
local jecs = require("@jecs")
|
|
||||||
|
|
||||||
local world = jecs.world()
|
|
||||||
local pair = jecs.pair
|
|
||||||
|
|
||||||
local IsA = world:entity()
|
|
||||||
|
|
||||||
local traits = {
|
|
||||||
IsA = IsA
|
|
||||||
}
|
|
||||||
|
|
||||||
world:set(IsA, jecs.OnAdd, function(component, id)
|
|
||||||
local second = jecs.pair_second(world, id)
|
|
||||||
assert(second ~= component, "circular")
|
|
||||||
|
|
||||||
local is_tag = jecs.is_tag(world, second)
|
|
||||||
world:added(component, function(entity, _, value)
|
|
||||||
if is_tag then
|
|
||||||
world:add(entity, second)
|
|
||||||
else
|
|
||||||
world:set(entity, second, value)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
world:removed(component, function(entity)
|
|
||||||
world:remove(entity, second)
|
|
||||||
end)
|
|
||||||
|
|
||||||
if not is_tag then
|
|
||||||
world:changed(component, function(entity, _, value)
|
|
||||||
world:set(entity, second, value)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
local r = jecs.record(world, second) :: jecs.Record
|
|
||||||
local archetype = r.archetype
|
|
||||||
if not archetype then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local types = archetype.types
|
|
||||||
|
|
||||||
for _, id in types do
|
|
||||||
if jecs.is_tag(world, id) then
|
|
||||||
world:add(component, id)
|
|
||||||
else
|
|
||||||
local metadata = world:get(second, id)
|
|
||||||
if not world:has(component, id) then
|
|
||||||
world:set(component, id, metadata)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- jecs.bulk_insert(world, component, ids, values)
|
|
||||||
end)
|
|
||||||
|
|
||||||
local Witch = world:entity()
|
|
||||||
local Werewolf = world:entity()
|
|
||||||
|
|
||||||
local WereWitch = world:entity()
|
|
||||||
world:add(WereWitch, pair(IsA, Witch))
|
|
||||||
world:add(WereWitch, pair(IsA, Werewolf))
|
|
||||||
|
|
||||||
local e = world:entity()
|
|
||||||
world:add(e, WereWitch)
|
|
||||||
print(world:has(e, pair(IsA, Witch))) -- false
|
|
||||||
print(world:has(e, Witch)) -- true
|
|
Loading…
Reference in a new issue