This repository has been archived by the owner on Dec 25, 2020. It is now read-only.
/
callback.rb
109 lines (92 loc) · 2.61 KB
/
callback.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module Wee
class CallbackRegistry
def initialize(prefix="")
@prefix = prefix
@next_id = 0
@callbacks = {} # {callback_id1 => callback1, callback_id2 => callback2}
@triggered = nil
@obj_map = {} # obj => [callback_id1, callback_id2, ...]
end
def empty?
@callbacks.empty?
end
def register(object, callback)
id = @next_id
@next_id += 1
@callbacks[id] = callback
(@obj_map[object] ||= []) << id
return "#{@prefix}#{id}"
end
def unregister(object)
if arr = @obj_map.delete(object)
arr.each {|id| @callbacks.delete(id) }
end
end
#
# NOTE that if fields named "xxx" and "xxx.yyy" occur, the value of
# @fields['xxx'] is { nil => ..., 'yyy' => ... }. This is required
# to make image buttons work correctly.
#
def prepare_triggered(ids_and_values)
@triggered = {}
ids_and_values.each do |id, value|
if id =~ /^#{@prefix}(\d+)([.](.*))?$/
id, suffix = Integer($1), $3
next unless @callbacks[id]
if @triggered[id].kind_of?(Hash)
@triggered[id][suffix] = value
elsif suffix
@triggered[id] = {nil => @triggered[id], suffix => value}
else
@triggered[id] = value
end
end
end
end
def reset_triggered
@triggered = nil
end
def each_triggered(object)
if ary = @obj_map[object]
for id in ary
yield @callbacks[id], @triggered[id] if @triggered.has_key?(id)
end
end
end
def each_triggered_call_with_value(object)
if ary = @obj_map[object]
for id in ary
@callbacks[id].call(@triggered[id]) if @triggered.has_key?(id)
end
end
end
def first_triggered(object)
if ary = @obj_map[object]
for id in ary
return @callbacks[id] if @triggered.has_key?(id)
end
end
return nil
end
end # class CallbackRegistry
class Callbacks
attr_reader :input_callbacks
attr_reader :action_callbacks
def initialize
@input_callbacks = CallbackRegistry.new("")
@action_callbacks = CallbackRegistry.new("a")
end
def unregister(object)
@input_callbacks.unregister(object)
@action_callbacks.unregister(object)
end
def with_triggered(ids_and_values)
@input_callbacks.prepare_triggered(ids_and_values)
@action_callbacks.prepare_triggered(ids_and_values)
yield
ensure
@input_callbacks.reset_triggered
@action_callbacks.reset_triggered
end
end # class Callbacks
end # module Wee