tiny-ecs/lib/tiny.lua

726 lines
22 KiB
Lua
Raw Normal View History

2015-05-17 00:13:19 +00:00
--[[
Copyright (c) 2015 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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
2015-04-27 06:12:11 +00:00
--- @module tiny-ecs
-- @author Calvin Rose
2015-05-17 00:13:19 +00:00
-- @license MIT
-- @copyright 2015
2015-07-08 00:55:25 +00:00
local tiny = { _VERSION = "1.1-6" }
2015-04-27 06:12:11 +00:00
-- Local versions of standard lua functions
local tinsert = table.insert
local tremove = table.remove
2015-05-17 00:13:19 +00:00
local tsort = table.sort
2015-04-27 06:12:11 +00:00
local pairs = pairs
local setmetatable = setmetatable
local type = type
2015-05-17 00:13:19 +00:00
local select = select
2015-04-27 06:12:11 +00:00
-- Local versions of the library functions
local tiny_manageEntities
local tiny_manageSystems
local tiny_addEntity
local tiny_addSystem
local tiny_add
local tiny_removeEntity
local tiny_removeSystem
local tiny_remove
--- Filter functions.
-- A Filter is a function that selects which Entities apply to a System.
2015-05-17 00:13:19 +00:00
-- Filters take two parameters, the System and the Entity, and return a boolean
-- 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.
2015-07-08 00:55:25 +00:00
-- Filter's returned by tiny-ecs's Filter functions are immutable and can be
-- used by multiple Systems.
2015-05-17 00:13:19 +00:00
--
-- local f1 = tiny.requireAll("position", "velocity", "size")
-- local f2 = tiny.requireAny("position", "velocity", "size")
--
-- local e1 = {
-- position = {2, 3},
-- velocity = {3, 3},
-- size = {4, 4}
-- }
--
-- local entity2 = {
-- position = {4, 5},
-- size = {4, 4}
-- }
--
-- local e3 = {
-- position = {2, 3},
-- velocity = {3, 3}
-- }
--
-- print(f1(nil, e1), f1(nil, e2), f1(nil, e3)) -- prints true, false, false
-- print(f2(nil, e1), f2(nil, e2), f2(nil, e3)) -- prints true, true, true
--
-- Filters can also be passed as arguments to other Filter constructors. This is
-- a powerful way to create complex, custom Filters that select a very specific
-- set of Entities.
--
-- -- Selects Entities with an "image" Component, but not Entities with a
-- -- "Player" or "Enemy" Component.
-- filter = tiny.requireAll("image", tiny.rejectAny("Player", "Enemy"))
--
2015-04-27 06:12:11 +00:00
-- @section Filter
2015-05-17 00:13:19 +00:00
--- Makes a Filter that selects Entities with all specified Components and
-- Filters.
2015-04-27 06:12:11 +00:00
function tiny.requireAll(...)
local components = {...}
local len = #components
2015-05-17 00:13:19 +00:00
return function(system, e)
2015-04-27 06:12:11 +00:00
local c
for i = 1, len do
c = components[i]
if type(c) == 'function' then
2015-05-17 00:13:19 +00:00
if not c(system, e) then
2015-04-27 06:12:11 +00:00
return false
end
elseif e[c] == nil then
return false
end
end
return true
end
end
2015-05-17 00:13:19 +00:00
--- Makes a Filter that selects Entities with at least one of the specified
-- Components and Filters.
function tiny.requireAny(...)
2015-04-27 06:12:11 +00:00
local components = {...}
local len = #components
2015-05-17 00:13:19 +00:00
return function(system, e)
2015-04-27 06:12:11 +00:00
local c
for i = 1, len do
c = components[i]
if type(c) == 'function' then
2015-05-17 00:13:19 +00:00
if c(system, e) then
2015-04-27 06:12:11 +00:00
return true
end
elseif e[c] ~= nil then
return true
end
end
return false
end
end
2015-05-17 00:13:19 +00:00
--- Makes a Filter that rejects Entities with all specified Components and
-- Filters, and selects all other Entities.
function tiny.rejectAll(...)
local components = {...}
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
--- Makes a Filter that rejects Entities with at least one of the specified
-- Components and Filters, and selects all other Entities.
function tiny.rejectAny(...)
local components = {...}
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 false
end
elseif e[c] ~= nil then
return false
end
end
return true
end
end
2015-04-27 06:12:11 +00:00
--- System functions.
-- A System is a wrapper around function callbacks for manipulating Entities.
2015-05-17 00:13:19 +00:00
-- Systems are implemented as tables that contain at least one method;
-- an update function that takes parameters like so:
--
-- * `function system:update(dt)`.
--
-- There are also a few other optional callbacks:
--
2015-07-08 00:55:25 +00:00
-- * `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.
2015-05-17 00:13:19 +00:00
--
-- 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
-- so:
-- system.filter = tiny.requireAll("a", "b", "c")
-- or
-- function system:filter(entity)
-- return entity.myRequiredComponentName ~= nil
-- end
--
-- All Systems also have a few important fields that are initialized when the
-- system is added to the World. A few are important, and few should be less
-- commonly used.
--
2015-07-08 00:55:25 +00:00
-- * 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.
2015-05-17 00:13:19 +00:00
-- * 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.
2015-07-08 00:55:25 +00:00
-- * The `entities` field is an ordered list of Entities in the System. This
2015-05-17 00:13:19 +00:00
-- list can be used to quickly iterate through all Entities in a System.
2015-07-08 00:55:25 +00:00
-- * 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)`.
2015-05-17 00:13:19 +00:00
-- * 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
-- the last update. If so, the `onModify` callback will be called on the System
-- in the next update, if it has one. This is usually managed by tiny-ecs, so
-- users should mostly ignore this, too.
--
2015-04-27 06:12:11 +00:00
-- @section System
-- Use an empty table as a key for identifying Systems. Any table that contains
-- this key is considered a System rather than an Entity.
local systemTableKey = { "SYSTEM_TABLE_KEY" }
2015-07-08 00:55:25 +00:00
-- Checks if a table is a System.
2015-04-27 06:12:11 +00:00
local function isSystem(table)
return table[systemTableKey]
end
-- Update function for all Processing Systems.
2015-05-17 00:13:19 +00:00
local function processingSystemUpdate(system, dt)
local entities = system.entities
2015-04-27 06:12:11 +00:00
local preProcess = system.preProcess
local process = system.process
local postProcess = system.postProcess
local entity
if preProcess then
2015-05-17 00:13:19 +00:00
preProcess(system, dt)
2015-04-27 06:12:11 +00:00
end
if process then
local len = #entities
for i = 1, len do
entity = entities[i]
process(system, entity, dt)
end
end
if postProcess then
2015-05-17 00:13:19 +00:00
postProcess(system, dt)
2015-04-27 06:12:11 +00:00
end
end
2015-05-17 00:13:19 +00:00
-- Sorts Systems by a function system.sort(entity1, entity2) on modify.
local function sortedSystemOnModify(system, dt)
local entities = system.entities
2015-07-08 00:55:25 +00:00
local indices = system.indices
2015-05-17 00:13:19 +00:00
local sortDelegate = system.sortDelegate
if not sortDelegate then
local compare = system.compare
sortDelegate = function(e1, e2)
2015-07-08 00:55:25 +00:00
return compare(system, e1, e2)
2015-05-17 00:13:19 +00:00
end
system.sortDelegate = sortDelegate
2015-04-27 06:12:11 +00:00
end
2015-05-17 00:13:19 +00:00
tsort(entities, sortDelegate)
for i = 1, #entities do
local entity = entities[i]
2015-07-08 00:55:25 +00:00
indices[entity] = i
2015-05-17 00:13:19 +00:00
end
end
2015-07-08 00:55:25 +00:00
--- 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.
2015-05-17 00:13:19 +00:00
--
2015-07-08 00:55:25 +00:00
-- function system:preProcess(entities, dt) -- Called before iteration.
-- function system:process(entities, dt) -- Process each entity.
-- function system:postProcess(entity, dt) -- Called after iteration.
2015-05-17 00:13:19 +00:00
--
2015-07-08 00:55:25 +00:00
-- Processing Systems have their own `update` method, so don't implement a
-- a custom `update` callback for Processing Systems.
-- @see system
function tiny.processingSystem(table)
table = table or {}
table[systemTableKey] = true
table.update = processingSystemUpdate
return table
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)`.
2015-05-17 00:13:19 +00:00
-- @see system
function tiny.sortedSystem(table)
2015-07-08 00:55:25 +00:00
table = table or {}
table[systemTableKey] = true
table.onModify = sortedSystemOnModify
return table
end
--- 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
-- @see sortedSystem
function tiny.sortedProcessingSystem(table)
2015-05-17 00:13:19 +00:00
table = table or {}
2015-04-27 06:12:11 +00:00
table[systemTableKey] = true
table.update = processingSystemUpdate
2015-05-17 00:13:19 +00:00
table.onModify = sortedSystemOnModify
2015-04-27 06:12:11 +00:00
return table
end
--- World functions.
2015-05-17 00:13:19 +00:00
-- A World is a container that manages Entities and Systems. Typically, a
-- program uses one World at a time.
--
-- For all World functions except `tiny.world(...)`, object-oriented syntax can
-- be used instead of the documented syntax. For example,
-- `tiny.add(world, e1, e2, e3)` is the same as `world:add(e1, e2, e3)`.
2015-04-27 06:12:11 +00:00
-- @section World
2015-05-17 00:13:19 +00:00
-- Forward declaration
local worldMetaTable
2015-04-27 06:12:11 +00:00
--- Creates a new World.
2015-07-08 00:55:25 +00:00
-- Can optionally add default Systems and Entities. Returns the new World along
-- with default Entities and Systems.
2015-04-27 06:12:11 +00:00
function tiny.world(...)
local ret = {
-- List of Entities to add
entitiesToAdd = {},
-- List of Entities to remove
entitiesToRemove = {},
-- List of Entities to add
systemsToAdd = {},
-- List of Entities to remove
systemsToRemove = {},
2015-05-17 00:13:19 +00:00
-- Set of Entities
2015-04-27 06:12:11 +00:00
entities = {},
2015-07-08 00:55:25 +00:00
-- Number of Entities in World
2015-04-27 06:12:11 +00:00
entityCount = 0,
2015-07-08 00:55:25 +00:00
-- List of Systems
systems = {}
2015-04-27 06:12:11 +00:00
}
tiny_add(ret, ...)
tiny_manageSystems(ret)
tiny_manageEntities(ret)
2015-07-08 00:55:25 +00:00
return setmetatable(ret, worldMetaTable), ...
2015-04-27 06:12:11 +00:00
end
--- Adds an Entity to the world.
2015-05-17 00:13:19 +00:00
-- Also call this on Entities that have changed Components such that they
2015-07-08 00:55:25 +00:00
-- match different Filters. Returns the Entity.
2015-04-27 06:12:11 +00:00
function tiny.addEntity(world, entity)
local e2a = world.entitiesToAdd
e2a[#e2a + 1] = entity
if world.entities[entity] then
tiny_removeEntity(world, entity)
end
2015-07-08 00:55:25 +00:00
return entity
2015-04-27 06:12:11 +00:00
end
tiny_addEntity = tiny.addEntity
2015-07-08 00:55:25 +00:00
--- Adds a System to the world. Returns the System.
2015-04-27 06:12:11 +00:00
function tiny.addSystem(world, system)
local s2a = world.systemsToAdd
s2a[#s2a + 1] = system
2015-07-08 00:55:25 +00:00
return system
2015-04-27 06:12:11 +00:00
end
tiny_addSystem = tiny.addSystem
2015-07-08 00:55:25 +00:00
--- Shortcut for adding multiple Entities and Systems to the World. Returns all
-- added Entities and Systems.
2015-04-27 06:12:11 +00:00
function tiny.add(world, ...)
2015-05-17 00:13:19 +00:00
local obj
for i = 1, select("#", ...) do
obj = select(i, ...)
if obj then
if isSystem(obj) then
tiny_addSystem(world, obj)
else -- Assume obj is an Entity
tiny_addEntity(world, obj)
end
2015-04-27 06:12:11 +00:00
end
end
2015-07-08 00:55:25 +00:00
return ...
2015-04-27 06:12:11 +00:00
end
tiny_add = tiny.add
2015-07-08 00:55:25 +00:00
--- Removes an Entity to the World. Returns the Entity.
2015-04-27 06:12:11 +00:00
function tiny.removeEntity(world, entity)
local e2r = world.entitiesToRemove
e2r[#e2r + 1] = entity
2015-07-08 00:55:25 +00:00
return entity
2015-04-27 06:12:11 +00:00
end
tiny_removeEntity = tiny.removeEntity
2015-07-08 00:55:25 +00:00
--- Removes a System from the world. Returns the System.
2015-04-27 06:12:11 +00:00
function tiny.removeSystem(world, system)
local s2r = world.systemsToRemove
s2r[#s2r + 1] = system
2015-07-08 00:55:25 +00:00
return system
2015-04-27 06:12:11 +00:00
end
tiny_removeSystem = tiny.removeSystem
2015-07-08 00:55:25 +00:00
--- Shortcut for removing multiple Entities and Systems from the World. Returns
-- all rmeove Systems and Entities
2015-04-27 06:12:11 +00:00
function tiny.remove(world, ...)
2015-05-17 00:13:19 +00:00
local obj
for i = 1, select("#", ...) do
obj = select(i, ...)
if obj then
if isSystem(obj) then
tiny_removeSystem(world, obj)
else -- Assume obj is an Entity
tiny_removeEntity(world, obj)
end
2015-04-27 06:12:11 +00:00
end
end
2015-07-08 00:55:25 +00:00
return ...
2015-04-27 06:12:11 +00:00
end
tiny_remove = tiny.remove
2015-05-17 00:13:19 +00:00
-- Adds and removes Systems that have been marked from the World.
function tiny_manageSystems(world)
2015-04-27 06:12:11 +00:00
local s2a, s2r = world.systemsToAdd, world.systemsToRemove
-- Early exit
if #s2a == 0 and #s2r == 0 then
return
end
local entities = world.entities
local systems = world.systems
2015-05-17 00:13:19 +00:00
local system, index, filter
local entityList, entityIndices, entityIndex, onRemove, onAdd
2015-04-27 06:12:11 +00:00
-- Remove Systems
for i = 1, #s2r do
system = s2r[i]
2015-07-08 00:55:25 +00:00
index = system.index
if system.world == world then
2015-04-27 06:12:11 +00:00
onRemove = system.onRemove
if onRemove then
2015-05-17 00:13:19 +00:00
entityList = system.entities
2015-04-27 06:12:11 +00:00
for j = 1, #entityList do
onRemove(system, entityList[j])
end
end
tremove(systems, index)
for j = index, #systems do
2015-07-08 00:55:25 +00:00
systems[j].index = j
2015-04-27 06:12:11 +00:00
end
end
s2r[i] = nil
2015-07-08 00:55:25 +00:00
-- Clean up System
system.world = nil
system.entities = nil
system.indices = nil
system.index = nil
2015-04-27 06:12:11 +00:00
end
-- Add Systems
for i = 1, #s2a do
system = s2a[i]
2015-07-08 00:55:25 +00:00
if systems[system.index] ~= system then
2015-04-27 06:12:11 +00:00
entityList = {}
entityIndices = {}
2015-05-17 00:13:19 +00:00
system.entities = entityList
system.indices = entityIndices
2015-07-08 00:55:25 +00:00
if system.active == nil then
system.active = true
end
2015-05-17 00:13:19 +00:00
system.modified = true
2015-07-08 00:55:25 +00:00
system.world = world
2015-04-27 06:12:11 +00:00
index = #systems + 1
2015-07-08 00:55:25 +00:00
system.index = index
2015-05-17 00:13:19 +00:00
systems[index] = system
2015-04-27 06:12:11 +00:00
-- Try to add Entities
onAdd = system.onAdd
filter = system.filter
if filter then
for entity in pairs(entities) do
if filter(system, entity) then
entityIndex = #entityList + 1
entityList[entityIndex] = entity
entityIndices[entity] = entityIndex
if onAdd then
onAdd(system, entity)
end
end
end
end
end
s2a[i] = nil
end
end
2015-05-17 00:13:19 +00:00
-- Adds and removes Entities that have been marked.
function tiny_manageEntities(world)
2015-04-27 06:12:11 +00:00
local e2a, e2r = world.entitiesToAdd, world.entitiesToRemove
-- Early exit
if #e2a == 0 and #e2r == 0 then
return
end
local entities = world.entities
local systems = world.systems
local entityCount = world.entityCount
2015-05-17 00:13:19 +00:00
local entity, system, index
local onRemove, onAdd, ses, seis, filter, tmpEntity
2015-04-27 06:12:11 +00:00
-- Remove Entities
for i = 1, #e2r do
entity = e2r[i]
if entities[entity] then
entities[entity] = nil
2015-07-08 00:55:25 +00:00
entityCount = entityCount - 1
2015-04-27 06:12:11 +00:00
for j = 1, #systems do
2015-05-17 00:13:19 +00:00
system = systems[j]
ses = system.entities
seis = system.indices
2015-04-27 06:12:11 +00:00
index = seis[entity]
if index then
2015-05-17 00:13:19 +00:00
system.modified = true
2015-04-27 06:12:11 +00:00
tmpEntity = ses[#ses]
ses[index] = tmpEntity
seis[tmpEntity] = index
seis[entity] = nil
ses[#ses] = nil
onRemove = system.onRemove
if onRemove then
onRemove(system, entity)
end
end
end
end
e2r[i] = nil
end
-- Add Entities
for i = 1, #e2a do
entity = e2a[i]
if not entities[entity] then
entities[entity] = true
2015-07-08 00:55:25 +00:00
entityCount = entityCount + 1
2015-04-27 06:12:11 +00:00
for j = 1, #systems do
2015-05-17 00:13:19 +00:00
system = systems[j]
ses = system.entities
seis = system.indices
2015-04-27 06:12:11 +00:00
filter = system.filter
if filter and filter(system, entity) then
2015-05-17 00:13:19 +00:00
system.modified = true
2015-04-27 06:12:11 +00:00
index = #ses + 1
ses[index] = entity
seis[entity] = index
onAdd = system.onAdd
if onAdd then
onAdd(system, entity)
end
end
end
end
e2a[i] = nil
end
-- Update Entity count
world.entityCount = entityCount
end
2015-07-08 00:55:25 +00:00
--- 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)
2015-04-27 06:12:11 +00:00
tiny_manageSystems(world)
tiny_manageEntities(world)
local systems = world.systems
2015-07-08 00:55:25 +00:00
local system, update, interval, onModify
2015-04-27 06:12:11 +00:00
-- Iterate through Systems IN ORDER
for i = 1, #systems do
2015-05-17 00:13:19 +00:00
system = systems[i]
2015-07-08 00:55:25 +00:00
if system.active and ((not filter) or filter(world, system)) then
2015-05-17 00:13:19 +00:00
-- Call the modify callback on Systems that have been modified.
onModify = system.onModify
if onModify and system.modified then
onModify(system, dt)
end
2015-07-08 00:55:25 +00:00
-- Update Systems that have an update method (most Systems)
2015-05-17 00:13:19 +00:00
update = system.update
if update then
2015-07-08 00:55:25 +00:00
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
2015-05-17 00:13:19 +00:00
end
system.modified = false
2015-04-27 06:12:11 +00:00
end
end
end
--- Removes all Entities from the World.
function tiny.clearEntities(world)
for e in pairs(world.entities) do
tiny_removeEntity(world, e)
end
end
--- Removes all Systems from the World.
function tiny.clearSystems(world)
local systems = world.systems
for i = #systems, 1, -1 do
2015-05-17 00:13:19 +00:00
tiny_removeSystem(world, systems[i])
2015-04-27 06:12:11 +00:00
end
end
2015-05-17 00:13:19 +00:00
--- Gets number of Entities in the World.
2015-04-27 06:12:11 +00:00
function tiny.getEntityCount(world)
return world.entityCount
end
2015-05-17 00:13:19 +00:00
--- Gets number of Systems in World.
2015-04-27 06:12:11 +00:00
function tiny.getSystemCount(world)
return #(world.systems)
end
2015-07-08 00:55:25 +00:00
--- Gets the index of the System in the World.
-- A simpler alternative is `system.index`.
2015-04-27 06:12:11 +00:00
function tiny.getSystemIndex(world, system)
2015-07-08 00:55:25 +00:00
return system.index
2015-04-27 06:12:11 +00:00
end
2015-07-08 00:55:25 +00:00
--- 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.
2015-04-27 06:12:11 +00:00
function tiny.setSystemIndex(world, system, index)
2015-07-08 00:55:25 +00:00
local oldIndex = system.index
2015-04-27 06:12:11 +00:00
local systems = world.systems
tremove(systems, oldIndex)
2015-05-17 00:13:19 +00:00
tinsert(systems, index, system)
2015-04-27 06:12:11 +00:00
for i = oldIndex, index, index >= oldIndex and 1 or -1 do
2015-07-08 00:55:25 +00:00
systems[i].index = i
2015-04-27 06:12:11 +00:00
end
2015-05-17 00:13:19 +00:00
return oldIndex
2015-04-27 06:12:11 +00:00
end
2015-05-17 00:13:19 +00:00
-- Construct world metatable.
worldMetaTable = {
__index = {
add = tiny.add,
addEntity = tiny.addEntity,
addSystem = tiny.addSystem,
remove = tiny.remove,
removeEntity = tiny.removeEntity,
2015-07-08 00:55:25 +00:00
removeSystem = tiny.removeSystem,
2015-05-17 00:13:19 +00:00
update = tiny.update,
clearEntities = tiny.clearEntities,
clearSystems = tiny.clearSystems,
getEntityCount = tiny.getEntityCount,
getSystemCount = tiny.getSystemCount,
getSystemIndex = tiny.getSystemIndex,
setSystemIndex = tiny.setSystemIndex
}
}
2015-04-27 06:12:11 +00:00
return tiny