tef-animation 0.1.1 → 0.2.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.
- checksums.yaml +5 -5
 - data/lib/tef/Animation/Animatable.rb +28 -0
 - data/lib/tef/Animation/Animation_Handler.rb +60 -25
 - data/lib/tef/Animation/Eyes.rb +24 -5
 - data/lib/tef/Animation/String.rb +29 -0
 - data/lib/tef/Sequencing/AudacityLabelReader.rb +52 -0
 - data/lib/tef/Sequencing/BaseSequence.rb +41 -18
 - data/lib/tef/Sequencing/EventCollector.rb +7 -3
 - data/lib/tef/Sequencing/SequencePlayer.rb +9 -1
 - data/lib/tef/Sequencing/Sheet.rb +16 -2
 - data/lib/tef/Sequencing/SheetSequence.rb +68 -34
 - data/lib/tef/animation.rb +3 -0
 - metadata +4 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 1db58af80b8a46f264d810c4119617e776dcb4036374041ce2051753003442d7
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 823d5ada4c84f7e5e83e04943a7005516deb343a140c7e0352d3bd9570b06fbf
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: f95e1a8b015fe89f8df92a51b7bb04683d69fc9f0e4bd5016350abc2f208379643371e2e25111491b0520a7acbfb43de17e2392bdb712eecca2c95d628833d8a
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: a5dff21053dee87aae002e2213c76b831fad03b7c48ee08b72e654474696a363f52adb9609a200d12dc96ad9c0fc46c0154cf00726f57d153a1f661fea0438d0
         
     | 
| 
         @@ -149,6 +149,8 @@ module TEF 
     | 
|
| 
       149 
149 
     | 
    
         
             
            				@animatable_colors = {}
         
     | 
| 
       150 
150 
     | 
    
         
             
            				@animatable_coordinates = {}
         
     | 
| 
       151 
151 
     | 
    
         | 
| 
      
 152 
     | 
    
         
            +
            				@animatable_pending_strings = [];
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
       152 
154 
     | 
    
         
             
            				self.class.get_attr_list.each do |key, val|
         
     | 
| 
       153 
155 
     | 
    
         
             
            					@animatable_attributes[key] = Value.new(val)
         
     | 
| 
       154 
156 
     | 
    
         
             
            				end
         
     | 
| 
         @@ -206,6 +208,11 @@ module TEF 
     | 
|
| 
       206 
208 
     | 
    
         
             
            				self.death_time = Time.at(0)
         
     | 
| 
       207 
209 
     | 
    
         
             
            			end
         
     | 
| 
       208 
210 
     | 
    
         | 
| 
      
 211 
     | 
    
         
            +
            			def is_dead?
         
     | 
| 
      
 212 
     | 
    
         
            +
            				return false if @death_time.nil?
         
     | 
| 
      
 213 
     | 
    
         
            +
            				return @death_time < Time.now();
         
     | 
| 
      
 214 
     | 
    
         
            +
            			end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
       209 
216 
     | 
    
         
             
            			# Quickly configure this object.
         
     | 
| 
       210 
217 
     | 
    
         
             
            			#
         
     | 
| 
       211 
218 
     | 
    
         
             
            			# This is a convenience function to very quickly and easily
         
     | 
| 
         @@ -225,6 +232,11 @@ module TEF 
     | 
|
| 
       225 
232 
     | 
    
         
             
            				raise ArgumentError, 'Config must be a hash!' unless h.is_a? Hash
         
     | 
| 
       226 
233 
     | 
    
         | 
| 
       227 
234 
     | 
    
         
             
            				h.each do |key, data|
         
     | 
| 
      
 235 
     | 
    
         
            +
            					if(key == :die_after)
         
     | 
| 
      
 236 
     | 
    
         
            +
            						die_in(data.to_f);
         
     | 
| 
      
 237 
     | 
    
         
            +
            						next;
         
     | 
| 
      
 238 
     | 
    
         
            +
            					end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
       228 
240 
     | 
    
         
             
            					value = 	@animatable_attributes[key] ||
         
     | 
| 
       229 
241 
     | 
    
         
             
            								@animatable_colors[key] ||
         
     | 
| 
       230 
242 
     | 
    
         
             
            								@animatable_coordinates[key]
         
     | 
| 
         @@ -245,6 +257,10 @@ module TEF 
     | 
|
| 
       245 
257 
     | 
    
         
             
            				''
         
     | 
| 
       246 
258 
     | 
    
         
             
            			end
         
     | 
| 
       247 
259 
     | 
    
         | 
| 
      
 260 
     | 
    
         
            +
            			def send_string(str)
         
     | 
| 
      
 261 
     | 
    
         
            +
            				@animatable_pending_strings << str;
         
     | 
| 
      
 262 
     | 
    
         
            +
            			end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
       248 
264 
     | 
    
         
             
            			private def all_animatable_attributes
         
     | 
| 
       249 
265 
     | 
    
         
             
            				out =  @animatable_attributes.values
         
     | 
| 
       250 
266 
     | 
    
         
             
            				out += @animatable_coordinates.values.map(&:animatable_attributes)
         
     | 
| 
         @@ -337,6 +353,18 @@ module TEF 
     | 
|
| 
       337 
353 
     | 
    
         | 
| 
       338 
354 
     | 
    
         
             
            				out_elements
         
     | 
| 
       339 
355 
     | 
    
         
             
            			end
         
     | 
| 
      
 356 
     | 
    
         
            +
             
     | 
| 
      
 357 
     | 
    
         
            +
            			def get_setss_strings()
         
     | 
| 
      
 358 
     | 
    
         
            +
            				return [] unless @module_id
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
            				out =  @animatable_pending_strings.map do |str|
         
     | 
| 
      
 361 
     | 
    
         
            +
            					"#{@module_id} #{str}"
         
     | 
| 
      
 362 
     | 
    
         
            +
            				end
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
            				@animatable_pending_strings.clear
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
            				return out;
         
     | 
| 
      
 367 
     | 
    
         
            +
            			end
         
     | 
| 
       340 
368 
     | 
    
         
             
            		end
         
     | 
| 
       341 
369 
     | 
    
         | 
| 
       342 
370 
     | 
    
         
             
            		class Box < Animatable
         
     | 
| 
         @@ -62,6 +62,26 @@ module TEF 
     | 
|
| 
       62 
62 
     | 
    
         
             
            				key
         
     | 
| 
       63 
63 
     | 
    
         
             
            			end
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
      
 65 
     | 
    
         
            +
            			private def internal_set_object(key, new_obj)
         
     | 
| 
      
 66 
     | 
    
         
            +
            				key = clean_key key
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            				@active_animations[key]&.module_id = nil;
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            				if new_obj.nil?
         
     | 
| 
      
 71 
     | 
    
         
            +
            					@pending_deletions[key] = true
         
     | 
| 
      
 72 
     | 
    
         
            +
            					@pending_creations.delete key
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            				elsif new_obj.is_a? Animatable
         
     | 
| 
      
 75 
     | 
    
         
            +
            					new_obj.module_id = key
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            					@active_animations[key] = new_obj
         
     | 
