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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

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

Parameters:

  • name (Symbol)

    The name of the event to be triggered later.

  • 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.



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

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)


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

def closure
  @closure
end

#nameString|Symbol (readonly, protected)

Returns:

  • (String|Symbol)


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

def name
  @name
end

#repositoryVedeu::Repositories::Repository Originally defined in module Repositories::Model

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 (Symbol)

    The name of the event to be triggered later.

  • 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:



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

.bound?(name) ⇒ Boolean

Parameters:

  • name (Symbol)

Returns:



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

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 (Symbol)

    The name of the event to be triggered later.

  • 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

.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 (Symbol)

    The name of the event to be triggered later.

  • 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:



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

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

  new(name, block, options).bind
end

.unbind(name) ⇒ Boolean

Parameters:

  • name (Symbol)

Returns:



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

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

#absent?(variable) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether a variable is nil or empty.

Parameters:

  • variable (String|Symbol|Array|Fixnum)

    The variable to check.

Returns:

#become(klass, attributes) ⇒ Class Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts one class into another.

Parameters:

  • klass (Class)

    The class to become an instance of.

  • attributes (Hash)

    The attributes of klass.

Returns:

  • (Class)

    Returns a new instance of klass.

#bindObject

See Also:



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

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

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

                   end

  repository.store(new_collection)

  true
end

#boolean(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating the value was a boolean.

Parameters:

  • value (void)

Returns:

#boolean?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value is a Boolean.

Parameters:

Returns:

#deadline?Boolean (private)

Returns a boolean indicating whether this event has a deadline.

Returns:



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

def deadline?
  @deadline > 0
end

#debounceFixnum|Float (private)

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

Returns:

  • (Fixnum|Float)


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

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

#debounce_expired?Boolean (private)

Returns a boolean indicating whether the debounce has expired.

Returns:



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

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:



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

def debouncing?
  @now = Vedeu.clock_time

  @deadline = @now + debounce unless deadline?

  options[:debounce] > 0
end

#defaultsHash<Symbol => void> (private)

The default values for a new instance of this class.

Returns:

  • (Hash<Symbol => void>)


286
287
288
289
290
291
# File 'lib/vedeu/events/event.rb', line 286

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)


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

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

#escape?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value is an escape sequence object (e.g. Vedeu::Cells::Escape.)

Returns:

#execute(*args) ⇒ void (private)

This method returns an undefined value.

Execute the code stored in the event closure.

Parameters:

  • args (void)


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

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

#falsy?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value should be considered false.

Parameters:

  • value (void)

Returns:

#hash?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value is a Hash.

Parameters:

  • value (Hash|void)

Returns:

#line_model?Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating the model is a Views::Line.

Returns:

#numeric?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value is a Fixnum.

Parameters:

  • value (Fixnum|void)

Returns:

#optionsHash<Symbol => void> (private)

Combines the options provided at instantiation with the default values.

Returns:

  • (Hash<Symbol => void>)


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

def options
  defaults.merge!(@options)
end

#present?(variable) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether a variable has a useful value.

Parameters:

  • variable (String|Symbol|Array|Fixnum)

    The variable to check.

Returns:

#snake_case(klass) ⇒ String Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts a class name to a lowercase snake case string.

Examples:

snake_case(MyClassName) # => "my_class_name"
snake_case(NameSpaced::ClassName)
# => "name_spaced/class_name"

snake_case('MyClassName') # => "my_class_name"
snake_case(NameSpaced::ClassName)
# => "name_spaced/class_name"

Parameters:

  • klass (Module|Class|String)

Returns:

  • (String)

#store(&block) ⇒ void Originally defined in module Repositories::Model

TODO:

Perhaps some validation could be added here?

Note:

If a block is given, store the model, return the model after yielding.

This method returns an undefined value.

Returns The model instance stored in the repository.

#stream_model?Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating the model is a Views::Stream.

Returns:

#string?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value is a Fixnum.

Parameters:

  • value (String|void)

Returns:

#throttle_expired?Boolean (private)

Returns a boolean indicating whether the throttle has expired.

Returns:



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

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:



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

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)


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

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

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

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

#truthy?(value) ⇒ Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating whether the value should be considered true.

Parameters:

  • value (void)

Returns:

#view_model?Boolean Originally defined in module Common

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a boolean indicating the model is a Views::View.

Returns: