Skip to content

Commit 210bf9a

Browse files
committed
Initial commit
0 parents  commit 210bf9a

File tree

4 files changed

+161
-0
lines changed

4 files changed

+161
-0
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.luacheckrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return {
2+
std = 'lua51+love',
3+
ignore = {'212'},
4+
}

main.lua

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
local manager = require 'roomy'.new()
2+
3+
local game, pause = {}, {}
4+
5+
function game:keypressed(key)
6+
if key == 'escape' then
7+
manager:push(pause, 'hiya!')
8+
end
9+
if key == 'space' then
10+
manager:switch(pause, 'switching')
11+
end
12+
end
13+
14+
function game:pause()
15+
print 'pause'
16+
end
17+
18+
function game:resume()
19+
print 'unpause'
20+
end
21+
22+
function game:draw()
23+
love.graphics.print 'this is the gameplay state'
24+
end
25+
26+
function pause:enter(previous, message)
27+
print(previous, message)
28+
end
29+
30+
function pause:keypressed(key)
31+
manager:pop()
32+
end
33+
34+
function pause:draw()
35+
love.graphics.print 'paused'
36+
end
37+
38+
function love.load()
39+
manager:hook()
40+
manager:switch(game)
41+
end

roomy.lua

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
local roomy = {}
2+
3+
local Manager = {}
4+
Manager.__index = Manager
5+
6+
function Manager:_switch(state, ...)
7+
local previous = self.stack[#self.stack]
8+
if previous then self:emit('leave', state, ...) end
9+
self.stack[math.max(#self.stack, 1)] = state
10+
self:emit('enter', previous or false, ...)
11+
end
12+
13+
function Manager:_push(state, ...)
14+
local previous = self.stack[#self.stack]
15+
if previous then self:emit('pause', state, ...) end
16+
self.stack[#self.stack + 1] = state
17+
self:emit('enter', previous or false, ...)
18+
end
19+
20+
function Manager:_pop(...)
21+
if #self.stack == 0 then
22+
error('No state to pop', 3)
23+
end
24+
if #self.stack == 1 then
25+
error('Cannot pop a state when there is no state below it on the stack', 3)
26+
end
27+
local previous = self.stack[#self.stack]
28+
self.stack[#self.stack] = nil
29+
self:emit('resume', previous, ...)
30+
end
31+
32+
function Manager:apply()
33+
if not self.action then return end
34+
if self.action.type == 'switch' then
35+
self:_switch(self.action.state, unpack(self.action.args))
36+
elseif self.action.type == 'push' then
37+
self:_push(self.action.state, unpack(self.action.args))
38+
elseif self.action.type == 'pop' then
39+
self:_pop(unpack(self.action.args))
40+
end
41+
self.action = nil
42+
end
43+
44+
function Manager:switch(state, ...)
45+
self.action = {type = 'switch', state = state, args = {...}}
46+
end
47+
48+
function Manager:push(state, ...)
49+
self.action = {type = 'push', state = state, args = {...}}
50+
end
51+
52+
function Manager:pop(...)
53+
self.action = {type = 'pop', args = {...}}
54+
end
55+
56+
function Manager:emit(event, ...)
57+
local state = self.stack[#self.stack]
58+
if not state then return end
59+
if state[event] then state[event](state, ...) end
60+
end
61+
62+
local defaultHookOptions = {
63+
callbacks = {
64+
'directorydropped',
65+
'draw',
66+
'filedropped',
67+
'focus',
68+
'keypressed',
69+
'keyreleased',
70+
'load',
71+
'lowmemory',
72+
'mousefocus',
73+
'mousemoved',
74+
'mousepressed',
75+
'mousereleased',
76+
'quit',
77+
'resize',
78+
'run',
79+
'textedited',
80+
'textinput',
81+
'threaderror',
82+
'touchmoved',
83+
'touchpressed',
84+
'touchreleased',
85+
'update',
86+
'visible',
87+
'wheelmoved',
88+
},
89+
applyBefore = 'update',
90+
}
91+
92+
function Manager:hook(options)
93+
options = options or defaultHookOptions
94+
for _, callbackName in ipairs(options.callbacks) do
95+
local oldCallback = love[callbackName]
96+
love[callbackName] = function(...)
97+
if oldCallback then oldCallback(...) end
98+
if callbackName == options.applyBefore then
99+
self:apply()
100+
end
101+
self:emit(callbackName, ...)
102+
end
103+
end
104+
end
105+
106+
function roomy.new()
107+
local manager = setmetatable({
108+
stack = {},
109+
action = nil,
110+
}, Manager)
111+
return manager
112+
end
113+
114+
return roomy

0 commit comments

Comments
 (0)