Module: Moon::Eventable

Included in:
Cursor2, Input::Observer, RenderContext, Scheduler::Jobs::Base, Movable2
Defined in:
lib/moon/packages/debug/eventable.rb,
lib/moon/packages/std/mixins/eventable.rb

Defined Under Namespace

Classes: Listener

Registration collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.filter_from_options(args) ⇒ Proc

Creates a filter proc from the given args

Parameters:

Returns:

  • (Proc)

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
# File 'lib/moon/packages/std/mixins/eventable.rb', line 38

def self.filter_from_options(args)
  return ->(event) { true } if args.empty?

  # #on's originally form expected that the args Array would be a list of
  # "keys" for Keyboard or Mouse Events
  opts = args.first
  if args.size > 1 || opts.is_a?(Symbolic) || opts.is_a?(Array)
    keys = args.flatten.map(&:to_sym)
    # adv_events uses a lambda / proc to determine if an Event should
    # be accepted by the listener
    # Here we are creating a lambda that takes an event, using the
    # keys from the #on, it checks if ANY of the keys matches event's key.
    ->(event) { keys.any? { |key| event.key == key } }
  else
    # on the other hand, adv_events expected a Hash with key value pairs
    # to check against the event's attributes

    if opts.is_a?(Hash)
      # if the user provided an options hash, with a filter key, treat
      # as the filter, otherwise, make a filter using the provided options
      opts.fetch(:filter) { Event.make_filter(opts) }
    else
      # otherwise, the object is treated as something callable
      opts
    end
  end
end

Instance Method Details

#allow_event?(event) ⇒ Boolean

Does this Eventable allow the event?

Parameters:

Returns:


195
196
197
# File 'lib/moon/packages/std/mixins/eventable.rb', line 195

def allow_event?(event)
  true
end

#clear_eventsObject

Clears all event listeners


71
72
73
74
# File 'lib/moon/packages/std/mixins/eventable.rb', line 71

def clear_events
  @typed_listeners = {}
  @classed_listeners = {}
end

#each_listener(event = nil) {|event, listener| ... } ⇒ Object

Yield Parameters:


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/moon/packages/std/mixins/eventable.rb', line 96

def each_listener(event = nil, &block)
  return to_enum(:each_listener, event) unless block_given?
  if event.is_a?(Event)
    type = event.type
  else
    type = event
    event = nil
  end

  each_typed_listener(type, &block)

  unless @classed_listeners.empty?
    @classed_listeners.each do |klass, listeners|
      if event   then next unless klass === event
      elsif type then next unless klass == type
      end
      listeners.each { |listener| block.call klass, listener }
    end
  end
end

#each_typed_listener(type = nil) {|type, listener| ... } ⇒ Enumerator

Returns unless a block is given.

Parameters:

  • type (Class, Symbol) (defaults to: nil)

Yield Parameters:

Returns:

  • (Enumerator)

    unless a block is given


80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/moon/packages/std/mixins/eventable.rb', line 80

def each_typed_listener(type = nil, &block)
  return to_enum(:each_typed_listener, type) unless block_given?
  return if @typed_listeners.empty?
  if type
    if listeners = @typed_listeners[type]
      listeners.each { |listener| block.call type, listener }
    end
  else
    @typed_listeners.each do |key, listeners|
      listeners.each { |listener| block.call key, listener }
    end
  end
end

#has_events?Boolean

Returns are there any active event listeners?.

Returns:

  • (Boolean)

    are there any active event listeners?


118
119
120
# File 'lib/moon/packages/std/mixins/eventable.rb', line 118

def has_events?
  !@classed_listeners.empty? || !@typed_listeners.empty?
end

#initialize_eventableObject


66
67
68
# File 'lib/moon/packages/std/mixins/eventable.rb', line 66

def initialize_eventable
  clear_events
end

#off(*listeners) ⇒ Object

Removes the listeners listed

Parameters:

  • listeners (Array<Moon::Listener>)

146
147
148
149
150
151
152
# File 'lib/moon/packages/std/mixins/eventable.rb', line 146

def off(*listeners)
  listeners.each do |listener|
    @classed_listeners.delete(listener.type)
    @typed_listeners.delete(listener.type)
  end
  listeners
end

#on(events, *args, &block) ⇒ Listener

Adds a new event listener.

Parameters:

  • events (Symbol, Class<Event>)

    events to listen for

  • args (Object)

    extra options

  • block (Proc)

    The block we want to execute when we catch the type.

Returns:


160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/moon/packages/std/mixins/eventable.rb', line 160

def on(events, *args, &block)
  filter = Eventable.filter_from_options(args)

  # if the event isn't an Array, make one, this allows the user to specify
  # multiple events with the same options
  events = [events] unless events.is_a?(Array)

  # add each listener object to the
  listeners = events.map do |event|
    add_listener(event, Listener.new(event, filter, block))
  end

  listeners.singularize
end

#ppd_ev(depth = 0) ⇒ Object


18
19
20
21
# File 'lib/moon/packages/debug/eventable.rb', line 18

def ppd_ev(depth = 0)
  Debug::Eventable.pretty_print(self, depth)
  self
end

#trigger(event = nil) ⇒ Object

Triggers an Event. For backwards compatability, trigger can also take a Symbol as an event, however, it will not trigger any Class based listeners.

Parameters:

  • event (Event) (defaults to: nil)

204
205
206
207
208
209
210
211
212
213
# File 'lib/moon/packages/std/mixins/eventable.rb', line 204

def trigger(event = nil)
  return unless has_events?
  event = yield self if block_given?
  event = Event.new(event) unless event.is_a?(Event)

  return unless allow_event?(event)

  trigger_any(event)
  trigger_event(event)
end

#typing(&block) ⇒ Listener

Shortcut for `on :typing, &block`

Returns:


178
179
180
# File 'lib/moon/packages/std/mixins/eventable.rb', line 178

def typing(&block)
  on(:typing, &block)
end