@@ -22,16 +22,17 @@ local setmetatable = setmetatable
2222local getmetatable = getmetatable
2323local ipairs = ipairs
2424local assert = assert
25+ local select = select
26+ local type = type
27+ local unpack = unpack
28+ local tmove = table.move
2529
2630local Delegate = {}
2731debug.setmetatable (System .emptyFn , Delegate )
2832
2933local multicast = setmetatable ({}, Delegate )
3034multicast .__index = multicast
3135
32- local memberMethod = setmetatable ({}, Delegate )
33- memberMethod .__index = memberMethod
34-
3536function multicast .__call (t , ...)
3637 local result
3738 for _ , f in ipairs (t ) do
@@ -40,10 +41,6 @@ function multicast.__call(t, ...)
4041 return result
4142end
4243
43- function memberMethod .__call (t , ...)
44- return t .method (t .target , ... )
45- end
46-
4744local function appendFn (t , f )
4845 if getmetatable (f ) == multicast then
4946 for _ , i in ipairs (f ) do
7572
7673Delegate .Combine = combine
7774
78- local function bind (target , method )
79- assert (method )
80- if target == nil then throw (ArgumentNullException ()) end
81-
82- local delegate = target [method ]
83- if delegate ~= nil then
84- return delegate
85- end
86-
87- local t = {
88- target = target ,
89- method = method ,
90- }
91- setmetatable (t , memberMethod )
92- target [method ] = t
93- return t
94- end
95-
96- Delegate .bind = bind
97- System .bind = bind
98-
99- local function equalsSingle (fn1 , fn2 )
100- if getmetatable (fn1 ) == memberMethod then
101- if getmetatable (fn2 ) == memberMethod then
102- return fn1 .target == fn2 .target and fn1 .method == fn2 .method
103- end
104- return false
105- end
106- if getmetatable (fn2 ) == memberMethod then return false end
107- return fn1 == fn2
108- end
109-
11075local function equalsMulticast (fn1 , fn2 , start , count )
11176 for i = 1 , count do
112- if not equalsSingle ( fn1 [start + i ], fn2 [i ]) then
77+ if fn1 [start + i ] ~= fn2 [i ] then
11378 return false
11479 end
11580 end
13196local function removeImpl (fn1 , fn2 )
13297 if getmetatable (fn2 ) ~= multicast then
13398 if getmetatable (fn1 ) ~= multicast then
134- if equalsSingle ( fn1 , fn2 ) then
99+ if fn1 == fn2 then
135100 return nil
136101 end
137102 else
138103 local count = # fn1
139104 for i = count , 1 , - 1 do
140- if equalsSingle ( fn1 [i ], fn2 ) then
105+ if fn1 [i ] == fn2 then
141106 if count == 2 then
142107 return fn1 [3 - i ]
143108 else
@@ -197,7 +162,7 @@ local function equals(fn1, fn2)
197162 return false
198163 end
199164 for i = 1 , len1 do
200- if not equalsSingle ( fn1 [i ], fn2 [2 ]) then
165+ if fn1 [i ] ~= fn2 [2 ] then
201166 return false
202167 end
203168 end
@@ -206,21 +171,18 @@ local function equals(fn1, fn2)
206171 return false
207172 end
208173 if getmetatable (fn2 ) == multicast then return false end
209- return equalsSingle ( fn1 , fn2 )
174+ return fn1 == fn2
210175end
211176
212177Delegate .__add = combine
213178multicast .__add = combine
214- memberMethod .__add = combine
215179
216180Delegate .__sub = remove
217181multicast .__sub = remove
218- memberMethod .__sub = remove
219182
220183multicast .__eq = equals
221- memberMethod .__eq = equals
222184
223- local metatableOfNil = debug.getmetatable (nil )
185+ local metatableOfNil = debug.getmetatable (nil )
224186 metatableOfNil .__add = function (a , b )
225187 if a == nil then
226188 if b == nil or type (b ) == " number" then
@@ -238,7 +200,7 @@ function Delegate.EqualsObj(this, obj)
238200 end
239201 if typename == " table" then
240202 local metatable = getmetatable (obj )
241- if metatable == multicast or metatable == memberMethod then
203+ if metatable == multicast then
242204 return equals (this , obj )
243205 end
244206 end
@@ -249,11 +211,11 @@ function Delegate.GetType(this)
249211 return System .typeof (Delegate )
250212end
251213
252- local genericKey = System .genericKey
214+ local multiKey = System .multiKey
253215
254216local mt = {}
255217local function makeGenericTypes (...)
256- local gt , gk = genericKey (mt , ... )
218+ local gt , gk = multiKey (mt , ... )
257219 local t = gt [gk ]
258220 if t == nil then
259221 t = setmetatable ({ ... }, Delegate )
@@ -264,3 +226,107 @@ end
264226
265227System .define (" System.Delegate" , Delegate )
266228setmetatable (Delegate , { __index = System .Object , __call = makeGenericTypes })
229+
230+ function System .bind (target , method )
231+ assert (method )
232+ if target == nil then throw (ArgumentNullException ()) end
233+ local f = target [method ]
234+ if f == nil then
235+ f = function (...)
236+ return method (target , ... )
237+ end
238+ target [method ] = f
239+ end
240+ return f
241+ end
242+
243+ local binds = setmetatable ({}, { __mode = " k" })
244+
245+ function System .bindX (f , n , ...)
246+ assert (f )
247+ local gt , gk = multiKey (binds , f , ... )
248+ local fn = gt [gk ]
249+ if fn == nil then
250+ local args = { ... }
251+ fn = function (...)
252+ local len = select (" #" , ... )
253+ if len == n then
254+ return f (... , unpack (args ))
255+ else
256+ assert (len > n )
257+ local t = { ... }
258+ for i = 1 , # args do
259+ local j = args [i ]
260+ if type (j ) == " number" then
261+ j = select (n + j , ... )
262+ assert (j )
263+ end
264+ t [n + i ] = j
265+ end
266+ return f (unpack (t , 1 , n + # args ))
267+ end
268+ end
269+ gt [gk ] = fn
270+ end
271+ return fn
272+ end
273+
274+ local function bind (f , create , ...)
275+ assert (f )
276+ local gt , gk = multiKey (binds , f , create )
277+ local fn = gt [gk ]
278+ if fn == nil then
279+ fn = create (f , ... )
280+ end
281+ return fn
282+ end
283+
284+ local function create1 (f , a )
285+ return function (...)
286+ return f (... , a )
287+ end
288+ end
289+
290+ function System .bind1 (f , a )
291+ return bind (f , create1 , a )
292+ end
293+
294+ local function create2 (f , a , b )
295+ return function (...)
296+ return f (... , a , b )
297+ end
298+ end
299+
300+ function System .bind2 (f , a , b )
301+ return bind (f , create2 , a , b )
302+ end
303+
304+ local function create3 (f , a , b , c )
305+ return function (...)
306+ return f (... , a , b , c )
307+ end
308+ end
309+
310+ function System .bind3 (f , a , b , c )
311+ return bind (f , create3 , a , b , c )
312+ end
313+
314+ local function create2_1 (f )
315+ return function (x1 , x2 , T1 , T2 )
316+ return f (x1 , x2 , T2 , T1 )
317+ end
318+ end
319+
320+ function System .bind2_1 (f )
321+ return bind (f , create2_1 )
322+ end
323+
324+ local function create0_2 (f )
325+ return function (x1 , x2 , T1 , T2 )
326+ return f (x1 , x2 , T2 )
327+ end
328+ end
329+
330+ function System .bind0_2 (f )
331+ return bind (f , create0_2 )
332+ end
0 commit comments