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
69 70 71 72 73 74 75 76 |
# File 'lib/motion/events.rb', line 69 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
87 88 89 90 91 |
# File 'lib/motion/events.rb', line 87 def cleanup off_all off_all_context true end |
#dealloc ⇒ Object
78 79 80 81 82 83 84 85 |
# File 'lib/motion/events.rb', line 78 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
112 113 114 115 116 117 |
# File 'lib/motion/events.rb', line 112 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
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/motion/events.rb', line 119 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
131 132 133 134 135 136 137 138 139 |
# File 'lib/motion/events.rb', line 131 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
141 142 143 |
# File 'lib/motion/events.rb', line 141 def off_all @events.removeAllObjects end |
#off_all_context ⇒ Object
149 150 151 152 153 154 155 156 157 |
# File 'lib/motion/events.rb', line 149 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) object.rmext_events_proxy.off_context(@weak_object) end end |
#off_context(context) ⇒ Object
145 146 147 |
# File 'lib/motion/events.rb', line 145 def off_context(context) @events.setObject(nil, forKey:context) end |
#on(event, limit: limit, inContext: context, withBlock: block) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/motion/events.rb', line 93 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
159 160 161 162 163 164 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 |
# File 'lib/motion/events.rb', line 159 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 |