-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up defer module and split DeferMethod to its own method
- Loading branch information
Showing
1 changed file
with
49 additions
and
45 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,78 @@ | ||
local _, addon = ... | ||
|
||
local queue = {} | ||
local function iterateQueue() | ||
local function iterate() | ||
for _, info in next, queue do | ||
if info.callback then | ||
info.callback(unpack(info.args)) | ||
local successful, ret = pcall(info.callback, unpack(info.args)) | ||
if not successful then | ||
error(ret) | ||
end | ||
elseif info.object then | ||
info.object[info.method](unpack(info.args)) | ||
local successful, ret = pcall(info.object[info.method], info.object, unpack(info.args)) | ||
if not successful then | ||
error(ret) | ||
end | ||
end | ||
end | ||
|
||
table.wipe(queue) | ||
return true -- unregister itself | ||
return true -- unregister event | ||
end | ||
|
||
local function deferFunction(callback, ...) | ||
local function defer(info) | ||
table.insert(queue, info) | ||
|
||
if not addon:IsEventRegistered('PLAYER_REGEN_ENABLED', iterate) then | ||
addon:RegisterEvent('PLAYER_REGEN_ENABLED', iterate) | ||
end | ||
end | ||
|
||
|
||
--[[ namespace:Defer(_callback_[, _..._]) | ||
Defers a function `callback` (with optional arguments) until after combat ends. | ||
Callback can be the global name of a function. | ||
Triggers immediately if player is not in combat. | ||
--]] | ||
function addon:Defer(callback, ...) | ||
if type(callback) == 'string' then | ||
callback = _G[callback] | ||
end | ||
|
||
addon:ArgCheck(callback, 1, 'function') | ||
|
||
if InCombatLockdown() then | ||
table.insert(queue, { | ||
defer({ | ||
callback = callback, | ||
args = {...}, | ||
}) | ||
|
||
if not addon:IsEventRegistered('PLAYER_REGEN_ENABLED', iterateQueue) then | ||
addon:RegisterEvent('PLAYER_REGEN_ENABLED', iterateQueue) | ||
end | ||
else | ||
callback(...) | ||
local successful, ret = pcall(callback, ...) | ||
if not successful then | ||
error(ret) | ||
end | ||
end | ||
end | ||
|
||
local function deferGlobalFunction(func, ...) | ||
deferFunction(_G[func], ...) | ||
end | ||
--[[ namespace:DeferMethod(_object_, _method_[, _..._]) | ||
Defers a `method` on `object` (with optional arguments) until after combat ends. | ||
Triggers immediately if player is not in combat. | ||
--]] | ||
function addon:DeferMethod(object, method, ...) | ||
addon:ArgCheck(object, 1, 'table') | ||
addon:ArgCheck(method, 2, 'string') | ||
addon:ArgCheck(object[method], 2, 'function') | ||
|
||
local function deferMethod(object, method, ...) | ||
if InCombatLockdown() then | ||
table.insert(queue, { | ||
defer({ | ||
object = object, | ||
method = method, | ||
args = {...}, | ||
}) | ||
|
||
if not addon:IsEventRegistered('PLAYER_REGEN_ENABLED', iterateQueue) then | ||
addon:RegisterEvent('PLAYER_REGEN_ENABLED', iterateQueue) | ||
end | ||
else | ||
object[method](...) | ||
end | ||
end | ||
|
||
--[[ namespace:Defer(_callback_[, _..._]) | ||
Defers a function `callback` (with optional arguments) until after combat ends. | ||
Immediately triggers if player is not in combat. | ||
--]] | ||
--[[ namespace:Defer(_object_, _method_[, _..._]) | ||
Defers a method `method` on `object` (with optional arguments) until after combat ends. | ||
Immediately triggers if player is not in combat. | ||
--]] | ||
function addon:Defer(...) | ||
if type(select(1, ...)) == 'table' then | ||
assert(type(select(2, ...)) == 'string', 'arg2 must be the name of a method') | ||
assert(type(select(1, ...)[select(2, ...)]) == 'function', 'arg2 must be the name of a method') | ||
deferMethod(...) | ||
elseif type(select(1, ...)) == 'function' then | ||
assert(type(select(1, ...)) == 'function', 'arg1 must be a function') | ||
deferFunction(...) | ||
elseif type(select(1, ...)) == 'string' and type(_G[select(1, ...)]) == 'function' then | ||
assert(type(_G[select(1, ...)]) == 'function', 'arg1 must be a function') | ||
deferGlobalFunction(...) | ||
else | ||
error('Invalid arguments passed to Defer') | ||
local successful, ret = pcall(object[method], object, ...) | ||
if not successful then | ||
error(ret) | ||
end | ||
end | ||
end |