diff --git a/concord/component.lua b/concord/component.lua index 7e0ae2d..7a81a52 100644 --- a/concord/component.lua +++ b/concord/component.lua @@ -8,6 +8,8 @@ function Component.new(populate) local component = setmetatable({ __populate = populate, __inherit = inherit, + + __isComponent = true, }, Component) component.__mt = {__index = component} diff --git a/concord/entity.lua b/concord/entity.lua index 4f2c022..f251002 100644 --- a/concord/entity.lua +++ b/concord/entity.lua @@ -1,5 +1,6 @@ local PATH = (...):gsub('%.[^%.]+$', '') +local Type = require(PATH..".type") local List = require(PATH..".list") local Entity = {} @@ -12,6 +13,8 @@ function Entity.new() components = {}, removed = {}, instances = List(), + + __isEntity = true, }, Entity) return e @@ -22,6 +25,10 @@ end -- @param ... The values passed to the Component -- @return self function Entity:give(component, ...) + if not Type.isComponent(component) then + error("bad argument #1 to 'Entity:give' (Component expected, got "..type(component)..")", 2) + end + self.components[component] = component:__initialize(...) return self @@ -31,6 +38,10 @@ end -- @param component The Component to remove -- @return self function Entity:remove(component) + if not Type.isComponent(component) then + error("bad argument #1 to 'Entity:remove' (Component expected, got "..type(component)..")") + end + self.removed[component] = true return self @@ -65,6 +76,10 @@ end -- @param component The Component to get -- @return The Bag from the Component function Entity:get(component) + if not Type.isComponent(component) then + error("bad argument #1 to 'Entity:get' (Component expected, got "..type(component)..")") + end + return self.components[component] end @@ -72,6 +87,10 @@ end -- @params component The Component to check against -- @return True if the entity has the Bag. False otherwise function Entity:has(component) + if not Type.isComponent(component) then + error("bad argument #1 to 'Entity:has' (Component expected, got "..type(component)..")") + end + return self.components[component] ~= nil end diff --git a/concord/init.lua b/concord/init.lua index fe40f14..8770362 100644 --- a/concord/init.lua +++ b/concord/init.lua @@ -1,5 +1,7 @@ local PATH = (...):gsub('%.init$', '') +local Type = require(PATH..".type") + local Concord = {} --- Initializes the library with some optional settings @@ -17,10 +19,18 @@ function Concord.init(settings) Concord.instances = {} Concord.addInstance = function(instance) + if not Type.isInstance(instance) then + error("bad argument #1 to 'Concord.addInstance' (Instance expected, got "..type(instance)..")", 2) + end + table.insert(Concord.instances, instance) end Concord.removeInstance = function(instance) + if not Type.isInstance(instance) then + error("bad argument #1 to 'Concord.addInstance' (Instance expected, got "..type(instance)..")", 2) + end + for i, instance in ipairs(Concord.instances) do table.remove(Concord.instances, i) break diff --git a/concord/instance.lua b/concord/instance.lua index 3247c09..b4a75f2 100644 --- a/concord/instance.lua +++ b/concord/instance.lua @@ -1,6 +1,9 @@ local PATH = (...):gsub('%.[^%.]+$', '') -local List = require(PATH..".list") +local Entity = require(PATH..".entity") +local System = require(PATH..".system") +local Type = require(PATH..".type") +local List = require(PATH..".list") local Instance = {} Instance.__index = Instance @@ -13,6 +16,8 @@ function Instance.new() systems = List(), events = {}, removed = {}, + + __isInstance = true, }, Instance) return instance @@ -22,6 +27,10 @@ end -- @param e The Entity to add -- @return self function Instance:addEntity(e) + if not Type.isEntity(e) then + error("bad argument #1 to 'Instance:addEntity' (Entity expected, got "..type(e)..")", 2) + end + e.instances:add(self) self.entities:add(e) self:checkEntity(e) @@ -33,6 +42,10 @@ end -- @param e The Entity to check -- @return self function Instance:checkEntity(e) + if not Type.isEntity(e) then + error("bad argument #1 to 'Instance:checkEntity' (Entity expected, got "..type(e)..")", 2) + end + for i = 1, self.systems.size do self.systems:get(i):__check(e) end @@ -44,6 +57,10 @@ end -- @param e The Entity to mark -- @return self function Instance:removeEntity(e) + if not Type.isEntity(e) then + error("bad argument #1 to 'Instance:removeEntity' (Entity expected, got "..type(e)..")", 2) + end + self.removed[#self.removed + 1] = e return self @@ -77,6 +94,10 @@ end -- @param enabled If the system is enabled. Defaults to true -- @return self function Instance:addSystem(system, eventName, callback, enabled) + if not Type.isSystem(system) then + error("bad argument #1 to 'Instance:addSystem' (System expected, got "..type(system)..")", 2) + end + if system.__instance and system.__instance ~= self then error("System already in instance '" ..tostring(system.__instance).."'") end @@ -106,6 +127,10 @@ end -- @param callback The callback it was registered with. Defaults to eventName -- @return self function Instance:enableSystem(system, eventName, callback) + if not Type.isSystem(system) then + error("bad argument #1 to 'Instance:enableSystem' (System expected, got "..type(system)..")", 2) + end + return self:setSystem(system, eventName, callback, true) end @@ -115,6 +140,10 @@ end -- @param callback The callback it was registered with. Defaults to eventName -- @return self function Instance:disableSystem(system, eventName, callback) + if not Type.isSystem(system) then + error("bad argument #1 to 'Instance:disableSystem' (System expected, got "..type(system)..")", 2) + end + return self:setSystem(system, eventName, callback, false) end @@ -125,17 +154,23 @@ end -- @param enable The state to set it to -- @return self function Instance:setSystem(system, eventName, callback, enable) + if not Type.isSystem(system) then + error("bad argument #1 to 'Instance:setSystem' (System expected, got "..type(system)..")", 2) + end + callback = callback or eventName - local listeners = self.events[eventName] + if callback then + local listeners = self.events[eventName] - if listeners then - for i = 1, #listeners do - local listener = listeners[i] + if listeners then + for i = 1, #listeners do + local listener = listeners[i] - if listener.system == system and listener.callback == callback then - listener.enabled = enable - break + if listener.system == system and listener.callback == callback then + listener.enabled = enable + break + end end end end @@ -148,6 +183,10 @@ end -- @param ... Parameters passed to listeners -- @return self function Instance:emit(eventName, ...) + if not eventName or type(eventName) ~= "string" then + error("bad argument #1 to 'Instance:emit' (String expected, got "..type(eventName)..")") + end + self:flush() local listeners = self.events[eventName] diff --git a/concord/pool.lua b/concord/pool.lua index 3fcf4c1..0faa85f 100644 --- a/concord/pool.lua +++ b/concord/pool.lua @@ -15,6 +15,8 @@ function Pool.new(name, filter) pool.name = name pool.filter = filter + pool.__isPool = true + return pool end diff --git a/concord/system.lua b/concord/system.lua index ffe3e47..36fbd94 100644 --- a/concord/system.lua +++ b/concord/system.lua @@ -11,6 +11,8 @@ System.mt = { __all = {}, __pools = {}, __instance = nil, + + __isSystem = true, }, systemProto) for _, filter in pairs(systemProto.__filter) do diff --git a/concord/type.lua b/concord/type.lua new file mode 100644 index 0000000..204aa79 --- /dev/null +++ b/concord/type.lua @@ -0,0 +1,19 @@ +local Type = {} + +function Type.isComponent(t) + return type(t) == "table" and t.__isComponent +end + +function Type.isEntity(t) + return type(t) == "table" and t.__isEntity +end + +function Type.isSystem(t) + return type(t) == "table" and t.__isSystem +end + +function Type.isInstance(t) + return type(t) == "table" and t.__isInstance +end + +return Type \ No newline at end of file