| 
      
 78 
     | 
    
         
            +
            					@pending_creations[key] = new_obj.creation_string
         
     | 
| 
      
 79 
     | 
    
         
            +
            					@pending_deletions.delete key
         
     | 
| 
      
 80 
     | 
    
         
            +
            				else
         
     | 
| 
      
 81 
     | 
    
         
            +
            					raise ArgumentError, 'New animation object is of invalid type'
         
     | 
| 
      
 82 
     | 
    
         
            +
            				end
         
     | 
| 
      
 83 
     | 
    
         
            +
            			end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
       65 
85 
     | 
    
         
             
            			# @return [Animatable] Returns the Animatable with matching key.
         
     | 
| 
       66 
86 
     | 
    
         
             
            			def [](key)
         
     | 
| 
       67 
87 
     | 
    
         
             
            				@active_animations[clean_key key]
         
     | 
| 
         @@ -77,25 +97,28 @@ module TEF 
     | 
|
| 
       77 
97 
     | 
    
         
             
            			#  either replace it with the given {Animatable}, or, if nil was
         
     | 
| 
       78 
98 
     | 
    
         
             
            			#  given, will delete the animation entry.
         
     | 
| 
       79 
99 
     | 
    
         
             
            			def []=(key, new_obj)
         
     | 
| 
       80 
     | 
    
         
            -
            				@animation_mutex.synchronize  
     | 
| 
       81 
     | 
    
         
            -
            					key  
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
      
 100 
     | 
    
         
            +
            				@animation_mutex.synchronize do
         
     | 
| 
      
 101 
     | 
    
         
            +
            					internal_set_object(key, new_obj)
         
     | 
| 
      
 102 
     | 
    
         
            +
            				end
         
     | 
| 
      
 103 
     | 
    
         
            +
            			end
         
     | 
| 
       84 
104 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
      
 105 
     | 
    
         
            +
            			def append_to_set(new_obj, set_no = 200)
         
     | 
| 
      
 106 
     | 
    
         
            +
            				@animation_mutex.synchronize do
         
     | 
| 
      
 107 
     | 
    
         
            +
            					start_no = { S: set_no, M: 0 };
         
     | 
| 
       88 
108 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
            					 
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
      
 109 
     | 
    
         
            +
            					until(@active_animations[clean_key start_no].nil? ||
         
     | 
| 
      
 110 
     | 
    
         
            +
            							@active_animations[clean_key start_no].is_dead?) do
         
     | 
| 
      
 111 
     | 
    
         
            +
            						start_no[:M] += 1
         
     | 
| 
      
 112 
     | 
    
         
            +
            					end
         
     | 
| 
       91 
113 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
            						 
     | 
| 
       94 
     | 
    
         
            -
            						@pending_deletions.delete key
         
     | 
| 
       95 
     | 
    
         
            -
            					else
         
     | 
| 
       96 
     | 
    
         
            -
            						raise ArgumentError, 'New animation object is of invalid type'
         
     | 
| 
      
 114 
     | 
    
         
            +
            					if(start_no[:M] >= 255)
         
     | 
| 
      
 115 
     | 
    
         
            +
            						raise ArgumentError, 'No more space for new animations!'
         
     | 
| 
       97 
116 
     | 
    
         
             
            					end
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            					internal_set_object(start_no, new_obj)
         
     | 
| 
      
 119 
     | 
    
         
            +
            				end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            				new_obj
         
     | 
| 
       99 
122 
     | 
    
         
             
            			end
         
     | 
| 
       100 
123 
     | 
    
         | 
| 
       101 
124 
     | 
    
         
             
            			# Internal function to join an Array of strings and send it onto
         
     | 
| 
         @@ -125,10 +148,11 @@ module TEF 
     | 
|
| 
       125 
148 
     | 
    
         
             
            			# using the main synch time, rather than using relative time.
         
     | 
| 
       126 
149 
     | 
    
         
             
            			private def update_deaths
         
     | 
| 
       127 
150 
     | 
    
         
             
            				death_reconfigs = [];
         
     | 
| 
      
 151 
     | 
    
         
            +
            				deletions = []
         
     | 
| 
       128 
152 
     | 
    
         | 
| 
       129 
     | 
    
         
            -
            				@animation_mutex.synchronize  
     | 
| 
      
 153 
     | 
    
         
            +
            				@animation_mutex.synchronize do
         
     | 
| 
       130 
154 
     | 
    
         
             
            					@active_animations.each do |key, animation|
         
     | 
| 
       131 
     | 
    
         
            -
            						if  
     | 
| 
      
 155 
     | 
    
         
            +
            						if animation.is_dead?
         
     | 
| 
       132 
156 
     | 
    
         
             
            							@pending_deletions[key] = :silent
         
     | 
| 
       133 
157 
     | 
    
         
             
            						end
         
     | 
| 
       134 
158 
     | 
    
         | 
| 
         @@ -137,14 +161,14 @@ module TEF 
     | 
|
| 
       137 
161 
     | 
    
         | 
| 
       138 
162 
     | 
    
         
             
            						death_reconfigs << new_death
         
     | 
| 
       139 
163 
     | 
    
         
             
            					end
         
     | 
| 
       140 
     | 
    
         
            -
            				}
         
     | 
| 
       141 
164 
     | 
    
         | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
            					 
     | 
| 
      
 165 
     | 
    
         
            +
            					@pending_deletions.each do |key, val|
         
     | 
| 
      
 166 
     | 
    
         
            +
            						deletions << "#{key};" unless val == :silent
         
     | 
| 
      
 167 
     | 
    
         
            +
            						@active_animations.delete key
         
     | 
| 
      
 168 
     | 
    
         
            +
            					end
         
     | 
| 
      
 169 
     | 
    
         
            +
            					@pending_deletions = {}
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
       146 
171 
     | 
    
         
             
            				end
         
     | 
| 
       147 
     | 
    
         
            -
            				@pending_deletions = {}
         
     | 
| 
       148 
172 
     | 
    
         | 
| 
       149 
173 
     | 
    
         
             
            				join_and_send('DTIME', death_reconfigs)
         
     | 
| 
       150 
174 
     | 
    
         
             
            				join_and_send('DELETE', deletions)
         
     | 
| 
         @@ -222,11 +246,11 @@ module TEF 
     | 
|
| 
       222 
246 
     | 
    
         
             
            			private def update_colors
         
     | 
| 
       223 
247 
     | 
    
         
             
            				pending_changes = []
         
     | 
| 
       224 
248 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
            				@animation_mutex.synchronize  
     | 
| 
      
 249 
     | 
    
         
            +
            				@animation_mutex.synchronize do
         
     | 
| 
       226 
250 
     | 
    
         
             
            					@active_animations.each do |key, anim|
         
     | 
| 
       227 
251 
     | 
    
         
             
            						pending_changes += anim.get_setc_strings
         
     | 
| 
       228 
252 
     | 
    
         
             
            					end
         
     | 
| 
       229 
     | 
    
         
            -
            				 
     | 
| 
      
 253 
     | 
    
         
            +
            				end
         
     | 
| 
       230 
254 
     | 
    
         | 
| 
       231 
255 
     | 
    
         
             
            				return if pending_changes.empty?
         
     | 
| 
       232 
256 
     | 
    
         
             
            				x_logd "Pending changes are #{pending_changes}"
         
     | 
| 
         @@ -234,6 +258,16 @@ module TEF 
     | 
|
| 
       234 
258 
     | 
    
         
             
            				join_and_send 'CSET', pending_changes
         
     | 
| 
       235 
259 
     | 
    
         
             
            			end
         
     | 
| 
       236 
260 
     | 
    
         | 
| 
      
 261 
     | 
    
         
            +
            			private def update_strings
         
     | 
| 
      
 262 
     | 
    
         
            +
            				@animation_mutex.synchronize do
         
     | 
| 
      
 263 
     | 
    
         
            +
            					@active_animations.values.each do |anim|
         
     | 
| 
      
 264 
     | 
    
         
            +
            						anim.get_setss_strings().each do |str|
         
     | 
| 
      
 265 
     | 
    
         
            +
            							@furcoms.send_message 'SSET', str
         
     | 
| 
      
 266 
     | 
    
         
            +
            						end
         
     | 
| 
      
 267 
     | 
    
         
            +
            					end
         
     | 
| 
      
 268 
     | 
    
         
            +
            				end
         
     | 
| 
      
 269 
     | 
    
         
            +
            			end
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
       237 
271 
     | 
    
         
             
            			# Update tick.
         
     | 
| 
       238 
272 
     | 
    
         
             
            			#
         
     | 
| 
       239 
273 
     | 
    
         
             
            			# Calling this function will send all updates and changes over the
         
     | 
| 
         @@ -252,6 +286,7 @@ module TEF 
     | 
|
| 
       252 
286 
     | 
    
         | 
| 
       253 
287 
     | 
    
         
             
            				update_values
         
     | 
| 
       254 
288 
     | 
    
         
             
            				update_colors
         
     | 
| 
      
 289 
     | 
    
         
            +
            				update_strings
         
     | 
| 
       255 
290 
     | 
    
         
             
            			end
         
     | 
| 
       256 
291 
     | 
    
         
             
            		end
         
     | 
| 
       257 
292 
     | 
    
         
             
            	end
         
     | 
    
        data/lib/tef/Animation/Eyes.rb
    CHANGED
    
    | 
         @@ -8,15 +8,34 @@ module TEF 
     | 
|
| 
       8 
8 
     | 
    
         
             
            		class Eye < Animatable
         
     | 
| 
       9 
9 
     | 
    
         
             
            			animatable_color :outer_color, 0
         
     | 
| 
       10 
10 
     | 
    
         
             
            			animatable_color :inner_color, 1
         
     | 
| 
      
 11 
     | 
    
         
            +
            			animatable_color :blush, 2
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            			animatable_attr :iris_x,  
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            			animatable_attr : 
     | 
| 
       15 
     | 
    
         
            -
            			animatable_attr : 
     | 
| 
       16 
     | 
    
         
            -
            			animatable_attr : 
     | 
| 
      
 13 
     | 
    
         
            +
            			animatable_attr :iris_x, 0x0
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            			animatable_attr :angry, 0x100
         
     | 
| 
      
 16 
     | 
    
         
            +
            			animatable_attr :happy, 0x101
         
     | 
| 
      
 17 
     | 
    
         
            +
            			animatable_attr :heart, 0x102
         
     | 
| 
      
 18 
     | 
    
         
            +
            			animatable_attr :surprised, 0x103
         
     | 
| 
      
 19 
     | 
    
         
            +
            			animatable_attr :shy, 0x104
         
     | 
| 
       17 
20 
     | 
    
         | 
| 
       18 
21 
     | 
    
         
             
            			def initialize()
         
     | 
| 
       19 
22 
     | 
    
         
             
            				super();
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            				@last_mood = :relaxed;
         
     | 
| 
      
 25 
     | 
    
         
            +
            				@animatable_colors[:blush].configure({ target: 0xFF000000, delay_a: 1 });
         
     | 
| 
      
 26 
     | 
    
         
            +
            			end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            			def set_mood(mood, amount: 1)
         
     | 
| 
      
 29 
     | 
    
         
            +
            				if @last_mood != :relaxed
         
     | 
| 
      
 30 
     | 
    
         
            +
            					@animatable_attributes[@last_mood].add = 0;
         
     | 
| 
      
 31 
     | 
    
         
            +
            				end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            				return if mood.nil?
         
     | 
| 
      
 34 
     | 
    
         
            +
            				@last_mood = mood.to_sym;
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            				return if @last_mood == :relaxed
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            				self.configure({ @last_mood.to_sym => { add: amount, dampen: 0.1 }});
         
     | 
| 
       20 
39 
     | 
    
         
             
            			end
         
     | 
| 
       21 
40 
     | 
    
         
             
            		end
         
     | 
| 
       22 
41 
     | 
    
         
             
            	end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'Animatable.rb'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TEF
         
     | 
| 
      
 5 
     | 
    
         
            +
            	module Animation
         
     | 
| 
      
 6 
     | 
    
         
            +
            		class StringDisplay < Animatable
         
     | 
| 
      
 7 
     | 
    
         
            +
            			animatable_color :color, 0
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            			animatable_attr :x, 1
         
     | 
| 
      
 10 
     | 
    
         
            +
            			animatable_attr :y, 2
         
     | 
| 
      
 11 
     | 
    
         
            +
            			animatable_attr :alignment, 3
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            			attr_reader :string
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            			def initialize()
         
     | 
| 
      
 16 
     | 
    
         
            +
            				super();
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            				self.string = "";
         
     | 
| 
      
 19 
     | 
    
         
            +
            			end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            			def string=(new_string)
         
     | 
| 
      
 22 
     | 
    
         
            +
            				return if new_string == @string
         
     | 
| 
      
 23 
     | 
    
         
            +
            				@string = new_string
         
     | 
| 
      
 24 
     | 
    
         
            +
            				
         
     | 
| 
      
 25 
     | 
    
         
            +
            				@animatable_pending_strings = [new_string]
         
     | 
| 
      
 26 
     | 
    
         
            +
            			end
         
     | 
| 
      
 27 
     | 
    
         
            +
            		end
         
     | 
| 
      
 28 
     | 
    
         
            +
            	end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            module TEF
         
     | 
| 
      
 3 
     | 
    
         
            +
            	module Sequencing
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            		# Audacity label reader helper.
         
     | 
| 
      
 6 
     | 
    
         
            +
            		#
         
     | 
| 
      
 7 
     | 
    
         
            +
            		# This class is meant to read in an exported list of Labels, as
         
     | 
| 
      
 8 
     | 
    
         
            +
            		# generated by audacity. It provides proper data conversion and a few
         
     | 
| 
      
 9 
     | 
    
         
            +
            		# convenience functions.
         
     | 
| 
      
 10 
     | 
    
         
            +
            		class AudacityReader
         
     | 
| 
      
 11 
     | 
    
         
            +
            			# Initialize a new reader.
         
     | 
| 
      
 12 
     | 
    
         
            +
            			#
         
     | 
| 
      
 13 
     | 
    
         
            +
            			# This will read in the given file and process it.
         
     | 
| 
      
 14 
     | 
    
         
            +
            			# Note that since Audacity does not export the name of different
         
     | 
| 
      
 15 
     | 
    
         
            +
            			# label tracks, it simply exports all labels, each label track should
         
     | 
| 
      
 16 
     | 
    
         
            +
            			# begin with a label called "TRACK: Name".
         
     | 
| 
      
 17 
     | 
    
         
            +
            			# This serves as a means to separate label tracks.
         
     | 
| 
      
 18 
     | 
    
         
            +
            			#
         
     | 
| 
      
 19 
     | 
    
         
            +
            			# @param [String] file The file to read.
         
     | 
| 
      
 20 
     | 
    
         
            +
            			#  Should be a tab-separated list of start and end time and label name.
         
     | 
| 
      
 21 
     | 
    
         
            +
            			def initialize(file)
         
     | 
| 
      
 22 
     | 
    
         
            +
            				@tracks = Hash.new({});
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            				File.open(file, 'r') do |f|
         
     | 
| 
      
 25 
     | 
    
         
            +
            					current_track = 'default';
         
     | 
| 
      
 26 
     | 
    
         
            +
            					@tracks['default'] = [];
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            					f.each do |line|
         
     | 
| 
      
 29 
     | 
    
         
            +
            						m = /^(?<start>[\.\d]+)\s+(?<stop>[\d\.]+)\s+(?<text>\S.+)/.match line
         
     | 
| 
      
 30 
     | 
    
         
            +
            						next unless m;
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            						if(m[:text] =~ /TRACK:\s*(\S.+)/)
         
     | 
| 
      
 33 
     | 
    
         
            +
            							current_track = $1;
         
     | 
| 
      
 34 
     | 
    
         
            +
            							@tracks[current_track] = [];
         
     | 
| 
      
 35 
     | 
    
         
            +
            						else
         
     | 
| 
      
 36 
     | 
    
         
            +
            							@tracks[current_track] << { start: m[:start].to_f, stop: m[:stop].to_f, text: m[:text] }
         
     | 
| 
      
 37 
     | 
    
         
            +
            						end
         
     | 
| 
      
 38 
     | 
    
         
            +
            					end
         
     | 
| 
      
 39 
     | 
    
         
            +
            				end
         
     | 
| 
      
 40 
     | 
    
         
            +
            			end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            			# @return [Array<{start: Numeric, stop: Numeric, text: String}] The
         
     | 
| 
      
 43 
     | 
    
         
            +
            			#  corresponding list of labels for the given track, or an empty
         
     | 
| 
      
 44 
     | 
    
         
            +
            			#  array if the track did not exist.
         
     | 
| 
      
 45 
     | 
    
         
            +
            			def [](name)
         
     | 
| 
      
 46 
     | 
    
         
            +
            				return [] if @tracks[name].nil?
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            				return @tracks[name]
         
     | 
| 
      
 49 
     | 
    
         
            +
            			end
         
     | 
| 
      
 50 
     | 
    
         
            +
            		end
         
     | 
| 
      
 51 
     | 
    
         
            +
            	end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -33,7 +33,7 @@ module TEF 
     | 
|
| 
       33 
33 
     | 
    
         
             
            			# purposes. Can be:
         
     | 
| 
       34 
34 
     | 
    
         
             
            			# - :uninitialized (right after construction)
         
     | 
| 
       35 
35 
     | 
    
         
             
            			# - :running (after having called setup())
         
     | 
| 
       36 
     | 
    
         
            -
            			# - : 
     | 
| 
      
 36 
     | 
    
         
            +
            			# - :idle (after teardown() was called)
         
     | 
| 
       37 
37 
     | 
    
         
             
            			attr_reader :state
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
            			# Initialize a BaseSequence.
         
     | 
| 
         @@ -50,7 +50,10 @@ module TEF 
     | 
|
| 
       50 
50 
     | 
    
         
             
            				@end_time   ||= options[:end_time];
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
52 
     | 
    
         
             
            				@offset = offset;
         
     | 
| 
       53 
     | 
    
         
            -
            				@slope  = slope;
         
     | 
| 
      
 53 
     | 
    
         
            +
            				@slope  = slope.round(6);
         
     | 
| 
      
 54 
     | 
    
         
            +
            				# Explanation: For some bizarre reason, rounding is necessary
         
     | 
| 
      
 55 
     | 
    
         
            +
            				# to avoid a glitch in the timing math. 6 digits of precision
         
     | 
| 
      
 56 
     | 
    
         
            +
            				# should be precise enough anyways.
         
     | 
| 
       54 
57 
     | 
    
         | 
| 
       55 
58 
     | 
    
         
             
            				@state = :uninitialized
         
     | 
| 
       56 
59 
     | 
    
         | 
| 
         @@ -60,17 +63,29 @@ module TEF 
     | 
|
| 
       60 
63 
     | 
    
         
             
            			def parent_start_time
         
     | 
| 
       61 
64 
     | 
    
         
             
            				@offset + @start_time / @slope
         
     | 
| 
       62 
65 
     | 
    
         
             
            			end
         
     | 
| 
      
 66 
     | 
    
         
            +
            			def parent_end_time
         
     | 
| 
      
 67 
     | 
    
         
            +
            				return nil if @end_time.nil?
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            				@offset + @end_time / @slope
         
     | 
| 
      
 70 
     | 
    
         
            +
            			end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            			def parent_end_time=(new_time)
         
     | 
| 
      
 73 
     | 
    
         
            +
            				if(new_time.nil?)
         
     | 
| 
      
 74 
     | 
    
         
            +
            					@end_time = nil;
         
     | 
| 
      
 75 
     | 
    
         
            +
            					return;
         
     | 
| 
      
 76 
     | 
    
         
            +
            				end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            				@end_time = (new_time - @offset) * @slope;
         
     | 
| 
      
 79 
     | 
    
         
            +
            			end
         
     | 
| 
       63 
80 
     | 
    
         | 
| 
       64 
81 
     | 
    
         
             
            			def setup()
         
     | 
| 
       65 
     | 
    
         
            -
            				 
     | 
| 
      
 82 
     | 
    
         
            +
            				return unless @state == :idle
         
     | 
| 
       66 
83 
     | 
    
         
             
            				@state = :running
         
     | 
| 
       67 
84 
     | 
    
         
             
            			end
         
     | 
| 
       68 
85 
     | 
    
         | 
| 
       69 
86 
     | 
    
         
             
            			def teardown()
         
     | 
| 
       70 
87 
     | 
    
         
             
            				return unless @state == :running
         
     | 
| 
       71 
     | 
    
         
            -
            				@state = : 
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
            				@opts_hash = nil;
         
     | 
| 
      
 88 
     | 
    
         
            +
            				@state = :idle
         
     | 
| 
       74 
89 
     | 
    
         
             
            			end
         
     | 
| 
       75 
90 
     | 
    
         | 
| 
       76 
91 
     | 
    
         
             
            			# Look for the next possible event that this sequence wants to
         
     | 
