vedeu 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vedeu/all.rb +2 -13
- data/lib/vedeu/api.rb +9 -9
- data/lib/vedeu/application/application_view.rb +3 -5
- data/lib/vedeu/bindings/bindings.rb +5 -1
- data/lib/vedeu/bindings/focus.rb +0 -5
- data/lib/vedeu/bindings/refresh.rb +0 -5
- data/lib/vedeu/bindings/system.rb +1 -6
- data/lib/vedeu/colours/all.rb +17 -0
- data/lib/vedeu/colours/background.rb +32 -28
- data/lib/vedeu/colours/backgrounds.rb +13 -9
- data/lib/vedeu/colours/colour.rb +106 -102
- data/lib/vedeu/colours/foreground.rb +32 -28
- data/lib/vedeu/colours/foregrounds.rb +13 -9
- data/lib/vedeu/colours/repository.rb +70 -0
- data/lib/vedeu/colours/translator.rb +267 -0
- data/lib/vedeu/configuration/api.rb +10 -7
- data/lib/vedeu/configuration/configuration.rb +2 -1
- data/lib/vedeu/dsl/border.rb +15 -2
- data/lib/vedeu/dsl/composition.rb +6 -4
- data/lib/vedeu/dsl/geometry.rb +14 -7
- data/lib/vedeu/dsl/group.rb +2 -2
- data/lib/vedeu/dsl/interface.rb +5 -3
- data/lib/vedeu/dsl/keymap.rb +9 -7
- data/lib/vedeu/dsl/line.rb +7 -4
- data/lib/vedeu/dsl/menu.rb +3 -0
- data/lib/vedeu/dsl/presentation.rb +20 -10
- data/lib/vedeu/dsl/shared.rb +4 -4
- data/lib/vedeu/dsl/stream.rb +2 -2
- data/lib/vedeu/dsl/text.rb +11 -5
- data/lib/vedeu/dsl/use.rb +2 -2
- data/lib/vedeu/dsl/view.rb +8 -6
- data/lib/vedeu/events/aliases.rb +91 -0
- data/lib/vedeu/events/all.rb +15 -0
- data/lib/vedeu/events/collection.rb +13 -0
- data/lib/vedeu/events/event.rb +244 -239
- data/lib/vedeu/events/repository.rb +30 -0
- data/lib/vedeu/events/trigger.rb +68 -64
- data/lib/vedeu/exceptions.rb +65 -54
- data/lib/vedeu/geometry/coordinate.rb +3 -1
- data/lib/vedeu/geometry/grid.rb +2 -4
- data/lib/vedeu/input/editor/all.rb +2 -1
- data/lib/vedeu/input/editor/{virtual_cursor.rb → cursor.rb} +10 -10
- data/lib/vedeu/input/editor/document.rb +7 -7
- data/lib/vedeu/input/editor/insert.rb +70 -0
- data/lib/vedeu/input/editor/line.rb +4 -16
- data/lib/vedeu/input/editor/lines.rb +2 -16
- data/lib/vedeu/input/input_translator.rb +2 -2
- data/lib/vedeu/input/key.rb +2 -2
- data/lib/vedeu/internal_api.rb +6 -6
- data/lib/vedeu/log/lockless_log_device.rb +0 -74
- data/lib/vedeu/models/focus.rb +3 -3
- data/lib/vedeu/models/interface.rb +3 -3
- data/lib/vedeu/models/menu.rb +2 -2
- data/lib/vedeu/models/views/char.rb +1 -1
- data/lib/vedeu/models/views/composition.rb +1 -1
- data/lib/vedeu/models/views/line.rb +1 -1
- data/lib/vedeu/models/views/stream.rb +1 -1
- data/lib/vedeu/models/views/view.rb +6 -7
- data/lib/vedeu/output/presentation/colour.rb +23 -21
- data/lib/vedeu/output/renderers/renderer_options.rb +2 -4
- data/lib/vedeu/output/text.rb +1 -1
- data/lib/vedeu/output/wordwrap.rb +18 -7
- data/lib/vedeu/plugins/plugin.rb +2 -2
- data/lib/vedeu/refresh/refresh_buffer.rb +3 -3
- data/lib/vedeu/refresh/refresh_group.rb +3 -3
- data/lib/vedeu/repositories/repository.rb +7 -6
- data/lib/vedeu/runtime/application.rb +1 -1
- data/lib/vedeu/runtime/main_loop.rb +3 -3
- data/lib/vedeu/runtime/router.rb +14 -11
- data/lib/vedeu/templating/helpers.rb +5 -5
- data/lib/vedeu/templating/template.rb +4 -4
- data/lib/vedeu/templating/view_template.rb +1 -1
- data/lib/vedeu/terminal/terminal.rb +2 -2
- data/lib/vedeu/version.rb +1 -1
- data/test/lib/vedeu/application/application_view_test.rb +1 -1
- data/test/lib/vedeu/colours/background_test.rb +93 -89
- data/test/lib/vedeu/colours/backgrounds_test.rb +11 -7
- data/test/lib/vedeu/colours/colour_test.rb +155 -151
- data/test/lib/vedeu/colours/foreground_test.rb +93 -89
- data/test/lib/vedeu/colours/foregrounds_test.rb +11 -7
- data/test/lib/vedeu/colours/repository_test.rb +97 -0
- data/test/lib/vedeu/colours/translator_test.rb +173 -0
- data/test/lib/vedeu/configuration/api_test.rb +4 -4
- data/test/lib/vedeu/dsl/border_test.rb +12 -0
- data/test/lib/vedeu/dsl/composition_test.rb +3 -3
- data/test/lib/vedeu/dsl/geometry_test.rb +11 -0
- data/test/lib/vedeu/dsl/group_test.rb +2 -2
- data/test/lib/vedeu/dsl/interface_test.rb +4 -4
- data/test/lib/vedeu/dsl/keymap_test.rb +8 -4
- data/test/lib/vedeu/dsl/line_test.rb +6 -3
- data/test/lib/vedeu/dsl/menu_test.rb +6 -0
- data/test/lib/vedeu/dsl/presentation_test.rb +16 -3
- data/test/lib/vedeu/dsl/stream_test.rb +1 -1
- data/test/lib/vedeu/dsl/text_test.rb +7 -0
- data/test/lib/vedeu/dsl/view_test.rb +3 -3
- data/test/lib/vedeu/events/aliases_test.rb +144 -0
- data/test/lib/vedeu/events/collection_test.rb +22 -0
- data/test/lib/vedeu/events/event_test.rb +84 -80
- data/test/lib/vedeu/events/repository_test.rb +28 -0
- data/test/lib/vedeu/events/trigger_test.rb +41 -37
- data/test/lib/vedeu/geometry/grid_test.rb +4 -4
- data/test/lib/vedeu/input/editor/{virtual_cursor_test.rb → cursor_test.rb} +3 -3
- data/test/lib/vedeu/input/editor/insert_test.rb +36 -0
- data/test/lib/vedeu/input/key_test.rb +1 -1
- data/test/lib/vedeu/models/cell_test.rb +1 -1
- data/test/lib/vedeu/models/focus_test.rb +4 -2
- data/test/lib/vedeu/models/menu_test.rb +1 -1
- data/test/lib/vedeu/models/views/char_test.rb +8 -4
- data/test/lib/vedeu/models/views/line_test.rb +4 -4
- data/test/lib/vedeu/models/views/stream_test.rb +3 -3
- data/test/lib/vedeu/models/views/view_test.rb +1 -1
- data/test/lib/vedeu/output/html_char_test.rb +4 -2
- data/test/lib/vedeu/output/presentation/colour_test.rb +5 -5
- data/test/lib/vedeu/output/presentation_test.rb +4 -4
- data/test/lib/vedeu/output/renderers/json_test.rb +4 -2
- data/test/lib/vedeu/plugins/plugin_test.rb +1 -1
- data/test/lib/vedeu/refresh/refresh_buffer_test.rb +1 -1
- data/test/lib/vedeu/refresh/refresh_group_test.rb +1 -1
- data/test/lib/vedeu/repositories/repository_test.rb +2 -2
- data/test/lib/vedeu/runtime/router_test.rb +6 -6
- data/test/lib/vedeu/templating/decoder_test.rb +2 -3
- data/test/lib/vedeu/templating/encoder_test.rb +2 -3
- data/test/lib/vedeu/templating/helpers_test.rb +6 -6
- data/test/lib/vedeu/templating/template_test.rb +2 -2
- data/test/lib/vedeu/templating/view_template_test.rb +13 -7
- data/test/lib/vedeu/terminal/terminal_test.rb +3 -3
- metadata +24 -19
- data/lib/vedeu/colours/colour_translator.rb +0 -260
- data/lib/vedeu/colours/colours.rb +0 -66
- data/lib/vedeu/events/event_aliases.rb +0 -87
- data/lib/vedeu/events/event_collection.rb +0 -9
- data/lib/vedeu/events/events.rb +0 -26
- data/test/lib/vedeu/colours/colour_translator_test.rb +0 -169
- data/test/lib/vedeu/colours/colours_test.rb +0 -93
- data/test/lib/vedeu/events/event_aliases_test.rb +0 -140
- data/test/lib/vedeu/events/event_collection_test.rb +0 -18
- data/test/lib/vedeu/events/events_test.rb +0 -24
data/lib/vedeu/dsl/shared.rb
CHANGED
@@ -20,11 +20,11 @@ module Vedeu
|
|
20
20
|
# when we define the interface or view, setting it here is just
|
21
21
|
# mirroring functionality of {Vedeu::DSL::Border.border}.
|
22
22
|
# @param block [Proc]
|
23
|
-
# @raise [Vedeu::InvalidSyntax] The required block was not given.
|
23
|
+
# @raise [Vedeu::Error::InvalidSyntax] The required block was not given.
|
24
24
|
# @return [Vedeu::Border]
|
25
25
|
# @see Vedeu::DSL::Border
|
26
26
|
def border(name = nil, &block)
|
27
|
-
fail Vedeu::InvalidSyntax, 'block not given' unless block_given?
|
27
|
+
fail Vedeu::Error::InvalidSyntax, 'block not given' unless block_given?
|
28
28
|
|
29
29
|
model_name = name ? name : model.name
|
30
30
|
|
@@ -63,11 +63,11 @@ module Vedeu
|
|
63
63
|
# when we define the interface or view, setting it here is just
|
64
64
|
# mirroring functionality of {Vedeu::DSL::Geometry.geometry}.
|
65
65
|
# @param block [Proc]
|
66
|
-
# @raise [Vedeu::InvalidSyntax] The required block was not given.
|
66
|
+
# @raise [Vedeu::Error::InvalidSyntax] The required block was not given.
|
67
67
|
# @return [Vedeu::Geometry]
|
68
68
|
# @see Vedeu::DSL::Geometry
|
69
69
|
def geometry(name = nil, &block)
|
70
|
-
fail Vedeu::InvalidSyntax, 'block not given' unless block_given?
|
70
|
+
fail Vedeu::Error::InvalidSyntax, 'block not given' unless block_given?
|
71
71
|
|
72
72
|
model_name = name ? name : model.name
|
73
73
|
|
data/lib/vedeu/dsl/stream.rb
CHANGED
@@ -21,10 +21,10 @@ module Vedeu
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# @param block [Proc]
|
24
|
-
# @raise [Vedeu::InvalidSyntax] The required block was not given.
|
24
|
+
# @raise [Vedeu::Error::InvalidSyntax] The required block was not given.
|
25
25
|
# @return [void]
|
26
26
|
def stream(&block)
|
27
|
-
fail Vedeu::InvalidSyntax, 'block not given' unless block_given?
|
27
|
+
fail Vedeu::Error::InvalidSyntax, 'block not given' unless block_given?
|
28
28
|
|
29
29
|
model.add(model.class.build(attributes, &block))
|
30
30
|
end
|
data/lib/vedeu/dsl/text.rb
CHANGED
@@ -58,11 +58,17 @@ module Vedeu
|
|
58
58
|
|
59
59
|
Vedeu::Text.add(value, options)
|
60
60
|
end
|
61
|
-
alias_method :
|
62
|
-
alias_method :
|
63
|
-
alias_method :
|
64
|
-
alias_method :
|
65
|
-
alias_method :
|
61
|
+
alias_method :text=, :text
|
62
|
+
alias_method :align, :text
|
63
|
+
alias_method :center, :text
|
64
|
+
alias_method :centre, :text
|
65
|
+
alias_method :left, :text
|
66
|
+
alias_method :right, :text
|
67
|
+
alias_method :align=, :text
|
68
|
+
alias_method :center=, :text
|
69
|
+
alias_method :centre=, :text
|
70
|
+
alias_method :left=, :text
|
71
|
+
alias_method :right=, :text
|
66
72
|
|
67
73
|
end # Text
|
68
74
|
|
data/lib/vedeu/dsl/use.rb
CHANGED
@@ -28,8 +28,8 @@ module Vedeu
|
|
28
28
|
#
|
29
29
|
# @param name [String] The name of the model with the value you wish to
|
30
30
|
# use.
|
31
|
-
# @raise [Vedeu::ModelNotFound|Vedeu::NoMethodError]
|
32
|
-
# attribute cannot be found.
|
31
|
+
# @raise [Vedeu::Error::ModelNotFound|Vedeu::Error::NoMethodError]
|
32
|
+
# The model or attribute cannot be found.
|
33
33
|
# @return [void] The stored model.
|
34
34
|
def use(name)
|
35
35
|
model.repository.by_name(name)
|
data/lib/vedeu/dsl/view.rb
CHANGED
@@ -126,10 +126,11 @@ module Vedeu
|
|
126
126
|
#
|
127
127
|
# @param block [Proc] The directives you wish to send to render.
|
128
128
|
# Typically includes `view` with associated sub-directives.
|
129
|
-
# @raise [Vedeu::InvalidSyntax] The required block was not given.
|
129
|
+
# @raise [Vedeu::Error::InvalidSyntax] The required block was not given.
|
130
130
|
# @return [Array<View>]
|
131
131
|
def renders(&block)
|
132
|
-
fail Vedeu::InvalidSyntax,
|
132
|
+
fail Vedeu::Error::InvalidSyntax,
|
133
|
+
'block not given' unless block_given?
|
133
134
|
|
134
135
|
store(:store_immediate, &block)
|
135
136
|
end
|
@@ -170,10 +171,11 @@ module Vedeu
|
|
170
171
|
#
|
171
172
|
# @param block [Proc] The directives you wish to send to render.
|
172
173
|
# Typically includes `view` with associated sub-directives.
|
173
|
-
# @raise [Vedeu::InvalidSyntax] The required block was not given.
|
174
|
+
# @raise [Vedeu::Error::InvalidSyntax] The required block was not given.
|
174
175
|
# @return [Array<View>]
|
175
176
|
def views(&block)
|
176
|
-
fail Vedeu::InvalidSyntax,
|
177
|
+
fail Vedeu::Error::InvalidSyntax,
|
178
|
+
'block not given' unless block_given?
|
177
179
|
|
178
180
|
store(:store_deferred, &block)
|
179
181
|
end
|
@@ -241,10 +243,10 @@ module Vedeu
|
|
241
243
|
# end
|
242
244
|
# end
|
243
245
|
#
|
244
|
-
# @raise [Vedeu::InvalidSyntax] The required block was not given.
|
246
|
+
# @raise [Vedeu::Error::InvalidSyntax] The required block was not given.
|
245
247
|
# @return [Vedeu::Views::Line]
|
246
248
|
def lines(&block)
|
247
|
-
fail Vedeu::InvalidSyntax, 'block not given' unless block_given?
|
249
|
+
fail Vedeu::Error::InvalidSyntax, 'block not given' unless block_given?
|
248
250
|
|
249
251
|
model.add(model.member.build(attributes, &block))
|
250
252
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
module Events
|
4
|
+
|
5
|
+
# Allows the storing of event aliases. Each alias can contain multiple event
|
6
|
+
# names.
|
7
|
+
#
|
8
|
+
module Aliases
|
9
|
+
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# @param alias_name [Symbol]
|
13
|
+
# @param event_name [Symbol]
|
14
|
+
# @return [Hash<Symbol => Array<Symbol>>]
|
15
|
+
def add(alias_name, event_name)
|
16
|
+
storage[alias_name] << event_name
|
17
|
+
end
|
18
|
+
alias_method :bind_alias, :add
|
19
|
+
|
20
|
+
# Return a boolean indicating whether the storage is empty.
|
21
|
+
#
|
22
|
+
# @return [Boolean]
|
23
|
+
def empty?
|
24
|
+
storage.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param alias_name [Symbol]
|
28
|
+
# @return [Array<Symbol>]
|
29
|
+
def find(alias_name)
|
30
|
+
storage[alias_name]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a boolean indicating whether the alias is registered.
|
34
|
+
#
|
35
|
+
# @param alias_name [Symbol]
|
36
|
+
# @return [Boolean]
|
37
|
+
def registered?(alias_name)
|
38
|
+
return false if alias_name.nil? || alias_name.empty?
|
39
|
+
return false if empty?
|
40
|
+
|
41
|
+
storage.include?(alias_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param alias_name [Symbol]
|
45
|
+
# @return [FalseClass|Hash<Symbol => Array<Symbol>>]
|
46
|
+
def remove(alias_name)
|
47
|
+
return false if empty?
|
48
|
+
return false unless registered?(alias_name)
|
49
|
+
|
50
|
+
storage.delete(alias_name)
|
51
|
+
storage
|
52
|
+
end
|
53
|
+
alias_method :unbind_alias, :remove
|
54
|
+
|
55
|
+
# @return [Hash<Symbol => Array<Symbol>>]
|
56
|
+
def reset
|
57
|
+
@storage = in_memory
|
58
|
+
end
|
59
|
+
alias_method :reset!, :reset
|
60
|
+
|
61
|
+
# Access to the storage for this repository.
|
62
|
+
#
|
63
|
+
# @return [Hash<Symbol => Array<Symbol>>]
|
64
|
+
def storage
|
65
|
+
@storage ||= in_memory
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param alias_name [Symbol]
|
69
|
+
# @param args [void]
|
70
|
+
# @return [FalseClass|Array<void>|void]
|
71
|
+
def trigger(alias_name, *args)
|
72
|
+
return [] unless registered?(alias_name)
|
73
|
+
|
74
|
+
storage[alias_name].map do |event_name|
|
75
|
+
Vedeu.log(type: :debug, message: "#{event_name}")
|
76
|
+
Vedeu::Events::Trigger.trigger(event_name, *args)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# @return [Hash<Symbol => Array<Symbol>>]
|
83
|
+
def in_memory
|
84
|
+
Hash.new { |hash, key| hash[key] = [] }
|
85
|
+
end
|
86
|
+
|
87
|
+
end # Aliases
|
88
|
+
|
89
|
+
end # Events
|
90
|
+
|
91
|
+
end # Vedeu
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
# Provides event driven control to Vedeu.
|
4
|
+
#
|
5
|
+
module Events
|
6
|
+
|
7
|
+
end # Events
|
8
|
+
|
9
|
+
end # Vedeu
|
10
|
+
|
11
|
+
require 'vedeu/events/collection'
|
12
|
+
require 'vedeu/events/aliases'
|
13
|
+
require 'vedeu/events/trigger'
|
14
|
+
require 'vedeu/events/repository'
|
15
|
+
require 'vedeu/events/event'
|
data/lib/vedeu/events/event.rb
CHANGED
@@ -1,282 +1,287 @@
|
|
1
1
|
module Vedeu
|
2
2
|
|
3
|
-
|
4
|
-
#
|
5
|
-
# Vedeu provides an event mechanism to facilitate the functionality of your
|
6
|
-
# application. The events are either Vedeu defined, ie. system events or user
|
7
|
-
# defined, ie. user events. User events allow you to orchestrate behaviour
|
8
|
-
# within your application, ie. the user presses a specific key, you trigger an
|
9
|
-
# event to make something happen. Eg. pressing 'p' instructs the player to
|
10
|
-
# play.
|
11
|
-
#
|
12
|
-
# Events described here assume that you have either included Vedeu in your
|
13
|
-
# class:
|
14
|
-
#
|
15
|
-
# class SomeClassInYourApplication
|
16
|
-
# include Vedeu
|
17
|
-
#
|
18
|
-
# bind :event_name do |arg1, arg2|
|
19
|
-
# # Things that should happen when the event is triggered; these can be
|
20
|
-
# # method calls or the triggering of another event or events.
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# or, you are prepared to use the `Vedeu` prefix:
|
24
|
-
#
|
25
|
-
# class SomeClassInYourApplication
|
26
|
-
# Vedeu.bind(:event_name) do
|
27
|
-
# # Not all events you define will have arguments; like methods.
|
28
|
-
# :do_stuff
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
class Event
|
32
|
-
|
33
|
-
include Vedeu::Model
|
34
|
-
|
35
|
-
class << self
|
36
|
-
|
37
|
-
# Register an event by name with optional delay (throttling) which when
|
38
|
-
# triggered will execute the code contained within the passed block.
|
39
|
-
#
|
40
|
-
# @param name [Symbol] The name of the event to be triggered later.
|
41
|
-
# @param options [Hash] The options to register the event with.
|
42
|
-
# @option options :delay [Fixnum|Float] Limits the execution of the
|
43
|
-
# triggered event to only execute when first triggered, with subsequent
|
44
|
-
# triggering being ignored until the delay has expired.
|
45
|
-
# @option options :debounce [Fixnum|Float] Limits the execution of the
|
46
|
-
# triggered event to only execute once the debounce has expired.
|
47
|
-
# Subsequent triggers before debounce expiry are ignored.
|
48
|
-
# @param block [Proc] The event to be executed when triggered. This block
|
49
|
-
# could be a method call, or the triggering of another event, or
|
50
|
-
# sequence of either/both.
|
51
|
-
#
|
52
|
-
# @example
|
53
|
-
# Vedeu.bind :my_event do |some, args|
|
54
|
-
# # ... some code here ...
|
55
|
-
#
|
56
|
-
# Vedeu.trigger(:my_other_event)
|
57
|
-
# end
|
58
|
-
#
|
59
|
-
# T = Triggered, X = Executed, i = Ignored.
|
60
|
-
#
|
61
|
-
# 0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6...
|
62
|
-
# .T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T
|
63
|
-
# .X...i...i...i...i...X...i...i...i...i...X...i...i...i...i...i...i...i
|
64
|
-
#
|
65
|
-
# Vedeu.bind(:my_delayed_event, { delay: 0.5 })
|
66
|
-
# # ... some code here ...
|
67
|
-
# end
|
68
|
-
#
|
69
|
-
# T = Triggered, X = Executed, i = Ignored.
|
70
|
-
#
|
71
|
-
# 0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6...
|
72
|
-
# .T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T
|
73
|
-
# .i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i...i
|
74
|
-
#
|
75
|
-
# Vedeu.bind(:my_debounced_event, { debounce: 0.7 })
|
76
|
-
# # ... some code here ...
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# @return [TrueClass]
|
80
|
-
def bind(name, options = {}, &block)
|
81
|
-
Vedeu.log(type: :event, message: "Binding: '#{name.inspect}'")
|
82
|
-
|
83
|
-
new(name, block, options).bind
|
84
|
-
end
|
85
|
-
alias_method :event, :bind
|
86
|
-
alias_method :register, :bind
|
3
|
+
module Events
|
87
4
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
5
|
+
# Contains all the logic of an event. Handles debouncing and throttling.
|
6
|
+
#
|
7
|
+
# Vedeu provides an event mechanism to facilitate the functionality of your
|
8
|
+
# application. The events are either Vedeu defined, ie. system events or
|
9
|
+
# user defined, ie. user events. User events allow you to orchestrate
|
10
|
+
# behaviour within your application, ie. the user presses a specific key,
|
11
|
+
# you trigger an event to make something happen. Eg. pressing 'p' instructs
|
12
|
+
# the player to play.
|
13
|
+
#
|
14
|
+
# Events described here assume that you have either included Vedeu in your
|
15
|
+
# class:
|
16
|
+
#
|
17
|
+
# class SomeClassInYourApplication
|
18
|
+
# include Vedeu
|
19
|
+
#
|
20
|
+
# bind :event_name do |arg1, arg2|
|
21
|
+
# # Things that should happen when the event is triggered; these can
|
22
|
+
# # be method calls or the triggering of another event or events.
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# or, you are prepared to use the `Vedeu` prefix:
|
26
|
+
#
|
27
|
+
# class SomeClassInYourApplication
|
28
|
+
# Vedeu.bind(:event_name) do
|
29
|
+
# # Not all events you define will have arguments; like methods.
|
30
|
+
# :do_stuff
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
class Event
|
34
|
+
|
35
|
+
include Vedeu::Model
|
36
|
+
|
37
|
+
class << self
|
38
|
+
|
39
|
+
# Register an event by name with optional delay (throttling) which when
|
40
|
+
# triggered will execute the code contained within the passed block.
|
41
|
+
#
|
42
|
+
# @param name [Symbol] The name of the event to be triggered later.
|
43
|
+
# @param options [Hash] The options to register the event with.
|
44
|
+
# @option options :delay [Fixnum|Float] Limits the execution of the
|
45
|
+
# triggered event to only execute when first triggered, with
|
46
|
+
# subsequent triggering being ignored until the delay has expired.
|
47
|
+
# @option options :debounce [Fixnum|Float] Limits the execution of the
|
48
|
+
# triggered event to only execute once the debounce has expired.
|
49
|
+
# Subsequent triggers before debounce expiry are ignored.
|
50
|
+
# @param block [Proc] The event to be executed when triggered. This
|
51
|
+
# block could be a method call, or the triggering of another event, or
|
52
|
+
# sequence of either/both.
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# Vedeu.bind :my_event do |some, args|
|
56
|
+
# # ... some code here ...
|
57
|
+
#
|
58
|
+
# Vedeu.trigger(:my_other_event)
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# T = Triggered, X = Executed, i = Ignored.
|
62
|
+
#
|
63
|
+
# 0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
|
64
|
+
# .T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
|
65
|
+
# .X...i...i...i...i...X...i...i...i...i...X...i...i...i...i...i...i..
|
66
|
+
#
|
67
|
+
# Vedeu.bind(:my_delayed_event, { delay: 0.5 })
|
68
|
+
# # ... some code here ...
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# T = Triggered, X = Executed, i = Ignored.
|
72
|
+
#
|
73
|
+
# 0.0.....0.2.....0.4.....0.6.....0.8.....1.0.....1.2.....1.4.....1.6.
|
74
|
+
# .T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T...T..
|
75
|
+
# .i...i...i...i...i...i...i...X...i...i...i...i...i...i...X...i...i..
|
76
|
+
#
|
77
|
+
# Vedeu.bind(:my_debounced_event, { debounce: 0.7 })
|
78
|
+
# # ... some code here ...
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# @return [TrueClass]
|
82
|
+
def bind(name, options = {}, &block)
|
83
|
+
Vedeu.log(type: :event, message: "Binding: '#{name.inspect}'")
|
84
|
+
|
85
|
+
new(name, block, options).bind
|
86
|
+
end
|
87
|
+
alias_method :event, :bind
|
88
|
+
alias_method :register, :bind
|
89
|
+
|
90
|
+
# Return a boolean indicating whether the named event is registered.
|
91
|
+
#
|
92
|
+
# @example
|
93
|
+
# Vedeu.bound?(:some_event)
|
94
|
+
#
|
95
|
+
# @param name [Symbol]
|
96
|
+
# @return [Boolean]
|
97
|
+
def bound?(name)
|
98
|
+
Vedeu.events.registered?(name) ||
|
99
|
+
Vedeu::Events::Aliases.registered?(name)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Unbind events from a named handler.
|
103
|
+
#
|
104
|
+
# Removes all events associated with the given name.
|
105
|
+
#
|
106
|
+
# @example
|
107
|
+
# Vedeu.unbind(:some_event)
|
108
|
+
#
|
109
|
+
# @param name [Symbol]
|
110
|
+
# @return [Boolean]
|
111
|
+
def unbind(name)
|
112
|
+
return false unless Vedeu.bound?(name)
|
113
|
+
|
114
|
+
Vedeu.log(type: :event, message: "Unbinding: '#{name.inspect}'")
|
115
|
+
|
116
|
+
Vedeu.events.remove(name)
|
117
|
+
|
118
|
+
true
|
119
|
+
end
|
120
|
+
|
121
|
+
extend Forwardable
|
122
|
+
|
123
|
+
def_delegators Vedeu::Events::Trigger, :trigger
|
124
|
+
|
125
|
+
end # Eigenclass
|
126
|
+
|
127
|
+
# Returns a new instance of Vedeu::Events::Event.
|
92
128
|
#
|
93
|
-
# @param
|
94
|
-
# @return [
|
95
|
-
def
|
96
|
-
|
129
|
+
# @param (see Vedeu::Events::Event.bind)
|
130
|
+
# @return [Vedeu::Events::Event]
|
131
|
+
def initialize(name, closure, options = {})
|
132
|
+
@name = name
|
133
|
+
@options = options
|
134
|
+
@closure = closure
|
135
|
+
@deadline = 0
|
136
|
+
@executed_at = 0
|
137
|
+
@now = 0
|
138
|
+
@repository = Vedeu.events
|
97
139
|
end
|
98
140
|
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
# @example
|
104
|
-
# Vedeu.unbind(:some_event)
|
105
|
-
#
|
106
|
-
# @param name [Symbol]
|
107
|
-
# @return [Boolean]
|
108
|
-
def unbind(name)
|
109
|
-
return false unless Vedeu.bound?(name)
|
141
|
+
# @see Vedeu::Events::Event.bind
|
142
|
+
def bind
|
143
|
+
if repository.registered?(name)
|
144
|
+
new_collection = repository.find(name).add(self)
|
110
145
|
|
111
|
-
|
146
|
+
else
|
147
|
+
new_collection = Vedeu::Events::Collection.new([self], nil, name)
|
112
148
|
|
113
|
-
|
149
|
+
end
|
150
|
+
|
151
|
+
repository.store(new_collection)
|
114
152
|
|
115
153
|
true
|
116
154
|
end
|
117
155
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
156
|
+
# Triggers the event based on debouncing and throttling conditions.
|
157
|
+
#
|
158
|
+
# @param args [Array]
|
159
|
+
# @return [void]
|
160
|
+
def trigger(*args)
|
161
|
+
return execute(*args) unless debouncing? || throttling?
|
123
162
|
|
124
|
-
|
125
|
-
#
|
126
|
-
# @param (see Vedeu::Event.bind)
|
127
|
-
# @return [Vedeu::Event]
|
128
|
-
def initialize(name, closure, options = {})
|
129
|
-
@name = name
|
130
|
-
@options = options
|
131
|
-
@closure = closure
|
132
|
-
@deadline = 0
|
133
|
-
@executed_at = 0
|
134
|
-
@now = 0
|
135
|
-
@repository = Vedeu.events
|
136
|
-
end
|
137
|
-
|
138
|
-
# @see Vedeu::Event.bind
|
139
|
-
def bind
|
140
|
-
if repository.registered?(name)
|
141
|
-
new_collection = repository.find(name).add(self)
|
142
|
-
|
143
|
-
else
|
144
|
-
new_collection = Vedeu::EventCollection.new([self], nil, name)
|
163
|
+
return execute(*args) if debouncing? && debounce_expired?
|
145
164
|
|
165
|
+
return execute(*args) if throttling? && throttle_expired?
|
146
166
|
end
|
147
167
|
|
148
|
-
|
149
|
-
|
150
|
-
true
|
151
|
-
end
|
168
|
+
protected
|
152
169
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
# @return [void]
|
157
|
-
def trigger(*args)
|
158
|
-
return execute(*args) unless debouncing? || throttling?
|
159
|
-
|
160
|
-
return execute(*args) if debouncing? && debounce_expired?
|
170
|
+
# @!attribute [r] closure
|
171
|
+
# @return [String]
|
172
|
+
attr_reader :closure
|
161
173
|
|
162
|
-
|
163
|
-
|
174
|
+
# @!attribute [r] name
|
175
|
+
# @return [String]
|
176
|
+
attr_reader :name
|
164
177
|
|
165
|
-
|
178
|
+
private
|
166
179
|
|
167
|
-
|
168
|
-
|
169
|
-
|
180
|
+
# Execute the code stored in the event closure.
|
181
|
+
#
|
182
|
+
# @param args [void]
|
183
|
+
# @return [void]
|
184
|
+
def execute(*args)
|
185
|
+
@deadline = 0 # reset deadline
|
186
|
+
@executed_at = @now # set execution time to now
|
187
|
+
@now = 0 # reset now
|
170
188
|
|
171
|
-
|
172
|
-
|
173
|
-
attr_reader :name
|
189
|
+
message = "Triggering: '#{name.inspect}'"
|
190
|
+
message << " with '#{args.inspect}'" if args.any?
|
174
191
|
|
175
|
-
|
192
|
+
Vedeu.log(type: :event, message: message)
|
176
193
|
|
177
|
-
|
178
|
-
|
179
|
-
# @param args [void]
|
180
|
-
# @return [void]
|
181
|
-
def execute(*args)
|
182
|
-
@deadline = 0 # reset deadline
|
183
|
-
@executed_at = @now # set execution time to now
|
184
|
-
@now = 0 # reset now
|
185
|
-
|
186
|
-
message = "Triggering: '#{name.inspect}'"
|
187
|
-
message << " with '#{args.inspect}'" if args.any?
|
194
|
+
closure.call(*args)
|
195
|
+
end
|
188
196
|
|
189
|
-
|
197
|
+
# Returns a boolean indicating whether throttling is required for this
|
198
|
+
# event. Setting the delay option to any value greater than 0 will enable
|
199
|
+
# throttling.
|
200
|
+
#
|
201
|
+
# @return [Boolean]
|
202
|
+
def throttling?
|
203
|
+
@now = Time.now.to_f
|
190
204
|
|
191
|
-
|
192
|
-
|
205
|
+
options[:delay] > 0
|
206
|
+
end
|
193
207
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
def throttling?
|
200
|
-
@now = Time.now.to_f
|
208
|
+
# Returns a boolean indicating whether the throttle has expired.
|
209
|
+
#
|
210
|
+
# @return [Boolean]
|
211
|
+
def throttle_expired?
|
212
|
+
return true if (@now - @executed_at) > delay
|
201
213
|
|
202
|
-
|
203
|
-
end
|
214
|
+
Vedeu.log(type: :event, message: "Throttling: '#{name.inspect}'")
|
204
215
|
|
205
|
-
|
206
|
-
|
207
|
-
# @return [Boolean]
|
208
|
-
def throttle_expired?
|
209
|
-
return true if (@now - @executed_at) > delay
|
216
|
+
false
|
217
|
+
end
|
210
218
|
|
211
|
-
|
219
|
+
# Returns a boolean indicating whether debouncing is required for this
|
220
|
+
# event. Setting the debounce option to any value greater than 0 will
|
221
|
+
# enable debouncing.
|
222
|
+
# Sets the deadline for when this event can be executed to a point in the
|
223
|
+
# future determined by the amount of debounce time left.
|
224
|
+
#
|
225
|
+
# @return [Boolean]
|
226
|
+
def debouncing?
|
227
|
+
@now = Time.now.to_f
|
212
228
|
|
213
|
-
|
214
|
-
end
|
229
|
+
@deadline = @now + debounce unless deadline?
|
215
230
|
|
216
|
-
|
217
|
-
|
218
|
-
# enable debouncing.
|
219
|
-
# Sets the deadline for when this event can be executed to a point in the
|
220
|
-
# future determined by the amount of debounce time left.
|
221
|
-
#
|
222
|
-
# @return [Boolean]
|
223
|
-
def debouncing?
|
224
|
-
@now = Time.now.to_f
|
231
|
+
options[:debounce] > 0
|
232
|
+
end
|
225
233
|
|
226
|
-
|
234
|
+
# Returns a boolean indicating whether the debounce has expired.
|
235
|
+
#
|
236
|
+
# @return [Boolean]
|
237
|
+
def debounce_expired?
|
238
|
+
return true if (@executed_at = @now) > @deadline
|
227
239
|
|
228
|
-
|
229
|
-
end
|
240
|
+
Vedeu.log(type: :event, message: "Debouncing: '#{name.inspect}'")
|
230
241
|
|
231
|
-
|
232
|
-
|
233
|
-
# @return [Boolean]
|
234
|
-
def debounce_expired?
|
235
|
-
return true if (@executed_at = @now) > @deadline
|
242
|
+
false
|
243
|
+
end
|
236
244
|
|
237
|
-
|
245
|
+
# Returns a boolean indicating whether this event has a deadline.
|
246
|
+
#
|
247
|
+
# @return [Boolean]
|
248
|
+
def deadline?
|
249
|
+
@deadline > 0
|
250
|
+
end
|
238
251
|
|
239
|
-
|
240
|
-
|
252
|
+
# Return the amount of time in seconds to debounce the event by.
|
253
|
+
#
|
254
|
+
# @return [Fixnum|Float]
|
255
|
+
def debounce
|
256
|
+
options[:debounce] || defaults[:debounce]
|
257
|
+
end
|
241
258
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
259
|
+
# Return the amount of time in seconds to throttle the event by.
|
260
|
+
#
|
261
|
+
# @return [Fixnum|Float]
|
262
|
+
def delay
|
263
|
+
options[:delay] || defaults[:delay]
|
264
|
+
end
|
248
265
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
266
|
+
# Combines the options provided at instantiation with the default values.
|
267
|
+
#
|
268
|
+
# @return [Hash]
|
269
|
+
def options
|
270
|
+
defaults.merge!(@options)
|
271
|
+
end
|
255
272
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
273
|
+
# The default values for a new instance of this class.
|
274
|
+
#
|
275
|
+
# @return [Hash]
|
276
|
+
def defaults
|
277
|
+
{
|
278
|
+
delay: 0.0,
|
279
|
+
debounce: 0.0,
|
280
|
+
}
|
281
|
+
end
|
262
282
|
|
263
|
-
#
|
264
|
-
#
|
265
|
-
# @return [Hash]
|
266
|
-
def options
|
267
|
-
defaults.merge!(@options)
|
268
|
-
end
|
283
|
+
end # Event
|
269
284
|
|
270
|
-
|
271
|
-
#
|
272
|
-
# @return [Hash]
|
273
|
-
def defaults
|
274
|
-
{
|
275
|
-
delay: 0.0,
|
276
|
-
debounce: 0.0,
|
277
|
-
}
|
278
|
-
end
|
279
|
-
|
280
|
-
end # Event
|
285
|
+
end # Events
|
281
286
|
|
282
287
|
end # Vedeu
|