Created
March 21, 2020 06:48
-
-
Save tesselode/1dfb1c0e1864da09defd0b8529d877e4 to your computer and use it in GitHub Desktop.
the promise implementation i'm currently using in my puzzle game
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
local function async(f) | |
local co | |
local function await(promise) | |
if promise:isFinished() then return end | |
promise:after(function() | |
local success, message = coroutine.resume(co) | |
if not success then error(message) end | |
end) | |
coroutine.yield() | |
end | |
co = coroutine.create(function() f(await) end) | |
local success, message = coroutine.resume(co) | |
if not success then error(message) end | |
return co | |
end |
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
function Board:rotate(x, y, counterClockwise) | |
assert(x >= 0 and x <= constant.boardWidth - 2 and y >= 0 and y <= constant.boardHeight - 2, | |
'trying to rotate tiles out of bounds') | |
util.async(function(await) | |
local promises = {} | |
local topLeft = self:getTileAt(x, y) | |
local topRight = self:getTileAt(x + 1, y) | |
local bottomRight = self:getTileAt(x + 1, y + 1) | |
local bottomLeft = self:getTileAt(x, y + 1) | |
if topLeft then | |
table.insert(promises, topLeft:rotate('topLeft', counterClockwise)) | |
end | |
if topRight then | |
table.insert(promises, topRight:rotate('topRight', counterClockwise)) | |
end | |
if bottomRight then | |
table.insert(promises, bottomRight:rotate('bottomRight', counterClockwise)) | |
end | |
if bottomLeft then | |
table.insert(promises, bottomLeft:rotate('bottomLeft', counterClockwise)) | |
end | |
self.pool:emit('onBoardRotatingTiles', self, x, y, counterClockwise) | |
local rotateTilesPromise = Promise.all(promises) | |
if self:willTilesFall() then | |
self.freeToRotate = false | |
await(rotateTilesPromise) | |
await(self:fallTiles()) | |
self.freeToRotate = true | |
end | |
local squares, numSquares, numNewSquares = self:checkSquares() | |
if numSquares > 0 and numNewSquares < 1 then | |
self.freeToRotate = false | |
await(rotateTilesPromise) | |
await(self:clearTiles(squares)) | |
self.freeToRotate = true | |
end | |
end) | |
end |
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
-- this is using classic for object orientation, but you can use any class library you like (or roll your own) | |
local Object = require 'lib.classic' | |
local Promise = Object:extend() | |
function Promise:new(f) | |
self._onFinish = {} | |
self._finished = false | |
if f then | |
f(function(...) self:finish(...) end) | |
end | |
end | |
function Promise:isFinished() | |
return self._finished | |
end | |
function Promise:finish(...) | |
for _, f in ipairs(self._onFinish) do | |
f(...) | |
end | |
self._finished = true | |
end | |
function Promise:after(f) | |
table.insert(self._onFinish, f) | |
return self | |
end | |
function Promise.all(promises) | |
return Promise(function(finish) | |
if #promises < 1 then | |
finish() | |
return | |
end | |
local finished = {} | |
for _, promise in ipairs(promises) do | |
finished[promise] = false | |
promise:after(function() | |
-- mark this child promise as finished | |
finished[promise] = true | |
-- if all child promises are finished... | |
for _, v in pairs(finished) do | |
if v == false then return end | |
end | |
-- finish the parent promise | |
finish() | |
end) | |
end | |
end) | |
end | |
return Promise |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment