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
@@ -4,7 +4,17 @@ $coordinate_def ||= {
|
|
4
4
|
y: 1,
|
5
5
|
}
|
6
6
|
|
7
|
+
# TheElectricFursuits module.
|
8
|
+
# @see https://github.com/TheElectricFursuits
|
7
9
|
module TEF
|
10
|
+
# Animation-Related Module
|
11
|
+
#
|
12
|
+
# This module wraps all classes related to TEF 'Synth'-Line animation.
|
13
|
+
# They are meant to provide an abstraction layer over the hardware-implemented
|
14
|
+
# animations that run on slave devices, such as the FurComs-Connected Synth Bit,
|
15
|
+
# and give the user full access to high-level functions such as configuring
|
16
|
+
# named parameters, setting up value smoothing and transitions, and
|
17
|
+
# creating and deleting objects.
|
8
18
|
module Animation
|
9
19
|
class Coordinate
|
10
20
|
$coordinate_def.each do |c, id|
|
data/lib/tef/Animation/Eyes.rb
CHANGED
data/lib/tef/Animation/Value.rb
CHANGED
@@ -1,14 +1,64 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
# TheElectricFursuits module.
|
3
|
+
# @see https://github.com/TheElectricFursuits
|
3
4
|
module TEF
|
5
|
+
# Animation-Related Module
|
6
|
+
#
|
7
|
+
# This module wraps all classes related to TEF 'Synth'-Line animation.
|
8
|
+
# They are meant to provide an abstraction layer over the hardware-implemented
|
9
|
+
# animations that run on slave devices, such as the FurComs-Connected Synth Bit,
|
10
|
+
# and give the user full access to high-level functions such as configuring
|
11
|
+
# named parameters, setting up value smoothing and transitions, and
|
12
|
+
# creating and deleting objects.
|
4
13
|
module Animation
|
5
14
|
class Value
|
6
15
|
PARAM_TYPES = [:add, :multiply, :dampen, :delay, :from, :jump, :velocity];
|
7
16
|
|
17
|
+
# @return [Integer] Hardware-Number of this Value
|
8
18
|
attr_reader :ID
|
9
19
|
|
20
|
+
# @return [String, nil] Module-ID of the {Animatable} that this
|
21
|
+
# Value belongs to.
|
10
22
|
attr_reader :module_id
|
11
23
|
|
24
|
+
# @!attribute [rw] add
|
25
|
+
# @return [Numeric] The add-offset to apply to this Value.
|
26
|
+
# Can be used either to set the absolute target (with {#from} being
|
27
|
+
# nil), or to specify an offset of the number grabbed from {#from}.
|
28
|
+
|
29
|
+
# @!attribute [rw] multiply
|
30
|
+
# @return [Numeric] Multiplication factor. Will be applied to
|
31
|
+
# ({#from} + {#add}) * {#multiply}. 0 means no multiplication.
|
32
|
+
|
33
|
+
# @!attribute [rw] dampen
|
34
|
+
# @return [Numeric] dampening factor. Causes the actual output value
|
35
|
+
# to smoothly transition to the target value ((from + add) * multiply).
|
36
|
+
# Larger values take longer (higher dampening)
|
37
|
+
|
38
|
+
# @!attribute [rw] delay
|
39
|
+
# @return [Numeric] delay factor. If it and {#dampen} are nonzero,
|
40
|
+
# will cause the actual output to oscillate slightly. Also
|
41
|
+
# causes {#velocity} to have an effect. Higher delays cause
|
42
|
+
# slower transitions, and may need more {#dampen}ing to mitigate
|
43
|
+
# overshoot.
|
44
|
+
|
45
|
+
# @!attribute [rw] from
|
46
|
+
# @return [String,nil] If not set to nil, defines the other {Value}
|
47
|
+
# that this Value will take the output from. Allows the user
|
48
|
+
# to follow some other parameter and create interesting linkages.
|
49
|
+
|
50
|
+
# @!attribute [w] jump
|
51
|
+
# @return [Numeric] Instantly jump to the given number, skipping
|
52
|
+
# animation and smoothing. Will not reconfigure the actual target,
|
53
|
+
# and can thusly be used to temporarily "bump" the value.
|
54
|
+
|
55
|
+
# @!attribute [w] velocity
|
56
|
+
# @return [Numeric] Set the velocity of the value. Only has an
|
57
|
+
# effect if {#dampen} and {#delay} are nonzero.
|
58
|
+
|
59
|
+
# Initialize a new Value.
|
60
|
+
# @param [Integer] value_num The hardware ID of this Value.
|
61
|
+
# must match the ID defined in the animation slaves.
|
12
62
|
def initialize(value_num)
|
13
63
|
@ID = value_num;
|
14
64
|
|
@@ -26,11 +76,22 @@ module TEF
|
|
26
76
|
end
|
27
77
|
end
|
28
78
|
|
79
|
+
# @return [String] Total ID of this Value, in the form
|
80
|
+
# 'SxxMxxVxx'
|
29
81
|
def total_id()
|
30
82
|
"#{@module_id}V#{@ID.to_s(16)}"
|
31
83
|
end
|
32
84
|
|
85
|
+
# Internal function to set any of the Value'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.
|
33
89
|
def generic_set(key, value)
|
90
|
+
if key == :from
|
91
|
+
self.from = value
|
92
|
+
return
|
93
|
+
end
|
94
|
+
|
34
95
|
raise ArgumentError, 'Key does not exist!' unless PARAM_TYPES.include? key
|
35
96
|
raise ArgumentError, "Input must be numeric!" unless value.is_a? Numeric
|
36
97
|
|
@@ -54,6 +115,13 @@ module TEF
|
|
54
115
|
end
|
55
116
|
end
|
56
117
|
|
118
|
+
# Configure the Value with a Hash.
|
119
|
+
#
|
120
|
+
# This lets the user configure the Value by passing a Hash.
|
121
|
+
# The data will be passed into the six attributes of this Value
|
122
|
+
# according to their key.
|
123
|
+
# @example
|
124
|
+
# a_color.configure({ add: 2, dampen: 10 })
|
57
125
|
def configure(data)
|
58
126
|
if data.is_a? Numeric
|
59
127
|
self.add = data
|
@@ -92,10 +160,16 @@ module TEF
|
|
92
160
|
return !@changes.empty?
|
93
161
|
end
|
94
162
|
|
163
|
+
# Internal function to strip trailing zeroes for floats
|
95
164
|
private def rcut(value)
|
96
165
|
value.to_s.gsub(/(\.)0+$/, '')
|
97
166
|
end
|
98
167
|
|
168
|
+
# @private
|
169
|
+
# Internal function to retrieve the list of changes for this Value.
|
170
|
+
# @note Do not call this as user unless you know what you are doing!
|
171
|
+
# This will delete the retrieved changes, which may cause loss of
|
172
|
+
# data if they are not properly sent to the animation slaves!
|
99
173
|
def set_string()
|
100
174
|
return nil unless has_changes?
|
101
175
|
|
@@ -1,13 +1,39 @@
|
|
1
1
|
|
2
2
|
require_relative 'Stack.rb'
|
3
3
|
|
4
|
+
# TheElectricFursuits module.
|
5
|
+
# @see https://github.com/TheElectricFursuits
|
4
6
|
module TEF
|
5
7
|
module ParameterStack
|
8
|
+
# Override class.
|
9
|
+
#
|
10
|
+
# This class represents one 'access point' for the software,
|
11
|
+
# with which it can override certain values of the {Stack}
|
12
|
+
# it belongs to.
|
13
|
+
#
|
14
|
+
# Using it is as simple as using a Hash:
|
15
|
+
# @example
|
16
|
+
# override = Override.new(central_stack, 10);
|
17
|
+
# override['SomeParam'] = 5
|
18
|
+
# override['SomeParam'] = nil # Relinquish control over the value.
|
6
19
|
class Override
|
7
20
|
include Comparable
|
8
21
|
|
22
|
+
# @return [Numeric] Level of this Override.
|
23
|
+
# Higher levels mean higher priority. The highest-level
|
24
|
+
# override that is active for any given key will determine
|
25
|
+
# that key's value!
|
9
26
|
attr_reader :level
|
10
27
|
|
28
|
+
# Initialize an Override.
|
29
|
+
#
|
30
|
+
# Values can be written into the Override immediately after
|
31
|
+
# creation. When the Override is no longer used,
|
32
|
+
# make sure to call {#destroy!}
|
33
|
+
#
|
34
|
+
# @param [Stack] stack The stack to write to.
|
35
|
+
# @param [Numeric] init_level Level of this Override.
|
36
|
+
# Can not be changed, is always the same for all keys!
|
11
37
|
def initialize(stack, init_level = 0)
|
12
38
|
raise ArgumentError, 'Handler must be CoreStack!' unless stack.is_a? Stack
|
13
39
|
|
@@ -21,10 +47,17 @@ module TEF
|
|
21
47
|
@stack.add_override self
|
22
48
|
end
|
23
49
|
|
50
|
+
# @return The value of this Override for a given key.
|
51
|
+
# @note This will not be the global key. Use {Stack#[]} to retrieve
|
52
|
+
# the currently active key.
|
24
53
|
def [](key)
|
25
54
|
@overrides[key]
|
26
55
|
end
|
27
56
|
|
57
|
+
# Set the value for the given key.
|
58
|
+
# Setting nil as value causes this Override to relinquish control
|
59
|
+
# @param key Hash-Key
|
60
|
+
# @param new_value User-defined value. If nil, relinquishes control.
|
28
61
|
def []=(key, new_value)
|
29
62
|
return if @overrides[key] == new_value
|
30
63
|
|
@@ -37,13 +70,18 @@ module TEF
|
|
37
70
|
@stack.override_claims self, key
|
38
71
|
end
|
39
72
|
|
73
|
+
# @return [true,false] Whether this Override includes a given key
|
40
74
|
def include?(key)
|
41
75
|
@overrides.include? key
|
42
76
|
end
|
77
|
+
|
78
|
+
# @return [Array] List of keys
|
43
79
|
def keys
|
44
80
|
@overrides.keys
|
45
81
|
end
|
46
82
|
|
83
|
+
# Delete a value for the given key.
|
84
|
+
# Equivalent to calling {#[]=} nil
|
47
85
|
def delete(key)
|
48
86
|
return unless @overrides.include? key
|
49
87
|
@overrides.delete key
|
@@ -53,6 +91,15 @@ module TEF
|
|
53
91
|
@stack.recompute_single key
|
54
92
|
end
|
55
93
|
|
94
|
+
# Destroy this Override.
|
95
|
+
#
|
96
|
+
# This function MUST be called if the user no longer
|
97
|
+
# needs this object. It relinquishes control over all the
|
98
|
+
# values that this Override formerly held.
|
99
|
+
#
|
100
|
+
# Note that nothing else is modified, and
|
101
|
+
# {Stack#add_override} could be used to re-add
|
102
|
+
# this Override.
|
56
103
|
def destroy!
|
57
104
|
@stack.remove_override self
|
58
105
|
end
|
@@ -1,10 +1,29 @@
|
|
1
1
|
|
2
2
|
require_relative 'Override.rb'
|
3
3
|
|
4
|
+
# TheElectricFursuits module.
|
5
|
+
# @see https://github.com/TheElectricFursuits
|
4
6
|
module TEF
|
7
|
+
# Module for the ParameterStack TEF code.
|
8
|
+
#
|
9
|
+
# The ParameterStack system is a module designed to let multiple different
|
10
|
+
# subsystems of code interact and configure certain core parameters.
|
11
|
+
# Each subystem is assigned its own {ParameterStack::Override}, and can
|
12
|
+
# seamlessly take and relinquish control over parameters at any time.
|
5
13
|
module ParameterStack
|
14
|
+
# Parameter Stack class.
|
15
|
+
#
|
16
|
+
# This class contains all parameters that have been configured by
|
17
|
+
# {Override}s. It provides a way to retrieve the currently valid
|
18
|
+
# coniguration, as well as letting the user (de)regsiter new {Override}s.
|
6
19
|
class Stack
|
20
|
+
|
21
|
+
# @return [Hash] Hash whose keys specify which parameters have been
|
22
|
+
# changed since the last recompute cycle.
|
7
23
|
attr_reader :changes
|
24
|
+
|
25
|
+
# @return [Hash] Hash of the overrides that have control over
|
26
|
+
# a given parameter key.
|
8
27
|
attr_reader :active_overrides
|
9
28
|
|
10
29
|
def initialize()
|
@@ -22,16 +41,32 @@ module TEF
|
|
22
41
|
@default_override = Override.new(self, -1);
|
23
42
|
end
|
24
43
|
|
44
|
+
# @return Returns the currently configured parameter for the given key.
|
25
45
|
def [](key)
|
26
46
|
@current_values[key]
|
27
47
|
end
|
48
|
+
|
49
|
+
# Set the default parameter for a given key.
|
50
|
+
#
|
51
|
+
# Default parameters have a level of -1, meaning that any
|
52
|
+
# {Override} with priority >= 0 (the default) will claim the value.
|
28
53
|
def []=(key, value)
|
29
54
|
@default_override[key] = value
|
30
55
|
end
|
56
|
+
|
31
57
|
def keys
|
32
58
|
@current_values.keys
|
33
59
|
end
|
34
60
|
|
61
|
+
# Add a callback for immediate parameter changes.
|
62
|
+
#
|
63
|
+
# The given block will be called for any change of a parameter,
|
64
|
+
# so should be used sparingly. Recursive parameter setting should also
|
65
|
+
# be carefully avoided!
|
66
|
+
#
|
67
|
+
# @param [Array] keys Key whitelist to trigger on.
|
68
|
+
# @yieldparam key Key that was changed.
|
69
|
+
# @yieldparam value New value of the key
|
35
70
|
def on_recompute(*keys, &block)
|
36
71
|
@recompute_blocks << {
|
37
72
|
block: block,
|
@@ -39,6 +74,16 @@ module TEF
|
|
39
74
|
}
|
40
75
|
end
|
41
76
|
|
77
|
+
# Add a callback to be called during {#process_changes}.
|
78
|
+
#
|
79
|
+
# The given block will be called if a change in a key specified by
|
80
|
+
# the filters occoured, and will be called during {#process_changes}.
|
81
|
+
#
|
82
|
+
# This lets the user only act on changes, and act on them in bunches,
|
83
|
+
# rather than on every individual change.
|
84
|
+
#
|
85
|
+
# @param [String, Regexp] filters List of filters to use. Acts like
|
86
|
+
# a whitelist, can be a Regexp
|
42
87
|
def on_change(*filters, &block)
|
43
88
|
filters = nil if filters.empty?
|
44
89
|
|
@@ -57,6 +102,11 @@ module TEF
|
|
57
102
|
end
|
58
103
|
end
|
59
104
|
|
105
|
+
# Check if an {Override} can claim a key.
|
106
|
+
#
|
107
|
+
# This is mainly an internal function. It will check if the passed
|
108
|
+
# {Override} has permission to claim the given key, and will
|
109
|
+
# change the value accordingly.
|
60
110
|
def override_claims(override, key)
|
61
111
|
return if !(@active_overrides[key].nil?) && (@active_overrides[key] > override)
|
62
112
|
|
@@ -69,6 +119,12 @@ module TEF
|
|
69
119
|
mark_key_change key
|
70
120
|
end
|
71
121
|
|
122
|
+
# Re-Calculate which {Override} is currently claiming a given key.
|
123
|
+
#
|
124
|
+
# This method is mainly for internal work. It will iterate through
|
125
|
+
# the list of {Overrides} to find the next in line that wants
|
126
|
+
# to claim the given key.
|
127
|
+
# May be slow!
|
72
128
|
def recompute_single(key)
|
73
129
|
old_value = @current_values[key]
|
74
130
|
|
@@ -95,6 +151,9 @@ module TEF
|
|
95
151
|
mark_key_change key if old_value != @current_values[key]
|
96
152
|
end
|
97
153
|
|
154
|
+
# Recompute the owner of the list of keys.
|
155
|
+
# Mainly an internal function, used by an {Override} that is
|
156
|
+
# de-registering itself.
|
98
157
|
def recompute(keys)
|
99
158
|
keys.each do |key|
|
100
159
|
recompute_single key
|
@@ -116,6 +175,11 @@ module TEF
|
|
116
175
|
return false
|
117
176
|
end
|
118
177
|
|
178
|
+
# Trigger processing of all {#on_change} callbacks.
|
179
|
+
#
|
180
|
+
# Works best when triggered after all changes for a given
|
181
|
+
# time-tick have been performed, such as during a
|
182
|
+
# {Sequencing::Player#after_exec} callback.
|
119
183
|
def process_changes()
|
120
184
|
change_list = @changes.keys
|
121
185
|
|
@@ -1,12 +1,47 @@
|
|
1
1
|
|
2
2
|
|
3
|
+
|
4
|
+
# TheElectricFursuits module.
|
5
|
+
# @see https://github.com/TheElectricFursuits
|
3
6
|
module TEF
|
7
|
+
# Program Selection related module
|
8
|
+
#
|
9
|
+
# This module is meant to wrap around the functions that define and help with
|
10
|
+
# program selection.
|
11
|
+
# Its main purpose is to provide an easy to use identification and selection
|
12
|
+
# system for the various animations and effects of a fursuit. Often, different
|
13
|
+
# effects can have the same name (such as a 'hello' animation), and
|
14
|
+
# even within a certain type of animation (a group), variations of the same
|
15
|
+
# animaton can occour.
|
16
|
+
#
|
17
|
+
# The code here thusly provides a {ProgramSelection::ID} for identification,
|
18
|
+
# as well as a {ProgramSelection::Selector} that eases selection of a fitting
|
19
|
+
# program in certain situations.
|
4
20
|
module ProgramSelection
|
21
|
+
# Program ID class.
|
22
|
+
#
|
23
|
+
# This class is meant to uniquely identify a specific program.
|
24
|
+
# It also provides a {#hash} and {#==} operator, allowing the use
|
25
|
+
# as hash key.
|
5
26
|
class ID
|
27
|
+
# @return [String] Main title of the program.
|
28
|
+
# Often defines the action the program will execute, i.e. 'hello'
|
29
|
+
# or 'red alert'
|
6
30
|
attr_reader :title
|
31
|
+
# @return [Array<String>] List of groups this program belongs to.
|
32
|
+
# Further defines the program by providing a bit of context, such as
|
33
|
+
# 'portal', 'glad os', etc.
|
7
34
|
attr_reader :groups
|
35
|
+
|
36
|
+
# @return [String] The variant of this program.
|
37
|
+
# Its main purpose is to separate different variations of the same
|
38
|
+
# general program, such as when there are different 'hello's from
|
39
|
+
# the same groups. Has no effect on the actual selection.
|
8
40
|
attr_reader :variant
|
9
41
|
|
42
|
+
# @return [Numeric] The hash key of this ID. Allows
|
43
|
+
# identification and comparison of keys in a Hash. Two keys match if
|
44
|
+
# they have the same groups, title and are of the same variant.
|
10
45
|
attr_reader :hash
|
11
46
|
|
12
47
|
def initialize(title, groups, variant)
|
@@ -17,6 +52,8 @@ module TEF
|
|
17
52
|
@hash = @title.hash ^ @groups.hash ^ @variant.hash
|
18
53
|
end
|
19
54
|
|
55
|
+
# @return [true, false] Two keys match if
|
56
|
+
# they have the same groups, title and are of the same variant.
|
20
57
|
def ==(other)
|
21
58
|
if other.is_a? String
|
22
59
|
@title == other
|
@@ -30,6 +67,8 @@ module TEF
|
|
30
67
|
end
|
31
68
|
alias eql? ==
|
32
69
|
|
70
|
+
# @return [-1..1] Sorting operator, sorts alphabetically by title,
|
71
|
+
# then group, then variant.
|
33
72
|
def <=>(other)
|
34
73
|
tsort = (@title <=> other.title)
|
35
74
|
return tsort unless tsort.zero?
|
@@ -40,6 +79,13 @@ module TEF
|
|
40
79
|
@variant <=> other.variant
|
41
80
|
end
|
42
81
|
|
82
|
+
# Compute the selection score for this ID.
|
83
|
+
# Used in {Selector} to determine the best-matching program ID
|
84
|
+
# for a given group scoring.
|
85
|
+
#
|
86
|
+
# @param [Hash<String, Numeric>] Hash of group weights. Any group
|
87
|
+
# of this ID that has a weight will be added to the score.
|
88
|
+
# @return [Numeric] Sum of the selected group weights.
|
43
89
|
def get_scoring(group_weights)
|
44
90
|
score = 0;
|
45
91
|
|
@@ -3,7 +3,16 @@ require_relative 'ProgramID.rb'
|
|
3
3
|
|
4
4
|
module TEF
|
5
5
|
module ProgramSelection
|
6
|
+
# Program Selector class.
|
7
|
+
#
|
8
|
+
# This class's purpose is to provide a central list of all known
|
9
|
+
# programs, as well as to give the user a method of easily selecting
|
10
|
+
# a matching program for a given situation or query.
|
6
11
|
class Selector
|
12
|
+
|
13
|
+
# @return [Hash<String, Numeric>] Weights of groups.
|
14
|
+
# Used when selecing a program via {#fetch_ID} or {#fetch_string}.
|
15
|
+
# Higher weights mean higher preference
|
7
16
|
attr_accessor :group_weights
|
8
17
|
|
9
18
|
def initialize()
|
@@ -13,6 +22,22 @@ module TEF
|
|
13
22
|
@group_weights = {}
|
14
23
|
end
|
15
24
|
|
25
|
+
# Register a new ID to the list of known {ID}s.
|
26
|
+
#
|
27
|
+
# This will ensure that the given {ID} is present in the list
|
28
|
+
# of known IDs. It will then return either the given {ID} or an equivalent
|
29
|
+
# ID already present in the list. Either can be used for identification.
|
30
|
+
#
|
31
|
+
# This function can be used in two ways, either by passing a {ID} as
|
32
|
+
# only argument, or by passing a String as first argument and optional
|
33
|
+
# group and variant specifiers.
|
34
|
+
#
|
35
|
+
# @param [ID, String] program Program {ID} OR a String to use
|
36
|
+
# as program title.
|
37
|
+
# @param [Array<String>] pgroups Optional list of groups to construct
|
38
|
+
# a new {ID} with.
|
39
|
+
# @param [String, nil] pvariant Optional variant specification to
|
40
|
+
# construct a new {ID} with.
|
16
41
|
def register_ID(program, pgroups = [], pvariant = nil)
|
17
42
|
if program.is_a? String
|
18
43
|
program = ID.new(program, pgroups, pvariant)
|
@@ -31,6 +56,21 @@ module TEF
|
|
31
56
|
program
|
32
57
|
end
|
33
58
|
|
59
|
+
# Fetch an {ID} from the list of known IDs.
|
60
|
+
#
|
61
|
+
# This will fetch a specific {ID} from the list of IDs, based on
|
62
|
+
# its title and group weights.
|
63
|
+
# The title MUST match the given title. Then, the group scoring
|
64
|
+
# of each matching ID will be calculated, based on {#group_weights} and
|
65
|
+
# the given group weights. From all IDs with maximum group weight,
|
66
|
+
# a random variant will be selected, and will be returned.
|
67
|
+
#
|
68
|
+
# @param [String] title Title to look for. Must exactly match the
|
69
|
+
# title of the {ID}.
|
70
|
+
# @param [Hash<String, Numeric>] group_weights Group weights. Higher
|
71
|
+
# group score means a specific {ID} will be preferred.
|
72
|
+
# @return [nil, ID] Either nil if no {ID} with matching title was found,
|
73
|
+
# or the ID with best group score.
|
34
74
|
def fetch_ID(title, group_weights = {})
|
35
75
|
return nil if @known_programs[title].nil?
|
36
76
|
|
@@ -56,6 +96,20 @@ module TEF
|
|
56
96
|
current_list.sample
|
57
97
|
end
|
58
98
|
|
99
|
+
# Fetch an {ID} based on a string.
|
100
|
+
#
|
101
|
+
# This function performs similarly to {#fetch_ID}, but is based on
|
102
|
+
# a more human readable string.
|
103
|
+
# The input is parsed as follows:
|
104
|
+
# - It is split at the first ' from '
|
105
|
+
# - The first part is taken as a title.
|
106
|
+
# - The second part will be split through ' and '. Each resulting
|
107
|
+
# array element is taken as group weight with a score of 2.
|
108
|
+
#
|
109
|
+
# @example
|
110
|
+
# selector.fetch_string('hello from portal and turret')
|
111
|
+
# # This is equivalent to:
|
112
|
+
# selector.fetch_ID('hello', { 'portal' => 2, 'turret' => 2})
|
59
113
|
def fetch_string(str)
|
60
114
|
title, groups = str.split(" from ");
|
61
115
|
groups ||= "";
|