tef-animation 0.1.0 → 0.1.1
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/tef/Animation/Animatable.rb +155 -2
- data/lib/tef/Animation/Animation_Handler.rb +81 -3
- data/lib/tef/Animation/Color.rb +70 -0
- data/lib/tef/Animation/Coordinate.rb +10 -0
- data/lib/tef/Animation/Eyes.rb +2 -0
- data/lib/tef/Animation/Value.rb +75 -1
- data/lib/tef/ParameterStack/Override.rb +47 -0
- data/lib/tef/ParameterStack/Stack.rb +64 -0
- data/lib/tef/ProgramSelection/ProgramID.rb +46 -0
- data/lib/tef/ProgramSelection/ProgramSelector.rb +54 -0
- data/lib/tef/ProgramSelection/SequenceCollection.rb +70 -4
- data/lib/tef/ProgramSelection/SoundCollection.rb +59 -22
- data/lib/tef/Sequencing/BaseSequence.rb +44 -2
- data/lib/tef/Sequencing/EventCollector.rb +74 -0
- data/lib/tef/Sequencing/SequencePlayer.rb +41 -1
- data/lib/tef/Sequencing/Sheet.rb +48 -0
- data/lib/tef/Sequencing/SheetSequence.rb +49 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92421ddea4eb5a58abffa7fdb3ec987f645281d7
|
4
|
+
data.tar.gz: c2fc1d82fdffc6ecc435ed47554f3dca0bb5834b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df1fd4e30609e37ee34281ccad04a759af87155757af7886d163c7082caa3e9427854b09353d042342ebd2e8e5d00c4ec3b79289bb7c7ecbff21353d1abb9e10
|
7
|
+
data.tar.gz: 96069806358729bff76ecebe28a925caf52d8587acc9ba05dc7950595e9ad1f3b5980b32a16ca84a074fd5f9ef896eda0c5d496061ab1c8c08f42806051cead0
|
@@ -3,24 +3,80 @@ require_relative 'Value.rb'
|
|
3
3
|
require_relative 'Color.rb'
|
4
4
|
require_relative 'Coordinate.rb'
|
5
5
|
|
6
|
+
# TheElectricFursuits module.
|
7
|
+
# @see https://github.com/TheElectricFursuits
|
6
8
|
module TEF
|
9
|
+
# Animation-Related Module
|
10
|
+
#
|
11
|
+
# This module wraps all classes related to TEF 'Synth'-Line animation.
|
12
|
+
# They are meant to provide an abstraction layer over the hardware-implemented
|
13
|
+
# animations that run on slave devices, such as the FurComs-Connected Synth Bit,
|
14
|
+
# and give the user full access to high-level functions such as configuring
|
15
|
+
# named parameters, setting up value smoothing and transitions, and
|
16
|
+
# creating and deleting objects.
|
7
17
|
module Animation
|
18
|
+
# Animatable base class.
|
19
|
+
#
|
20
|
+
# This class implements all necessary functions to write a custom
|
21
|
+
# animatable object with ease. It provides a DSL to easily
|
22
|
+
# register new animatable colours, values and coordinates, and handles
|
23
|
+
# updating and configuring them.
|
24
|
+
#
|
25
|
+
# By inheriting from this base class, the user must only define
|
26
|
+
# the animatable properties of their object by using:
|
27
|
+
# - {Animatable#animatable_attr}
|
28
|
+
# - {Animatable#animatable_color}
|
29
|
+
# - {Animatable#animatable_coordinate}
|
30
|
+
#
|
31
|
+
# The object must also be passed to the Animation handler, by calling:
|
32
|
+
# handler['S123M123'] = your_instance;
|
8
33
|
class Animatable
|
34
|
+
# @return [String, nil] Module ID of this object as in SxxMxx, or nil.
|
9
35
|
attr_reader :module_id
|
36
|
+
|
37
|
+
# @return [Time, nil] If set, returns the time this object will
|
38
|
+
# auto-delete. This will not delete the Ruby object, but it will
|
39
|
+
# send a delete request to the animation slaves.
|
10
40
|
attr_reader :death_time
|
11
41
|
|
42
|
+
# @return [Numeric, nil] If set, returns the time (in s) that this
|
43
|
+
# object will live for. If the object is currently a live animation,
|
44
|
+
# setting this will make the object die in the given number of
|
45
|
+
# seconds. If it is not currently animated, it will make the object
|
46
|
+
# die after the given number of seconds, starting from when it
|
47
|
+
# was registered with the handler.
|
12
48
|
attr_reader :death_delay
|
13
49
|
|
50
|
+
# @private
|
51
|
+
# @return [Array<{Symbol, Integer>] List of registered animatable attributes
|
14
52
|
def self.get_attr_list
|
15
53
|
@class_attribute_list ||= {}
|
16
54
|
end
|
55
|
+
# @private
|
56
|
+
# @return [Array<Symbol, Integer>] List of registered animatable colours
|
17
57
|
def self.get_color_list
|
18
58
|
@class_color_list ||= {}
|
19
59
|
end
|
60
|
+
# @private
|
61
|
+
# @return [Array<Symbol, Integer>] List of registered animatable coordinates
|
20
62
|
def self.get_coordinate_list
|
21
63
|
@class_coordinate_list ||= {}
|
22
64
|
end
|
23
65
|
|
66
|
+
# Defines a new animatable attribute.
|
67
|
+
#
|
68
|
+
# The defined attribute will become accessible via a getter and
|
69
|
+
# convenience setter function, giving the user access to the
|
70
|
+
# created {Value} instance.
|
71
|
+
#
|
72
|
+
# @param name [Symbol] Name of the attribute, as symbol. Will
|
73
|
+
# create getter and setter functions.
|
74
|
+
# @param id [Numeric] Address of the animatable attribute. Must match
|
75
|
+
# the address defined in the animation C++ code!
|
76
|
+
#
|
77
|
+
# @!macro [attach] anim.attribute
|
78
|
+
# @!attribute [rw] $1
|
79
|
+
# @return [Value] Animated value '$1' (ID $2)
|
24
80
|
def self.animatable_attr(name, id)
|
25
81
|
get_attr_list()[name] = id
|
26
82
|
|
@@ -37,6 +93,19 @@ module TEF
|
|
37
93
|
end
|
38
94
|
end
|
39
95
|
|
96
|
+
# Defines a new animatable color
|
97
|
+
#
|
98
|
+
# The defined color will become accessible via a getter and
|
99
|
+
# convenience setter function, giving the user access to the
|
100
|
+
# created {Color} instance.
|
101
|
+
#
|
102
|
+
# @param name [Symbol] Name of the color, as symbol. Will
|
103
|
+
# create getter and setter functions.
|
104
|
+
# @param id [Numeric] Address of the animatable color. Must match
|
105
|
+
# the address defined in the animation C++ code!
|
106
|
+
# @!macro [attach] anim.color
|
107
|
+
# @!attribute [rw] $1
|
108
|
+
# @return [Color] Animated color '$1' (ID $2)
|
40
109
|
def self.animatable_color(name, id)
|
41
110
|
get_color_list()[name] = id
|
42
111
|
|
@@ -49,6 +118,20 @@ module TEF
|
|
49
118
|
end
|
50
119
|
end
|
51
120
|
|
121
|
+
# Defines a new animatable coordinate.
|
122
|
+
#
|
123
|
+
# The defined coordinate will become accessible via a getter and
|
124
|
+
# convenience setter function, giving the user access to the
|
125
|
+
# created {Value} instance.
|
126
|
+
#
|
127
|
+
# @param name [Symbol] Name of the coordinate, as symbol. Will
|
128
|
+
# create getter and setter functions.
|
129
|
+
# @param id [Numeric] Starting address of the coordinates. Expects
|
130
|
+
# the coordinate parameters to be sequential!
|
131
|
+
#
|
132
|
+
# @!macro [attach] anim.attribute
|
133
|
+
# @!attribute [rw] $1
|
134
|
+
# @return [Coordinate] Coordinate for '$1' (ID $2)
|
52
135
|
def self.animatable_coordinate(name, start)
|
53
136
|
get_coordinate_list()[name] = start
|
54
137
|
|
@@ -57,6 +140,10 @@ module TEF
|
|
57
140
|
end
|
58
141
|
end
|
59
142
|
|
143
|
+
# Initialize a generic animatable object.
|
144
|
+
#
|
145
|
+
# This will initialize the necessary internal hashes
|
146
|
+
# that contain the animatable attributes, colors and coordinates.
|
60
147
|
def initialize()
|
61
148
|
@animatable_attributes = {}
|
62
149
|
@animatable_colors = {}
|
@@ -84,6 +171,21 @@ module TEF
|
|
84
171
|
@death_time_changed = true
|
85
172
|
end
|
86
173
|
|
174
|
+
# Make this object die in a given number of seconds.
|
175
|
+
# After the timer set here expires, the object will automatically
|
176
|
+
# be deleted. As the slaves will do it automatically, it is good
|
177
|
+
# practice to give any temporary object a death time, if possible, to
|
178
|
+
# have them automatically cleaned up.
|
179
|
+
#
|
180
|
+
# It is possible to remove a death time or extend it, by calling
|
181
|
+
# this function another time.
|
182
|
+
#
|
183
|
+
# @note This will not delete the Ruby object, but it will be
|
184
|
+
# unregistered from the {Animation::Handler}. It can safely
|
185
|
+
# be re-registered to re-create a new object.
|
186
|
+
#
|
187
|
+
# @param t [Numeric, nil] The time, in seconds until this object will
|
188
|
+
# be killed.
|
87
189
|
def die_in(t)
|
88
190
|
if t.nil?
|
89
191
|
self.death_time = nil
|
@@ -98,10 +200,25 @@ module TEF
|
|
98
200
|
@death_delay = t
|
99
201
|
end
|
100
202
|
|
203
|
+
# Instantly deletes this object from the animation slaves.
|
204
|
+
# @see #die_in
|
101
205
|
def die!
|
102
206
|
self.death_time = Time.at(0)
|
103
207
|
end
|
104
208
|
|
209
|
+
# Quickly configure this object.
|
210
|
+
#
|
211
|
+
# This is a convenience function to very quickly and easily
|
212
|
+
# (re)configure this animatable object. It will take a hash
|
213
|
+
# or named options, and will pass the values of the hash to
|
214
|
+
# the matching {Value}, {Color} or {Coordinate}
|
215
|
+
#
|
216
|
+
# @see Value#configure
|
217
|
+
# @see Color#configure
|
218
|
+
# @see Coordinate#configure
|
219
|
+
#
|
220
|
+
# @example
|
221
|
+
# my_box.configure up: 10, down: 5, left: { dampen: 0.4, add: 2 }
|
105
222
|
def configure(h = nil, **opts)
|
106
223
|
h ||= opts;
|
107
224
|
|
@@ -118,17 +235,29 @@ module TEF
|
|
118
235
|
end
|
119
236
|
end
|
120
237
|
|
238
|
+
# Return a default creation string.
|
239
|
+
#
|
240
|
+
# This function MUST be overwritten by the user to provide a proper
|
241
|
+
# creation string! It will be sent over FurComs via the 'NEW' topic
|
242
|
+
# and must contain all necessary information for the slaves to
|
243
|
+
# construct the matching object.
|
121
244
|
def creation_string
|
122
|
-
|
245
|
+
''
|
123
246
|
end
|
124
247
|
|
125
|
-
def all_animatable_attributes
|
248
|
+
private def all_animatable_attributes
|
126
249
|
out = @animatable_attributes.values
|
127
250
|
out += @animatable_coordinates.values.map(&:animatable_attributes)
|
128
251
|
|
129
252
|
out.flatten
|
130
253
|
end
|
131
254
|
|
255
|
+
# @private
|
256
|
+
# Set the module ID of this object manually.
|
257
|
+
#
|
258
|
+
# @note Do not call this function, it is purely internal.
|
259
|
+
# Only the {Handler} may set the module ID, otherwise undefined
|
260
|
+
# behavior may occour!
|
132
261
|
def module_id=(new_str)
|
133
262
|
unless new_str =~ /^S[\d]{1,3}M[\d]{1,3}$/ || new_str.nil?
|
134
263
|
raise ArgumentError, 'Target must be a valid Animation Value'
|
@@ -143,6 +272,10 @@ module TEF
|
|
143
272
|
@module_id = new_str
|
144
273
|
end
|
145
274
|
|
275
|
+
# @private
|
276
|
+
#
|
277
|
+
# Returns a String to be sent via FurComs to configure the object
|
278
|
+
# to die in a certain number of seconds.
|
146
279
|
def death_time_string
|
147
280
|
return nil unless @death_time_changed
|
148
281
|
|
@@ -155,6 +288,23 @@ module TEF
|
|
155
288
|
"#{@module_id} #{remaining_time};"
|
156
289
|
end
|
157
290
|
|
291
|
+
# @private
|
292
|
+
#
|
293
|
+
# Returns an array of 'SET' Hashes, to be sent over the FurComs
|
294
|
+
# bus, 'SET' topic. They represent raw value configurations of the
|
295
|
+
# animatable values.
|
296
|
+
#
|
297
|
+
# The {Handler} that called this function has the duty of packing
|
298
|
+
# them into complete commands, as the initial module ID can be
|
299
|
+
# left out for sequential value access, saving a few bytes
|
300
|
+
# each transfer.
|
301
|
+
#
|
302
|
+
# @note Never call this unless you are the {Handler}! It will
|
303
|
+
# mark the changes as already transmitted, so manually calling
|
304
|
+
# this will cause data loss!
|
305
|
+
#
|
306
|
+
# @return [Array<Hash>] An array containing Hashes outlining each
|
307
|
+
# value's SET string.
|
158
308
|
def get_set_strings()
|
159
309
|
return [] unless @module_id
|
160
310
|
|
@@ -170,6 +320,9 @@ module TEF
|
|
170
320
|
out_elements
|
171
321
|
end
|
172
322
|
|
323
|
+
# @private
|
324
|
+
#
|
325
|
+
# @see #get_set_strings
|
173
326
|
def get_setc_strings()
|
174
327
|
return [] unless @module_id
|
175
328
|
|
@@ -3,11 +3,36 @@ require 'xasin_logger'
|
|
3
3
|
|
4
4
|
require_relative 'Animatable.rb'
|
5
5
|
|
6
|
+
# TheElectricFursuits module.
|
7
|
+
# @see https://github.com/TheElectricFursuits
|
6
8
|
module TEF
|
7
9
|
module Animation
|
10
|
+
# Animation object handler.
|
11
|
+
#
|
12
|
+
# This class is the handler for one coherent animation system.
|
13
|
+
# Its main purpose is to (de)register animatable objects, distributing
|
14
|
+
# IDs and handing out packed update messages onto a FurComs bus.
|
8
15
|
class Handler
|
9
16
|
include XasLogger::Mix
|
10
17
|
|
18
|
+
# Initialize a Handler.
|
19
|
+
#
|
20
|
+
# This will initialize a handler and connect it to the passed FurComs
|
21
|
+
# bus.
|
22
|
+
# The user may immediately start registering objects after creating
|
23
|
+
# this class, though if the FurComs bus is not connected yet this may
|
24
|
+
# cause very early messages to be lost!
|
25
|
+
#
|
26
|
+
# @param [FurComs::Base] furcoms_bus The FurComs Bus connecting
|
27
|
+
# instance. Must support send_message(topic, data), nothing else.
|
28
|
+
#
|
29
|
+
# @note {#update_tick} MUST be called after performing any
|
30
|
+
# changes, be it adding a new {Animatable} or changing values
|
31
|
+
# of a known animatable. It is recommended to call this function
|
32
|
+
# only after all changes for a given tick have been performed, so
|
33
|
+
# that they can be sent over as a batch.
|
34
|
+
# {Sequencing::Player#after_exec} can be used to register a callback
|
35
|
+
# to call {#update_tick}.
|
11
36
|
def initialize(furcoms_bus)
|
12
37
|
@furcoms = furcoms_bus
|
13
38
|
|
@@ -20,6 +45,13 @@ module TEF
|
|
20
45
|
init_x_log('Animation Handler')
|
21
46
|
end
|
22
47
|
|
48
|
+
# Create a String key representation.
|
49
|
+
#
|
50
|
+
# This will take either a hash or a String,
|
51
|
+
# convert it to a standard String key representation, and then
|
52
|
+
# verify it for correctness.
|
53
|
+
# @param [String, Hash] key the key to clean up.
|
54
|
+
# @return [String] Cleaned string
|
23
55
|
def clean_key(key)
|
24
56
|
key = 'S%<S>dM%<M>d' % key if key.is_a? Hash
|
25
57
|
|
@@ -30,10 +62,20 @@ module TEF
|
|
30
62
|
key
|
31
63
|
end
|
32
64
|
|
65
|
+
# @return [Animatable] Returns the Animatable with matching key.
|
33
66
|
def [](key)
|
34
67
|
@active_animations[clean_key key]
|
35
68
|
end
|
36
69
|
|
70
|
+
# Register or replace a {Animatable}.
|
71
|
+
#
|
72
|
+
# This lets the user register a new {Animatable} object with given
|
73
|
+
# key, or replace or delete a pre-existing animation object.
|
74
|
+
#
|
75
|
+
# @param [String, Hash] key The key to write into.
|
76
|
+
# @param [Animatable, nil] Will delete any pre-existing animation, then
|
77
|
+
# either replace it with the given {Animatable}, or, if nil was
|
78
|
+
# given, will delete the animation entry.
|
37
79
|
def []=(key, new_obj)
|
38
80
|
@animation_mutex.synchronize {
|
39
81
|
key = clean_key key
|
@@ -42,18 +84,23 @@ module TEF
|
|
42
84
|
|
43
85
|
if new_obj.nil?
|
44
86
|
@pending_deletions[key] = true
|
87
|
+
@pending_creations.delete key
|
45
88
|
|
46
89
|
elsif new_obj.is_a? Animatable
|
47
90
|
new_obj.module_id = key
|
48
91
|
|
49
92
|
@active_animations[key] = new_obj
|
50
93
|
@pending_creations[key] = new_obj.creation_string
|
94
|
+
@pending_deletions.delete key
|
51
95
|
else
|
52
96
|
raise ArgumentError, 'New animation object is of invalid type'
|
53
97
|
end
|
54
98
|
}
|
55
99
|
end
|
56
100
|
|
101
|
+
# Internal function to join an Array of strings and send it onto
|
102
|
+
# the FurComs bus on a given topic.
|
103
|
+
# Useful to batch-send, which is a bit more efficient.
|
57
104
|
private def join_and_send(topic, data)
|
58
105
|
return if data.empty?
|
59
106
|
|
@@ -70,8 +117,12 @@ module TEF
|
|
70
117
|
@furcoms.send_message topic, out_str
|
71
118
|
end
|
72
119
|
|
73
|
-
#
|
74
|
-
|
120
|
+
# Internal function to send out death updates.
|
121
|
+
# This will send out to topic DTIME, updating the Animatable's
|
122
|
+
# death_time, as well as sending to DELETE for deleted animations.
|
123
|
+
#
|
124
|
+
# @todo Replace this with a time-synched system
|
125
|
+
# using the main synch time, rather than using relative time.
|
75
126
|
private def update_deaths
|
76
127
|
death_reconfigs = [];
|
77
128
|
|
@@ -99,6 +150,9 @@ module TEF
|
|
99
150
|
join_and_send('DELETE', deletions)
|
100
151
|
end
|
101
152
|
|
153
|
+
# Private function to send out creation strings.
|
154
|
+
# Will simply send a string per new object, as we do not often
|
155
|
+
# need to initialize objects.
|
102
156
|
private def update_creations
|
103
157
|
@pending_creations.each do |key, val|
|
104
158
|
@furcoms.send_message('NEW', val)
|
@@ -107,6 +161,15 @@ module TEF
|
|
107
161
|
@pending_creations = {}
|
108
162
|
end
|
109
163
|
|
164
|
+
# Internal function to optimize sending values.
|
165
|
+
#
|
166
|
+
# Updating values can be optimized in certain ways. The initial
|
167
|
+
# value specifier can be left out if the next value to update
|
168
|
+
# has an ID one after the former message.
|
169
|
+
#
|
170
|
+
# This can significantly reduce message length, for example after
|
171
|
+
# creating a new object and initializing it. Being able to leave out the
|
172
|
+
# Value ID saves about 10 bytes per value!
|
110
173
|
private def optimize_and_send(messages)
|
111
174
|
last_change = {}
|
112
175
|
out_str = '';
|
@@ -137,11 +200,13 @@ module TEF
|
|
137
200
|
@furcoms.send_message 'SET', out_str
|
138
201
|
end
|
139
202
|
|
203
|
+
# Internal function, will merely collect
|
204
|
+
# the change strings from all known animations.
|
140
205
|
private def update_values()
|
141
206
|
pending_changes = []
|
142
207
|
|
143
208
|
@animation_mutex.synchronize {
|
144
|
-
@active_animations.each do |
|
209
|
+
@active_animations.each do |_, anim|
|
145
210
|
pending_changes += anim.get_set_strings
|
146
211
|
end
|
147
212
|
}
|
@@ -152,6 +217,8 @@ module TEF
|
|
152
217
|
optimize_and_send pending_changes
|
153
218
|
end
|
154
219
|
|
220
|
+
# Internal function, will collect all color change strings from
|
221
|
+
# active animations and send it over FurComs
|
155
222
|
private def update_colors
|
156
223
|
pending_changes = []
|
157
224
|
|
@@ -167,6 +234,17 @@ module TEF
|
|
167
234
|
join_and_send 'CSET', pending_changes
|
168
235
|
end
|
169
236
|
|
237
|
+
# Update tick.
|
238
|
+
#
|
239
|
+
# Calling this function will send all updates and changes over the
|
240
|
+
# FurComs bus. It is ensured that they occour in the following order:
|
241
|
+
#
|
242
|
+
# - All modules that have actively been deleted in Ruby will be
|
243
|
+
# deleted.
|
244
|
+
# - Newly created and registered {Animatable}s will be created
|
245
|
+
# on the animation slaves.
|
246
|
+
# - All {Value} changes of all {Animatable}s will be sent.
|
247
|
+
# - All {Color} changes will be sent.
|
170
248
|
def update_tick()
|
171
249
|
update_creations
|
172
250
|
|
data/lib/tef/Animation/Color.rb
CHANGED
@@ -1,13 +1,64 @@
|
|
1
1
|
|
2
|
+
|
3
|
+
# TheElectricFursuits module.
|
4
|
+
# @see https://github.com/TheElectricFursuits
|
2
5
|
module TEF
|
6
|
+
# Animation-Related Module
|
7
|
+
#
|
8
|
+
# This module wraps all classes related to TEF 'Synth'-Line animation.
|
9
|
+
# They are meant to provide an abstraction layer over the hardware-implemented
|
10
|
+
# animations that run on slave devices, such as the FurComs-Connected Synth Bit,
|
11
|
+
# and give the user full access to high-level functions such as configuring
|
12
|
+
# named parameters, setting up value smoothing and transitions, and
|
13
|
+
# creating and deleting objects.
|
3
14
|
module Animation
|
4
15
|
class Color
|
5
16
|
PARAM_TYPES = [:jump, :velocity, :target, :delay_a, :delay_b];
|
6
17
|
|
18
|
+
# @return [Integer] Hardware-Number of this Color
|
7
19
|
attr_reader :ID
|
8
20
|
|
21
|
+
# @return [String, nil] Module-ID of the {Animatable} that this
|
22
|
+
# color belongs to.
|
9
23
|
attr_reader :module_id
|
10
24
|
|
25
|
+
# @!attribute [rw] jump
|
26
|
+
# Immediately set the color of this Color to the jump value,
|
27
|
+
# skipping animation. If animation is set, the Color will then
|
28
|
+
# fade back to the value defined by {#target}
|
29
|
+
# @return [Numeric] Current RGB color code.
|
30
|
+
|
31
|
+
# @!attribute [rw] velocity
|
32
|
+
# Set the animation buffer to the given color. Has no effect
|
33
|
+
# unless {#delay_b} was configued, in which case the animation will
|
34
|
+
# temporarily fade to velocity, then fade back to {#target}
|
35
|
+
# @return [Numeric] Current RGB color code.
|
36
|
+
|
37
|
+
# @!attribute [rw] target
|
38
|
+
# Target of the color animation. Set this as hexadecimal RGB color
|
39
|
+
# code, i.e. 0xRRGGBB, with an optional alpha channel (i.e. 0xFF000000)
|
40
|
+
# for a fully transparent black.
|
41
|
+
|
42
|
+
# @!attribute [rw] delay_a
|
43
|
+
# Smoothing delay for color transition. If {#delay_b} is zero and
|
44
|
+
# delay_a is nonzero, setting {#target} will cause the actual
|
45
|
+
# color to slowly transition to {#target}. Larger values cause
|
46
|
+
# *faster* transitions!
|
47
|
+
#
|
48
|
+
# If delay_b is set, delay_a defines the smoothing speed between the
|
49
|
+
# 'velocity' color and the actual color.
|
50
|
+
|
51
|
+
# @!attribute [rw] delay_b
|
52
|
+
# Smoothing delay for color transition. If both {#delay_a} and delay_b
|
53
|
+
# are nonzero, setting {#target} will cause a smooth transition of the
|
54
|
+
# output color.
|
55
|
+
#
|
56
|
+
# delay_b defines the transition speed of {#target} to an internal,
|
57
|
+
# non-visible 'velocity' color.
|
58
|
+
|
59
|
+
# Initialize a new color.
|
60
|
+
# @param [Integer] value_num The hardware ID of this Color.
|
61
|
+
# must match the ID defined in the animation slaves.
|
11
62
|
def initialize(value_num)
|
12
63
|
@ID = value_num;
|
13
64
|
|
@@ -25,10 +76,16 @@ module TEF
|
|
25
76
|
end
|
26
77
|
end
|
27
78
|
|
79
|
+
# @return [String] Total ID of this Color, in the form
|
80
|
+
# 'SxxMxxVxx'
|
28
81
|
def total_id()
|
29
82
|
"#{@module_id}V#{@ID}"
|
30
83
|
end
|
31
84
|
|
85
|
+
# Internal function to set any of the Color's parameters.
|
86
|
+
#
|
87
|
+
# This can be called by the user, but it is preferrable to use
|
88
|
+
# {#configure} or the matching parameter setter functions.
|
32
89
|
def generic_set(key, value)
|
33
90
|
raise ArgumentError, 'Key does not exist!' unless PARAM_TYPES.include? key
|
34
91
|
raise ArgumentError, "Input must be numeric!" unless value.is_a? Numeric
|
@@ -53,6 +110,13 @@ module TEF
|
|
53
110
|
end
|
54
111
|
end
|
55
112
|
|
113
|
+
# Configure the color with a hash.
|
114
|
+
#
|
115
|
+
# This lets the user configure the color by passing a hash.
|
116
|
+
# The data will be passed into the five attributes of this color
|
117
|
+
# according to their key.
|
118
|
+
# @example
|
119
|
+
# a_color.configure({ delay_a: 10, target: 0xFF0000 })
|
56
120
|
def configure(data)
|
57
121
|
if data.is_a? Numeric
|
58
122
|
self.target = data
|
@@ -69,10 +133,16 @@ module TEF
|
|
69
133
|
return !@changes.empty?
|
70
134
|
end
|
71
135
|
|
136
|
+
# Internal function to strip trailing zeroes for floats
|
72
137
|
private def rcut(value)
|
73
138
|
value.to_s.gsub(/(\.)0+$/, '')
|
74
139
|
end
|
75
140
|
|
141
|
+
# @private
|
142
|
+
# Internal function to retrieve the list of changes for this color.
|
143
|
+
# @note Do not call this as user unless you know what you are doing!
|
144
|
+
# This will delete the retrieved changes, which may cause loss of
|
145
|
+
# data if they are not properly sent to the animation slaves!
|
76
146
|
def set_string()
|
77
147
|
return nil unless has_changes?
|
78
148
|
|