|
|
(4 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
− | Also known as SECS (pronounce as 'sex'). | + | Also known as SECL. |
| This is a simple implementation of classes that works, it's not commented, so it's a nice test of your lua skills. | | This is a simple implementation of classes that works, it's not commented, so it's a nice test of your lua skills. |
| | | |
− | Remember to check here once in a while, it might have updated.
| + | The current version can always be found [https://github.com/bartbes/love-misc-libs in the love-misc-libs repository] |
| | | |
− | ==Basic version== | + | ==Basic version example== |
− | <source lang="lua">
| |
− | --[[
| |
− | Copyright (c) 2009 Bart van Strien
| |
− | | |
− | 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.
| |
− | ]]
| |
− | | |
− | __HAS_SECS_COMPATIBLE_CLASSES__ = true
| |
− | | |
− | local class_mt = {}
| |
− | | |
− | function class_mt:__index(key)
| |
− | return self.__baseclass[key]
| |
− | end
| |
− | | |
− | class = setmetatable({ __baseclass = {} }, class_mt)
| |
− | | |
− | function class:new(...)
| |
− | local c = {}
| |
− | c.__baseclass = self
| |
− | setmetatable(c, getmetatable(self))
| |
− | if c.init then
| |
− | c:init(...)
| |
− | end
| |
− | return c
| |
− | end
| |
− | </source>
| |
− | | |
− | ===Example===
| |
| <source lang="lua"> | | <source lang="lua"> |
| require "class" --this assumes you've saved the code above in class.lua | | require "class" --this assumes you've saved the code above in class.lua |
Line 68: |
Line 20: |
| </source> | | </source> |
| | | |
− | ==Class Commons enabled basic version==
| + | ==Advanced version example== |
− | <source lang="lua">
| |
− | --[[
| |
− | Copyright (c) 2009-2011 Bart van Strien
| |
− | | |
− | 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.
| |
− | ]]
| |
− | | |
− | local class_mt = {}
| |
− | | |
− | function class_mt:__index(key)
| |
− | return self.__baseclass[key]
| |
− | end
| |
− | | |
− | class = setmetatable({ __baseclass = {} }, class_mt)
| |
− | | |
− | function class:new(...)
| |
− | local c = {}
| |
− | c.__baseclass = self
| |
− | setmetatable(c, getmetatable(self))
| |
− | if c.init then
| |
− | c:init(...)
| |
− | end
| |
− | return c
| |
− | end
| |
− | | |
− | if class_commons ~= false then --on by default
| |
− | common = {}
| |
− | | |
− | function common.class(name, t, parent)
| |
− | parent = parent or class
| |
− | t.__baseclass = parent
| |
− | return setmetatable(t, getmetatable(parent))
| |
− | end
| |
− | | |
− | function common.instance(class, ...)
| |
− | return class:new(...)
| |
− | end
| |
− | end
| |
− | </source>
| |
− | | |
− | ==Advanced version== | |
− | <source lang="lua">
| |
− | --[[
| |
− | Copyright (c) 2009 Bart van Strien
| |
− | | |
− | 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.
| |
− | ]]
| |
− | | |
− | __HAS_SECS_COMPATIBLE_CLASSES__ = true
| |
− | | |
− | local class_mt = {}
| |
− | | |
− | function class_mt:__index(key)
| |
− | if rawget(self, "__baseclass") then
| |
− | return self.__baseclass[key]
| |
− | end
| |
− | return nil
| |
− | end
| |
− | | |
− | class = setmetatable({ __baseclass = {} }, class_mt)
| |
− | | |
− | function class:new(...)
| |
− | local c = {}
| |
− | c.__baseclass = self
| |
− | setmetatable(c, getmetatable(self))
| |
− | if c.init then
| |
− | c:init(...)
| |
− | end
| |
− | return c
| |
− | end
| |
− | | |
− | function class:convert(t)
| |
− | t.__baseclass = self
| |
− | setmetatable(t, getmetatable(self))
| |
− | return t
| |
− | end
| |
− | | |
− | function class:addparent(...)
| |
− | if not rawget(self.__baseclass, "__isparenttable") then
| |
− | local t = {__isparenttable = true, self.__baseclass, ...}
| |
− | local mt = {}
| |
− | function mt:__index(key)
| |
− | for i, v in pairs(self) do
| |
− | if i ~= "__isparenttable" and v[key] then
| |
− | return v[key]
| |
− | end
| |
− | end
| |
− | return nil
| |
− | end
| |
− | self.__baseclass = setmetatable(t, mt)
| |
− | else
| |
− | for i, v in ipairs{...} do
| |
− | table.insert(self.__baseclass, v)
| |
− | end
| |
− | end
| |
− | return self
| |
− | end
| |
− | | |
− | function class:setmetamethod(name, value)
| |
− | local mt = getmetatable(self)
| |
− | local newmt = {}
| |
− | for i, v in pairs(mt) do
| |
− | newmt[i] = v
| |
− | end
| |
− | newmt[name] = value
| |
− | setmetatable(self, newmt)
| |
− | end
| |
− | </source>
| |
− | | |
− | ===Example===
| |
| <source lang="lua"> | | <source lang="lua"> |
| --NOTE: this example only contains features the basic version doesn't, if you want to see those functions see the basic example | | --NOTE: this example only contains features the basic version doesn't, if you want to see those functions see the basic example |
Line 245: |
Line 49: |
| </source> | | </source> |
| | | |
− | ==Full version (AKA overcomplicated)== | + | ==Full version example== |
− | <source lang="lua">
| |
− | --[[
| |
− | Copyright (c) 2009 Bart van Strien
| |
− | | |
− | 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.
| |
− | ]]
| |
− | | |
− | __HAS_SECS_COMPATIBLE_CLASSES__ = true
| |
− | | |
− | local class_mt = {}
| |
− | | |
− | function class_mt:__index(key)
| |
− | if rawget(self, "__baseclass") then
| |
− | return self.__baseclass[key]
| |
− | end
| |
− | return nil
| |
− | end
| |
− | | |
− | function class_mt:__call(...)
| |
− | return self:new(...)
| |
− | end
| |
− | | |
− | function class_mt:__add(parent)
| |
− | return self:addparent(parent)
| |
− | end
| |
− | | |
− | function class_mt:__eq(other)
| |
− | if not other.__baseclass or other.__baseclass ~= self.__baseclass then return false end
| |
− | for i, v in pairs(self) do
| |
− | if not other[i] then
| |
− | return false
| |
− | end
| |
− | end
| |
− | for i, v in pairs(other) do
| |
− | if not self[i] then
| |
− | return false
| |
− | end
| |
− | end
| |
− | return true
| |
− | end
| |
− | | |
− | function class_mt:__lt(other)
| |
− | if not other.__baseclass then return false end
| |
− | if rawget(other.__baseclass, "__isparenttable") then
| |
− | for i, v in pairs(other.__baseclass) do
| |
− | if self == v or getmetatable(self).__lt(self, v) then return true end
| |
− | end
| |
− | else
| |
− | if self == other.__baseclass or getmetatable(self).__lt(self, other.__baseclass) then return true end
| |
− | end
| |
− | return false
| |
− | end
| |
− | | |
− | function class_mt:__le(other)
| |
− | return (self < other or self == other)
| |
− | end
| |
− | | |
− | local pt_mt = {}
| |
− | function pt_mt:__index(key)
| |
− | for i, v in pairs(self) do
| |
− | if i ~= "__isparenttable" and v[key] then
| |
− | return v[key]
| |
− | end
| |
− | end
| |
− | return nil
| |
− | end
| |
− | | |
− | class = setmetatable({ __baseclass = {} }, class_mt)
| |
− | | |
− | function class:new(...)
| |
− | local c = {}
| |
− | c.__baseclass = self
| |
− | setmetatable(c, getmetatable(self))
| |
− | if c.init then
| |
− | c:init(...)
| |
− | end
| |
− | return c
| |
− | end
| |
− | | |
− | function class:convert(t)
| |
− | t.__baseclass = self
| |
− | setmetatable(t, getmetatable(self))
| |
− | return t
| |
− | end
| |
− | | |
− | function class:addparent(...)
| |
− | if not rawget(self.__baseclass, "__isparenttable") then
| |
− | local t = {__isparenttable = true, self.__baseclass, ...}
| |
− | self.__baseclass = setmetatable(t, pt_mt)
| |
− | else
| |
− | for i, v in ipairs{...} do
| |
− | table.insert(self.__baseclass, v)
| |
− | end
| |
− | end
| |
− | return self
| |
− | end
| |
− | | |
− | function class:setmetamethod(name, value)
| |
− | local mt = getmetatable(self)
| |
− | local newmt = {}
| |
− | for i, v in pairs(mt) do
| |
− | newmt[i] = v
| |
− | end
| |
− | newmt[name] = value
| |
− | setmetatable(self, newmt)
| |
− | end
| |
− | </source>
| |
− | | |
− | | |
− | ===Example===
| |
| <source lang="lua"> | | <source lang="lua"> |
| --NOTE: This example only contains features the advanced version doesn't have | | --NOTE: This example only contains features the advanced version doesn't have |
Line 403: |
Line 78: |
| </source> | | </source> |
| | | |
− | ==Revised version== | + | ==Revised version example == |
− | Warning, this might update more than the others.
| |
− | <source lang="lua">
| |
− | --[[
| |
− | Copyright (c) 2010 Bart van Strien
| |
− | | |
− | 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.
| |
− | ]]
| |
− | | |
− | __HAS_SECS_COMPATIBLE_CLASSES__ = true
| |
− | | |
− | local class_mt = {}
| |
− | | |
− | function class_mt:__index(key)
| |
− | if key == "__private" or (rawget(self, "__private") and self.__private[key]) then
| |
− | return nil
| |
− | end
| |
− | if rawget(self, "__baseclass") then
| |
− | return self.__baseclass[key]
| |
− | end
| |
− | return nil
| |
− | end
| |
− | | |
− | function class_mt:__call(...)
| |
− | return self:new(...)
| |
− | end
| |
− | | |
− | function class_mt:__add(parent)
| |
− | return self:addparent(parent)
| |
− | end
| |
− | | |
− | function class_mt:__eq(other)
| |
− | if not other.__baseclass or other.__baseclass ~= self.__baseclass then return false end
| |
− | for i, v in pairs(self) do
| |
− | if not other[i] then
| |
− | return false
| |
− | end
| |
− | end
| |
− | for i, v in pairs(other) do
| |
− | if not self[i] then
| |
− | return false
| |
− | end
| |
− | end
| |
− | return true
| |
− | end
| |
− | | |
− | function class_mt:__lt(other)
| |
− | if not other.__baseclass then return false end
| |
− | if rawget(other.__baseclass, "__isparenttable") then
| |
− | for i, v in pairs(other.__baseclass) do
| |
− | if self == v or getmetatable(self).__lt(self, v) then return true end
| |
− | end
| |
− | else
| |
− | if self == other.__baseclass or getmetatable(self).__lt(self, other.__baseclass) then return true end
| |
− | end
| |
− | return false
| |
− | end
| |
− | | |
− | function class_mt:__le(other)
| |
− | return (self < other or self == other)
| |
− | end
| |
− | | |
− | local pt_mt = {}
| |
− | function pt_mt:__index(key)
| |
− | for i, v in pairs(self) do
| |
− | if i ~= "__isparenttable" and v[key] then
| |
− | return v[key]
| |
− | end
| |
− | end
| |
− | return nil
| |
− | end
| |
− | | |
− | class = setmetatable({ __baseclass = {} }, class_mt)
| |
− | | |
− | function class:new(...)
| |
− | local c = {}
| |
− | c.__baseclass = self
| |
− | setmetatable(c, getmetatable(self))
| |
− | c:__init(...)
| |
− | return c
| |
− | end
| |
− | | |
− | function class:__init(...)
| |
− | local args = {...}
| |
− | if rawget(self, "init") then
| |
− | args = {self:init(...) or ...}
| |
− | end
| |
− | if self.__baseclass.__init then
| |
− | self.__baseclass:__init(unpack(args))
| |
− | end
| |
− | end
| |
− | | |
− | function class:convert(t)
| |
− | t.__baseclass = self
| |
− | setmetatable(t, getmetatable(self))
| |
− | return t
| |
− | end
| |
− | | |
− | function class:addparent(...)
| |
− | if not rawget(self.__baseclass, "__isparenttable") then
| |
− | local t = {__isparenttable = true, self.__baseclass, ...}
| |
− | self.__baseclass = setmetatable(t, pt_mt)
| |
− | else
| |
− | for i, v in ipairs{...} do
| |
− | table.insert(self.__baseclass, v)
| |
− | end
| |
− | end
| |
− | return self
| |
− | end
| |
− | | |
− | function class:setmetamethod(name, value)
| |
− | local mt = getmetatable(self)
| |
− | local newmt = {}
| |
− | for i, v in pairs(mt) do
| |
− | newmt[i] = v
| |
− | end
| |
− | newmt[name] = value
| |
− | setmetatable(self, newmt)
| |
− | end
| |
− | </source>
| |
− | | |
− | ===Example===
| |
| Same as full. | | Same as full. |
| | | |
| ==See also== | | ==See also== |
− | [[User:Bartbes|Bartbes]], creator and maintainer of SECS. | + | [[User:Bartbes|Bartbes]], creator and maintainer of SECL. |
| | | |
| {{#set:LOVE Version=Any}} | | {{#set:LOVE Version=Any}} |
| {{#set:Description=A class implementation}} | | {{#set:Description=A class implementation}} |
| + | {{#set:Keyword=Class}} |
| [[Category:Libraries]] | | [[Category:Libraries]] |