1
0
Fork 0
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:
Étienne Fildadut 2019-12-24 19:52:48 +01:00
parent 16e533d176
commit b5324faace
3 changed files with 80 additions and 52 deletions

View file

@ -1,5 +1,7 @@
--- ubiquitousse.ecs --- 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: --- Entity Component System library, inspired by the excellent tiny-ecs. Main differences include:
-- * ability to nest systems; -- * 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. -- 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 -- 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. -- 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 = :(...) add = :(e, ...)
for _, e in ipairs({...}) do if e ~= nil and @filter(e) then
if @filter(e) then if @_first == nil then
if @_first == nil then @_first = { e, nil }
@_first = { e, nil } elseif @compare(e, @_first[1]) then
elseif @compare(e, @_first[1]) then @_first = { e, @_first }
@_first = { e, @_first } else
else let entity = @_first
let entity = @_first while entity[2] ~= nil do
while entity[2] ~= nil do if @compare(e, entity[2][1]) then
if @compare(e, entity[2][1]) then entity[2] = { e, entity[2] }
entity[2] = { e, entity[2] } break
break
end
entity = entity[2]
end
if entity[2] == nil then
entity[2] = { e, nil }
end end
entity = entity[2]
end end
for _, s in ipairs(@systems) do if entity[2] == nil then
s:add(e) entity[2] = { e, nil }
end end
@entityCount += 1
@onAdd(e)
end 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 end
return ...
end, end,
--- Remove entities to the system and its subsystems. --- 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. -- If you intend to call this on a subsystem instead of the world, please read the warning in :add.
remove = :(...) remove = :(e, ...)
for _, e in ipairs({...}) do if e ~= nil and @filter(e) then
if @filter(e) then let found = false
let found = false if @_first == nil then
if @_first == nil then return
return elseif @_first[1] == e then
elseif @_first[1] == e then @_first = @_first[2]
@_first = @_first[2] found = true
found = true else
else let entity = @_first
let entity = @_first while entity[2] ~= nil do
while entity[2] ~= nil do if entity[2][1] == e then
if entity[2][1] == e then entity[2] = entity[2][2]
entity[2] = entity[2][2] found = true
found = true break
break
end
entity = entity[2]
end end
end entity = entity[2]
if found then
for _, s in ipairs(@systems) do
s:remove(e)
end
@entityCount -= 1
@onRemove(e)
end end
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
end, end,
--- Returns an iterator that iterate through the entties in this system. --- Returns an iterator that iterate through the entties in this system.
@ -300,9 +307,31 @@ let any = (...)
end end
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. --- ECS module.
return { return {
world = world, world = world,
all = all, all = all,
any = any any = any,
scene = scene
} }

View file

@ -1,6 +1,6 @@
--- ubiquitousse.scene --- ubiquitousse.scene
-- Optional dependencies: ubiquitousse.time (to provide each scene a time registry) -- 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 if not loaded then time = nil end
--- Scene management. --- Scene management.

View file

@ -1,6 +1,5 @@
--- ubiquitousse.time --- ubiquitousse.time
-- Depends on a backend. -- Depends on a backend.
local ease = require((...):match("^.-time")..".easing") local ease = require((...):match("^.-time")..".easing")
local time local time