mirror of
https://github.com/Keyslam-Group/Concord.git
synced 2025-09-02 04:13:58 -04:00
Error handling overhaul
This commit is contained in:
parent
743d662ef9
commit
892f4d4700
6 changed files with 57 additions and 28 deletions
|
@ -16,19 +16,19 @@ Component.__mt = {
|
|||
-- @treturn Component A new ComponentClass
|
||||
function Component.new(name, populate)
|
||||
if (type(name) ~= "string") then
|
||||
error("bad argument #1 to 'Component.new' (string expected, got "..type(name)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Component.new' (string expected, got %s)", type(name))
|
||||
end
|
||||
|
||||
if (string.match(name, Components.__REJECT_MATCH) ~= "") then
|
||||
error("bad argument #1 to 'Component.new' (Component names can't start with '"..Components.__REJECT_PREFIX.."', got "..name..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Component.new' (Component names can't start with '%s', got %s)", Components.__REJECT_PREFIX, name)
|
||||
end
|
||||
|
||||
if (rawget(Components, name)) then
|
||||
error("bad argument #1 to 'Component.new' (ComponentClass with name '"..name.."' was already registerd)", 2) -- luacheck: ignore
|
||||
Utils.error(2, "bad argument #1 to 'Component.new' (ComponentClass with name '%s' was already registerd)", name) -- luacheck: ignore
|
||||
end
|
||||
|
||||
if (type(populate) ~= "function" and type(populate) ~= "nil") then
|
||||
error("bad argument #1 to 'Component.new' (function/nil expected, got "..type(populate)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Component.new' (function/nil expected, got %s)", type(populate))
|
||||
end
|
||||
|
||||
local componentClass = setmetatable({
|
||||
|
|
|
@ -18,7 +18,7 @@ Entity.__mt = {
|
|||
-- @treturn Entity A new Entity
|
||||
function Entity.new(world)
|
||||
if (world ~= nil and not Type.isWorld(world)) then
|
||||
error("bad argument #1 to 'Entity.new' (world/nil expected, got "..type(world)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Entity.new' (world/nil expected, got %s)", type(world))
|
||||
end
|
||||
|
||||
local e = setmetatable({
|
||||
|
@ -68,7 +68,7 @@ function Entity:give(name, ...)
|
|||
local ok, componentClass = Components.try(name)
|
||||
|
||||
if not ok then
|
||||
error("bad argument #1 to 'Entity:get' ("..componentClass..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Entity:get' (%s)", componentClass)
|
||||
end
|
||||
|
||||
give(self, name, componentClass, ...)
|
||||
|
@ -85,7 +85,7 @@ function Entity:ensure(name, ...)
|
|||
local ok, componentClass = Components.try(name)
|
||||
|
||||
if not ok then
|
||||
error("bad argument #1 to 'Entity:ensure' ("..componentClass..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Entity:ensure' (%s)", componentClass)
|
||||
end
|
||||
|
||||
if self[name] then
|
||||
|
@ -104,7 +104,7 @@ function Entity:remove(name)
|
|||
local ok, componentClass = Components.try(name)
|
||||
|
||||
if not ok then
|
||||
error("bad argument #1 to 'Entity:remove' ("..componentClass..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Entity:remove' (%s)", componentClass)
|
||||
end
|
||||
|
||||
remove(self, name)
|
||||
|
@ -118,7 +118,7 @@ end
|
|||
-- @treturn Entity self
|
||||
function Entity:assemble(assemblage, ...)
|
||||
if type(assemblage) ~= "function" then
|
||||
error("bad argument #1 to 'Entity:assemble' (function expected, got "..type(assemblage)..")")
|
||||
Utils.error(2, "bad argument #1 to 'Entity:assemble' (function expected, got %s)", type(assemblage))
|
||||
end
|
||||
|
||||
assemblage(self, ...)
|
||||
|
@ -154,7 +154,7 @@ function Entity:has(name)
|
|||
local ok, componentClass = Components.try(name)
|
||||
|
||||
if not ok then
|
||||
error("bad argument #1 to 'Entity:has' ("..componentClass..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Entity:has' (%s)", componentClass)
|
||||
end
|
||||
|
||||
return self[name] and true or false
|
||||
|
@ -167,7 +167,7 @@ function Entity:get(name)
|
|||
local ok, componentClass = Components.try(name)
|
||||
|
||||
if not ok then
|
||||
error("bad argument #1 to 'Entity:get' ("..componentClass..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'Entity:get' (%s)", componentClass)
|
||||
end
|
||||
|
||||
return self[name]
|
||||
|
@ -219,7 +219,7 @@ function Entity:deserialize(data)
|
|||
local componentData = data[i]
|
||||
|
||||
if (not Components.has(componentData.__name)) then
|
||||
error("bad argument #1 to 'Entity:deserialize' (ComponentClass '"..tostring(componentData.__name).."' wasn't yet loaded)") -- luacheck: ignore
|
||||
Utils.error(2, "bad argument #1 to 'Entity:deserialize' (ComponentClass '%s' wasn't yet loaded)", tostring(componentData.__name)) -- luacheck: ignore
|
||||
end
|
||||
|
||||
local componentClass = Components[componentData.__name]
|
||||
|
|
|
@ -6,6 +6,7 @@ local PATH = (...):gsub('%.[^%.]+$', '')
|
|||
|
||||
local List = require(PATH..".list")
|
||||
local Type = require(PATH..".type")
|
||||
local Utils = require(PATH..".utils")
|
||||
local Components = require(PATH..".components")
|
||||
|
||||
|
||||
|
@ -20,18 +21,18 @@ Filter.__mt = {
|
|||
-- @tparam onComponent Optional function, called when a component is valid.
|
||||
function Filter.validate (name, def, onComponent)
|
||||
if type(def) ~= 'table' then
|
||||
error("invalid component list for filter '"..name.."' (table expected, got "..type(def)..")", 3)
|
||||
Utils.error(3, "invalid component list for filter '%s' (table expected, got %s)", name, type(def))
|
||||
end
|
||||
|
||||
if not onComponent and def.constructor and not Type.isCallable(def.constructor) then
|
||||
error("invalid pool constructor (callable expected, got "..type(def.constructor)..")", 3)
|
||||
Utils.error(3, "invalid pool constructor for filter '%s' (callable expected, got %s)", name, type(def.constructor))
|
||||
end
|
||||
|
||||
for n, component in ipairs(def) do
|
||||
local ok, err, reject = Components.try(component, true)
|
||||
|
||||
if not ok then
|
||||
error("invalid component for filter '"..name.."' at position #"..n.." ("..err..")", 3)
|
||||
Utils.error(3, "invalid component for filter '%s' at position #%d (%s)", name, n, err)
|
||||
end
|
||||
|
||||
if onComponent then
|
||||
|
@ -61,14 +62,38 @@ function Filter.parse (name, def)
|
|||
return required, rejected
|
||||
end
|
||||
|
||||
local REQUIRED_METHODS = {"add", "remove", "has", "clear"}
|
||||
local VALID_POOL_TYPES = {table=true, userdata=true, lightuserdata=true, cdata=true}
|
||||
|
||||
function Filter.isValidPool (name, pool)
|
||||
local poolType = type(pool)
|
||||
--Check that pool is not nil
|
||||
if not VALID_POOL_TYPES[poolType] then
|
||||
Utils.error(3, "invalid value returned by pool '%s' constructor (table expected, got %s).", name, type(pool))
|
||||
end
|
||||
|
||||
--Check if methods are callables
|
||||
for _, method in ipairs(REQUIRED_METHODS) do
|
||||
if not Type.isCallable(pool[method]) then
|
||||
Utils.error(3, "invalid :%s method on pool '%s' (callable expected, got %s).", method, name, type(pool[method]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a new Filter
|
||||
-- @string name Name for the Filter.
|
||||
-- @tparam table definition Table containing the Filter Definition
|
||||
-- @treturn Filter The new Filter
|
||||
-- @treturn Pool The associated Pool
|
||||
function Filter.new (name, def)
|
||||
local constructor = def.constructor or List
|
||||
local pool = constructor(def)
|
||||
local pool
|
||||
|
||||
if def.constructor then
|
||||
pool = def.constructor(def)
|
||||
Filter.isValidPool(name, pool)
|
||||
else
|
||||
pool = List()
|
||||
end
|
||||
|
||||
local required, rejected = Filter.parse(name, def)
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ System.mt = {
|
|||
function System.new(definition)
|
||||
for name, def in pairs(definition) do
|
||||
if type(name) ~= 'string' then
|
||||
error("invalid name for filter (string key expected, got "..type(name)..")", 2)
|
||||
Utils.error(2, "invalid name for filter (string key expected, got %s)", type(name))
|
||||
end
|
||||
|
||||
Filter.validate(name, def)
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
local Utils = {}
|
||||
|
||||
function Utils.error(level, str, ...)
|
||||
error(string.format(str, ...), level + 1)
|
||||
end
|
||||
|
||||
--- Does a shallow copy of a table and appends it to a target table.
|
||||
-- @param orig Table to copy
|
||||
-- @param target Table to append to
|
||||
|
@ -22,13 +26,13 @@ end
|
|||
-- @treturn table The namespace table
|
||||
function Utils.loadNamespace(pathOrFiles, namespace)
|
||||
if type(pathOrFiles) ~= "string" and type(pathOrFiles) ~= "table" then
|
||||
error("bad argument #1 to 'loadNamespace' (string/table of strings expected, got "..type(pathOrFiles)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'loadNamespace' (string/table of strings expected, got %s)", type(pathOrFiles))
|
||||
end
|
||||
|
||||
if type(pathOrFiles) == "string" then
|
||||
local info = love.filesystem.getInfo(pathOrFiles) -- luacheck: ignore
|
||||
if info == nil or info.type ~= "directory" then
|
||||
error("bad argument #1 to 'loadNamespace' (path '"..pathOrFiles.."' not found)", 2)
|
||||
Utils.error(2, "bad argument #1 to 'loadNamespace' (path '%s' not found)", pathOrFiles)
|
||||
end
|
||||
|
||||
local files = love.filesystem.getDirectoryItems(pathOrFiles)
|
||||
|
@ -50,7 +54,7 @@ function Utils.loadNamespace(pathOrFiles, namespace)
|
|||
elseif type(pathOrFiles) == "table" then
|
||||
for _, path in ipairs(pathOrFiles) do
|
||||
if type(path) ~= "string" then
|
||||
error("bad argument #2 to 'loadNamespace' (string/table of strings expected, got table containing "..type(path)..")", 2) -- luacheck: ignore
|
||||
Utils.error(2, "bad argument #2 to 'loadNamespace' (string/table of strings expected, got table containing %s)", type(path)) -- luacheck: ignore
|
||||
end
|
||||
|
||||
local name = path
|
||||
|
|
|
@ -52,7 +52,7 @@ end
|
|||
-- @treturn World self
|
||||
function World:addEntity(e)
|
||||
if not Type.isEntity(e) then
|
||||
error("bad argument #1 to 'World:addEntity' (Entity expected, got "..type(e)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'World:addEntity' (Entity expected, got %s)", type(e))
|
||||
end
|
||||
|
||||
if e.__world then
|
||||
|
@ -70,7 +70,7 @@ end
|
|||
-- @treturn World self
|
||||
function World:removeEntity(e)
|
||||
if not Type.isEntity(e) then
|
||||
error("bad argument #1 to 'World:removeEntity' (Entity expected, got "..type(e)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'World:removeEntity' (Entity expected, got %s)", type(e))
|
||||
end
|
||||
|
||||
self.__removed:add(e)
|
||||
|
@ -207,7 +207,7 @@ function World:addSystem(systemClass)
|
|||
local ok, err = tryAddSystem(self, systemClass)
|
||||
|
||||
if not ok then
|
||||
error("bad argument #1 to 'World:addSystem' ("..err..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'World:addSystem' (%s)", err)
|
||||
end
|
||||
|
||||
return self
|
||||
|
@ -225,7 +225,7 @@ function World:addSystems(...)
|
|||
|
||||
local ok, err = tryAddSystem(self, systemClass)
|
||||
if not ok then
|
||||
error("bad argument #"..i.." to 'World:addSystems' ("..err..")", 2)
|
||||
Utils.error(2, "bad argument #%d to 'World:addSystems' (%s)", i, err)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -237,7 +237,7 @@ end
|
|||
-- @treturn boolean
|
||||
function World:hasSystem(systemClass)
|
||||
if not Type.isSystemClass(systemClass) then
|
||||
error("bad argument #1 to 'World:getSystem' (systemClass expected, got "..type(systemClass)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'World:hasSystem' (SystemClass expected, got %s)", type(systemClass))
|
||||
end
|
||||
|
||||
return self.__systemLookup[systemClass] and true or false
|
||||
|
@ -248,7 +248,7 @@ end
|
|||
-- @treturn System System to get
|
||||
function World:getSystem(systemClass)
|
||||
if not Type.isSystemClass(systemClass) then
|
||||
error("bad argument #1 to 'World:getSystem' (systemClass expected, got "..type(systemClass)..")", 2)
|
||||
Utils.error(2, "bad argument #1 to 'World:getSystem' (SystemClass expected, got %s)", type(systemClass))
|
||||
end
|
||||
|
||||
return self.__systemLookup[systemClass]
|
||||
|
@ -261,7 +261,7 @@ end
|
|||
-- @treturn World self
|
||||
function World:emit(functionName, ...)
|
||||
if not functionName or type(functionName) ~= "string" then
|
||||
error("bad argument #1 to 'World:emit' (String expected, got "..type(functionName)..")")
|
||||
Utils.error(2, "bad argument #1 to 'World:emit' (String expected, got %s)", type(functionName))
|
||||
end
|
||||
|
||||
local shouldFlush = self.__emitSDepth == 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue