Class: Vedeu::Events::Event

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Repositories::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 bound the events within your classes:

class SomeClassInYourApplication
  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

  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 Repositories::Model

#repository

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Repositories::Model

included, #store

Methods included from Common

#absent?, #array?, #boolean, #boolean?, #empty_value?, #escape?, #falsy?, #hash?, #line_model?, #numeric?, #positionable?, #present?, #snake_case, #stream_model?, #string?, #symbol?, #truthy?, #view_model?

Constructor Details

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

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

Parameters:

  • name (NilClass|Symbol|String)

    The name of the model or target model to act upon. May default to ‘Vedeu.focus`.

  • options (Hash<Symbol => void>) (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.



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

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)

Returns:

  • (String)


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

def closure
  @closure
end

#nameString|Symbol (readonly, protected)

Returns:

  • (String|Symbol)


174
175
176
# File 'lib/vedeu/events/event.rb', line 174

def name
  @name
end

Class Method Details

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

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

Parameters:

  • name (NilClass|Symbol|String)

    The name of the model or target model to act upon. May default to ‘Vedeu.focus`.

  • options (Hash<Symbol => void>) (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:



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

.bound?(name) ⇒ Boolean

Parameters:

  • name (NilClass|Symbol|String)

    The name of the model or target model to act upon. May default to ‘Vedeu.focus`.

Returns:



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

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

.eventBoolean

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

Parameters:

  • name (NilClass|Symbol|String)

    The name of the model or target model to act upon. May default to ‘Vedeu.focus`.

  • options (Hash<Symbol => void>)

    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:



92
93
94
95
96
# File 'lib/vedeu/events/event.rb', line 92

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

  new(name, block, options).bind
end

.registerBoolean

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

Parameters:

  • name (NilClass|Symbol|String)

    The name of the model or target model to act upon. May default to ‘Vedeu.focus`.

  • options (Hash<Symbol => void>)

    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:



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

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

  new(name, block, options).bind
end

.unbind(name) ⇒ Boolean

Parameters:

  • name (NilClass|Symbol|String)

    The name of the model or target model to act upon. May default to ‘Vedeu.focus`.

Returns:



106
107
108
109
110
111
112
113
114
115
# File 'lib/vedeu/events/event.rb', line 106

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:



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/vedeu/events/event.rb', line 139

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

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

                   end

  repository.store(new_collection)

  true
end

#deadline?Boolean (private)

Returns a boolean indicating whether this event has a deadline.

Returns:



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

def deadline?
  @deadline > 0
end

#debounceFixnum|Float (private)

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

Returns:

  • (Fixnum|Float)


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

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

#debounce_expired?Boolean (private)

Returns a boolean indicating whether the debounce has expired.

Returns:



244
245
246
247
248
249
250
# File 'lib/vedeu/events/event.rb', line 244

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.

Returns:



233
234
235
236
237
238
239
# File 'lib/vedeu/events/event.rb', line 233

def debouncing?
  @now = Vedeu.clock_time

  @deadline = @now + debounce unless deadline?

  options[:debounce] > 0
end

#defaultsHash<Symbol => void> (private)

The default options/attributes for a new instance of this class.

Returns:

  • (Hash<Symbol => void>)


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

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)


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

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.

Parameters:

  • args (void)


182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/vedeu/events/event.rb', line 182

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

  message = if args.size > 1
              "Triggering: '#{name.inspect}' with #{args.inspect}"

            elsif args.one?
              "Triggering: '#{name.inspect}' for #{args.first.inspect}"

            else
              "Triggering: '#{name.inspect}'"

            end

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

  closure.call(*args)
end

#optionsHash<Symbol => void> (private)

Combines the options provided at instantiation with the default values.

Returns:

  • (Hash<Symbol => void>)


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

def options
  defaults.merge!(@options)
end

#throttle_expired?Boolean (private)

Returns a boolean indicating whether the throttle has expired.

Returns:



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

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.

Returns:



208
209
210
211
212
# File 'lib/vedeu/events/event.rb', line 208

def throttling?
  @now = Vedeu.clock_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)


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

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

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

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