Class: Vedeu::Events::Event

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Model
Defined in:
lib/vedeu/events/event.rb

Overview

Contains all the logic of an event. Handles debouncing and throttling.

Vedeu provides an event mechanism to facilitate the functionality of your application. The events are either Vedeu defined, ie. system events or user defined, ie. user events. User events allow you to orchestrate behaviour within your application, ie. the user presses a specific key, you trigger an event to make something happen. Eg. pressing ‘p’ instructs the player to play.

Events described here assume that you have either included Vedeu in your class:

class SomeClassInYourApplication
  include Vedeu

  bind :event_name do |arg1, arg2|
    # Things that should happen when the event is triggered; these can
    # be method calls or the triggering of another event or events.
  end

or, you are prepared to use the ‘Vedeu` prefix:

class SomeClassInYourApplication
  Vedeu.bind(:event_name) do
    # Not all events you define will have arguments; like methods.
    :do_stuff
  end

Instance Attribute Summary collapse

Attributes included from Model

#repository

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Model

#deputy, #dsl_class, included, #store

Methods included from Common

#demodulize, #present?, #snake_case

Constructor Details

#initialize(name, closure, options = {}) ⇒ Vedeu::Events::Event

Returns a new instance of Vedeu::Events::Event.



131
132
133
134
135
136
137
138
139
# File 'lib/vedeu/events/event.rb', line 131

def initialize(name, closure, options = {})
  @name         = name
  @options      = options
  @closure      = closure
  @deadline     = 0
  @executed_at  = 0
  @now          = 0
  @repository   = Vedeu.events
end

Instance Attribute Details

#closureString (readonly, protected)



172
173
174
# File 'lib/vedeu/events/event.rb', line 172

def closure
  @closure
end

#nameString (readonly, protected)



176
177
178
# File 'lib/vedeu/events/event.rb', line 176

def name
  @name
end

Class Method Details

.bind(name, options = {}, &block) ⇒ TrueClass

Register an event by name with optional delay (throttling) which when triggered will execute the code contained within the passed block.

Examples:

Vedeu.bind :my_event do |some, args|
  # ... some code here ...

  Vedeu.trigger(:my_other_event)
end

T = Triggered, X = Executed, i = Ignored.

0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
.T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
.X...i...i...i...i...X...i...i...i...i...X...i...i...i...i...i...i..

Vedeu.bind(:my_delayed_event, { delay: 0.5 })
  # ... some code here ...
end

T = Triggered, X = Executed, i = Ignored.

0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
.T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
.i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i..

Vedeu.bind(:my_debounced_event, { debounce: 0.7 })
  # ... some code here ...
end

Options Hash (options):

  • :delay (Fixnum|Float)

    Limits the execution of the triggered event to only execute when first triggered, with subsequent triggering being ignored until the delay has expired.

  • :debounce (Fixnum|Float)

    Limits the execution of the triggered event to only execute once the debounce has expired. Subsequent triggers before debounce expiry are ignored.



82
83
84
85
86
# File 'lib/vedeu/events/event.rb', line 82

def bind(name, options = {}, &block)
  Vedeu.log(type: :event, message: "Binding: '#{name.inspect}'")

  new(name, block, options).bind
end

.bound?(name) ⇒ Boolean

Return a boolean indicating whether the named event is registered.

Examples:

Vedeu.bound?(:some_event)


97
98
99
100
# File 'lib/vedeu/events/event.rb', line 97

def bound?(name)
  Vedeu.events.registered?(name) ||
    Vedeu::Events::Aliases.registered?(name)
end

.eventTrueClass

Register an event by name with optional delay (throttling) which when triggered will execute the code contained within the passed block.

Examples:

Vedeu.bind :my_event do |some, args|
  # ... some code here ...

  Vedeu.trigger(:my_other_event)
end

T = Triggered, X = Executed, i = Ignored.

0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
.T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
.X...i...i...i...i...X...i...i...i...i...X...i...i...i...i...i...i..

Vedeu.bind(:my_delayed_event, { delay: 0.5 })
  # ... some code here ...
end

T = Triggered, X = Executed, i = Ignored.

0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
.T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
.i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i..

Vedeu.bind(:my_debounced_event, { debounce: 0.7 })
  # ... some code here ...
end


87
88
89
90
91
# File 'lib/vedeu/events/event.rb', line 87

def bind(name, options = {}, &block)
  Vedeu.log(type: :event, message: "Binding: '#{name.inspect}'")

  new(name, block, options).bind
end

.registerTrueClass

Register an event by name with optional delay (throttling) which when triggered will execute the code contained within the passed block.

Examples:

Vedeu.bind :my_event do |some, args|
  # ... some code here ...

  Vedeu.trigger(:my_other_event)
end

T = Triggered, X = Executed, i = Ignored.

0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
.T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
.X...i...i...i...i...X...i...i...i...i...X...i...i...i...i...i...i..

Vedeu.bind(:my_delayed_event, { delay: 0.5 })
  # ... some code here ...
end

T = Triggered, X = Executed, i = Ignored.

0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
.T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
.i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i..

Vedeu.bind(:my_debounced_event, { debounce: 0.7 })
  # ... some code here ...
end


88
89
90
91
92
# File 'lib/vedeu/events/event.rb', line 88

def bind(name, options = {}, &block)
  Vedeu.log(type: :event, message: "Binding: '#{name.inspect}'")

  new(name, block, options).bind
end

.unbind(name) ⇒ Boolean

Unbind events from a named handler.

Removes all events associated with the given name.

Examples:

Vedeu.unbind(:some_event)


111
112
113
114
115
116
117
118
119
# File 'lib/vedeu/events/event.rb', line 111

def unbind(name)
  return false unless Vedeu.bound?(name)

  Vedeu.log(type: :event, message: "Unbinding: '#{name.inspect}'")

  Vedeu.events.remove(name)

  true
end

Instance Method Details

#bindObject

See Also:



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/vedeu/events/event.rb', line 142

def bind
  if repository.registered?(name)
    new_collection = repository.find(name).add(self)

  else
    new_collection = Vedeu::Events::Collection.new([self], nil, name)

  end

  repository.store(new_collection)

  true
end

#deadline?Boolean (private)

Returns a boolean indicating whether this event has a deadline.



248
249
250
# File 'lib/vedeu/events/event.rb', line 248

def deadline?
  @deadline > 0
end

#debounceFixnum|Float (private)

Return the amount of time in seconds to debounce the event by.



255
256
257
# File 'lib/vedeu/events/event.rb', line 255

def debounce
  options[:debounce] || defaults[:debounce]
end

#debounce_expired?Boolean (private)

Returns a boolean indicating whether the debounce has expired.



237
238
239
240
241
242
243
# File 'lib/vedeu/events/event.rb', line 237

def debounce_expired?
  return true if (@executed_at = @now) > @deadline

  Vedeu.log(type: :event, message: "Debouncing: '#{name.inspect}'")

  false
end

#debouncing?Boolean (private)

Returns a boolean indicating whether debouncing is required for this event. Setting the debounce option to any value greater than 0 will enable debouncing. Sets the deadline for when this event can be executed to a point in the future determined by the amount of debounce time left.



226
227
228
229
230
231
232
# File 'lib/vedeu/events/event.rb', line 226

def debouncing?
  @now = Time.now.to_f

  @deadline = @now + debounce unless deadline?

  options[:debounce] > 0
end

#defaultsHash (private)

The default values for a new instance of this class.



276
277
278
279
280
281
# File 'lib/vedeu/events/event.rb', line 276

def defaults
  {
    delay:      0.0,
    debounce:   0.0,
  }
end

#delayFixnum|Float (private)

Return the amount of time in seconds to throttle the event by.



262
263
264
# File 'lib/vedeu/events/event.rb', line 262

def delay
  options[:delay] || defaults[:delay]
end

#execute(*args) ⇒ void (private)

This method returns an undefined value.

Execute the code stored in the event closure.



184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/vedeu/events/event.rb', line 184

def execute(*args)
  @deadline    = 0    # reset deadline
  @executed_at = @now # set execution time to now
  @now         = 0    # reset now

  message = "Triggering: '#{name.inspect}'"
  message << " with '#{args.inspect}'" if args.any?

  Vedeu.log(type: :event, message: message)

  closure.call(*args)
end

#optionsHash (private)

Combines the options provided at instantiation with the default values.



269
270
271
# File 'lib/vedeu/events/event.rb', line 269

def options
  defaults.merge!(@options)
end

#throttle_expired?Boolean (private)

Returns a boolean indicating whether the throttle has expired.



211
212
213
214
215
216
217
# File 'lib/vedeu/events/event.rb', line 211

def throttle_expired?
  return true if (@now - @executed_at) > delay

  Vedeu.log(type: :event, message: "Throttling: '#{name.inspect}'")

  false
end

#throttling?Boolean (private)

Returns a boolean indicating whether throttling is required for this event. Setting the delay option to any value greater than 0 will enable throttling.



202
203
204
205
206
# File 'lib/vedeu/events/event.rb', line 202

def throttling?
  @now = Time.now.to_f

  options[:delay] > 0
end

#trigger(*args) ⇒ void

This method returns an undefined value.

Triggers the event based on debouncing and throttling conditions.



160
161
162
163
164
165
166
# File 'lib/vedeu/events/event.rb', line 160

def trigger(*args)
  return execute(*args) unless debouncing? || throttling?

  return execute(*args) if debouncing? && debounce_expired?

  return execute(*args) if throttling? && throttle_expired?
end