vedeu 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|