mirror of
https://github.com/kikito/middleclass.git
synced 2024-10-05 23:24:17 +00:00
removed getterSetters from main MiddleClass (use a mixin instead). Added destroy. Fixed bug with destroying stateful objects
This commit is contained in:
parent
bf24742c9c
commit
64f2d89281
27
MiddleClass.lua
Normal file → Executable file
27
MiddleClass.lua
Normal file → Executable file
@ -58,6 +58,8 @@ Object.subclass = function(theClass, name)
|
||||
|
||||
_classes[theSubclass]=theSubclass --registers the new class on the list of _classes
|
||||
|
||||
theClass:subclassed(theSubclass) -- hook method. By default it does nothing
|
||||
|
||||
return theSubclass
|
||||
end
|
||||
|
||||
@ -72,10 +74,12 @@ Object.includes = function(theClass, module, ... )
|
||||
if type(module.included)=="function" then module:included(theClass, ... ) end
|
||||
end
|
||||
|
||||
-- root of initialize and __tostring methods
|
||||
-- built-in methods
|
||||
Object.__classDict = {
|
||||
initialize = function(instance, ...) end, -- end of the initialize() call chain
|
||||
__tostring = function(instance) return ("instance of ".. instance.class.name) end
|
||||
initialize = function(instance, ...) end, -- empty method
|
||||
destroy = function(instance) end, -- empty method
|
||||
__tostring = function(instance) return ("instance of ".. instance.class.name) end,
|
||||
subclassed = function(theClass, other) end -- empty method
|
||||
}
|
||||
|
||||
-- This allows doing tostring(obj) and Object() instead of Object:new()
|
||||
@ -84,23 +88,6 @@ setmetatable(Object, { __index = Object.__classDict, __newindex = Object.__class
|
||||
__call = Object.new
|
||||
})
|
||||
|
||||
-- Getter/Setter related methods
|
||||
function Object.getterFor(theClass, attr) return 'get' .. attr:gsub("^%l", string.upper) end
|
||||
function Object.setterFor(theClass, attr) return 'set' .. attr:gsub("^%l", string.upper) end
|
||||
function Object.getter(theClass, attributeName, defaultValue)
|
||||
theClass[theClass:getterFor(attributeName)] = function(self)
|
||||
if(self[attributeName]~=nil) then return self[attributeName] end
|
||||
return defaultValue
|
||||
end
|
||||
end
|
||||
function Object.setter(theClass, attributeName)
|
||||
theClass[theClass:setterFor(attributeName)] = function(self, value) self[attributeName] = value end
|
||||
end
|
||||
function Object.getterSetter(theClass, attributeName, defaultValue)
|
||||
theClass:getter(attributeName, defaultValue)
|
||||
theClass:setter(attributeName)
|
||||
end
|
||||
|
||||
-- Returns true if aClass is a subclass of other, false otherwise
|
||||
function subclassOf(other, aClass)
|
||||
if aClass == nil or other==nil then return false end
|
||||
|
30
MindState.lua
Normal file → Executable file
30
MindState.lua
Normal file → Executable file
@ -39,11 +39,33 @@ local _ignoredMethods = {
|
||||
states=1, initialize=1,
|
||||
gotoState=1, pushState=1, popState=1, popAllStates=1, getCurrentState=1, isInState=1,
|
||||
enterState=1, exitState=1, pushedState=1, poppedState=1, pausedState=1, continuedState=1,
|
||||
addState=1, subclass=1, includes=1
|
||||
addState=1, subclass=1, includes=1, destroy=1
|
||||
}
|
||||
|
||||
local _prevSubclass = StatefulObject.subclass -- previous way of creating subclasses (used to redefine subclass itself)
|
||||
|
||||
|
||||
-- The State class; is the father of all State objects
|
||||
local State = class('State', Object)
|
||||
|
||||
function State.subclass(theClass, name, theStatefulClass)
|
||||
local theSubClass = Object.subclass(theClass, name)
|
||||
local superDict = (theClass==State and theClass.__classDict or theStatefulClass.superclass.__classDict)
|
||||
theSubClass.subclass = State.subclass
|
||||
|
||||
local mt = getmetatable(theSubClass)
|
||||
mt.__newindex = function(_, methodName, method)
|
||||
if type(method) == 'function' then
|
||||
local fenv = getfenv(method)
|
||||
local newenv = setmetatable( {super = superDict}, {__index = fenv, __newindex = fenv} )
|
||||
setfenv( method, newenv )
|
||||
end
|
||||
rawset(theSubClass.__classDict, methodName, method)
|
||||
end
|
||||
|
||||
return theSubClass
|
||||
end
|
||||
|
||||
------------------------------------
|
||||
-- INSTANCE METHODS
|
||||
------------------------------------
|
||||
@ -203,15 +225,17 @@ end
|
||||
------------------------------------
|
||||
|
||||
--[[ Adds a new state to the "states" class member.
|
||||
superState is optional. If nil, Object will be the parent class of the new state
|
||||
superState is optional. If nil, State will be the parent class of the new state
|
||||
returns the newly created state
|
||||
]]
|
||||
function StatefulObject.addState(theClass, stateName, superState)
|
||||
superState = superState or State
|
||||
--print(theClass.name, stateName, superState.name)
|
||||
assert(subclassOf(StatefulObject, theClass), "Use class:addState instead of class.addState")
|
||||
assert(theClass.states[stateName]==nil, "The class " .. theClass.name .. " already has a state called '" .. stateName)
|
||||
assert(type(stateName)=="string", "stateName must be a string")
|
||||
-- states are just regular classes. If superState is nil, this uses Object as superClass
|
||||
local state = class(stateName, superState)
|
||||
local state = superState:subclass(stateName, theClass)
|
||||
theClass.states[stateName] = state
|
||||
return state
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user