Skip to content

Instantly share code, notes, and snippets.

@erinlin
Last active January 26, 2017 13:29
Show Gist options
  • Save erinlin/cb2b949da508d19149d8 to your computer and use it in GitHub Desktop.
Save erinlin/cb2b949da508d19149d8 to your computer and use it in GitHub Desktop.
[CoronaSDK/Lua] Function Delegate
-------------------------------------
-- function delegate
-- Author: Erin Lin
-- www.erinylin.com
-- 簡易模擬 C# delegate
-- licensed under the MIT license.
-- 2015, 02
-------------------------------------
--[[
Usage1:
local function step1()
print("Step1")
end
local function step2()
print("Step2")
end
local function step3()
print("Step3")
end
local delegate = require("FuncDelegate").new()
delegate:insert( step1 ):insert( step2 ):insert( step3 )
-- Output:
-- Step1
-- Step2
-- Step3
Usage 2:
local function step1( n )
print("Step1", n )
return n + 10
end
local function step2( n )
print("Step2", n )
return n + 20
end
local function step3( n )
print("Step3", n )
return n + 30
end
local delegate = require("FuncDelegate").new()
delegate:insert( step1 ):insert( step2 ):insert( step3 )
print("delegate:run( 0 ) =", delegate:run( 0 ) )
print("delegate:runWithSameArgs( 0 ) =", delegate:runWithSameArgs( 0 ) )
-- Output:
-- Step1 0
-- Step2 10
-- Step3 30
-- delegate:run( 0 ) = 60
-- Step1 0
-- Step2 0
-- Step3 0
-- delegate:runWithSameArgs( 0 ) = 10
--]]
local M = {
_pool = {}
}
local M_mt = {__index=M}
local unpack = unpack
local t = {
remove = table.remove,
insert = table.insert,
indexOf = function(list, value)
local n = 0
for k, v in next, list do
if v==value then return k end
end
return -1
end
}
function M:insert( element )
assert( type(element)=="function", "argument must be a type of function")
local index = t.indexOf( self._pool, element )
if index<0 then
t.insert( self._pool, element )
end
return self
end
function M:remove( element )
local index = t.indexOf( self._pool, element )
if index > -1 then
t.remove( self._pool, index )
end
return self
end
-- will pass retrun result to next function
-- 會將前一個函式的回傳值傳到下一個函式,但是如果都是無回傳,用 run or runWithSame 都無所謂
function M:run( ... )
local result = arg or {}
for i=1,#self._pool do
result = { self._pool[i](unpack( result )) }
end
return unpack( result )
end
-- use same arguments for every function
-- 全部函式都用一開始的傳入值
function M:runWithSameArgs( ... )
local params = arg or {}
local result = {}
for i=1, #self._pool do
result = { self._pool[i](unpack( params )) }
end
-- only return last function's result
return unpack(result)
end
function M:clear()
for i=#self._pool,1,-1 do
self._pool[i] = nil
end
end
function M.new()
local obj = {}
setmetatable( obj, M_mt )
obj._pool = {}
return obj
end
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment