tef-animation 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 ||= "";
|