Skip to content

Commit

Permalink
Updated for LOVE v0.7.0
Browse files Browse the repository at this point in the history
Signed-off-by: Luke Perkin <lukeperkin@gmail.com>
  • Loading branch information
Luke Perkin committed Jan 20, 2011
1 parent d0cefad commit 079e9a6
Show file tree
Hide file tree
Showing 58 changed files with 953 additions and 923 deletions.
415 changes: 0 additions & 415 deletions goo old/goo.lua

This file was deleted.

File renamed without changes.
225 changes: 112 additions & 113 deletions MindState.lua → goo/MindState.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
-- Based on Unrealscript's stateful objects
-----------------------------------------------------------------------------------

require 'MiddleClass.lua'
--[[ StatefulObject declaration
* Stateful classes have a list of states (accesible through class.states).
* When a method is invoked on an instance of such classes, it is first looked up on the class current state (accesible through class.currentState)
Expand All @@ -13,8 +12,8 @@ require 'MiddleClass.lua'
]]
StatefulObject = class('StatefulObject')

StatefulObject.states = {} -- the root state list

StatefulObject.states = {} -- the root state list

local private = setmetatable({}, {__mode = "k"}) -- weak table storing private references

-- Instance methods
Expand All @@ -27,9 +26,9 @@ local private = setmetatable({}, {__mode = "k"}) -- weak table storing private
function StatefulObject:initialize(initParameters)
super.initialize(self)
initParameters = initParameters or {} --initialize to empty table if nil
self.states = {}
private[self] = {
stateStack = {}
self.states = {}
private[self] = {
stateStack = {}
}
for stateName,stateClass in pairs(self.class.states) do
local state = stateClass:new(unpack(initParameters[stateName] or {}))
Expand All @@ -42,116 +41,116 @@ end
If the current state has a method called onExitState, it will be called, with the instance as a parameter.
If the "next" state exists and has a method called onExitState, it will be called, with the instance as a parameter.
use gotoState(nil) for setting states to nothing
This method invokes the exitState and enterState functions if they exist on the current state
This method invokes the exitState and enterState functions if they exist on the current state
Second parameter is optional. If true, the stack will be conserved. Otherwise, it will be popped.
]]
function StatefulObject:gotoState(newStateName, keepStack)
assert(self.states~=nil, "Attribute 'states' not detected. check that you called instance:gotoState and not instance.gotoState, and that you invoked super.initialize(self) in the constructor.")

local prevState = self:getCurrentState()

-- If we're trying to go to a state in which we already are, return (do nothing)
if(prevState~=nil and prevState.name == newStateName) then return end

local nextState
if(newStateName~=nil) then
nextState = self.states[newStateName]
assert(nextState~=nil, "State '" .. newStateName .. "' not found")

local prevState = self:getCurrentState()

-- If we're trying to go to a state in which we already are, return (do nothing)
if(prevState~=nil and prevState.name == newStateName) then return end

local nextState
if(newStateName~=nil) then
nextState = self.states[newStateName]
assert(nextState~=nil, "State '" .. newStateName .. "' not found")
end

-- Invoke exitState on the previous state
-- Invoke exitState on the previous state
if(prevState~=nil and type(prevState.exitState) == "function") then prevState.exitState(self, newStateName) end

-- Empty the stack unless keepStack is true.
if(keepStack~=true) then self:popAllStates() end

-- replace the top of the stack with the new state
local stack = private[self].stateStack

-- Empty the stack unless keepStack is true.
if(keepStack~=true) then self:popAllStates() end

