From 153f326612ec3559a673e6c7bc828c251b4818f0 Mon Sep 17 00:00:00 2001 From: bakpakin Date: Tue, 5 May 2015 22:03:04 +0800 Subject: [PATCH] Add two new filter functions - rejectAll and rejectOne. --- spec/tiny_spec.lua | 15 +++++++++++ tiny.lua | 65 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/spec/tiny_spec.lua b/spec/tiny_spec.lua index 0a0859c..d75f75e 100644 --- a/spec/tiny_spec.lua +++ b/spec/tiny_spec.lua @@ -58,6 +58,13 @@ describe('tiny-ecs:', function() local fxform = tiny.requireAll("xform") local fall = tiny.requireOne("spinalTap", "onlyTen", "littleMan") + -- Only select Entities without "spinalTap" + local frtap = tiny.rejectOne("spinalTap") + + -- Select Entities without all three: "spinalTap", "onlyTen", and + -- "littleMan" + local frall = tiny.rejectAll("spinalTap", "onlyTen", "littleMan") + assert.truthy(fall(nil, entity1)) assert.truthy(ftap(nil, entity1)) assert.falsy(ftap(nil, entity2)) @@ -68,6 +75,14 @@ describe('tiny-ecs:', function() assert.truthy(fall(nil, entity2)) assert.truthy(fall(nil, entity3)) + assert.falsy(frtap(nil, entity1)) + assert.truthy(frtap(nil, entity2)) + assert.truthy(frtap(nil, entity3)) + + assert.truthy(frall(nil, entity1)) + assert.truthy(frall(nil, entity2)) + assert.truthy(frall(nil, entity3)) + end) end) diff --git a/tiny.lua b/tiny.lua index 0fbce1d..6bac623 100644 --- a/tiny.lua +++ b/tiny.lua @@ -23,7 +23,7 @@ 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-1" } +local tiny = { _VERSION = "dev" } -- Local versions of standard lua functions local tinsert = table.insert @@ -33,6 +33,7 @@ local pairs = pairs local ipairs = ipairs local setmetatable = setmetatable local type = type +local select = select -- Local versions of the library functions local tiny_manageEntities @@ -75,6 +76,14 @@ local tiny_remove -- 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.rejectOne("Player", "Enemy")) +-- -- @section Filter --- Makes a Filter that selects Entities with all specified Components and @@ -121,6 +130,50 @@ function tiny.requireOne(...) end 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 + 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. +-- @param ... List of required Components and other Filters. +function tiny.rejectOne(...) + 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 + --- System functions. -- A System is a wrapper around function callbacks for manipulating Entities. -- @section System @@ -335,8 +388,9 @@ tiny_addSystem = tiny.addSystem -- @see addEntity -- @see addSystem function tiny.add(world, ...) - local args = {...} - for _, obj in ipairs(args) do + local obj + for i = 1, select("#", ...) do + obj = select(i, ...) if isSystem(obj) then tiny_addSystem(world, obj) else -- Assume obj is an Entity @@ -370,8 +424,9 @@ tiny_removeSystem = tiny.removeSystem -- @see removeEntity -- @see removeSystem function tiny.remove(world, ...) - local args = {...} - for _, obj in ipairs(args) do + local obj + for i = 1, select("#", ...) do + obj = select(i, ...) if isSystem(obj) then tiny_removeSystem(world, obj) else -- Assume obj is an Entity