Class: Vedeu::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

#demodulize, #deputy, #dsl_class, included, #store

Constructor Details

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

Returns a new instance of Vedeu::Event.

Parameters:

  • name (Symbol)

    The name of the event to be triggered later.

  • options (Hash) (defaults to: {})

    The options to register the event with.

  • block (Proc)

    The event to be executed when triggered. This block could be a method call, or the triggering of another event, or sequence of either/both.



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

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

Instance Attribute Details

#closureString (readonly, protected)

Returns:

  • (String)


154
155
156
# File 'lib/vedeu/events/event.rb', line 154

def closure
  @closure
end

#deadlineString (protected)

Returns:

  • (String)


162
163
164
# File 'lib/vedeu/events/event.rb', line 162

def deadline
  @deadline
end

#executed_atString (protected)

Returns:

  • (String)


166
167
168
# File 'lib/vedeu/events/event.rb', line 166

def executed_at
  @executed_at
end

#nameString (readonly, protected)

Returns:

  • (String)


158
159
160
# File 'lib/vedeu/events/event.rb', line 158

def name
  @name
end

#nowString (protected)

Returns:

  • (String)


170
171
172
# File 'lib/vedeu/events/event.rb', line 170

def now
  @now
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...T
.X...i...i...i...i...X...i...i...i...i...X...i...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...T
.i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i...i

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

Parameters:

  • name (Symbol)

    The name of the event to be triggered later.

  • options (Hash) (defaults to: {})

    The options to register the event with.

  • block (Proc)

    The event to be executed when triggered. This block could be a method call, or the triggering of another event, or sequence of either/both.

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.

Returns:

  • (TrueClass)


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

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

  new(name, options, block).bind
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...T
.X...i...i...i...i...X...i...i...i...i...X...i...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...T
.i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i...i

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

Parameters:

  • name (Symbol)

    The name of the event to be triggered later.

  • options (Hash)

    The options to register the event with.

  • block (Proc)

    The event to be executed when triggered. This block could be a method call, or the triggering of another event, or sequence of either/both.

Returns:

  • (TrueClass)


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

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

  new(name, options, block).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...T
.X...i...i...i...i...X...i...i...i...i...X...i...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...T
.i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i...i

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

Parameters:

  • name (Symbol)

    The name of the event to be triggered later.

  • options (Hash)

    The options to register the event with.

  • block (Proc)

    The event to be executed when triggered. This block could be a method call, or the triggering of another event, or sequence of either/both.

Returns:

  • (TrueClass)


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, options, block).bind
end

.unbind(name) ⇒ Boolean Also known as: unevent

Unbind events from a named handler.

Parameters:

  • name (String)

Returns:

  • (Boolean)


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

def unbind(name)
  return false unless Vedeu.events.registered?(name)

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

  Vedeu.events.remove(name)
  true
end

Instance Method Details

#bindObject

See Also:



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/vedeu/events/event.rb', line 124

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

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

  end

  repository.store(new_collection)

  true
end

#deadline?Boolean (private)

Returns a boolean indicating if this event has a deadline.

Returns:

  • (Boolean)


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

def deadline?
  @deadline > 0
end

#debounceFixnum|Float (private)

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

Returns:

  • (Fixnum|Float)


285
286
287
# File 'lib/vedeu/events/event.rb', line 285

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

#debounce_expired?Boolean (private)

Returns a boolean indicating whether the debounce has expired.

Returns:

  • (Boolean)


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

def debounce_expired?
  return true if set_executed > 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.

Returns:

  • (Boolean)


217
218
219
220
221
222
223
# File 'lib/vedeu/events/event.rb', line 217

def debouncing?
  set_time

  set_deadline unless deadline?

  options[:debounce] > 0
end

#defaultsHash (private)

The default values for a new instance of this class.

Returns:

  • (Hash)


306
307
308
309
310
311
# File 'lib/vedeu/events/event.rb', line 306

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

#delayFixnum|Float (private)

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

Returns:

  • (Fixnum|Float)


292
293
294
# File 'lib/vedeu/events/event.rb', line 292

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

#elapsed_timeFloat (private)

Returns the time in seconds since the last triggering of this event.

Returns:

  • (Float)


239
240
241
# File 'lib/vedeu/events/event.rb', line 239

def elapsed_time
  now - @executed_at
end

#execute(*args) ⇒ void (private)

This method returns an undefined value.

Execute the code stored in the event closure.

Parameters:

  • args (void)


178
179
180
181
182
183
184
185
186
187
188
# File 'lib/vedeu/events/event.rb', line 178

def execute(*args)
  reset_deadline

  set_executed

  reset_time

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

  closure.call(*args)
end

#optionsHash (private)

Combines the options provided at instantiation with the default values.

Returns:

  • (Hash)


299
300
301
# File 'lib/vedeu/events/event.rb', line 299

def options
  defaults.merge!(@options)
end

#reset_deadlineFixnum (private)

Resets the deadline of this event.

Returns:

  • (Fixnum)


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

def reset_deadline
  @deadline = 0
end

#reset_timeFixnum (private)

Returns:

  • (Fixnum)


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

def reset_time
  @now = 0
end

#set_deadlineNilClass (private)

Sets the deadline for when this event can be executed to a point in the future determined by the amount of debounce time left.

Returns:

  • (NilClass)


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

def set_deadline
  @deadline = now + debounce

  nil
end

#set_executedFloat (private)

Returns:

  • (Float)


244
245
246
# File 'lib/vedeu/events/event.rb', line 244

def set_executed
  @executed_at = now
end

#set_timeFloat (private)

Returns:

  • (Float)


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

def set_time
  @now = Time.now.to_f
end

#throttle_expired?Boolean (private)

Returns a boolean indicating whether the throttle has expired.

Returns:

  • (Boolean)


204
205
206
207
208
209
210
# File 'lib/vedeu/events/event.rb', line 204

def throttle_expired?
  return true if elapsed_time > 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.

Returns:

  • (Boolean)


195
196
197
198
199
# File 'lib/vedeu/events/event.rb', line 195

def throttling?
  set_time

  options[:delay] > 0
end

#trigger(*args) ⇒ void

This method returns an undefined value.

Triggers the event based on debouncing and throttling conditions.

Parameters:

  • args (Array)


142
143
144
145
146
147
148
# File 'lib/vedeu/events/event.rb', line 142

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

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

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