Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- This lib provides state-automato into love2d, with autotracking
- and autogenerating handlers, like love.update/love.mousemoved etc.
- Wroted by Tommy (aka Snusmumriken aka HDPLocust)
- If you see it, you will go to jail.
- Reference manual:
- Using:
- --initialisation state-system
- state = require 'states'
- --initialisation table for state #1
- local stateA = {}
- function stateA:load()
- self.x, self.y = 0.0
- end
- function stateA:update(dt)
- self.x, self.y = self.x + dt, self.y + dt^2
- end
- function stateA:draw()
- if love.keyboard.isDown('2') then state:set('B') end
- love.graphics.rectangle('line', self.x, self.y)
- end
- --initialisation table for state #2
- local stateB = {}
- function stateB:load()
- self.rect = {10, 20, 40, 30}
- self.bool = false
- end
- function stateB:keypressed(key, unicode, isrepeat) -- Any arguments that any version of LOVE send it
- if key == ' ' then self.bool = not self.bool end
- if key == '1' then state:set('A') end
- end
- function stateB:draw()
- if self.bool then
- love.graphics.setColor(100, 200, 100)
- else
- love.graphics.setColor(200, 100, 100)
- end
- love.graphics.rectangle('line', unpack(self.rect))
- -- attaching states:
- state:new('A', stateA)
- state:new('B', stateB)
- state:set('A')
- end
- ]]
- local type = type
- local love = require'love'
- if not love then error('This lib only for LOVE2D framework. download it here: https://love2d.org', 2) end
- local function err(v, str, ...)
- if not v then error(str:format(...), 3) end
- end
- local callbacks = {'update', 'draw'}
- --track love.handlers of current version of LOVE2d
- for k, _ in pairs(love.handlers) do
- callbacks[#callbacks + 1] = tostring(k)
- end
- --Initialise state defaults
- local function state(t, name, global)
- local s = t or {}
- s.State = global
- s.Name = name
- s.Break = {}
- return s
- end
- --State manager
- local states = {}
- function states:__new()
- self.state = {} --state list
- self.stack = {} --current stack
- self.debug = true
- self.__index = self
- return self
- end
- --Self and additional love callback initialisation
- --(load/update/draw/keypressed/keyreleased etc)
- function states:init()
- local temp_stack = {}
- for _, k in ipairs(callbacks) do
- --initialisation self methods like self:update(dt)
- self[k] = function(self, ...)
- for i = 1, #temp_stack do temp_stack[i] = nil end
- for i = 1, #self.stack do temp_stack[i] = self.stack[i] end
- local startStackPosition = 1
- -- roll back and find first callback-overrider state
- for i = #temp_stack, 1, -1 do
- local v = temp_stack[i]
- if v.Break and v.Break[k] then
- startStackPosition = i
- break
- end
- end
- -- call callbacks from all states in stack, start from first overrider
- for i = startStackPosition, #temp_stack do
- local s = temp_stack[i]
- if type(s[k]) == 'function' then
- s[k](s, ...)
- end
- end
- end
- --optional addition methods for love, if not defined
- if not love[k] then
- love[k] = function(...)
- self[k](self, ...)
- end
- end
- end
- return self
- end
- function states:new(n, t, ...)
- err(type(n) == 'string', 'Arg#1: State name expected, got "%s"', type(n))
- err(type(t) == 'table', 'Arg#2: State table expected, got "%s"', type(t))
- local st = state(t, n, self)
- self.state[n] = st
- if type(st.init) == 'function' then
- st:init(...)
- end
- return st
- end
- function states:set(name, ...)
- err(type(name) == 'string', 'Arg#1: State name expected, got: "%s"', type(name))
- local s = self.state[name]
- err(s,'Arg#1: Name of defined state required, got: "%s"', tostring(name))
- if self.debug then love.window.setTitle(name) end
- for i = #self.stack, 1, -1 do
- local s = self.stack[i]
- if type(s.unload) == 'function' then
- s:unload()
- end
- end
- self.stack = {s}
- if type(s.load) == 'function' then
- s:load(...)
- end
- end
- -- override_table is table with callback-keys, if key [keypressed] == true then after that state this callback brakes
- function states:push(name, ...)
- local s = self.state[name]
- err(s, 'Arg#1: Name of defined state required, got: "%s"', type(name))
- self.stack[#self.stack + 1] = s
- if type(s.load) == 'function' then
- s:load(...)
- end
- end
- function states:pop(...)
- err(#self.stack > 0, 'More pops then pushes')
- local s = table.remove(self.stack)
- if type(s.unload) == 'function' then
- s:unload(...)
- end
- end
- function states:getStack()
- return self.stack
- end
- return states:__new():init()
Add Comment
Please, Sign In to add comment