| 
         @@ -83,32 +98,40 @@ module TEF 
     | 
|
| 
       83 
98 
     | 
    
         
             
            			# @note When using BaseSequence as base class, the user
         
     | 
| 
       84 
99 
     | 
    
         
             
            			#  shall overload {#overload_append_events} rather than this function!
         
     | 
| 
       85 
100 
     | 
    
         
             
            			def append_events(collector)
         
     | 
| 
      
 101 
     | 
    
         
            +
            				return if @state == :uninitialized
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       86 
103 
     | 
    
         
             
            				local_collector = collector.offset_collector(@offset, @slope);
         
     | 
| 
       87 
104 
     | 
    
         | 
| 
      
 105 
     | 
    
         
            +
            				# Return if the collector has events before our start time
         
     | 
| 
       88 
106 
     | 
    
         
             
            				return if local_collector.has_events? &&
         
     | 
| 
       89 
107 
     | 
    
         
             
            							 local_collector.event_time < @start_time
         
     | 
| 
       90 
     | 
    
         
            -
            				return if @state == :torn_down
         
     | 
| 
       91 
108 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
            				if  
     | 
| 
      
 109 
     | 
    
         
            +
            				if !@end_time.nil?
         
     | 
| 
      
 110 
     | 
    
         
            +
            					if @state == :running
         
     | 
| 
      
 111 
     | 
    
         
            +
            	 					local_collector.add_event({
         
     | 
| 
      
 112 
     | 
    
         
            +
            	 						time: [@end_time, local_collector.start_time + 0.01].max,
         
     | 
| 
      
 113 
     | 
    
         
            +
            	 						code: proc { self.teardown() }
         
     | 
| 
      
 114 
     | 
    
         
            +
            	 					})
         
     | 
| 
      
 115 
     | 
    
         
            +
            					end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            					return if local_collector.start_time >= @end_time
         
     | 
| 
      
 118 
     | 
    
         
            +
             				end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            				if @state == :idle
         
     | 
| 
       93 
121 
     | 
    
         
             
            					local_collector.add_event({
         
     | 
| 
       94 
122 
     | 
    
         
             
            						time: [@start_time, local_collector.start_time + 0.01].max,
         
     | 
| 
       95 
123 
     | 
    
         
             
            						code: proc { self.setup() }
         
     | 
| 
       96 
124 
     | 
    
         
             
            					});
         
     | 
| 
       97 
125 
     | 
    
         
             
            				end
         
     | 
| 
       98 
126 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
            				 
     | 
| 
       100 
     | 
    
         
            -
            					overload_append_events(local_collector)
         
     | 
| 
       101 
     | 
    
         
            -
            				end
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
            				if !@end_time.nil?
         
     | 
| 
       104 
     | 
    
         
            -
            					local_collector.add_event({
         
     | 
| 
       105 
     | 
    
         
            -
            						time: @end_time,
         
     | 
| 
       106 
     | 
    
         
            -
            						code: proc { self.teardown() }
         
     | 
| 
       107 
     | 
    
         
            -
            					})
         
     | 
| 
       108 
     | 
    
         
            -
            				end
         
     | 
| 
      
 127 
     | 
    
         
            +
            				overload_append_events(local_collector)
         
     | 
| 
       109 
128 
     | 
    
         
             
            			end
         
     | 
| 
       110 
129 
     | 
    
         | 
| 
       111 
130 
     | 
    
         
             
            			def overload_append_events(_collector) end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            			def destroy!()
         
     | 
| 
      
 133 
     | 
    
         
            +
            				teardown() if @state == :running
         
     | 
| 
      
 134 
     | 
    
         
            +
            			end
         
     | 
| 
       112 
135 
     | 
    
         
             
            		end
         
     | 
| 
       113 
136 
     | 
    
         
             
            	end
         
     | 
| 
       114 
137 
     | 
    
         
             
            end
         
     | 
| 
         @@ -41,8 +41,9 @@ module TEF 
     | 
|
| 
       41 
41 
     | 
    
         
             
            			# This should only be done via {EventCollector#offset_collector}!
         
     | 
| 
       42 
42 
     | 
    
         
             
            			def initialize(parent, total_offset, total_slope)
         
     | 
| 
       43 
43 
     | 
    
         
             
            				@parent = parent
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       44 
45 
     | 
    
         
             
            				@total_offset = total_offset
         
     | 
| 
       45 
     | 
    
         
            -
            				@total_slope  = total_slope
         
     | 
| 
      
 46 
     | 
    
         
            +
            				@total_slope  = total_slope.to_f
         
     | 
| 
       46 
47 
     | 
    
         
             
            			end
         
     | 
| 
       47 
48 
     | 
    
         | 
| 
       48 
49 
     | 
    
         
             
            			# @param [Time, nil] global_time Time to convert
         
     | 
| 
         @@ -50,7 +51,7 @@ module TEF 
     | 
|
| 
       50 
51 
     | 
    
         
             
            			def convert_to_local(global_time)
         
     | 
| 
       51 
52 
     | 
    
         
             
            				return nil if global_time.nil?
         
     | 
| 
       52 
53 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
            				(global_time - @total_offset) * @total_slope
         
     | 
| 
      
 54 
     | 
    
         
            +
            				((global_time - @total_offset) * @total_slope).round(3)
         
     | 
| 
       54 
55 
     | 
    
         
             
            			end
         
     | 
| 
       55 
56 
     | 
    
         | 
| 
       56 
57 
     | 
    
         
             
            			# @param [Numeric, nil] local_time Time (abstract) to convert back
         
     | 
| 
         @@ -59,7 +60,7 @@ module TEF 
     | 
|
| 
       59 
60 
     | 
    
         
             
            			def convert_to_global(local_time)
         
     | 
| 
       60 
61 
     | 
    
         
             
            				return nil if local_time.nil?
         
     | 
| 
       61 
62 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
            				@total_offset + (local_time.to_f / @total_slope)
         
     | 
| 
      
 63 
     | 
    
         
            +
            				@total_offset + (local_time.to_f.round(3) / @total_slope)
         
     | 
| 
       63 
64 
     | 
    
         
             
            			end
         
     | 
| 
       64 
65 
     | 
    
         | 
| 
       65 
66 
     | 
    
         
             
            			# (see EventCollector#start_time)
         
     | 
| 
         @@ -133,8 +134,11 @@ module TEF 
     | 
|
| 
       133 
134 
     | 
    
         
             
            			# and set the event list to [event], else append the event
         
     | 
| 
       134 
135 
     | 
    
         
             
            			# to the event list.
         
     | 
| 
       135 
136 
     | 
    
         
             
            			def add_event(event)
         
     | 
| 
      
 137 
     | 
    
         
            +
            				event = event.clone
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
       136 
139 
     | 
    
         
             
            				return if event[:time] <= @start_time
         
     | 
| 
       137 
140 
     | 
    
         
             
            				return if (!@event_time.nil?) && (event[:time] > @event_time)
         
     | 
| 
      
 141 
     | 
    
         
            +
            				return unless event[:code].is_a? Proc
         
     | 
| 
       138 
142 
     | 
    
         | 
| 
       139 
143 
     | 
    
         
             
            				if (!@event_time.nil?) && (event[:time] == @event_time)
         
     | 
| 
       140 
144 
     | 
    
         
             
            					@current_events << event
         
     | 
| 
         @@ -108,7 +108,15 @@ module TEF 
     | 
|
| 
       108 
108 
     | 
    
         
             
            				loop do
         
     | 
| 
       109 
109 
     | 
    
         
             
            					@sequenceMutex.synchronize do
         
     | 
| 
       110 
110 
     | 
    
         
             
            						@retryCollecting = false
         
     | 
| 
       111 
     | 
    
         
            -
            						@activeSequences.delete_if  
     | 
| 
      
 111 
     | 
    
         
            +
            						@activeSequences.delete_if do |k, seq|
         
     | 
| 
      
 112 
     | 
    
         
            +
            							if(seq.parent_end_time <= Time.now())
         
     | 
| 
      
 113 
     | 
    
         
            +
            								seq.destroy!()
         
     | 
| 
      
 114 
     | 
    
         
            +
            								true
         
     | 
| 
      
 115 
     | 
    
         
            +
            							else
         
     | 
| 
      
 116 
     | 
    
         
            +
            								false
         
     | 
| 
      
 117 
     | 
    
         
            +
            							end
         
     | 
| 
      
 118 
     | 
    
         
            +
            						end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
       112 
120 
     | 
    
         
             
            						@activeSequences.each { |k, seq| seq.append_events @collector }
         
     | 
| 
       113 
121 
     | 
    
         
             
            					end
         
     | 
| 
       114 
122 
     | 
    
         | 
    
        data/lib/tef/Sequencing/Sheet.rb
    CHANGED
    
    | 
         @@ -25,6 +25,11 @@ module TEF 
     | 
|
| 
       25 
25 
     | 
    
         
             
            			#  execution!
         
     | 
| 
       26 
26 
     | 
    
         
             
            			attr_accessor :end_time
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
            			# If set non-nil, determines the timespan after which a given
         
     | 
| 
      
 29 
     | 
    
         
            +
            			# sequence will repeat itself. Does not influence start_time and
         
     | 
| 
      
 30 
     | 
    
         
            +
            			# end_time.
         
     | 
| 
      
 31 
     | 
    
         
            +
            			attr_accessor :repeat_time
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       28 
33 
     | 
    
         
             
            			# @return [Numeric, nil] Tempo of the sheet. Defines the execution
         
     | 
| 
       29 
34 
     | 
    
         
             
            			#  speed in BPM. If left nil, the execution speed of the parent
         
     | 
| 
       30 
35 
     | 
    
         
             
            			#  sheet is used.
         
     | 
| 
         @@ -38,6 +43,7 @@ module TEF 
     | 
|
| 
       38 
43 
     | 
    
         
             
            			# @see SheetSequence#at
         
     | 
| 
       39 
44 
     | 
    
         
             
            			# @see SheetSequence#after
         
     | 
| 
       40 
45 
     | 
    
         
             
            			# @see SheetSequence#play
         
     | 
| 
      
 46 
     | 
    
         
            +
            			attr_reader :fill_block
         
     | 
| 
       41 
47 
     | 
    
         
             
            			attr_reader :setup_block
         
     | 
| 
       42 
48 
     | 
    
         
             
            			attr_reader :teardown_block
         
     | 
| 
       43 
49 
     | 
    
         | 
| 
         @@ -47,13 +53,17 @@ module TEF 
     | 
|
| 
       47 
53 
     | 
    
         
             
            			# {#start_time}, {#end_time} and by supplying at least a
         
     | 
| 
       48 
54 
     | 
    
         
             
            			# {#sequence}
         
     | 
| 
       49 
55 
     | 
    
         
             
            			def initialize()
         
     | 
| 
       50 
     | 
    
         
            -
            				@start_time =  
     | 
| 
      
 56 
     | 
    
         
            +
            				@start_time = nil;
         
     | 
| 
       51 
57 
     | 
    
         
             
            				@end_time = nil;
         
     | 
| 
      
 58 
     | 
    
         
            +
            				@repeat_time = nil;
         
     | 
| 
       52 
59 
     | 
    
         | 
| 
       53 
60 
     | 
    
         
             
            				@tempo = nil
         
     | 
| 
       54 
61 
     | 
    
         | 
| 
      
 62 
     | 
    
         
            +
            				@fill_block = nil;
         
     | 
| 
       55 
63 
     | 
    
         
             
            				@setup_block = nil;
         
     | 
| 
       56 
64 
     | 
    
         
             
            				@teardown_block = nil;
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            				yield(self) if(block_given?)
         
     | 
| 
       57 
67 
     | 
    
         
             
            			end
         
     | 
| 
       58 
68 
     | 
    
         | 
| 
       59 
69 
     | 
    
         
             
            			# Configure a block to call when setting up the {SheetSequence}.
         
     | 
| 
         @@ -64,10 +74,14 @@ module TEF 
     | 
|
| 
       64 
74 
     | 
    
         
             
            			# @see SheetSequence#at
         
     | 
| 
       65 
75 
     | 
    
         
             
            			# @see SheetSequence#after
         
     | 
| 
       66 
76 
     | 
    
         
             
            			# @see SheetSequence#play
         
     | 
| 
       67 
     | 
    
         
            -
            			def  
     | 
| 
      
 77 
     | 
    
         
            +
            			def setup(&block)
         
     | 
| 
       68 
78 
     | 
    
         
             
            				@setup_block = block;
         
     | 
| 
       69 
79 
     | 
    
         
             
            			end
         
     | 
| 
       70 
80 
     | 
    
         | 
| 
      
 81 
     | 
    
         
            +
            			def notes(&block)
         
     | 
| 
      
 82 
     | 
    
         
            +
            				@fill_block = block;
         
     | 
| 
      
 83 
     | 
    
         
            +
            			end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
       71 
85 
     | 
    
         
             
            			# Configure the block to call when the {SheetSequence} is about to
         
     | 
| 
       72 
86 
     | 
    
         
             
            			# be torn down. Use this to stop or delete any resources allocated
         
     | 
| 
       73 
87 
     | 
    
         
             
            			# to the sheet.
         
     | 
| 
         @@ -13,7 +13,6 @@ module TEF 
     | 
|
| 
       13 
13 
     | 
    
         
             
            		# Think of the {Sheet} as being the script for a play or movie, while
         
     | 
| 
       14 
14 
     | 
    
         
             
            		# the {SheetSequence} has the job of actually performing everything.
         
     | 
| 
       15 
15 
     | 
    
         
             
            		class SheetSequence < BaseSequence
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
16 
     | 
    
         
             
            			# Initialize a SheetSequence.
         
     | 
| 
       18 
17 
     | 
    
         
             
            			#
         
     | 
| 
       19 
18 
     | 
    
         
             
            			# This is mostly done via {Player#[]=} by passing a {Sheet}.
         
     | 
| 
         @@ -24,36 +23,43 @@ module TEF 
     | 
|
| 
       24 
23 
     | 
    
         
             
            			# The user may also call {#at} and {#after} manually to add additional
         
     | 
| 
       25 
24 
     | 
    
         
             
            			# events.
         
     | 
| 
       26 
25 
     | 
    
         
             
            			def initialize(offset, slope, **options)
         
     | 
| 
       27 
     | 
    
         
            -
            				super(offset, slope, **options);
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
26 
     | 
    
         
             
            				raise ArgumentError, 'Sheet must be supplied!' unless options[:sheet]
         
     | 
| 
       30 
27 
     | 
    
         | 
| 
       31 
28 
     | 
    
         
             
            				@sheet = options[:sheet]
         
     | 
| 
       32 
29 
     | 
    
         | 
| 
       33 
30 
     | 
    
         
             
            				if @sheet.tempo
         
     | 
| 
       34 
     | 
    
         
            -
            					 
     | 
| 
      
 31 
     | 
    
         
            +
            					slope *= (@sheet.tempo / (60.to_f * (options[:top_slope] || 1)))
         
     | 
| 
       35 
32 
     | 
    
         
             
            				end
         
     | 
| 
       36 
33 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
            				 
     | 
| 
       38 
     | 
    
         
            -
            				@end_time = @sheet.end_time
         
     | 
| 
      
 34 
     | 
    
         
            +
            				super(offset, slope, **options);
         
     | 
| 
       39 
35 
     | 
    
         | 
| 
       40 
36 
     | 
    
         
             
            				@notes = []
         
     | 
| 
       41 
37 
     | 
    
         
             
            				@latest_note_time = nil;
         
     | 
| 
       42 
38 
     | 
    
         | 
| 
       43 
39 
     | 
    
         
             
            				@subprograms = []
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
40 
     | 
    
         
             
            				@active_music = []
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            				@start_time = @sheet.start_time
         
     | 
| 
      
 43 
     | 
    
         
            +
            				@end_time = @sheet.end_time
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            				if block = @sheet.fill_block
         
     | 
| 
      
 46 
     | 
    
         
            +
            					instance_exec(@opts_hash, &block)
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            					@start_time ||= @notes[0]&.dig(:time) || 0;
         
     | 
| 
      
 49 
     | 
    
         
            +
            					@end_time	||= @notes[-1]&.dig(:time) || 0;
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            					@state = :idle;
         
     | 
| 
      
 52 
     | 
    
         
            +
            				end
         
     | 
| 
       46 
53 
     | 
    
         
             
            			end
         
     | 
| 
       47 
54 
     | 
    
         | 
| 
       48 
55 
     | 
    
         
             
            			def setup()
         
     | 
| 
      
 56 
     | 
    
         
            +
            				return unless @state == :idle
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
       49 
58 
     | 
    
         
             
            				super();
         
     | 
| 
       50 
59 
     | 
    
         | 
| 
       51 
60 
     | 
    
         
             
            				if block = @sheet.setup_block
         
     | 
| 
       52 
     | 
    
         
            -
            					instance_exec(@opts_hash 
     | 
| 
      
 61 
     | 
    
         
            +
            					instance_exec(@opts_hash, &block)
         
     | 
| 
       53 
62 
     | 
    
         
             
            				end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            				return unless @end_time.nil?
         
     | 
| 
       56 
     | 
    
         
            -
            				@end_time = (@notes[-1]&.dig(:time) || 0) + 0.01
         
     | 
| 
       57 
63 
     | 
    
         
             
            			end
         
     | 
| 
       58 
64 
     | 
    
         | 
| 
       59 
65 
     | 
    
         
             
            			def teardown()
         
     | 
| 
         @@ -65,12 +71,18 @@ module TEF 
     | 
|
| 
       65 
71 
     | 
    
         | 
| 
       66 
72 
     | 
    
         
             
            				@subprograms.each(&:teardown)
         
     | 
| 
       67 
73 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
            				@active_music.each  
     | 
| 
      
 74 
     | 
    
         
            +
            				@active_music.each do |pid|
         
     | 
| 
      
 75 
     | 
    
         
            +
            					self.kill pid
         
     | 
| 
      
 76 
     | 
    
         
            +
            				end
         
     | 
| 
       69 
77 
     | 
    
         | 
| 
       70 
     | 
    
         
            -
            				 
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
            				super();
         
     | 
| 
      
 79 
     | 
    
         
            +
            			end
         
     | 
| 
       72 
80 
     | 
    
         | 
| 
      
 81 
     | 
    
         
            +
            			def destroy!()
         
     | 
| 
       73 
82 
     | 
    
         
             
            				super();
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            				@notes = nil;
         
     | 
| 
      
 85 
     | 
    
         
            +
            				@subprograms.each(&:destroy!)
         
     | 
| 
       74 
86 
     | 
    
         
             
            			end
         
     | 
| 
       75 
87 
     | 
    
         | 
| 
       76 
88 
     | 
    
         
             
            			# Insert an event or subsheet into the event list.
         
     | 
| 
         @@ -91,6 +103,14 @@ module TEF 
     | 
|
| 
       91 
103 
     | 
    
         
             
            			# the {Sheet#teardown} block. Sub-Sequences as well as notes
         
     | 
| 
       92 
104 
     | 
    
         
             
            			# played by {#play} are automatically torn down.
         
     | 
| 
       93 
105 
     | 
    
         
             
            			def at(time, **options, &block)
         
     | 
| 
      
 106 
     | 
    
         
            +
            				time = time.to_f
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            				if repeat_time = @sheet.repeat_time
         
     | 
| 
      
 109 
     | 
    
         
            +
            					time = time % repeat_time
         
     | 
| 
      
 110 
     | 
    
         
            +
            				end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            				time = time.round(3);
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
       94 
114 
     | 
    
         
             
            				@latest_note_time = time;
         
     | 
| 
       95 
115 
     | 
    
         | 
| 
       96 
116 
     | 
    
         
             
            				options[:sequence] = SheetSequence if options[:sheet]
         
     | 
| 
         @@ -101,6 +121,10 @@ module TEF 
     | 
|
| 
       101 
121 
     | 
    
         | 
| 
       102 
122 
     | 
    
         
             
            					prog = prog.new(time, options[:slope], **options)
         
     | 
| 
       103 
123 
     | 
    
         | 
| 
      
 124 
     | 
    
         
            +
            					if e_time = options[:end_time]
         
     | 
| 
      
 125 
     | 
    
         
            +
            						prog.parent_end_time = e_time;
         
     | 
| 
      
 126 
     | 
    
         
            +
            					end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
       104 
128 
     | 
    
         
             
            					i = @subprograms.bsearch_index { |s| s.parent_start_time > prog.parent_start_time }
         
     | 
| 
       105 
129 
     | 
    
         
             
            					@subprograms.insert((i || -1), prog);
         
     | 
| 
       106 
130 
     | 
    
         | 
| 
         @@ -138,7 +162,7 @@ module TEF 
     | 
|
| 
       138 
162 
     | 
    
         | 
| 
       139 
163 
     | 
    
         
             
            				Thread.new do
         
     | 
| 
       140 
164 
     | 
    
         
             
            					@active_music << play_pid
         
     | 
| 
       141 
     | 
    
         
            -
            					Process.wait( 
     | 
| 
      
 165 
     | 
    
         
            +
            					Process.wait(play_pid)
         
     | 
| 
       142 
166 
     | 
    
         
             
            					@active_music.delete play_pid
         
     | 
| 
       143 
167 
     | 
    
         
             
            				end
         
     | 
| 
       144 
168 
     | 
    
         | 
| 
         @@ -148,22 +172,36 @@ module TEF 
     | 
|
| 
       148 
172 
     | 
    
         
             
            			# Shorthand to kill
         
     | 
| 
       149 
173 
     | 
    
         
             
            			def kill(pid)
         
     | 
| 
       150 
174 
     | 
    
         
             
            				Process.kill('QUIT', pid);
         
     | 
| 
      
 175 
     | 
    
         
            +
            			rescue Errno::ESRCH
         
     | 
| 
      
 176 
     | 
    
         
            +
            				return false
         
     | 
| 
       151 
177 
     | 
    
         
             
            			end
         
     | 
| 
       152 
178 
     | 
    
         | 
| 
       153 
179 
     | 
    
         
             
            			private def overload_append_events(collector)
         
     | 
| 
       154 
180 
     | 
    
         
             
            				i = 0
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
            					 
     | 
| 
       158 
     | 
    
         
            -
            					 
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
            					 
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            				if(@sheet.repeat_time)
         
     | 
| 
      
 183 
     | 
    
         
            +
            					repeat_cycle = (collector.start_time / @sheet.repeat_time).floor
         
     | 
| 
      
 184 
     | 
    
         
            +
            					repeat_shift_time = repeat_cycle * @sheet.repeat_time
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            					# This will wrap around and thusly implement the repeating nature
         
     | 
| 
      
 187 
     | 
    
         
            +
            					# of this sequence
         
     | 
| 
      
 188 
     | 
    
         
            +
            					collector = collector.offset_collector(repeat_shift_time, 1);
         
     | 
| 
      
 189 
     | 
    
         
            +
            				end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
            				@subprograms.each do |program|
         
     | 
| 
      
 192 
     | 
    
         
            +
            					if(collector.event_time &&
         
     | 
| 
      
 193 
     | 
    
         
            +
            						(collector.event_time < program.parent_start_time))
         
     | 
| 
      
 194 
     | 
    
         
            +
            						next
         
     | 
| 
      
 195 
     | 
    
         
            +
            					end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
            					program.append_events collector
         
     | 
| 
      
 198 
     | 
    
         
            +
            				end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
            				return if @notes.empty?
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            				if(@sheet.repeat_time)
         
     | 
| 
      
 203 
     | 
    
         
            +
            					if(collector.start_time >= @notes[-1][:time])
         
     | 
| 
      
 204 
     | 
    
         
            +
            						collector = collector.offset_collector(@sheet.repeat_time, 1);
         
     | 
| 
       167 
205 
     | 
    
         
             
            					end
         
     | 
| 
       168 
206 
     | 
    
         
             
            				end
         
     | 
| 
       169 
207 
     | 
    
         | 
| 
         @@ -172,13 +210,9 @@ module TEF 
     | 
|
| 
       172 
210 
     | 
    
         | 
| 
       173 
211 
     | 
    
         
             
            				note_time = @notes[i][:time]
         
     | 
| 
       174 
212 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
            				 
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
            					collector.add_event  
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
            					next_note = @notes[i += 1]
         
     | 
| 
       180 
     | 
    
         
            -
            					break unless next_note
         
     | 
| 
       181 
     | 
    
         
            -
            					break if next_note[:time] != note_time
         
     | 
| 
      
 213 
     | 
    
         
            +
            				until (note = @notes[i])&.dig(:time) != note_time
         
     | 
| 
      
 214 
     | 
    
         
            +
            					i += 1;
         
     | 
| 
      
 215 
     | 
    
         
            +
            					collector.add_event note
         
     | 
| 
       182 
216 
     | 
    
         
             
            				end
         
     | 
| 
       183 
217 
     | 
    
         
             
            			end
         
     | 
| 
       184 
218 
     | 
    
         
             
            		end
         
     | 
    
        data/lib/tef/animation.rb
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         | 
| 
       2 
2 
     | 
    
         
             
            require_relative 'Animation/Animation_Handler.rb'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require_relative 'Animation/Eyes.rb'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'Animation/String.rb'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            require_relative 'ParameterStack/Stack.rb'
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
         @@ -9,3 +10,5 @@ require_relative 'ProgramSelection/SequenceCollection.rb' 
     | 
|
| 
       9 
10 
     | 
    
         
             
            require_relative 'ProgramSelection/SoundCollection.rb'
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
            require_relative 'Sequencing/SequencePlayer.rb'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            require_relative 'Sequencing/AudacityLabelReader.rb'
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: tef-animation
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - TheSystem
         
     | 
| 
         @@ -65,6 +65,7 @@ files: 
     | 
|
| 
       65 
65 
     | 
    
         
             
            - lib/tef/Animation/Color.rb
         
     | 
| 
       66 
66 
     | 
    
         
             
            - lib/tef/Animation/Coordinate.rb
         
     | 
| 
       67 
67 
     | 
    
         
             
            - lib/tef/Animation/Eyes.rb
         
     | 
| 
      
 68 
     | 
    
         
            +
            - lib/tef/Animation/String.rb
         
     | 
| 
       68 
69 
     | 
    
         
             
            - lib/tef/Animation/Value.rb
         
     | 
| 
       69 
70 
     | 
    
         
             
            - lib/tef/ParameterStack/Override.rb
         
     | 
| 
       70 
71 
     | 
    
         
             
            - lib/tef/ParameterStack/Stack.rb
         
     | 
| 
         @@ -72,6 +73,7 @@ files: 
     | 
|
| 
       72 
73 
     | 
    
         
             
            - lib/tef/ProgramSelection/ProgramSelector.rb
         
     | 
| 
       73 
74 
     | 
    
         
             
            - lib/tef/ProgramSelection/SequenceCollection.rb
         
     | 
| 
       74 
75 
     | 
    
         
             
            - lib/tef/ProgramSelection/SoundCollection.rb
         
     | 
| 
      
 76 
     | 
    
         
            +
            - lib/tef/Sequencing/AudacityLabelReader.rb
         
     | 
| 
       75 
77 
     | 
    
         
             
            - lib/tef/Sequencing/BaseSequence.rb
         
     | 
| 
       76 
78 
     | 
    
         
             
            - lib/tef/Sequencing/EventCollector.rb
         
     | 
| 
       77 
79 
     | 
    
         
             
            - lib/tef/Sequencing/SequencePlayer.rb
         
     | 
| 
         @@ -97,8 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       97 
99 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       98 
100 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       99 
101 
     | 
    
         
             
            requirements: []
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
            rubygems_version: 2.5.2.1
         
     | 
| 
      
 102 
     | 
    
         
            +
            rubygems_version: 3.0.6
         
     | 
| 
       102 
103 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       103 
104 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       104 
105 
     | 
    
         
             
            summary: TEF Animation and Sequencing code
         
     |