Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local _G
- = _G
- local setmetatable, assert, type, tostring, pairs, sprintf
- = setmetatable, assert, type, tostring, pairs, string.format
- local middleclass = {
- _VERSION = 'middleclass v3.0.0',
- _DESCRIPTION = 'Object Orientation for Lua',
- _LICENSE = [[
- MIT LICENSE
- Copyright (c) 2011 Enrique García Cota
- 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 function _setClassDictionariesMetatables(aClass)
- local dict = aClass.__instanceDict
- dict.__index = dict
- local super = aClass.super
- if super then
- local superStatic = super.static
- setmetatable(dict, super.__instanceDict)
- setmetatable(aClass.static, { __index = function(_, k) return dict[k] or superStatic[k] end })
- else
- setmetatable(aClass.static, { __index = function(_, k) return dict[k] end })
- end
- end
- local function _setClassMetatable(aClass)
- setmetatable(aClass, {
- __tostring = function() return sprintf("class %s", aClass.name) end,
- __index = aClass.static,
- __newindex = aClass.__instanceDict,
- __call = function(self, ...) return self:new(...) end
- })
- end
- local function _createClass(name, super)
- local aClass = {
- name = name,
- super = super,
- static = {},
- __mixins = {},
- __instanceDict = {}
- }
- aClass.subclasses = setmetatable({}, { __mode = 'k' })
- _setClassDictionariesMetatables(aClass)
- _setClassMetatable(aClass)
- return aClass
- end
- local function _createLookupMetaMethod(aClass, name)
- return function(...)
- local method = aClass.super[name]
- assert(type(method) == 'function',
- sprintf("class '%s' doesn't implement metamethod '%s'", tostring(aClass), name))
- return method(...)
- end
- end
- local function _setClassMetamethods(aClass)
- for _, m in ipairs(aClass.__metamethods) do
- aClass[m]= _createLookupMetaMethod(aClass, m)
- end
- end
- local function _setDefaultInitializeMethod(aClass, super)
- aClass.__init = function(instance, ...)
- return super.__init(instance, ...)
- end
- end
- local function _includeMixin(aClass, mixin)
- assert(type(mixin) == 'table',
- "mixin must be a table")
- for name, method in pairs(mixin) do
- if name ~= 'included' and name ~= 'static' then
- aClass[name] = method
- end
- end
- if mixin.static then
- for name, method in pairs(mixin.static) do
- aClass.static[name] = method
- end
- end
- if type(mixin.included) == 'function' then
- mixin:included(aClass)
- end
- aClass.__mixins[mixin] = true
- end
- local Object = _createClass("Object", nil)
- Object.static.__metamethods = {
- '__add',
- '__call',
- '__concat',
- '__div',
- '__le',
- '__lt',
- '__mod',
- '__mul',
- '__pow',
- '__sub',
- '__tostring',
- '__unm'
- }
- function Object.static:allocate()
- assert(type(self) == 'table',
- "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
- return setmetatable({ class = self }, self.__instanceDict)
- end
- function Object.static:new(...)
- local instance = self:allocate()
- instance:__init(...)
- return instance
- end
- function Object.static:subclass(name)
- assert(type(self) == 'table',
- "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
- assert(type(name) == "string",
- "You must provide a name(string) for your class")
- local subclass = _createClass(name, self)
- _setClassMetamethods(subclass)
- _setDefaultInitializeMethod(subclass, self)
- self.subclasses[subclass] = true
- self:subclassed(subclass)
- return subclass
- end
- function Object.static:subclassed(other)
- end
- function Object.static:isSubclassOf(other)
- return (
- type(other) == 'table' and
- type(self) == 'table' and
- type(self.super) == 'table' and
- (
- self.super == other
- or
- type(self.super.isSubclassOf) == 'function' and
- self.super:isSubclassOf(other)
- )
- )
- end
- function Object.static:include(...)
- assert(type(self) == 'table',
- "Make sure you that you are using 'Class:include' instead of 'Class.include'")
- local l = select('#', ...)
- for i = 1, l do
- _includeMixin(self, select(i, ...))
- end
- return self
- end
- function Object.static:includes(mixin)
- return (
- type(mixin) == 'table' and
- type(self) == 'table' and
- type(self.__mixins) == 'table' and
- (
- self.__mixins[mixin]
- or
- type(self.super) == 'table' and
- type(self.super.includes) == 'function' and
- self.super:includes(mixin)
- )
- )
- end
- function Object:__init()
- end
- function Object:__tostring()
- return sprintf("instance of %s", tostring(self.class))
- end
- function Object:isInstanceOf(aClass)
- return (
- type(aClass) == 'table' and
- type(self) == 'table' and
- type(self.class) == 'table' and
- (
- aClass == self.class
- or
- type(aClass.isSubclassOf) == 'function' and
- self.class:isSubclassOf(aClass)
- )
- )
- end
- function Object:_areFieldsEqual(other, ...)
- local l = select('#', ...)
- for i = 1, l do
- if self[select(i, ...)] ~= other[select(i, ...)] then
- return false
- end
- end
- return true
- end
- function Object:_isEquatableTo(other)
- return (
- type(other) == 'table' and
- type(other.class) == 'table' and
- (
- other.class == self.class
- or
- type(other.isSubclassOf) == 'function' and
- other:isSubclassOf(self.class)
- )
- )
- end
- function Object:_isEqualTo(other, ...)
- return (
- self:_isEquatableTo(other) and
- self:_areFieldsEqual(other, ...)
- )
- end
- function middleclass.class(name, super, ...)
- super = super or Object
- return super:subclass(name, ...)
- end
- middleclass.Object = Object
- setmetatable(middleclass, {
- __call = function(_, ...)
- return middleclass.class(...)
- end
- })
- return middleclass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement