Class: RMExtensions::EventsProxy
- Inherits:
-
Object
- Object
- RMExtensions::EventsProxy
- Defined in:
- lib/motion/events.rb
Overview
Proxy class used to hold the actual listeners and contexts where listening and watches for the real class intended to hold the observation to be deallocated, so the events can be cleaned up.
Instance Method Summary collapse
- #cleanup ⇒ Object
- #dealloc ⇒ Object
-
#initialize(obj) ⇒ EventsProxy
constructor
A new instance of EventsProxy.
-
#listening_to(object) ⇒ Object
this is called in the reverse direction than normal.
- #now_and_on(event, inContext: context, withBlock: block) ⇒ Object
- #off(event, inContext: context, withBlock: block) ⇒ Object
- #off_all ⇒ Object
- #off_all_context ⇒ Object
- #off_context(context) ⇒ Object
- #on(event, limit: limit, inContext: context, withBlock: block) ⇒ Object
- #trigger(event, value) ⇒ Object
Constructor Details
#initialize(obj) ⇒ EventsProxy
Returns a new instance of EventsProxy.
73 74 75 76 77 78 79 80 |
# File 'lib/motion/events.rb', line 73 def initialize(obj) @weak_object = WeakRef.new(obj) @events = NSMapTable.weakToStrongObjectsMapTable @listenings = NSHashTable.weakObjectsHashTable if ::RMExtensions.debug? p "CREATED EventsProxy: #{@weak_object.rmext_object_desc}" end end |
Instance Method Details
#cleanup ⇒ Object
91 92 93 94 95 |
# File 'lib/motion/events.rb', line 91 def cleanup off_all off_all_context true end |
#dealloc ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/motion/events.rb', line 82 def dealloc @did_dealloc = true cleanup if ::RMExtensions.debug? p "DEALLOC EventsProxy: #{@weak_object.rmext_object_desc}" end super end |
#listening_to(object) ⇒ Object
this is called in the reverse direction than normal
116 117 118 119 120 121 |
# File 'lib/motion/events.rb', line 116 def listening_to(object) if ::RMExtensions.debug? p "CONTEXT:", @weak_object.rmext_object_desc, "LISTENING TO:", object.rmext_object_desc end @listenings.addObject(object) end |
#now_and_on(event, inContext: context, withBlock: block) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/motion/events.rb', line 123 def now_and_on(event, inContext:context, withBlock:block) rmext_inline_or_on_main_q do res = EventResponse.new res.context = context res.value = nil res.target = @weak_object res.event = event block.call(res) end on(event, limit:-1, inContext:context, withBlock:block) end |
#off(event, inContext: context, withBlock: block) ⇒ Object
135 136 137 138 139 140 141 142 143 |
# File 'lib/motion/events.rb', line 135 def off(event, inContext:context, withBlock:block) return if event.nil? || block.nil? event = event.to_s context ||= self.class return unless context_events = @events.objectForKey(context) return unless context_event_blocks = context_events.objectForKey(event) context_event_blocks.delete block nil end |
#off_all ⇒ Object
145 146 147 |
# File 'lib/motion/events.rb', line 145 def off_all @events.removeAllObjects end |
#off_all_context ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/motion/events.rb', line 153 def off_all_context while object = @listenings.anyObject if ::RMExtensions.debug? p "CONTEXT:", @weak_object.rmext_object_desc, "UNLISTENING TO:", object.rmext_object_desc end @listenings.removeObject(object) if object.rmext_events_proxy? object.rmext_events_proxy.off_context(@weak_object) end end end |
#off_context(context) ⇒ Object
149 150 151 |
# File 'lib/motion/events.rb', line 149 def off_context(context) @events.setObject(nil, forKey:context) end |
#on(event, limit: limit, inContext: context, withBlock: block) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/motion/events.rb', line 97 def on(event, limit:limit, inContext:context, withBlock:block) return if event.nil? || block.nil? event = event.to_s context ||= self.class unless context_events = @events.objectForKey(context) context_events = {} @events.setObject(context_events, forKey:context) end unless context_event_blocks = context_events.objectForKey(event) context_event_blocks = {} context_events.setObject(context_event_blocks, forKey:event) end block.weak! context_event_blocks[block] = limit # i.e.: controller/view listening_to model context.rmext_events_proxy.listening_to(@weak_object) end |
#trigger(event, value) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/motion/events.rb', line 165 def trigger(event, value) rmext_inline_or_on_main_q do next if @did_dealloc next if event.nil? event = event.to_s keyEnumerator = @events.keyEnumerator contexts = [] while context = keyEnumerator.nextObject contexts.push context end while context = contexts.pop if context_events = @events.objectForKey(context) if event_blocks = context_events[event] blocks = event_blocks.keys if ::RMExtensions.debug? p "TRIGGER:", event, "OBJECT:", @weak_object.rmext_object_desc, "CONTEXT:", context.rmext_object_desc, "BLOCKS SIZE:", blocks.size end while block = blocks.pop limit = event_blocks[block] res = EventResponse.new res.context = context res.value = value res.target = @weak_object res.event = event block.call(res) if limit == 1 # off if ::RMExtensions.debug? p "LIMIT REACHED:", event, "OBJECT:", @weak_object.rmext_object_desc, "CONTEXT:", context.rmext_object_desc end off(event, inContext:context, withBlock:block) elsif limit > 1 context_events[block] -= 1 end end end end end end nil end |