mirror of
https://github.com/bakpakin/tiny-ecs.git
synced 2026-07-22 07:56:52 -06:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08e5f13d85 | ||
|
|
cbf71d2cb2 | ||
|
|
93a19d93c8 | ||
|
|
4148855233 | ||
|
|
27f881444a | ||
|
|
3b4bd9920b | ||
|
|
206361ca38 | ||
|
|
29158282bd |
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2015 Calvin Rose
|
Copyright (c) 2016 Calvin Rose
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package = "tiny-ecs"
|
||||||
|
version = "1.3-1"
|
||||||
|
source = {
|
||||||
|
url = "git://github.com/bakpakin/tiny-ecs",
|
||||||
|
tag = "1.3-1"
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
summary = "Entity Component System for Lua.",
|
||||||
|
detailed = [[
|
||||||
|
Pure Lua implementation of an easy to use, compact, fast, and flexible
|
||||||
|
Entity Component System. Works well with Object Orientation.
|
||||||
|
]],
|
||||||
|
homepage = "https://github.com/bakpakin/tiny-ecs",
|
||||||
|
license = "MIT"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1"
|
||||||
|
}
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
tiny = "tiny.lua"
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
-2
@@ -90,6 +90,49 @@ describe('tiny-ecs:', function()
|
|||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("Can use functions as subfilters", function()
|
||||||
|
|
||||||
|
local f1 = tiny.requireAny('a', 'b', 'c')
|
||||||
|
local f2 = tiny.requireAll('x', 'y', 'z')
|
||||||
|
local f = tiny.requireAll(f1, f2)
|
||||||
|
|
||||||
|
assert.truthy(f(nil, {
|
||||||
|
x = true, y = true, z = true, a = true, b = true, c = true
|
||||||
|
}))
|
||||||
|
assert.truthy(f(nil, {
|
||||||
|
x = true, y = true, z = true, a = true
|
||||||
|
}))
|
||||||
|
assert.falsy(f(nil, {
|
||||||
|
x = true, y = true, a = true
|
||||||
|
}))
|
||||||
|
assert.falsy(f(nil, {
|
||||||
|
x = true, y = true, z = true
|
||||||
|
}))
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Can use string filters", function()
|
||||||
|
|
||||||
|
local f = tiny.filter('a|b|c')
|
||||||
|
|
||||||
|
assert.truthy(f(nil, {
|
||||||
|
a = true, b = true, c = true
|
||||||
|
}))
|
||||||
|
assert.truthy(f(nil, {
|
||||||
|
a = true
|
||||||
|
}))
|
||||||
|
assert.truthy(f(nil, {
|
||||||
|
b = true
|
||||||
|
}))
|
||||||
|
assert.truthy(f(nil, {
|
||||||
|
c = true
|
||||||
|
}))
|
||||||
|
assert.falsy(f(nil, {
|
||||||
|
x = true, y = true, z = true
|
||||||
|
}))
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('World:', function()
|
describe('World:', function()
|
||||||
@@ -190,9 +233,11 @@ describe('tiny-ecs:', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it("Remove Entities Multiple Times", function()
|
it("Remove Entities Multiple Times", function()
|
||||||
|
assert.equals(3, world:getEntityCount())
|
||||||
world:update(1)
|
world:update(1)
|
||||||
world:remove(entity1, entity2, entity3)
|
world:remove(entity1, entity2, entity3)
|
||||||
world:update(2)
|
world:update(2)
|
||||||
|
assert.equals(0, world:getEntityCount())
|
||||||
world:remove(entity1, entity2, entity3)
|
world:remove(entity1, entity2, entity3)
|
||||||
world:update(2)
|
world:update(2)
|
||||||
assert.equals(2, world:getSystemCount())
|
assert.equals(2, world:getSystemCount())
|
||||||
@@ -227,12 +272,12 @@ describe('tiny-ecs:', function()
|
|||||||
|
|
||||||
it("Sorts Entities in Sorting Systems", function()
|
it("Sorts Entities in Sorting Systems", function()
|
||||||
local sortsys = tiny.sortedProcessingSystem()
|
local sortsys = tiny.sortedProcessingSystem()
|
||||||
sortsys.filter = tiny.requireAll("vel")
|
sortsys.filter = tiny.filter("vel|xform")
|
||||||
function sortsys:compare(e1, e2)
|
function sortsys:compare(e1, e2)
|
||||||
return e1.vel.x < e2.vel.x
|
return e1.vel.x < e2.vel.x
|
||||||
end
|
end
|
||||||
world:add(sortsys)
|
world:add(sortsys)
|
||||||
world:update(0)
|
world:refresh()
|
||||||
assert.equals(sortsys.entities[1], entity2)
|
assert.equals(sortsys.entities[1], entity2)
|
||||||
assert.equals(sortsys.entities[2], entity3)
|
assert.equals(sortsys.entities[2], entity3)
|
||||||
assert.equals(sortsys.entities[3], entity1)
|
assert.equals(sortsys.entities[3], entity1)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
--[[
|
--[[
|
||||||
Copyright (c) 2015 Calvin Rose
|
Copyright (c) 2016 Calvin Rose
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
@@ -23,13 +23,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
-- @author Calvin Rose
|
-- @author Calvin Rose
|
||||||
-- @license MIT
|
-- @license MIT
|
||||||
-- @copyright 2015
|
-- @copyright 2015
|
||||||
local tiny = { _VERSION = "1.2-1" }
|
local tiny = { _VERSION = "scm" }
|
||||||
|
|
||||||
-- Local versions of standard lua functions
|
-- Local versions of standard lua functions
|
||||||
local tinsert = table.insert
|
local tinsert = table.insert
|
||||||
local tremove = table.remove
|
local tremove = table.remove
|
||||||
local tsort = table.sort
|
local tsort = table.sort
|
||||||
local pairs = pairs
|
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local type = type
|
local type = type
|
||||||
local select = select
|
local select = select
|
||||||
@@ -85,88 +84,121 @@ local tiny_remove
|
|||||||
--
|
--
|
||||||
-- @section Filter
|
-- @section Filter
|
||||||
|
|
||||||
|
-- A helper function to compile filters.
|
||||||
|
local filterJoin
|
||||||
|
|
||||||
|
-- A helper function to filters from string
|
||||||
|
local filterBuildString
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
local loadstring = loadstring or load
|
||||||
|
local function getchr(c)
|
||||||
|
return "\\" .. c:byte()
|
||||||
|
end
|
||||||
|
local function make_safe(text)
|
||||||
|
return ("%q"):format(text):gsub('\n', 'n'):gsub("[\128-\255]", getchr)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function filterJoinRaw(prefix, seperator, ...)
|
||||||
|
local accum = {}
|
||||||
|
local build = {}
|
||||||
|
for i = 1, select('#', ...) do
|
||||||
|
local item = select(i, ...)
|
||||||
|
if type(item) == 'string' then
|
||||||
|
accum[#accum + 1] = ("(e[%s] ~= nil)"):format(make_safe(item))
|
||||||
|
elseif type(item) == 'function' then
|
||||||
|
build[#build + 1] = ('local subfilter_%d_ = select(%d, ...)'):format(i, i)
|
||||||
|
accum[#accum + 1] = ('(subfilter_%d_(system, e))'):format(i)
|
||||||
|
else
|
||||||
|
error 'Filter token must be a string or a filter function.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local source = ('do %s\n return function(system, e) return %s(%s) end end'):format(
|
||||||
|
table.concat(build, '\n'),
|
||||||
|
prefix,
|
||||||
|
table.concat(accum, seperator)
|
||||||
|
)
|
||||||
|
local loader, err = loadstring(source)
|
||||||
|
if err then error(err) end
|
||||||
|
return loader(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function filterJoin(...)
|
||||||
|
local state, value = pcall(filterJoinRaw, ...)
|
||||||
|
if state then return value else return nil, value end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function buildPart(str)
|
||||||
|
local accum = {}
|
||||||
|
local subParts = {}
|
||||||
|
str = str:gsub('%b()', function(p)
|
||||||
|
subParts[#subParts + 1] = buildPart(p:sub(2, -2))
|
||||||
|
return ('\255%d'):format(#subParts)
|
||||||
|
end)
|
||||||
|
for invert, part, sep in str:gmatch('(%!?)([^%|%&%!]+)([%|%&%!]?)') do
|
||||||
|
if part:match('^\255%d+$') then
|
||||||
|
local partIndex = tonumber(part:match(part:sub(2)))
|
||||||
|
accum[#accum + 1] = ('%s(%s)'):format(invert == '' and '' or 'not', subParts[partIndex])
|
||||||
|
else
|
||||||
|
accum[#accum + 1] = ("(e[%s] %s nil)"):format(make_safe(part), invert == '' and '~=' or '==')
|
||||||
|
end
|
||||||
|
if sep ~= '' then
|
||||||
|
accum[#accum + 1] = (sep == '|' and ' or ' or ' and ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(accum)
|
||||||
|
end
|
||||||
|
|
||||||
|
function filterBuildString(str)
|
||||||
|
local source = ("return function(_, e) return %s end"):format(buildPart(str))
|
||||||
|
local loader, err = loadstring(source)
|
||||||
|
if err then
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
|
return loader()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Makes a Filter that selects Entities with all specified Components and
|
--- Makes a Filter that selects Entities with all specified Components and
|
||||||
-- Filters.
|
-- Filters.
|
||||||
function tiny.requireAll(...)
|
function tiny.requireAll(...)
|
||||||
local components = {...}
|
return filterJoin('', ' and ', ...)
|
||||||
local len = #components
|
|
||||||
return function(system, e)
|
|
||||||
local c
|
|
||||||
for i = 1, len do
|
|
||||||
c = components[i]
|
|
||||||
if type(c) == 'function' then
|
|
||||||
if not c(system, e) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
elseif e[c] == nil then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Makes a Filter that selects Entities with at least one of the specified
|
--- Makes a Filter that selects Entities with at least one of the specified
|
||||||
-- Components and Filters.
|
-- Components and Filters.
|
||||||
function tiny.requireAny(...)
|
function tiny.requireAny(...)
|
||||||
local components = {...}
|
return filterJoin('', ' or ', ...)
|
||||||
local len = #components
|
|
||||||
return function(system, e)
|
|
||||||
local c
|
|
||||||
for i = 1, len do
|
|
||||||
c = components[i]
|
|
||||||
if type(c) == 'function' then
|
|
||||||
if c(system, e) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
elseif e[c] ~= nil then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Makes a Filter that rejects Entities with all specified Components and
|
--- Makes a Filter that rejects Entities with all specified Components and
|
||||||
-- Filters, and selects all other Entities.
|
-- Filters, and selects all other Entities.
|
||||||
function tiny.rejectAll(...)
|
function tiny.rejectAll(...)
|
||||||
local components = {...}
|
return filterJoin('not', ' and ', ...)
|
||||||
local len = #components
|
|
||||||
return function(system, e)
|
|
||||||
local c
|
|
||||||
for i = 1, len do
|
|
||||||
c = components[i]
|
|
||||||
if type(c) == 'function' then
|
|
||||||
if not c(system, e) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
elseif e[c] == nil then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Makes a Filter that rejects Entities with at least one of the specified
|
--- Makes a Filter that rejects Entities with at least one of the specified
|
||||||
-- Components and Filters, and selects all other Entities.
|
-- Components and Filters, and selects all other Entities.
|
||||||
function tiny.rejectAny(...)
|
function tiny.rejectAny(...)
|
||||||
local components = {...}
|
return filterJoin('not', ' or ', ...)
|
||||||
local len = #components
|
end
|
||||||
return function(system, e)
|
|
||||||
local c
|
--- Makes a Filter from a string. Syntax of `pattern` is as follows.
|
||||||
for i = 1, len do
|
--
|
||||||
c = components[i]
|
-- * Tokens are alphanumeric strings including underscores.
|
||||||
if type(c) == 'function' then
|
-- * Tokens can be separated by |, &, or surrounded by parentheses.
|
||||||
if c(system, e) then
|
-- * Tokens can be prefixed with !, and are then operated on with a boolean 'not'.
|
||||||
return false
|
--
|
||||||
end
|
-- Examples are best:
|
||||||
elseif e[c] ~= nil then
|
-- 'a|b|c' - Matches entities with an 'a' component OR a 'b' component or a 'c' component.
|
||||||
return false
|
-- 'a&!b&c' - Matches entities with an 'a' component AND NOT a 'b' component AND a 'c' component.
|
||||||
end
|
-- 'a|(b&c&d)|e - Matches 'a' OR ('b' AND 'c' AND 'd') OR 'e'
|
||||||
end
|
-- @param pattern
|
||||||
return true
|
function tiny.filter(pattern)
|
||||||
end
|
local state, value = pcall(filterBuildString, pattern)
|
||||||
|
if state then return value else return nil, value end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- System functions.
|
--- System functions.
|
||||||
@@ -248,11 +280,22 @@ local function processingSystemUpdate(system, dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if process then
|
if process then
|
||||||
local entities = system.entities
|
if system.nocache then
|
||||||
local len = #entities
|
local entities = system.world.entityList
|
||||||
for i = 1, len do
|
local filter = system.filter
|
||||||
local entity = entities[i]
|
if filter then
|
||||||
process(system, entity, dt)
|
for i = 1, #entities do
|
||||||
|
local entity = entities[i]
|
||||||
|
if filter(system, entity) then
|
||||||
|
process(system, entity, dt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local entities = system.entities
|
||||||
|
for i = 1, #entities do
|
||||||
|
process(system, entities[i], dt)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -261,7 +304,7 @@ local function processingSystemUpdate(system, dt)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sorts Systems by a function system.sort(entity1, entity2) on modify.
|
-- Sorts Systems by a function system.sortDelegate(entity1, entity2) on modify.
|
||||||
local function sortedSystemOnModify(system, dt)
|
local function sortedSystemOnModify(system, dt)
|
||||||
local entities = system.entities
|
local entities = system.entities
|
||||||
local indices = system.indices
|
local indices = system.indices
|
||||||
@@ -275,8 +318,7 @@ local function sortedSystemOnModify(system, dt)
|
|||||||
end
|
end
|
||||||
tsort(entities, sortDelegate)
|
tsort(entities, sortDelegate)
|
||||||
for i = 1, #entities do
|
for i = 1, #entities do
|
||||||
local entity = entities[i]
|
indices[entities[i]] = i
|
||||||
indices[entity] = i
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -371,6 +413,9 @@ function tiny.world(...)
|
|||||||
-- Set of Entities
|
-- Set of Entities
|
||||||
entities = {},
|
entities = {},
|
||||||
|
|
||||||
|
-- List of Entities
|
||||||
|
entityList = {},
|
||||||
|
|
||||||
-- Number of Entities in World
|
-- Number of Entities in World
|
||||||
entityCount = 0,
|
entityCount = 0,
|
||||||
|
|
||||||
@@ -473,7 +518,7 @@ function tiny_manageSystems(world)
|
|||||||
world.systemsToAdd = {}
|
world.systemsToAdd = {}
|
||||||
world.systemsToRemove = {}
|
world.systemsToRemove = {}
|
||||||
|
|
||||||
local entities = world.entities
|
local worldEntityList = world.entityList
|
||||||
local systems = world.systems
|
local systems = world.systems
|
||||||
|
|
||||||
-- Remove Systems
|
-- Remove Systems
|
||||||
@@ -481,7 +526,7 @@ function tiny_manageSystems(world)
|
|||||||
local system = s2r[i]
|
local system = s2r[i]
|
||||||
local index = system.index
|
local index = system.index
|
||||||
local onRemove = system.onRemove
|
local onRemove = system.onRemove
|
||||||
if onRemove then
|
if onRemove and not system.nocache then
|
||||||
local entityList = system.entities
|
local entityList = system.entities
|
||||||
for j = 1, #entityList do
|
for j = 1, #entityList do
|
||||||
onRemove(system, entityList[j])
|
onRemove(system, entityList[j])
|
||||||
@@ -507,11 +552,11 @@ function tiny_manageSystems(world)
|
|||||||
-- Add Systems
|
-- Add Systems
|
||||||
for i = 1, #s2a do
|
for i = 1, #s2a do
|
||||||
local system = s2a[i]
|
local system = s2a[i]
|
||||||
if systems[system.index] ~= system then
|
if systems[system.index or 0] ~= system then
|
||||||
local entityList = {}
|
if not system.nocache then
|
||||||
local entityIndices = {}
|
system.entities = {}
|
||||||
system.entities = entityList
|
system.indices = {}
|
||||||
system.indices = entityIndices
|
end
|
||||||
if system.active == nil then
|
if system.active == nil then
|
||||||
system.active = true
|
system.active = true
|
||||||
end
|
end
|
||||||
@@ -526,16 +571,21 @@ function tiny_manageSystems(world)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Try to add Entities
|
-- Try to add Entities
|
||||||
local onAdd = system.onAdd
|
if not system.nocache then
|
||||||
local filter = system.filter
|
local entityList = system.entities
|
||||||
if filter then
|
local entityIndices = system.indices
|
||||||
for entity in pairs(entities) do
|
local onAdd = system.onAdd
|
||||||
if filter(system, entity) then
|
local filter = system.filter
|
||||||
local entityIndex = #entityList + 1
|
if filter then
|
||||||
entityList[entityIndex] = entity
|
for j = 1, #worldEntityList do
|
||||||
entityIndices[entity] = entityIndex
|
local entity = worldEntityList[j]
|
||||||
if onAdd then
|
if filter(system, entity) then
|
||||||
onAdd(system, entity)
|
local entityIndex = #entityList + 1
|
||||||
|
entityList[entityIndex] = entity
|
||||||
|
entityIndices[entity] = entityIndex
|
||||||
|
if onAdd then
|
||||||
|
onAdd(system, entity)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -562,6 +612,7 @@ function tiny_manageEntities(world)
|
|||||||
world.entitiesToRemove = {}
|
world.entitiesToRemove = {}
|
||||||
|
|
||||||
local entities = world.entities
|
local entities = world.entities
|
||||||
|
local entityList = world.entityList
|
||||||
local systems = world.systems
|
local systems = world.systems
|
||||||
local entityCount = world.entityCount
|
local entityCount = world.entityCount
|
||||||
|
|
||||||
@@ -571,31 +622,33 @@ function tiny_manageEntities(world)
|
|||||||
if entities[entity] then
|
if entities[entity] then
|
||||||
for j = 1, #systems do
|
for j = 1, #systems do
|
||||||
local system = systems[j]
|
local system = systems[j]
|
||||||
local ses = system.entities
|
if not system.nocache then
|
||||||
local seis = system.indices
|
local ses = system.entities
|
||||||
local index = seis[entity]
|
local seis = system.indices
|
||||||
local filter = system.filter
|
local index = seis[entity]
|
||||||
if filter and filter(system, entity) then
|
local filter = system.filter
|
||||||
if not index then
|
if filter and filter(system, entity) then
|
||||||
system.modified = true
|
if not index then
|
||||||
index = #ses + 1
|
system.modified = true
|
||||||
ses[index] = entity
|
index = #ses + 1
|
||||||
seis[entity] = index
|
ses[index] = entity
|
||||||
local onAdd = system.onAdd
|
seis[entity] = index
|
||||||
if onAdd then
|
local onAdd = system.onAdd
|
||||||
onAdd(system, entity)
|
if onAdd then
|
||||||
|
onAdd(system, entity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif index then
|
||||||
|
system.modified = true
|
||||||
|
local tmpEntity = ses[#ses]
|
||||||
|
ses[index] = tmpEntity
|
||||||
|
seis[tmpEntity] = index
|
||||||
|
seis[entity] = nil
|
||||||
|
ses[#ses] = nil
|
||||||
|
local onRemove = system.onRemove
|
||||||
|
if onRemove then
|
||||||
|
onRemove(system, entity)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
elseif index then
|
|
||||||
system.modified = true
|
|
||||||
local tmpEntity = ses[#ses]
|
|
||||||
ses[index] = tmpEntity
|
|
||||||
seis[tmpEntity] = index
|
|
||||||
seis[entity] = nil
|
|
||||||
ses[#ses] = nil
|
|
||||||
local onRemove = system.onRemove
|
|
||||||
if onRemove then
|
|
||||||
onRemove(system, entity)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -606,50 +659,63 @@ function tiny_manageEntities(world)
|
|||||||
-- Remove Entities
|
-- Remove Entities
|
||||||
for i = 1, #e2r do
|
for i = 1, #e2r do
|
||||||
local entity = e2r[i]
|
local entity = e2r[i]
|
||||||
if entities[entity] then
|
e2r[i] = nil
|
||||||
|
local listIndex = entities[entity]
|
||||||
|
if listIndex then
|
||||||
|
-- Remove Entity from world state
|
||||||
|
local lastEntity = entityList[#entityList]
|
||||||
|
entities[lastEntity] = listIndex
|
||||||
entities[entity] = nil
|
entities[entity] = nil
|
||||||
|
entityList[listIndex] = lastEntity
|
||||||
|
entityList[#entityList] = nil
|
||||||
entityCount = entityCount - 1
|
entityCount = entityCount - 1
|
||||||
|
-- Remove from cached systems
|
||||||
for j = 1, #systems do
|
for j = 1, #systems do
|
||||||
local system = systems[j]
|
local system = systems[j]
|
||||||
local ses = system.entities
|
if not system.nocache then
|
||||||
local seis = system.indices
|
local ses = system.entities
|
||||||
local index = seis[entity]
|
local seis = system.indices
|
||||||
if index then
|
local index = seis[entity]
|
||||||
system.modified = true
|
if index then
|
||||||
local tmpEntity = ses[#ses]
|
system.modified = true
|
||||||
ses[index] = tmpEntity
|
local tmpEntity = ses[#ses]
|
||||||
seis[tmpEntity] = index
|
ses[index] = tmpEntity
|
||||||
seis[entity] = nil
|
seis[tmpEntity] = index
|
||||||
ses[#ses] = nil
|
seis[entity] = nil
|
||||||
local onRemove = system.onRemove
|
ses[#ses] = nil
|
||||||
if onRemove then
|
local onRemove = system.onRemove
|
||||||
onRemove(system, entity)
|
if onRemove then
|
||||||
|
onRemove(system, entity)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
e2r[i] = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add Entities
|
-- Add Entities
|
||||||
for i = 1, #e2a do
|
for i = 1, #e2a do
|
||||||
local entity = e2a[i]
|
local entity = e2a[i]
|
||||||
if not entities[entity] then
|
if not entities[entity] then
|
||||||
entities[entity] = true
|
local listIndex = #entityList + 1
|
||||||
|
entities[entity] = listIndex
|
||||||
|
entityList[listIndex] = entity
|
||||||
entityCount = entityCount + 1
|
entityCount = entityCount + 1
|
||||||
for j = 1, #systems do
|
for j = 1, #systems do
|
||||||
local system = systems[j]
|
local system = systems[j]
|
||||||
local ses = system.entities
|
if not system.nocache then
|
||||||
local seis = system.indices
|
local ses = system.entities
|
||||||
local filter = system.filter
|
local seis = system.indices
|
||||||
if filter and filter(system, entity) then
|
local filter = system.filter
|
||||||
system.modified = true
|
if filter and filter(system, entity) then
|
||||||
local index = #ses + 1
|
system.modified = true
|
||||||
ses[index] = entity
|
local index = #ses + 1
|
||||||
seis[entity] = index
|
ses[index] = entity
|
||||||
local onAdd = system.onAdd
|
seis[entity] = index
|
||||||
if onAdd then
|
local onAdd = system.onAdd
|
||||||
onAdd(system, entity)
|
if onAdd then
|
||||||
|
onAdd(system, entity)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -667,6 +733,17 @@ end
|
|||||||
function tiny.refresh(world)
|
function tiny.refresh(world)
|
||||||
tiny_manageSystems(world)
|
tiny_manageSystems(world)
|
||||||
tiny_manageEntities(world)
|
tiny_manageEntities(world)
|
||||||
|
local systems = world.systems
|
||||||
|
for i = 1, #systems do
|
||||||
|
local system = systems[i]
|
||||||
|
if system.active then
|
||||||
|
local onModify = system.onModify
|
||||||
|
if onModify and system.modified then
|
||||||
|
onModify(system, 0)
|
||||||
|
end
|
||||||
|
system.modified = false
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Updates the World by dt (delta time). Takes an optional parameter, `filter`,
|
--- Updates the World by dt (delta time). Takes an optional parameter, `filter`,
|
||||||
@@ -716,8 +793,9 @@ end
|
|||||||
|
|
||||||
--- Removes all Entities from the World.
|
--- Removes all Entities from the World.
|
||||||
function tiny.clearEntities(world)
|
function tiny.clearEntities(world)
|
||||||
for e in pairs(world.entities) do
|
local el = world.entityList
|
||||||
tiny_removeEntity(world, e)
|
for i = 1, #el do
|
||||||
|
tiny_removeEntity(world, el[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user