mirror of
https://github.com/Reuh/ubiquitousse.git
synced 2025-10-27 17:19:31 +00:00
Add ecs.scene
This commit is contained in:
parent
16e533d176
commit
b5324faace
3 changed files with 80 additions and 52 deletions
129
ecs/ecs.can
129
ecs/ecs.can
|
|
@ -1,5 +1,7 @@
|
|||
--- ubiquitousse.ecs
|
||||
-- No dependency.
|
||||
-- Optional dependency: ubiquitousse.scene, to allow quick creation of ECS-based scenes.
|
||||
local loaded, newScene = pcall(require, (...):match("^(.-)ecs").."scene")
|
||||
if not loaded then newScene = nil end
|
||||
|
||||
--- Entity Component System library, inspired by the excellent tiny-ecs. Main differences include:
|
||||
-- * ability to nest systems;
|
||||
|
|
@ -109,65 +111,70 @@ let system_mt = {
|
|||
-- If this is called on a subsystem instead of the world, be warned that this will bypass all the parent's systems filters.
|
||||
-- Since :remove will not search for entities in systems where they should have been filtered out, the added entities will not be removed
|
||||
-- when calling :remove on a parent system or the world. The entity can only be removed by calling :remove on the system :add was called on.
|
||||
add = :(...)
|
||||
for _, e in ipairs({...}) do
|
||||
if @filter(e) then
|
||||
if @_first == nil then
|
||||
@_first = { e, nil }
|
||||
elseif @compare(e, @_first[1]) then
|
||||
@_first = { e, @_first }
|
||||
else
|
||||
let entity = @_first
|
||||
while entity[2] ~= nil do
|
||||
if @compare(e, entity[2][1]) then
|
||||
entity[2] = { e, entity[2] }
|
||||
break
|
||||
end
|
||||
entity = entity[2]
|
||||
end
|
||||
if entity[2] == nil then
|
||||
entity[2] = { e, nil }
|
||||
add = :(e, ...)
|
||||
if e ~= nil and @filter(e) then
|
||||
if @_first == nil then
|
||||
@_first = { e, nil }
|
||||
elseif @compare(e, @_first[1]) then
|
||||
@_first = { e, @_first }
|
||||
else
|
||||
let entity = @_first
|
||||
while entity[2] ~= nil do
|
||||
if @compare(e, entity[2][1]) then
|
||||
entity[2] = { e, entity[2] }
|
||||
break
|
||||
end
|
||||
entity = entity[2]
|
||||
end
|
||||
for _, s in ipairs(@systems) do
|
||||
s:add(e)
|
||||
if entity[2] == nil then
|
||||
entity[2] = { e, nil }
|
||||
end
|
||||
@entityCount += 1
|
||||
@onAdd(e)
|
||||
end
|
||||
for _, s in ipairs(@systems) do
|
||||
s:add(e)
|
||||
end
|
||||
@entityCount += 1
|
||||
@onAdd(e)
|
||||
end
|
||||
if ... then
|
||||
return e, @add(...)
|
||||
else
|
||||
return e
|
||||
end
|
||||
return ...
|
||||
end,
|
||||
--- Remove entities to the system and its subsystems.
|
||||
-- If you intend to call this on a subsystem instead of the world, please read the warning in :add.
|
||||
remove = :(...)
|
||||
for _, e in ipairs({...}) do
|
||||
if @filter(e) then
|
||||
let found = false
|
||||
if @_first == nil then
|
||||
return
|
||||
elseif @_first[1] == e then
|
||||
@_first = @_first[2]
|
||||
found = true
|
||||
else
|
||||
let entity = @_first
|
||||
while entity[2] ~= nil do
|
||||
if entity[2][1] == e then
|
||||
entity[2] = entity[2][2]
|
||||
found = true
|
||||
break
|
||||
end
|
||||
entity = entity[2]
|
||||
remove = :(e, ...)
|
||||
if e ~= nil and @filter(e) then
|
||||
let found = false
|
||||
if @_first == nil then
|
||||
return
|
||||
elseif @_first[1] == e then
|
||||
@_first = @_first[2]
|
||||
found = true
|
||||
else
|
||||
let entity = @_first
|
||||
while entity[2] ~= nil do
|
||||
if entity[2][1] == e then
|
||||
entity[2] = entity[2][2]
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if found then
|
||||
for _, s in ipairs(@systems) do
|
||||
s:remove(e)
|
||||
end
|
||||
@entityCount -= 1
|
||||
@onRemove(e)
|
||||
entity = entity[2]
|
||||
end
|
||||
end
|
||||
if found then
|
||||
for _, s in ipairs(@systems) do
|
||||
s:remove(e)
|
||||
end
|
||||
@entityCount -= 1
|
||||
@onRemove(e)
|
||||
end
|
||||
end
|
||||
if ... then
|
||||
return e, @remove(...)
|
||||
else
|
||||
return e
|
||||
end
|
||||
end,
|
||||
--- Returns an iterator that iterate through the entties in this system.
|
||||
|
|
@ -300,9 +307,31 @@ let any = (...)
|
|||
end
|
||||
end
|
||||
|
||||
let scene = (name, systems={}, entities={})
|
||||
let s = newScene(name)
|
||||
let w
|
||||
|
||||
function s:enter()
|
||||
w = world(unpack(systems))
|
||||
w:add(unpack(entities))
|
||||
end
|
||||
function s:exit()
|
||||
w:destroy()
|
||||
end
|
||||
function s:update(dt)
|
||||
w:update(dt)
|
||||
end
|
||||
function s:draw()
|
||||
w:draw()
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
--- ECS module.
|
||||
return {
|
||||
world = world,
|
||||
all = all,
|
||||
any = any
|
||||
any = any,
|
||||
scene = scene
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
--- ubiquitousse.scene
|
||||
-- Optional dependencies: ubiquitousse.time (to provide each scene a time registry)
|
||||
local loaded, time = pcall(require, (...):match("^.-ubiquitousse%.").."time")
|
||||
local loaded, time = pcall(require, (...):match("^(.-)scene").."time")
|
||||
if not loaded then time = nil end
|
||||
|
||||
--- Scene management.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
--- ubiquitousse.time
|
||||
-- Depends on a backend.
|
||||
|
||||
local ease = require((...):match("^.-time")..".easing")
|
||||
local time
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue