31 Commits

Author SHA1 Message Date
bakpakin
f0e6ce7880 Update to version 1.1-7. 2015-08-05 21:01:53 -04:00
bakpakin
26f8259f2b Add tiny.refresh for updating a World without updating Systems. 2015-07-29 12:40:13 -04:00
bakpakin
b1c7e2ba83 Update to version 1.1-6. 2015-07-07 19:47:06 -04:00
bakpakin
6b549fcbc1 Readd tiny.getSystemIndex(world, system) 2015-07-07 19:26:12 -04:00
bakpakin
b9d994ad50 Update documentation for what functions return.
Remove useless code in world metatable
Make tiny.world(...) return newworld, ...
2015-07-07 19:05:56 -04:00
bakpakin
ce8ca35f7e Remove world.systemIndices to fix possible obscure bugs.
Remove tiny.getSystemIndex(world, system) in favor of a System 'index'
field.
Add some comments and documentation.
2015-07-06 23:28:50 -04:00
bakpakin
19ae03707f Make tiny.add, tiny.remove, and similar methods return entities and systems. 2015-07-06 22:01:06 -04:00
bakpakin
c1f1225248 Update to version 1.1-5. 2015-06-21 14:48:48 -04:00
bakpakin
45e8552054 Fix entity count in worlds. 2015-06-21 14:42:03 -04:00
bakpakin
f187dce4fd Update documentation. 2015-06-19 19:45:26 -04:00
bakpakin
927652597c Update to version 1.1-4. 2015-06-19 19:08:06 -04:00
bakpakin
6b3af0f2da Remove 2.0-1 from existence. 2015-06-19 18:55:06 -04:00
bakpakin
31f3396db1 Change System API again.
Remove tiny.getSystemEntityCount because it's useless and deprecation is for chumps.
2015-06-19 18:48:18 -04:00
bakpakin
cb9ab332d2 Fix sorting + add sorting test. 2015-06-18 16:02:16 -04:00
bakpakin
1fd32dab9a Add "world" flag in Systems. Clean up Systems when removing them from Worlds. 2015-06-18 15:19:21 -04:00
bakpakin
0a12897695 Correct use of 'self' in intervalSystemUpdate 2015-06-17 10:35:47 -04:00
bakpakin
e44ac6cdb3 Update to version 2.0-1 2015-06-16 23:48:57 -04:00
bakpakin
6f299470d0 Add CHANGELOG.md 2015-06-16 23:44:19 -04:00
bakpakin
61ffd2551b Readd tiny.processingSystem(table). 2015-06-16 23:26:48 -04:00
bakpakin
c66ed98a5a Add License sticker to README.md. 2015-06-16 23:13:53 -04:00
bakpakin
2621bd16a3 Add tiny.getSystemEntityCount(system). 2015-06-16 22:51:23 -04:00
bakpakin
c408267932 Update documentation. 2015-06-16 22:39:10 -04:00
bakpakin
557927577d Fix sorting. Change API for creating Systems to be more flexible. 2015-06-16 21:15:30 -04:00
bakpakin
cbfc3d360f Add attributes to tiny.system. Implement Interval Systems. 2015-06-16 20:28:21 -04:00
bakpakin
d35d62ed3c Add optional filter to tiny.update(world, dt, [filter]) 2015-06-16 19:45:09 -04:00
bakpakin
74666ca0c3 Fix adding inactive Systems. 2015-06-16 19:14:56 -04:00
bakpakin
5978ace463 Update to version 1.1-3 2015-06-14 10:22:03 -04:00
bakpakin
a504bd6336 Add removeSystem to World metatable. 2015-06-14 10:17:18 -04:00
bakpakin
69ae37586e Fix scm rockspec. 2015-06-07 20:05:56 -04:00
bakpakin
44fb94c457 Add scm rockspec. Fix README. 2015-06-07 18:47:50 -04:00
bakpakin
9230dad1e1 Update README.md to direct users to demo. 2015-05-17 08:26:04 +08:00
10 changed files with 320 additions and 163 deletions
+9 -10
View File
@@ -1,4 +1,7 @@
# tiny-ecs #
[![License](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENSE)
Tiny-ecs is an Entity Component System for lua that's simple, flexible, and useful.
Because of lua's tabular nature, Entity Component Systems are a natural choice
for simulating large and complex systems. For more explanation on Entity
@@ -8,6 +11,8 @@ Component Systems, here is some
Tiny-ecs also works well with objected oriented programming in lua because
Systems and Entities do not use metatables. This means you can subclass your
Systems and Entities, and use existing lua class frameworks with tiny-ecs, no problem.
For an example on how to use tiny-ecs with object-oriented lua, take a look at the
demo branch, specifically the systems and entities sub-directories.
## Overview ##
Tiny-ecs has four important types: Worlds, Filters, Systems, and Entities.
@@ -29,7 +34,7 @@ Systems in tiny-ecs describe how to update Entities. Systems select certain Enti
using a Filter, and then only update those select Entities. Some Systems don't
update Entities, and instead just act as function callbacks every update. Tiny-ecs
provides functions for creating Systems easily, as well as creating Systems that
can be used in an object orientented fashion.
can be used in an object oriented fashion.
### Filters ###
Filters are used to select Entities. Filters can be any lua function, but
@@ -64,7 +69,7 @@ end
## Use It ##
Copy paste tiny.lua into your source folder. For stability and consistent API,
please use a tagged release or use luarocks. Tagged releases will have a version
number in `tiny._VERSION`, while other commits will just have the string 'dev'.
number in `tiny._VERSION`, while other commits will just have the string 'scm'.
## Luarocks ##
Tiny-ecs is also on [Luarocks](https://luarocks.org/) and can be installed with
@@ -73,7 +78,7 @@ Tiny-ecs is also on [Luarocks](https://luarocks.org/) and can be installed with
## Demo ##
Check out the [demo](https://github.com/bakpakin/tiny-ecs/tree/demo-commandokibbles), a game
originally written for Ludum Dare 32 with the theme 'An Unconventional Weapon'. The demo uses
[LOVE](https://love2d.org/), an amazing game framework for lua.
[LÖVE](https://love2d.org/), an amazing game framework for lua.
## Testing ##
Tiny-ecs uses [busted](http://olivinelabs.com/busted/) for testing. Install and run
@@ -83,10 +88,4 @@ Tiny-ecs uses [busted](http://olivinelabs.com/busted/) for testing. Install and
See API [here](http://bakpakin.github.io/tiny-ecs/doc/).
For the most up-to-date documentation, read the source code, or generate the HTML
locally with [LDoc](http://stevedonovan.github.io/ldoc/).
## TODO ##
* More testing
* Performance testing / optimization
* Add more System types
* Improve Documentation
See the original forum thread [here](https://love2d.org/forums/viewtopic.php?f=5&t=79937&p=182589).
+1
View File
@@ -10,3 +10,4 @@ style = '!fixed'
package = 'tiny-ecs'
not_luadoc = true
boilerplate = true
no_return_or_parms = true
+24
View File
@@ -0,0 +1,24 @@
package = "tiny-ecs"
version = "1.1-3"
source = {
url = "git://github.com/bakpakin/tiny-ecs",
tag = "1.1-3"
}
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"
}
}
+24
View File
@@ -0,0 +1,24 @@
package = "tiny-ecs"
version = "1.1-4"
source = {
url = "git://github.com/bakpakin/tiny-ecs",
tag = "1.1-4"
}
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"
}
}
+24
View File
@@ -0,0 +1,24 @@
package = "tiny-ecs"
version = "1.1-5"
source = {
url = "git://github.com/bakpakin/tiny-ecs",
tag = "1.1-5"
}
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"
}
}
+24
View File
@@ -0,0 +1,24 @@
package = "tiny-ecs"
version = "1.1-6"
source = {
url = "git://github.com/bakpakin/tiny-ecs",
tag = "1.1-6"
}
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"
}
}
+24
View File
@@ -0,0 +1,24 @@
package = "tiny-ecs"
version = "1.1-7"
source = {
url = "git://github.com/bakpakin/tiny-ecs",
tag = "1.1-7"
}
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"
}
}
+15 -2
View File
@@ -211,8 +211,21 @@ describe('tiny-ecs:', function()
world:update(1)
world:setSystemIndex(moveSystem, 2)
world:update(1)
assert.equals(2, world:getSystemIndex(moveSystem))
assert.equals(1, world:getSystemIndex(oneTimeSystem))
assert.equals(2, moveSystem.index)
assert.equals(1, oneTimeSystem.index)
end)
it("Sorts Entities in Sorting Systems", function()
local sortsys = tiny.sortedProcessingSystem()
sortsys.filter = tiny.requireAll("vel")
function sortsys:compare(e1, e2)
return e1.vel.x < e2.vel.x
end
world:add(sortsys)
world:update(0)
assert.equals(sortsys.entities[1], entity2)
assert.equals(sortsys.entities[2], entity3)
assert.equals(sortsys.entities[3], entity1)
end)
end)
+23
View File
@@ -0,0 +1,23 @@
package = "tiny-ecs"
version = "scm-0"
source = {
url = "git://github.com/bakpakin/tiny-ecs",
}
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"
}
}
+152 -151
View File
@@ -23,14 +23,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-- @author Calvin Rose
-- @license MIT
-- @copyright 2015
local tiny = { _VERSION = "1.1-2" }
local tiny = { _VERSION = "1.1-7" }
-- Local versions of standard lua functions
local tinsert = table.insert
local tremove = table.remove
local tsort = table.sort
local pairs = pairs
local ipairs = ipairs
local setmetatable = setmetatable
local type = type
local select = select
@@ -51,8 +50,8 @@ local tiny_remove
-- value indicating if the Entity should be processed by the System.
--
-- Filters must be added to Systems by setting the `filter` field of the System.
-- Filter's returned by `tiny.requireAll` and `tiny.requireAny` are immutable
-- and can be used by multiple Systems.
-- Filter's returned by tiny-ecs's Filter functions are immutable and can be
-- used by multiple Systems.
--
-- local f1 = tiny.requireAll("position", "velocity", "size")
-- local f2 = tiny.requireAny("position", "velocity", "size")
@@ -88,7 +87,6 @@ local tiny_remove
--- Makes a Filter that selects Entities with all specified Components and
-- Filters.
-- @param ... List of required Components and other Filters.
function tiny.requireAll(...)
local components = {...}
local len = #components
@@ -110,7 +108,6 @@ end
--- Makes a Filter that selects Entities with at least one of the specified
-- Components and Filters.
-- @param ... List of required Components and other Filters.
function tiny.requireAny(...)
local components = {...}
local len = #components
@@ -132,7 +129,6 @@ end
--- Makes a Filter that rejects Entities with all specified Components and
-- Filters, and selects all other Entities.
-- @param ... List of required Components and other Filters.
function tiny.rejectAll(...)
local components = {...}
local len = #components
@@ -154,7 +150,6 @@ end
--- Makes a Filter that rejects Entities with at least one of the specified
-- Components and Filters, and selects all other Entities.
-- @param ... List of required Components and other Filters.
function tiny.rejectAny(...)
local components = {...}
local len = #components
@@ -183,10 +178,15 @@ end
--
-- There are also a few other optional callbacks:
--
-- * `function system:filter(entity)`
-- * `function system:onAdd(entity)`
-- * `function system:onRemove(entity)`
-- * `function system:onModify(dt)`
-- * `function system:filter(entity)` - Returns true if this System should
-- include this Entity, otherwise should return false. If this isn't specified,
-- no Entities are included in the System.
-- * `function system:onAdd(entity)` - Called when an Entity is added to the
-- System.
-- * `function system:onRemove(entity)` - Called when an Entity is removed
-- from the System.
-- * `function system:onModify(dt)` - Called when the System is modified by
-- adding or removing Entities from the System.
--
-- For Filters, it is convenient to use `tiny.requireAll` or `tiny.requireAny`,
-- but one can write their own filters as well. Set the Filter of a System like
@@ -201,11 +201,20 @@ end
-- system is added to the World. A few are important, and few should be less
-- commonly used.
--
-- * The `world` field points to the World that the System belongs to. Useful
-- for adding and removing Entities from the world dynamically via the System.
-- * The `active` flag is whether or not the System is updated automatically.
-- Inactive Systems should be updated manually or not at all via
-- `system:update(dt)`. Defaults to true.
-- * The 'entities' field is an ordered list of Entities in the System. This
-- * The `entities` field is an ordered list of Entities in the System. This
-- list can be used to quickly iterate through all Entities in a System.
-- * The `interval` field is an optional field that makes Systems update at
-- certain intervals using buffered time, regardless of World update frequency.
-- For example, to make a System update once a second, set the System's interval
-- to 1.
-- * The `index` field is the System's index in the World. Lower indexed
-- Systems are processed before higher indices. The `index` is a read only
-- field; to set the `index`, use `tiny.setSystemIndex(world, system)`.
-- * The `indices` field is a table of Entity keys to their indices in the
-- `entities` list. Most Systems can ignore this.
-- * The `modified` flag is an indicator if the System has been modified in
@@ -219,20 +228,11 @@ end
-- this key is considered a System rather than an Entity.
local systemTableKey = { "SYSTEM_TABLE_KEY" }
-- Check if tables are systems.
-- Checks if a table is a System.
local function isSystem(table)
return table[systemTableKey]
end
--- Creates a default System.
-- @param table A table to be used as a System, or `nil` to create a new System.
-- @return A new System or System class
function tiny.system(table)
table = table or {}
table[systemTableKey] = true
return table
end
-- Update function for all Processing Systems.
local function processingSystemUpdate(system, dt)
local entities = system.entities
@@ -258,24 +258,45 @@ local function processingSystemUpdate(system, dt)
end
end
--- Creates a Processing System.
-- Sorts Systems by a function system.sort(entity1, entity2) on modify.
local function sortedSystemOnModify(system, dt)
local entities = system.entities
local indices = system.indices
local sortDelegate = system.sortDelegate
if not sortDelegate then
local compare = system.compare
sortDelegate = function(e1, e2)
return compare(system, e1, e2)
end
system.sortDelegate = sortDelegate
end
tsort(entities, sortDelegate)
for i = 1, #entities do
local entity = entities[i]
indices[entity] = i
end
end
--- Creates a new System or System class from the supplied table. If `table` is
-- nil, creates a new table.
function tiny.system(table)
table = table or {}
table[systemTableKey] = true
return table
end
--- Creates a new Processing System or Processing System class. Processing
-- Systems process each entity individual, and are usually what is needed.
-- Processing Systems have three extra callbacks besides those inheritted from
-- vanilla Systems.
--
-- A Processing System iterates through its Entities in no particluar order, and
-- updates them individually. It has two important fields:
-- function system:preProcess(entities, dt) -- Called before iteration.
-- function system:process(entities, dt) -- Process each entity.
-- function system:postProcess(entity, dt) -- Called after iteration.
--
-- * `function system:process(entity, dt)`
-- * `function system:filter(entity)`
--
-- There are also a few other optional callbacks, including the optional
-- callbacks in `tiny.system`:
--
-- * `function system:preProcess(entities, dt)`
-- * `function system:postProcess(entities, dt)`
--
-- @param table A table to be used as a System, or `nil` to create a new
-- Processing System.
-- Processing Systems have their own `update` method, so don't implement a
-- a custom `update` callback for Processing Systems.
-- @see system
-- @return A new Processing System or Processing System class
function tiny.processingSystem(table)
table = table or {}
table[systemTableKey] = true
@@ -283,45 +304,31 @@ function tiny.processingSystem(table)
return table
end
-- Sorts Systems by a function system.sort(entity1, entity2) on modify.
local function sortedSystemOnModify(system, dt)
local entities = system.entities
local entityIndices = system.entityIndices
local sortDelegate = system.sortDelegate
if not sortDelegate then
local compare = system.compare
sortDelegate = function(e1, e2)
compare(system, e1, e2)
end
system.sortDelegate = sortDelegate
end
tsort(entities, sortDelegate)
for i = 1, #entities do
local entity = entities[i]
entityIndices[entity] = i
end
--- Creates a new Sorted System or Sorted System class. Sorted Systems sort
-- their Entities according to a user-defined method, `system:compare(e1, e2)`,
-- which should return true if `e1` should come before `e2` and false otherwise.
-- Sorted Systems also override the default System's `onModify` callback, so be
-- careful if defining a custom callback. However, for processing the sorted
-- entities, consider `tiny.sortedProcessingSystem(table)`.
-- @see system
function tiny.sortedSystem(table)
table = table or {}
table[systemTableKey] = true
table.onModify = sortedSystemOnModify
return table
end
--- Creates a Sorted Processing System. A Sorted System iterates through its
-- Entities in a specific order, and updates them individually. It has three
-- important methods:
--
-- * `function system:process(entity, dt)`
-- * `function system:compare(entity1, entity2)`
-- * `function system:filter(entity)`
--
-- Sorted Systems have the same optitonal callbacks as ProcessingSystems.
-- @param table A table to be used as a System, or `nil` to create a new
-- Sorted System.
--- Creates a new Sorted Processing System or Sorted Processing System class.
-- Sorted Processing Systems have both the aspects of Processing Systems and
-- Sorted Systems.
-- @see system
-- @see processingSystem
-- @return A new Sorted System or Sorted System class
function tiny.sortedSystem(table)
-- @see sortedSystem
function tiny.sortedProcessingSystem(table)
table = table or {}
table[systemTableKey] = true
table.update = processingSystemUpdate
table.onModify = sortedSystemOnModify
table.sort = sortedSystemOnModify
return table
end
@@ -338,11 +345,9 @@ end
local worldMetaTable
--- Creates a new World.
-- Can optionally add default Systems and Entities.
-- @param ... Systems and Entities to add to the World
-- @return A new World
-- Can optionally add default Systems and Entities. Returns the new World along
-- with default Entities and Systems.
function tiny.world(...)
local ret = {
-- List of Entities to add
@@ -360,53 +365,43 @@ function tiny.world(...)
-- Set of Entities
entities = {},
-- Number of Entities in World.
-- Number of Entities in World
entityCount = 0,
-- List of System Data. A data element is a table with 4
-- keys: system, indices, entities, and active.
systems = {},
-- Table of Systems to System Indices
systemIndices = {}
-- List of Systems
systems = {}
}
tiny_add(ret, ...)
tiny_manageSystems(ret)
tiny_manageEntities(ret)
return setmetatable(ret, worldMetaTable)
return setmetatable(ret, worldMetaTable), ...
end
--- Adds an Entity to the world.
-- Also call this on Entities that have changed Components such that they
-- match different Filters.
-- @param world
-- @param entity
-- match different Filters. Returns the Entity.
function tiny.addEntity(world, entity)
local e2a = world.entitiesToAdd
e2a[#e2a + 1] = entity
if world.entities[entity] then
tiny_removeEntity(world, entity)
end
return entity
end
tiny_addEntity = tiny.addEntity
--- Adds a System to the world.
-- @param world
-- @param system
--- Adds a System to the world. Returns the System.
function tiny.addSystem(world, system)
local s2a = world.systemsToAdd
s2a[#s2a + 1] = system
return system
end
tiny_addSystem = tiny.addSystem
--- Shortcut for adding multiple Entities and Systems to the World.
-- @param world
-- @param ... Systems and Entities
-- @see addEntity
-- @see addSystem
--- Shortcut for adding multiple Entities and Systems to the World. Returns all
-- added Entities and Systems.
function tiny.add(world, ...)
local obj
for i = 1, select("#", ...) do
@@ -419,32 +414,28 @@ function tiny.add(world, ...)
end
end
end
return ...
end
tiny_add = tiny.add
--- Removes an Entity to the World.
-- @param world
-- @param entity
--- Removes an Entity to the World. Returns the Entity.
function tiny.removeEntity(world, entity)
local e2r = world.entitiesToRemove
e2r[#e2r + 1] = entity
return entity
end
tiny_removeEntity = tiny.removeEntity
--- Removes a System from the world.
-- @param world
-- @param system
--- Removes a System from the world. Returns the System.
function tiny.removeSystem(world, system)
local s2r = world.systemsToRemove
s2r[#s2r + 1] = system
return system
end
tiny_removeSystem = tiny.removeSystem
--- Shortcut for removing multiple Entities and Systems from the World.
-- @param world
-- @param ... Systems and Entities
-- @see removeEntity
-- @see removeSystem
--- Shortcut for removing multiple Entities and Systems from the World. Returns
-- all removed Systems and Entities
function tiny.remove(world, ...)
local obj
for i = 1, select("#", ...) do
@@ -457,12 +448,12 @@ function tiny.remove(world, ...)
end
end
end
return ...
end
tiny_remove = tiny.remove
-- Adds and removes Systems that have been marked from the World.
function tiny_manageSystems(world)
local s2a, s2r = world.systemsToAdd, world.systemsToRemove
-- Early exit
@@ -470,7 +461,6 @@ function tiny_manageSystems(world)
return
end
local systemIndices = world.systemIndices
local entities = world.entities
local systems = world.systems
local system, index, filter
@@ -479,8 +469,8 @@ function tiny_manageSystems(world)
-- Remove Systems
for i = 1, #s2r do
system = s2r[i]
index = systemIndices[system]
if index then
index = system.index
if system.world == world then
onRemove = system.onRemove
if onRemove then
entityList = system.entities
@@ -488,27 +478,35 @@ function tiny_manageSystems(world)
onRemove(system, entityList[j])
end
end
systemIndices[system] = nil
tremove(systems, index)
for j = index, #systems do
systemIndices[systems[j]] = j
systems[j].index = j
end
end
s2r[i] = nil
-- Clean up System
system.world = nil
system.entities = nil
system.indices = nil
system.index = nil
end
-- Add Systems
for i = 1, #s2a do
system = s2a[i]
if not systemIndices[system] then
if systems[system.index] ~= system then
entityList = {}
entityIndices = {}
system.entities = entityList
system.indices = entityIndices
system.active = true
if system.active == nil then
system.active = true
end
system.modified = true
system.world = world
index = #systems + 1
systemIndices[system] = index
system.index = index
systems[index] = system
-- Try to add Entities
@@ -529,12 +527,10 @@ function tiny_manageSystems(world)
end
s2a[i] = nil
end
end
-- Adds and removes Entities that have been marked.
function tiny_manageEntities(world)
local e2a, e2r = world.entitiesToAdd, world.entitiesToRemove
-- Early exit
@@ -553,6 +549,7 @@ function tiny_manageEntities(world)
entity = e2r[i]
if entities[entity] then
entities[entity] = nil
entityCount = entityCount - 1
for j = 1, #systems do
system = systems[j]
@@ -567,7 +564,6 @@ function tiny_manageEntities(world)
seis[tmpEntity] = index
seis[entity] = nil
ses[#ses] = nil
entityCount = entityCount - 1
onRemove = system.onRemove
if onRemove then
onRemove(system, entity)
@@ -580,12 +576,12 @@ function tiny_manageEntities(world)
e2r[i] = nil
end
-- Add Entities
for i = 1, #e2a do
entity = e2a[i]
if not entities[entity] then
entities[entity] = true
entityCount = entityCount + 1
for j = 1, #systems do
system = systems[j]
@@ -597,7 +593,6 @@ function tiny_manageEntities(world)
index = #ses + 1
ses[index] = entity
seis[entity] = index
entityCount = entityCount + 1
onAdd = system.onAdd
if onAdd then
onAdd(system, entity)
@@ -612,25 +607,32 @@ function tiny_manageEntities(world)
-- Update Entity count
world.entityCount = entityCount
end
--- Updates the World.
-- Put this in your main loop.
-- @param world
-- @param dt Delta time
function tiny.update(world, dt)
--- Manages Entities and Systems marked for deletion or addition. Call this
-- before modifying Systems and Entities outside of a call to `tiny.update`.
-- Do not call this within a call to `tiny.update`.
function tiny.refresh(world)
tiny_manageSystems(world)
tiny_manageEntities(world)
end
--- Updates the World by dt (delta time). Takes an optional parameter, `filter`,
-- which is a Filter that selects Systems from the World, and updates only those
-- Systems. If `filter` is not supplied, all Systems are updated. Put this
-- function in your main loop.
function tiny.update(world, dt, filter)
tiny_manageSystems(world)
tiny_manageEntities(world)
local systems = world.systems
local system, update, onModify, entities
local system, update, interval, onModify
-- Iterate through Systems IN ORDER
for i = 1, #systems do
system = systems[i]
if system.active then
if system.active and ((not filter) or filter(world, system)) then
-- Call the modify callback on Systems that have been modified.
onModify = system.onModify
@@ -638,10 +640,22 @@ function tiny.update(world, dt)
onModify(system, dt)
end
--Update Systems that have an update method (most Systems)
-- Update Systems that have an update method (most Systems)
update = system.update
if update then
update(system, dt)
interval = system.interval
if interval then
local bufferedTime = (system.bufferedTime or 0) + dt
while bufferedTime >= interval do
bufferedTime = bufferedTime - interval
if update then
update(system, interval)
end
end
system.bufferedTime = bufferedTime
else
update(system, dt)
end
end
system.modified = false
@@ -650,7 +664,6 @@ function tiny.update(world, dt)
end
--- Removes all Entities from the World.
-- @param world
function tiny.clearEntities(world)
for e in pairs(world.entities) do
tiny_removeEntity(world, e)
@@ -658,7 +671,6 @@ function tiny.clearEntities(world)
end
--- Removes all Systems from the World.
-- @param world
function tiny.clearSystems(world)
local systems = world.systems
for i = #systems, 1, -1 do
@@ -667,46 +679,33 @@ function tiny.clearSystems(world)
end
--- Gets number of Entities in the World.
-- @param world
-- @return An integer
function tiny.getEntityCount(world)
return world.entityCount
end
--- Gets number of Systems in World.
-- @param world
-- @return An integer
function tiny.getSystemCount(world)
return #(world.systems)
end
--- Gets the index of a System in the World. Lower indexed Systems are processed
-- before higher indexed systems.
-- @param world
-- @param system
-- @return An integer between 1 and world:getSystemCount() inclusive
--- Gets the index of the System in the World.
-- A simpler alternative is `system.index`.
function tiny.getSystemIndex(world, system)
return world.systemIndices[system]
return system.index
end
--- Sets the index of a System in the World. Changes the order in
-- which they Systems processed, because lower indexed Systems are processed
-- first.
-- @param world
-- @param system
-- @param index
-- @return Old index
--- Sets the index of a System in the World, and returns the old index. Changes
-- the order in which they Systems processed, because lower indexed Systems are
-- processed first. Returns the old system.index.
function tiny.setSystemIndex(world, system, index)
local systemIndices = world.systemIndices
local oldIndex = systemIndices[system]
local oldIndex = system.index
local systems = world.systems
local system = systems[oldIndex]
tremove(systems, oldIndex)
tinsert(systems, index, system)
for i = oldIndex, index, index >= oldIndex and 1 or -1 do
systemIndices[systems[i]] = i
systems[i].index = i
end
return oldIndex
@@ -720,6 +719,8 @@ worldMetaTable = {
addSystem = tiny.addSystem,
remove = tiny.remove,
removeEntity = tiny.removeEntity,
removeSystem = tiny.removeSystem,
refresh = tiny.refresh,
update = tiny.update,
clearEntities = tiny.clearEntities,
clearSystems = tiny.clearSystems,