mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-24 17:10:03 +00:00
decouple start
This commit is contained in:
parent
5deb7e5b35
commit
adeb562baa
7 changed files with 152 additions and 150 deletions
15
.luaurc
15
.luaurc
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"jecs": "src",
|
"jecs": "src",
|
||||||
"testkit": "testkit",
|
"testkit": "testkit",
|
||||||
"mirror": "mirror",
|
"mirror": "mirror",
|
||||||
}
|
},
|
||||||
}
|
languageMode: "strict"
|
||||||
|
}
|
||||||
|
|
BIN
demo.rbxl
BIN
demo.rbxl
Binary file not shown.
|
@ -7,7 +7,7 @@ local Scheduler = std.Scheduler
|
||||||
local world = std.world
|
local world = std.world
|
||||||
|
|
||||||
local function start(modules)
|
local function start(modules)
|
||||||
local scheduler = Scheduler.new(world, ReplicatedStorage.std.components)
|
local scheduler = Scheduler.new(world, require(ReplicatedStorage.std.components))
|
||||||
for _, module in modules do
|
for _, module in modules do
|
||||||
require(module)(scheduler)
|
require(module)(scheduler)
|
||||||
end
|
end
|
|
@ -19,7 +19,6 @@ local std = {
|
||||||
world = world :: World,
|
world = world :: World,
|
||||||
pair = jecs.pair,
|
pair = jecs.pair,
|
||||||
__ = jecs.w,
|
__ = jecs.w,
|
||||||
start = require(script.start)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return std
|
return std
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||||
local start = require(ReplicatedStorage.std.start)
|
local start = require(ReplicatedStorage.start)
|
||||||
|
|
||||||
start(script.Parent:WaitForChild("systems"):GetChildren())
|
start(script.Parent:WaitForChild("systems"):GetChildren())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||||
local start = require(ReplicatedStorage.std.start)
|
local start = require(ReplicatedStorage.start)
|
||||||
|
|
||||||
start(script.Parent:WaitForChild("systems"):GetChildren())
|
start(script.Parent:WaitForChild("systems"):GetChildren())
|
||||||
|
|
280
src/init.luau
280
src/init.luau
|
@ -740,172 +740,174 @@ local function world_clear(world: World, entity: i53)
|
||||||
entity_move(world.entityIndex, entity, record, ROOT_ARCHETYPE)
|
entity_move(world.entityIndex, entity, record, ROOT_ARCHETYPE)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function archetype_fast_delete_last(columns: { Column },
|
local world_delete: (world: World, entity: i53) -> ()
|
||||||
column_count: number, types: { i53 }, entity: i53)
|
do
|
||||||
|
local function archetype_fast_delete_last(columns: { Column },
|
||||||
|
column_count: number, types: { i53 }, entity: i53)
|
||||||
|
|
||||||
for i, column in columns do
|
for i, column in columns do
|
||||||
column[column_count] = nil
|
column[column_count] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function archetype_fast_delete(columns: { Column },
|
local function archetype_fast_delete(columns: { Column },
|
||||||
column_count: number, row, types, entity)
|
column_count: number, row, types, entity)
|
||||||
|
|
||||||
for i, column in columns do
|
for i, column in columns do
|
||||||
column[row] = column[column_count]
|
column[row] = column[column_count]
|
||||||
column[column_count] = nil
|
column[column_count] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local function archetype_delete(world: World,
|
||||||
|
archetype: Archetype, row: number)
|
||||||
|
|
||||||
local function archetype_delete(world: World,
|
local entityIndex = world.entityIndex
|
||||||
archetype: Archetype, row: number)
|
local columns = archetype.columns
|
||||||
|
local types = archetype.types
|
||||||
|
local entities = archetype.entities
|
||||||
|
local column_count = #entities
|
||||||
|
local last = #entities
|
||||||
|
local move = entities[last]
|
||||||
|
local delete = entities[row]
|
||||||
|
entities[row] = move
|
||||||
|
entities[last] = nil
|
||||||
|
|
||||||
local entityIndex = world.entityIndex
|
if row ~= last then
|
||||||
local columns = archetype.columns
|
-- TODO: should be "entity_index_sparse_get(entityIndex, move)"
|
||||||
local types = archetype.types
|
local record_to_move = entityIndex.sparse[move]
|
||||||
local entities = archetype.entities
|
if record_to_move then
|
||||||
local column_count = #entities
|
record_to_move.row = row
|
||||||
local last = #entities
|
end
|
||||||
local move = entities[last]
|
end
|
||||||
local delete = entities[row]
|
|
||||||
entities[row] = move
|
|
||||||
entities[last] = nil
|
|
||||||
|
|
||||||
if row ~= last then
|
-- TODO: if last == 0 then deactivate table
|
||||||
-- TODO: should be "entity_index_sparse_get(entityIndex, move)"
|
|
||||||
local record_to_move = entityIndex.sparse[move]
|
|
||||||
if record_to_move then
|
|
||||||
record_to_move.row = row
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO: if last == 0 then deactivate table
|
for _, id in types do
|
||||||
|
invoke_hook(world, EcsOnRemove, id, delete)
|
||||||
|
end
|
||||||
|
|
||||||
for _, id in types do
|
if row == last then
|
||||||
invoke_hook(world, EcsOnRemove, id, delete)
|
archetype_fast_delete_last(columns, column_count, types, delete)
|
||||||
end
|
else
|
||||||
|
archetype_fast_delete(columns, column_count, row, types, delete)
|
||||||
|
end
|
||||||
|
|
||||||
if row == last then
|
local component_index = world.componentIndex
|
||||||
archetype_fast_delete_last(columns, column_count, types, delete)
|
local archetypes = world.archetypes
|
||||||
else
|
|
||||||
archetype_fast_delete(columns, column_count, row, types, delete)
|
|
||||||
end
|
|
||||||
|
|
||||||
local component_index = world.componentIndex
|
local idr = component_index[delete]
|
||||||
local archetypes = world.archetypes
|
if idr then
|
||||||
|
local children = {}
|
||||||
|
for archetype_id in idr.cache do
|
||||||
|
local idr_archetype = archetypes[archetype_id]
|
||||||
|
|
||||||
local idr = component_index[delete]
|
for i, child in idr_archetype.entities do
|
||||||
if idr then
|
table.insert(children, child)
|
||||||
local children = {}
|
end
|
||||||
for archetype_id in idr.cache do
|
end
|
||||||
local idr_archetype = archetypes[archetype_id]
|
local flags = idr.flags
|
||||||
|
if bit32.band(flags, ECS_ID_DELETE) ~= 0 then
|
||||||
|
for _, child in children do
|
||||||
|
-- Cascade deletion to children
|
||||||
|
world_delete(world, child)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _, child in children do
|
||||||
|
world_remove(world, child, delete)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
for i, child in idr_archetype.entities do
|
component_index[delete] = nil
|
||||||
table.insert(children, child)
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
local flags = idr.flags
|
|
||||||
if bit32.band(flags, ECS_ID_DELETE) ~= 0 then
|
|
||||||
for _, child in children do
|
|
||||||
-- Cascade deletion to children
|
|
||||||
world_delete(world, child)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for _, child in children do
|
|
||||||
world_remove(world, child, delete)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
component_index[delete] = nil
|
-- TODO: iterate each linked record.
|
||||||
end
|
-- local r = ECS_PAIR(delete, EcsWildcard)
|
||||||
|
-- local idr_r = component_index[r]
|
||||||
|
-- if idr_r then
|
||||||
|
-- -- Doesn't work for relations atm
|
||||||
|
-- for archetype_id in idr_o.cache do
|
||||||
|
-- local children = {}
|
||||||
|
-- local idr_r_archetype = archetypes[archetype_id]
|
||||||
|
-- local idr_r_types = idr_r_archetype.types
|
||||||
|
|
||||||
-- TODO: iterate each linked record.
|
-- for _, child in idr_r_archetype.entities do
|
||||||
-- local r = ECS_PAIR(delete, EcsWildcard)
|
-- table.insert(children, child)
|
||||||
-- local idr_r = component_index[r]
|
-- end
|
||||||
-- if idr_r then
|
|
||||||
-- -- Doesn't work for relations atm
|
|
||||||
-- for archetype_id in idr_o.cache do
|
|
||||||
-- local children = {}
|
|
||||||
-- local idr_r_archetype = archetypes[archetype_id]
|
|
||||||
-- local idr_r_types = idr_r_archetype.types
|
|
||||||
|
|
||||||
-- for _, child in idr_r_archetype.entities do
|
-- for _, id in idr_r_types do
|
||||||
-- table.insert(children, child)
|
-- local relation = ECS_ENTITY_T_HI(id)
|
||||||
-- end
|
-- if world_target(world, child, relation) == delete then
|
||||||
|
-- world_remove(world, child, ECS_PAIR(relation, delete))
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
-- for _, id in idr_r_types do
|
local o = ECS_PAIR(EcsWildcard, delete)
|
||||||
-- local relation = ECS_ENTITY_T_HI(id)
|
local idr_o = component_index[o]
|
||||||
-- if world_target(world, child, relation) == delete then
|
|
||||||
-- world_remove(world, child, ECS_PAIR(relation, delete))
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
local o = ECS_PAIR(EcsWildcard, delete)
|
if idr_o then
|
||||||
local idr_o = component_index[o]
|
for archetype_id in idr_o.cache do
|
||||||
|
local children = {}
|
||||||
|
local idr_o_archetype = archetypes[archetype_id]
|
||||||
|
-- In the future, this needs to be optimized to only
|
||||||
|
-- look for linked records instead of doing this linearly
|
||||||
|
|
||||||
if idr_o then
|
local idr_o_types = idr_o_archetype.types
|
||||||
for archetype_id in idr_o.cache do
|
|
||||||
local children = {}
|
|
||||||
local idr_o_archetype = archetypes[archetype_id]
|
|
||||||
-- In the future, this needs to be optimized to only
|
|
||||||
-- look for linked records instead of doing this linearly
|
|
||||||
|
|
||||||
local idr_o_types = idr_o_archetype.types
|
for _, child in idr_o_archetype.entities do
|
||||||
|
table.insert(children, child)
|
||||||
|
end
|
||||||
|
|
||||||
for _, child in idr_o_archetype.entities do
|
for _, id in idr_o_types do
|
||||||
table.insert(children, child)
|
if not ECS_IS_PAIR(id) then
|
||||||
end
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
for _, id in idr_o_types do
|
local id_record = component_index[id]
|
||||||
if not ECS_IS_PAIR(id) then
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
|
|
||||||
local id_record = component_index[id]
|
if id_record then
|
||||||
|
local flags = id_record.flags
|
||||||
|
if bit32.band(flags, ECS_ID_DELETE) ~= 0 then
|
||||||
|
for _, child in children do
|
||||||
|
-- Cascade deletions of it has Delete as component trait
|
||||||
|
world_delete(world, child)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local object = ECS_ENTITY_T_LO(id)
|
||||||
|
if object == delete then
|
||||||
|
for _, child in children do
|
||||||
|
world_remove(world, child, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
component_index[o] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if id_record then
|
function world_delete(world: World, entity: i53)
|
||||||
local flags = id_record.flags
|
local entityIndex = world.entityIndex
|
||||||
if bit32.band(flags, ECS_ID_DELETE) ~= 0 then
|
|
||||||
for _, child in children do
|
|
||||||
-- Cascade deletions of it has Delete as component trait
|
|
||||||
world_delete(world, child)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local object = ECS_ENTITY_T_LO(id)
|
|
||||||
if object == delete then
|
|
||||||
for _, child in children do
|
|
||||||
world_remove(world, child, id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
component_index[o] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function world_delete(world: World, entity: i53)
|
local record = entityIndex.sparse[entity]
|
||||||
local entityIndex = world.entityIndex
|
if not record then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local record = entityIndex.sparse[entity]
|
local archetype = record.archetype
|
||||||
if not record then
|
local row = record.row
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local archetype = record.archetype
|
if archetype then
|
||||||
local row = record.row
|
-- In the future should have a destruct mode for
|
||||||
|
-- deleting archetypes themselves. Maybe requires recycling
|
||||||
|
archetype_delete(world, archetype, row)
|
||||||
|
end
|
||||||
|
|
||||||
if archetype then
|
record.archetype = nil :: any
|
||||||
-- In the future should have a destruct mode for
|
entityIndex.sparse[entity] = nil
|
||||||
-- deleting archetypes themselves. Maybe requires recycling
|
end
|
||||||
archetype_delete(world, archetype, row)
|
|
||||||
end
|
|
||||||
|
|
||||||
record.archetype = nil :: any
|
|
||||||
entityIndex.sparse[entity] = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function world_contains(world: World, entity): boolean
|
local function world_contains(world: World, entity): boolean
|
||||||
|
|
Loading…
Reference in a new issue