-- replace the top of the stack with the new state
local stack = private[self].stateStack
stack[math.max(#stack,1)] = nextState

-- Invoke enterState on the new state. 2nd parameter is the name of the previous state, or nil
if(nextState~=nil and type(nextState.enterState) == "function") then
-- Invoke enterState on the new state. 2nd parameter is the name of the previous state, or nil
if(nextState~=nil and type(nextState.enterState) == "function") then
nextState.enterState(self, prevState~=nil and prevState.name or nil)
end
end

function StatefulObject:pushState(newStateName)
assert(type(newState)=='string', "newStateName must be a string.")
end

function StatefulObject:pushState(newStateName)
assert(type(newState)=='string', "newStateName must be a string.")
assert(self.states~=nil, "Attribute 'states' not detected. check that you called instance:pushState and not instance.pushState, and that you invoked super.initialize(self) in the constructor.")

local nextState = self.states[newStateName]
assert(nextState~=nil, "State '" .. newStateName .. "' not found")

-- If we attempt to push a state and the state is already on return (do nothing)
local stack = private[self].stateStack

local nextState = self.states[newStateName]
assert(nextState~=nil, "State '" .. newStateName .. "' not found")

-- If we attempt to push a state and the state is already on return (do nothing)
local stack = private[self].stateStack
for _,state in ipairs(stack) do
if(state.name == newStateName) then return end
end

-- Invoke pausedState on the previous state
local prevState = self:getCurrentState()
if(prevState~=nil and type(prevState.pausedState) == "function") then prevState.pausedState(self) end

-- Do the push
table.insert(stack, nextState)

-- Invoke pushState on the next state
if(type(nextState.pushedState) == "function") then nextState.pushedState(self) end

return nextState
end

-- If a state name is given, it will attempt to remove it from the stack. If not found on the stack it will do nothing.
-- If no state name is give, this pops the top state from the stack, if any. Otherwise it does nothing.
-- Callbacks will be called when needed.
function StatefulObject:popState(stateName)
end

-- Invoke pausedState on the previous state
local prevState = self:getCurrentState()
if(prevState~=nil and type(prevState.pausedState) == "function") then prevState.pausedState(self) end

-- Do the push
table.insert(stack, nextState)

-- Invoke pushState on the next state
if(type(nextState.pushedState) == "function") then nextState.pushedState(self) end

return nextState
end

-- If a state name is given, it will attempt to remove it from the stack. If not found on the stack it will do nothing.
-- If no state name is give, this pops the top state from the stack, if any. Otherwise it does nothing.
-- Callbacks will be called when needed.
function StatefulObject:popState(stateName)
assert(self.states~=nil, "Attribute 'states' not detected. check that you called instance:popState and not instance.popState, and that you invoked super.initialize(self) in the constructor.")

-- Invoke poppedState on the previous state
local prevState = self:getCurrentState()
if(prevState~=nil and type(prevState.poppedState) == "function") then prevState.poppedState(self) end

-- Do the pop

-- Invoke poppedState on the previous state
local prevState = self:getCurrentState()
if(prevState~=nil and type(prevState.poppedState) == "function") then prevState.poppedState(self) end

-- Do the pop
local stack = private[self].stateStack
table.remove(stack, #stack)

-- Invoke continuedState on the new state
local newState = self:getCurrentState()
if(newState~=nil and type(newState.continuedState) == "function") then newState.continuedState(self) end

return newState
end

function StatefulObject:popAllStates()
local state = self:popState()
while(state~=nil) do state = self:popState() end
end

function StatefulObject:getCurrentState()
local stack = private[self].stateStack
table.remove(stack, #stack)

-- Invoke continuedState on the new state
local newState = self:getCurrentState()
if(newState~=nil and type(newState.continuedState) == "function") then newState.continuedState(self) end

return newState
end

function StatefulObject:popAllStates()
local state = self:popState()
while(state~=nil) do state = self:popState() end
end

function StatefulObject:getCurrentState()
local stack = private[self].stateStack
if #stack == 0 then return nil end
return(stack[#stack])
if #stack == 0 then return nil end
return(stack[#stack])
end

--[[
Returns true if the object is in the state named 'stateName'
If second(optional) parameter is true, this method returns true if the state is on the stack instead
]]
function StatefulObject:inState(stateName, testStateStack)
local stack = private[self].stateStack

if(testStateStack==true) then

--[[
Returns true if the object is in the state named 'stateName'
If second(optional) parameter is true, this method returns true if the state is on the stack instead
]]
function StatefulObject:inState(stateName, testStateStack)
local stack = private[self].stateStack

if(testStateStack==true) then
for _,state in ipairs(stack) do
if(state.name == stateName) then return true end
end
else --testStateStack==false
local state = stack[#stack]
if(state~=nil and state.name == stateName) then return true end
end

return false
end

end
else --testStateStack==false
local state = stack[#stack]
if(state~=nil and state.name == stateName) then return true end
end

return false
end


-- Class methods

Expand All @@ -169,12 +168,12 @@ function StatefulObject:addState(stateName, superState)
return state
end

-- These methods will not be overriden by the states.
local ignoredMethods = {
states=1, initialize=1,
gotoState=1, pushState=1, popState=1, popAllStates=1, getCurrentState=1, inState=1,
enterState=1, exitState=1, pushedState=1, poppedState=1, pausedState=1, continuedState=1,
addState=1, subclass=1, includes=1
-- These methods will not be overriden by the states.
local ignoredMethods = {
states=1, initialize=1,
gotoState=1, pushState=1, popState=1, popAllStates=1, getCurrentState=1, inState=1,
enterState=1, exitState=1, pushedState=1, poppedState=1, pausedState=1, continuedState=1,
addState=1, subclass=1, includes=1
}
local prevSubclass = StatefulObject.subclass
--[[ creates a stateful subclass
Expand All @@ -194,15 +193,15 @@ function StatefulObject:subclass(name)

--make sure that the currentState is used on the method lookup function before looking on the class dict
local classDict = theClass.__classDict
classDict.__index = function(instance, methodName)
-- If the method isn't on the 'ignoredMethods' list, look through the stack to see if it is defined
if(ignoredMethods[methodName]~=1) then
local stack = private[instance].stateStack
local method
for i = #stack,1,-1 do -- reversal loop
method = stack[i][methodName]
if(method~=nil) then return method end
end
classDict.__index = function(instance, methodName)
-- If the method isn't on the 'ignoredMethods' list, look through the stack to see if it is defined
if(ignoredMethods[methodName]~=1) then
local stack = private[instance].stateStack
local method
for i = #stack,1,-1 do -- reversal loop
method = stack[i][methodName]
if(method~=nil) then return method end
end
end
--if ignored or not found, look on the class itself
return classDict[methodName]
Expand Down Expand Up @@ -232,4 +231,4 @@ function StatefulObject:includes(module, ...)
state:includes(moduleState, ...)
end
end
end
end
Loading

0 comments on commit 079e9a6

Please sign in to comment.