tef-animation 0.1.0

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.
@@ -0,0 +1,49 @@
1
+
2
+ $coordinate_def ||= {
3
+ x: 0,
4
+ y: 1,
5
+ }
6
+
7
+ module TEF
8
+ module Animation
9
+ class Coordinate
10
+ $coordinate_def.each do |c, id|
11
+ define_method(c.to_s) do
12
+ @animatable_attributes[c]
13
+ end
14
+
15
+ define_method("#{c}=") do |arg|
16
+ if arg.is_a? Numeric
17
+ @animatable_attributes[c].add = arg
18
+ else
19
+ @animatable_attributes[c].from = arg
20
+ end
21
+ end
22
+ end
23
+
24
+ def initialize(start_offset)
25
+ @animatable_attributes = {}
26
+
27
+ $coordinate_def.each do |key, v|
28
+ @animatable_attributes[key] = Value.new(v + start_offset)
29
+ end
30
+ end
31
+
32
+ def animatable_attributes
33
+ @animatable_attributes.values
34
+ end
35
+
36
+ def configure(data)
37
+ raise ArgumentError, 'Coordinate config must be a hash!' unless data.is_a? Hash
38
+
39
+ data.each do |key, value|
40
+ coord = @animatable_attributes[key]
41
+
42
+ raise ArgumentError, "Coordinate #{key} does not exist!" unless coord
43
+
44
+ coord.configure value
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+
2
+ require_relative 'Animatable.rb'
3
+
4
+ module TEF
5
+ module Animation
6
+ class Eye < Animatable
7
+ animatable_color :outer_color, 0
8
+ animatable_color :inner_color, 1
9
+
10
+ animatable_attr :iris_x, 0x10
11
+ animatable_attr :iris_y, 0x11
12
+ animatable_attr :top, 0x12
13
+ animatable_attr :bottom, 0x13
14
+ animatable_attr :eye_closure, 0x14
15
+
16
+ def initialize()
17
+ super();
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,133 @@
1
+
2
+
3
+ module TEF
4
+ module Animation
5
+ class Value
6
+ PARAM_TYPES = [:add, :multiply, :dampen, :delay, :from, :jump, :velocity];
7
+
8
+ attr_reader :ID
9
+
10
+ attr_reader :module_id
11
+
12
+ def initialize(value_num)
13
+ @ID = value_num;
14
+
15
+ @current = Hash.new(0);
16
+ @changes = {}
17
+
18
+ @is_animated = false;
19
+ end
20
+
21
+ def module_id=(new_id)
22
+ @module_id = new_id
23
+
24
+ PARAM_TYPES.each do |key|
25
+ @changes[:key] = true if @current[key] != 0
26
+ end
27
+ end
28
+
29
+ def total_id()
30
+ "#{@module_id}V#{@ID.to_s(16)}"
31
+ end
32
+
33
+ def generic_set(key, value)
34
+ raise ArgumentError, 'Key does not exist!' unless PARAM_TYPES.include? key
35
+ raise ArgumentError, "Input must be numeric!" unless value.is_a? Numeric
36
+
37
+ return if (value == @current[key] && ![:jump, :velocity].include?(key))
38
+
39
+ if [:multiply, :dampen, :delay].include? key
40
+ @is_animated = true
41
+ end
42
+
43
+ @current[key] = value
44
+ @changes[key] = true
45
+ end
46
+
47
+ [:jump, :velocity, :add, :multiply, :dampen, :delay].each do |key|
48
+ define_method(key.to_s) do
49
+ @current[key]
50
+ end
51
+
52
+ define_method("#{key}=") do |input|
53
+ generic_set key, input
54
+ end
55
+ end
56
+
57
+ def configure(data)
58
+ if data.is_a? Numeric
59
+ self.add = data
60
+ elsif data.is_a? Hash
61
+ data.each do |key, value|
62
+ generic_set key, value
63
+ end
64
+ else
65
+ self.from = data;
66
+ end
67
+ end
68
+
69
+ def from() return @current[:from] end
70
+
71
+ def from=(target)
72
+ if target.is_a? Value
73
+ target = target.total_id
74
+ end
75
+
76
+ if target.nil?
77
+ target = 'S0M0V0'
78
+ end
79
+
80
+ unless target =~ /^S[\d]{1,3}M[\da-f]{1,3}V\d+$/
81
+ raise ArgumentError, 'Target must be a valid Animation Value'
82
+ end
83
+
84
+ return if target == @current[:from]
85
+
86
+ @current[:from] = target
87
+ @changes[:from] = true
88
+ @is_animated = true
89
+ end
90
+
91
+ def has_changes?
92
+ return !@changes.empty?
93
+ end
94
+
95
+ private def rcut(value)
96
+ value.to_s.gsub(/(\.)0+$/, '')
97
+ end
98
+
99
+ def set_string()
100
+ return nil unless has_changes?
101
+
102
+ if !@is_animated
103
+ return nil unless @changes[:add]
104
+
105
+ out_str = "J#{rcut(@current[:add])};"
106
+
107
+ @changes = {}
108
+
109
+ return out_str
110
+ end
111
+
112
+ out_str = [];
113
+
114
+ out_str << "J#{rcut(@current[:jump])}" if @changes[:jump]
115
+ out_str << "V#{rcut(@current[:velocity])}" if @changes[:velocity]
116
+
117
+ out_str << @current[:from] if @changes[:from]
118
+
119
+ config_strs = [];
120
+ config_strs_out = [];
121
+ [:add, :multiply, :dampen, :delay].each do |k|
122
+ config_strs << rcut(@current[k])
123
+
124
+ config_strs_out = config_strs.dup if @changes[k]
125
+ end
126
+
127
+ @changes = {}
128
+
129
+ (out_str + config_strs_out).join(' ') + ';'
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,66 @@
1
+
2
+ require_relative 'Stack.rb'
3
+
4
+ module TEF
5
+ module ParameterStack
6
+ class Override
7
+ include Comparable
8
+
9
+ attr_reader :level
10
+
11
+ def initialize(stack, init_level = 0)
12
+ raise ArgumentError, 'Handler must be CoreStack!' unless stack.is_a? Stack
13
+
14
+ @stack = stack
15
+
16
+ @level = init_level;
17
+ @overrides = {}
18
+
19
+ @valid_until = nil;
20
+
21
+ @stack.add_override self
22
+ end
23
+
24
+ def [](key)
25
+ @overrides[key]
26
+ end
27
+
28
+ def []=(key, new_value)
29
+ return if @overrides[key] == new_value
30
+
31
+ if new_value.nil?
32
+ delete(key)
33
+ return
34
+ end
35
+
36
+ @overrides[key] = new_value
37
+ @stack.override_claims self, key
38
+ end
39
+
40
+ def include?(key)
41
+ @overrides.include? key
42
+ end
43
+ def keys
44
+ @overrides.keys
45
+ end
46
+
47
+ def delete(key)
48
+ return unless @overrides.include? key
49
+ @overrides.delete key
50
+
51
+ return unless @stack.active_overrides[key] == self
52
+
53
+ @stack.recompute_single key
54
+ end
55
+
56
+ def destroy!
57
+ @stack.remove_override self
58
+ end
59
+
60
+ def <=>(other)
61
+ return @level <=> other.level if other.level != @level
62
+ return self.hash <=> other.hash
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,149 @@
1
+
2
+ require_relative 'Override.rb'
3
+
4
+ module TEF
5
+ module ParameterStack
6
+ class Stack
7
+ attr_reader :changes
8
+ attr_reader :active_overrides
9
+
10
+ def initialize()
11
+ @current_values = {}
12
+ @active_overrides = {}
13
+
14
+ @changes = {}
15
+
16
+ @override_list_mutex = Mutex.new()
17
+ @override_list = []
18
+
19
+ @recompute_blocks = []
20
+ @value_change_blocks = []
21
+
22
+ @default_override = Override.new(self, -1);
23
+ end
24
+
25
+ def [](key)
26
+ @current_values[key]
27
+ end
28
+ def []=(key, value)
29
+ @default_override[key] = value
30
+ end
31
+ def keys
32
+ @current_values.keys
33
+ end
34
+
35
+ def on_recompute(*keys, &block)
36
+ @recompute_blocks << {
37
+ block: block,
38
+ keys: keys
39
+ }
40
+ end
41
+
42
+ def on_change(*filters, &block)
43
+ filters = nil if filters.empty?
44
+
45
+ @value_change_blocks << {
46
+ block: block,
47
+ filters: filters
48
+ }
49
+ end
50
+
51
+ private def mark_key_change(key)
52
+ @changes[key] = true
53
+
54
+ @recompute_blocks.each do |block_cfg|
55
+ next unless block_cfg[:keys].include? key
56
+ block_cfg[:block].call(key, @current_values[key])
57
+ end
58
+ end
59
+
60
+ def override_claims(override, key)
61
+ return if !(@active_overrides[key].nil?) && (@active_overrides[key] > override)
62
+
63
+ @active_overrides[key] = override;
64
+ value = override[key];
65
+
66
+ return if @current_values[key] == value
67
+
68
+ @current_values[key] = value
69
+ mark_key_change key
70
+ end
71
+
72
+ def recompute_single(key)
73
+ old_value = @current_values[key]
74
+
75
+ found_override = false;
76
+
77
+ @override_list_mutex.synchronize do
78
+ @override_list.each do |override|
79
+ next unless override.include? key
80
+
81
+ @active_overrides[key] = override;
82
+ @current_values[key] = override[key];
83
+
84
+ found_override = true;
85
+
86
+ break;
87
+ end
88
+ end
89
+
90
+ if !found_override
91
+ @current_values.delete key
92
+ @active_overrides.delete key
93
+ end
94
+
95
+ mark_key_change key if old_value != @current_values[key]
96
+ end
97
+
98
+ def recompute(keys)
99
+ keys.each do |key|
100
+ recompute_single key
101
+ end
102
+ end
103
+
104
+ private def keys_match_filters(keys, filters)
105
+ return true if filters.nil?
106
+
107
+ filters = [filters] unless filters.is_a? Array
108
+
109
+ filters.each do |filter|
110
+ keys.each do |key|
111
+ return true if filter.is_a?(Regexp) && key =~ filter
112
+ return true if filter.is_a?(String) && key == filter
113
+ end
114
+ end
115
+
116
+ return false
117
+ end
118
+
119
+ def process_changes()
120
+ change_list = @changes.keys
121
+
122
+ @value_change_blocks.each do |block_cfg|
123
+ next unless keys_match_filters change_list, block_cfg[:filters]
124
+
125
+ block_cfg[:block].call()
126
+ end
127
+
128
+ @changes = {}
129
+ end
130
+
131
+ def add_override(override)
132
+ @override_list_mutex.synchronize do
133
+ @override_list << override unless @override_list.include? override
134
+ @override_list.sort!
135
+ end
136
+ end
137
+
138
+ def remove_override(override)
139
+ return unless @override_list.include? override
140
+
141
+ @override_list_mutex.synchronize do
142
+ @override_list.delete override
143
+ end
144
+
145
+ recompute override.keys
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,56 @@
1
+
2
+
3
+ module TEF
4
+ module ProgramSelection
5
+ class ID
6
+ attr_reader :title
7
+ attr_reader :groups
8
+ attr_reader :variant
9
+
10
+ attr_reader :hash
11
+
12
+ def initialize(title, groups, variant)
13
+ @title = title;
14
+ @groups = groups.sort
15
+ @variant = variant
16
+
17
+ @hash = @title.hash ^ @groups.hash ^ @variant.hash
18
+ end
19
+
20
+ def ==(other)
21
+ if other.is_a? String
22
+ @title == other
23
+ elsif other.is_a? ID
24
+ return false if @title != other.title
25
+ return false if @variant != other.variant
26
+ return false if @groups != other.groups
27
+
28
+ true
29
+ end
30
+ end
31
+ alias eql? ==
32
+
33
+ def <=>(other)
34
+ tsort = (@title <=> other.title)
35
+ return tsort unless tsort.zero?
36
+
37
+ gsort = (@groups <=> other.groups)
38
+ return gsort unless gsort.zero?
39
+
40
+ @variant <=> other.variant
41
+ end
42
+
43
+ def get_scoring(group_weights)
44
+ score = 0;
45
+
46
+ @groups.each do |g|
47
+ if weight = group_weights[g]
48
+ score += weight
49
+ end
50
+ end
51
+
52
+ score
53
+ end
54
+ end
55
+ end
56
+ end