-
-
Save nadar71/7018aec0c6838386ba63 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
statemachine.lua | |
Copyright (c) 2013 Erin Lin | |
erinylin.blogspot.com | |
Licensed under the MIT license. | |
Usage: | |
local sm = require("statemachine") | |
local process = sm.new(function(self, time) | |
self:sleep(100) | |
print("hello") | |
self:sleep(100) | |
print("hehe...") | |
self:sleep(100) | |
print("end") | |
end) | |
process:run() | |
local process1 = sm.new(function(self, time) | |
local txt = display.newText( "Press Me", display.contentCenterX, display.contentCenterY, native.systemFont, 32) | |
txt:addEventListener("touch", function(evt) | |
self:continue() | |
end) | |
self:waiting() | |
txt.text = "Hello!" | |
self:sleep(200) | |
txt.text = "Bye Bye!" | |
end) | |
process1:run() | |
]]-- | |
local StateMachine = {} | |
local StateMachine_mt = { __index = StateMachine } | |
local coroutine = { | |
yield = coroutine.yield, | |
resume = coroutine.resume, | |
create = coroutine.create, | |
status = coroutine.status | |
} | |
function StateMachine:sleep(msec) | |
self._wakeup = system.getTimer() + msec | |
while self._wakeup > 0 do | |
coroutine.yield() | |
end | |
end | |
function StateMachine:enterFrame(event) | |
if self._wakeup > 0 then | |
if event.time > self._wakeup then | |
self._wakeup = 0 | |
end | |
else | |
local state = coroutine.status(self._co) | |
if state == "suspended" then | |
coroutine.resume(self._co, self) | |
elseif state == "dead" then | |
if self._isLoop then | |
self._co = coroutine.create( self._callback ) | |
else | |
Runtime:removeEventListener("enterFrame", self) | |
self._co = nil | |
end | |
end | |
end | |
end | |
function StateMachine:pause() | |
self._stopTime = system.getTimer() | |
Runtime:removeEventListener("enterFrame", self) | |
end | |
function StateMachine:resume() | |
if self._co then | |
if self._wakeup > 0 then | |
self._wakeup = self._wakeup + system.getTimer() - self._stopTime | |
end | |
Runtime:addEventListener("enterFrame", self) | |
else | |
self:run() | |
end | |
end | |
-- you can loop this. | |
function StateMachine:run(isLoop) | |
self._isLoop = isLoop | |
if not self._co then | |
self._wakeup = 0 | |
self._stopTime = 0 | |
Runtime:addEventListener("enterFrame", self ) | |
self._co = coroutine.create( self._callback ) | |
end | |
end | |
function StateMachine:isRunning() | |
return self._co ~= nil | |
end | |
function StateMachine:destroy() | |
Runtime:removeEventListener("enterFrame", self ) | |
self._callback, self._co, self = nil, nil, nil | |
end | |
function StateMachine:cancel() | |
Runtime:removeEventListener("enterFrame", self ) | |
self._co = nil | |
end | |
function StateMachine:waiting() | |
self._isPass = false | |
while not self._isPass do | |
coroutine.yield() | |
end | |
end | |
function StateMachine:continue() | |
self._isPass = true | |
end | |
local function new(callback) | |
local ds = {} | |
setmetatable(ds, StateMachine_mt) | |
ds._callback = callback | |
ds._wakeup = 0 | |
return ds | |
end | |
return {new=new} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment