tef-animation 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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