Commit 7b8cdd87995abd72ff8f8b45e3e6c9ecd1ccf1e1
1 parent
b10df488
Exists in
ui
Remake quase completo
Showing
7 changed files
with
338 additions
and
365 deletions
Show diff stats
Assets/Scripts/Player Manager/AnimationReference.cs
... | ... | @@ -21,13 +21,15 @@ public class AnimationReference { |
21 | 21 | |
22 | 22 | public AnimationReference(string name, string subtitle, short type) |
23 | 23 | : this(name, subtitle, type, 0F) { |
24 | - this.speed = context.getSpeedByType(Subtitle.TYPE_WORD); | |
24 | + this.speed = context.subtitles.getSpeedByType(Subtitle.TYPE_WORD); | |
25 | 25 | } |
26 | 26 | |
27 | - public void play() | |
27 | + public AnimationReference play() | |
28 | 28 | { |
29 | 29 | this.state = context.COMPONENT_ANIMATION.CrossFadeQueued(this.name, context.fadeLength, QueueMode.CompleteOthers); |
30 | 30 | this.state.speed = this.speed; |
31 | + | |
32 | + return this; | |
31 | 33 | } |
32 | 34 | |
33 | 35 | } |
34 | 36 | \ No newline at end of file | ... | ... |
Assets/Scripts/Player Manager/GenericPlayerManager.cs
... | ... | @@ -10,15 +10,17 @@ using UnityEngine.UI; |
10 | 10 | |
11 | 11 | public abstract class GenericPlayerManager : MonoBehaviour { |
12 | 12 | |
13 | - public static GenericPlayerManager context; | |
13 | + private System.Object LOCKER_PLAY = new System.Object(); | |
14 | + private System.Object LOCKER_LOAD = new System.Object(); | |
15 | + private System.Object LOCKER_PARALLEL_LOAD = new System.Object(); | |
14 | 16 | |
15 | - private const string DEFAULT_ANIMATION = "_default"; | |
17 | + private string RA_LOCKER_LOADANDPLAY = "LoadAndPlay"; | |
18 | + private string RA_LOCKER_PLAY = "Play"; | |
16 | 19 | |
17 | - public float fadeLength = 0.6F; | |
18 | - public string gloss = ""; | |
20 | + public static GenericPlayerManager context; | |
19 | 21 | |
20 | - // Vetor usado para quebrar a glosa | |
21 | - private static String[] stringPos = { DEFAULT_ANIMATION }; | |
22 | + public string DEFAULT_ANIMATION = "_default"; | |
23 | + public float fadeLength = 0.6F; | |
22 | 24 | |
23 | 25 | // Referencia para o avatar |
24 | 26 | private GameObject AVATAR; |
... | ... | @@ -32,27 +34,26 @@ public abstract class GenericPlayerManager : MonoBehaviour { |
32 | 34 | public HashSet<string> nonexistentAssetBundles = new HashSet<string>(); |
33 | 35 | |
34 | 36 | private Queue<Gloss> glossQueue = new Queue<Gloss>(); |
37 | + private Gloss lastGloss = null; | |
35 | 38 | |
36 | 39 | // Sinais de intervalo de animações: não sinaliza reprodução na UI |
37 | - private HashSet<string> intervalAnimations = new HashSet<string>(); | |
40 | + public HashSet<string> intervalAnimations = new HashSet<string>(); | |
38 | 41 | // Sinais ignorados na apresentação de legenda |
39 | - private HashSet<string> flags = new HashSet<string>(); | |
42 | + public HashSet<string> flags = new HashSet<string>(); | |
40 | 43 | |
41 | - // True quando está reproduzindo alguma animação de intervalo | |
42 | - private volatile bool playingIntervalAnimation = false; | |
43 | 44 | // True quando está na função LoadAndPlay |
44 | - private volatile bool loading = false; | |
45 | + public volatile bool loading = false; | |
45 | 46 | // True quando está reproduzindo qualquer animação |
46 | - private volatile bool playing = false; | |
47 | + public volatile bool playing = false; | |
47 | 48 | // True quando é chamada a função de pausa |
48 | - private volatile bool paused = false; | |
49 | + public volatile bool paused = false; | |
49 | 50 | // True quando é possível repetir |
50 | - private volatile bool repeatable = false; | |
51 | + public volatile bool repeatable = false; | |
51 | 52 | |
52 | 53 | // Gerenciador de animações de intervalo |
53 | 54 | public RandomAnimations randomAnimations; |
54 | 55 | // Gerenciados de legendas |
55 | - private Subtitle subtitles = null; | |
56 | + public Subtitle subtitles = null; | |
56 | 57 | |
57 | 58 | public virtual void Start() |
58 | 59 | { |
... | ... | @@ -81,11 +82,10 @@ public abstract class GenericPlayerManager : MonoBehaviour { |
81 | 82 | this.intervalAnimations.Add(DEFAULT_ANIMATION); |
82 | 83 | } |
83 | 84 | |
84 | - public bool isPlayingIntervalAnimation() { return playingIntervalAnimation; } | |
85 | - public bool isLoading() { return loading; } | |
86 | - public bool isPlaying() { return playing; } | |
87 | - public bool isPaused() { return paused; } | |
88 | - public bool isRepeatable() { return ! String.IsNullOrEmpty(gloss); } | |
85 | + public bool isLoading() { return this.loading; } | |
86 | + public bool isPlaying() { return this.playing; } | |
87 | + public bool isPaused() { return this.paused; } | |
88 | + public bool isRepeatable() { return this.lastGloss != null; } | |
89 | 89 | |
90 | 90 | /* Configura as animações de intervalo */ |
91 | 91 | public void setRandomAnimations(string[] intervalAnimations) |
... | ... | @@ -102,67 +102,46 @@ public abstract class GenericPlayerManager : MonoBehaviour { |
102 | 102 | // Define a velocidade das animacões com base no slider da GUI |
103 | 103 | public void setSlider(float sliderPosition) |
104 | 104 | { |
105 | - subtitles.SliderPosition = sliderPosition; | |
106 | - subtitles.updateWordSpeed(); | |
107 | - subtitles.updateLetterSpeed(); | |
108 | - subtitles.updateNumberSpeed(); | |
105 | + this.subtitles.SliderPosition = sliderPosition; | |
106 | + this.subtitles.updateWordSpeed(); | |
107 | + this.subtitles.updateLetterSpeed(); | |
108 | + this.subtitles.updateNumberSpeed(); | |
109 | 109 | |
110 | - if ( ! paused) lock (animQueue) | |
111 | - { | |
112 | - foreach (AnimationReference reference in animQueue) | |
113 | - if (reference.type != Subtitle.TYPE_NONE && reference.state != null) | |
114 | - reference.state.speed = getSpeedByType(reference.type); | |
115 | - } | |
116 | - } | |
117 | - | |
118 | - public float getSpeedByType(short type) | |
119 | - { | |
120 | - switch (type) | |
110 | + if ( ! this.paused) lock (this.glossQueue) | |
121 | 111 | { |
122 | - case Subtitle.TYPE_WORD: return subtitles.WordSpeed; | |
123 | - case Subtitle.TYPE_LETTER: return subtitles.LetterSpeed; | |
124 | - case Subtitle.TYPE_NUMBER: return subtitles.NumberSpeed; | |
112 | + this.glossQueue.Peek().updateSpeed(); | |
125 | 113 | } |
126 | - | |
127 | - return 2F; | |
128 | 114 | } |
129 | 115 | |
130 | - | |
131 | - public void stopAll() | |
116 | + public void stop() | |
132 | 117 | { |
133 | - foreach (Gloss gloss in this.glossQueue) gloss.destroy(); | |
134 | - gloss.Clear(); | |
135 | - | |
136 | - //StopCoroutine("loadAndPlay"); | |
137 | - this.randomAnimations.unlockFor("loadAndPlay"); | |
138 | - loading = false; | |
139 | - | |
140 | - stopAnimations(); | |
141 | - } | |
142 | - | |
143 | - public void stopAnimations() | |
144 | - { | |
145 | - StopCoroutine("handleStates"); | |
146 | - this.randomAnimations.unlockFor("handleStates"); | |
147 | - | |
118 | + StopCoroutine("LoadAndPlay"); | |
119 | + this.randomAnimations.unlockFor(RA_LOCKER_LOADANDPLAY); | |
120 | + this.randomAnimations.unlockFor(RA_LOCKER_PLAY); | |
148 | 121 | this.subtitles.setText(""); |
149 | 122 | |
150 | - lock (animQueue) { animQueue.Clear(); } | |
151 | - | |
152 | - COMPONENT_ANIMATION.Stop(); | |
153 | - COMPONENT_ANIMATION.CrossFade(DEFAULT_ANIMATION, fadeLength, PlayMode.StopAll); | |
123 | + foreach (Gloss gloss in this.glossQueue) gloss.destroy(); | |
124 | + this.glossQueue.Clear(); | |
154 | 125 | |
155 | - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", 2F); | |
126 | + this.COMPONENT_ANIMATION.Stop(); | |
127 | + this.COMPONENT_ANIMATION.CrossFade(DEFAULT_ANIMATION, fadeLength, PlayMode.StopAll); | |
128 | + //this.COMPONENT_ANIMATION.CrossFadeQueued(DEFAULT_ANIMATION, context.fadeLength, QueueMode.CompleteOthers); | |
156 | 129 | |
157 | - playing = false; | |
158 | - paused = false; | |
130 | + this.playing = false; | |
131 | + this.paused = false; | |
132 | + this.loading = false; | |
159 | 133 | onPlayingStateChange(); |
160 | 134 | } |
161 | 135 | |
162 | 136 | public void repeat() |
163 | 137 | { |
164 | - stopAll(); | |
165 | - play(this.gloss, true, true, true); | |
138 | + stop(); | |
139 | + playLast(); | |
140 | + } | |
141 | + | |
142 | + public void playLast() { | |
143 | + StopCoroutine("Play"); | |
144 | + StartCoroutine("LoadAndPlay"); | |
166 | 145 | } |
167 | 146 | |
168 | 147 | |
... | ... | @@ -174,26 +153,20 @@ public abstract class GenericPlayerManager : MonoBehaviour { |
174 | 153 | */ |
175 | 154 | public abstract WWW loadAssetBundle(string aniName); |
176 | 155 | |
177 | - | |
178 | 156 | /** |
179 | 157 | * Listen to changes in the playing status. |
180 | 158 | */ |
181 | - protected abstract void onPlayingStateChange(); | |
159 | + public abstract void onPlayingStateChange(); | |
160 | + | |
182 | 161 | |
183 | 162 | public void setPauseState(bool paused) |
184 | 163 | { |
185 | 164 | if (this.paused != paused) |
186 | 165 | { |
187 | 166 | this.paused = paused; |
188 | - | |
189 | - lock (animQueue) | |
190 | - { | |
191 | - foreach (AnimationReference reference in animQueue) | |
192 | - if (reference.state != null) | |
193 | - reference.state.speed = paused ? 0F : getSpeedByType(reference.type); | |
194 | - } | |
195 | - | |
196 | 167 | onPlayingStateChange(); |
168 | + | |
169 | + this.lastGloss.setPlayingState( ! paused); | |
197 | 170 | } |
198 | 171 | } |
199 | 172 | |
... | ... | @@ -201,263 +174,84 @@ public abstract class GenericPlayerManager : MonoBehaviour { |
201 | 174 | setPauseState( ! this.paused); |
202 | 175 | } |
203 | 176 | |
204 | - public bool play() | |
205 | - { | |
206 | - if (playing) | |
207 | - setPauseState( ! paused); | |
208 | - else | |
209 | - return play(this.gloss, true, true, true); | |
210 | - | |
211 | - return true; | |
212 | - } | |
213 | - | |
214 | - public bool play(string gloss) | |
215 | - { | |
216 | - this.gloss = gloss; | |
217 | - return this.play(); | |
218 | - } | |
219 | - | |
220 | - public bool playNext(string gloss) { | |
221 | - this.gloss = gloss; | |
222 | - return play(gloss, true, false, true); | |
223 | - } | |
224 | - | |
225 | - private System.Object playLocker = new System.Object(); | |
226 | - | |
227 | 177 | public bool play(string gloss, bool stopLoading, bool stopPlaying, bool forceLoading) |
228 | 178 | { |
229 | - lock (this.playLocker) | |
179 | + System.Threading.Thread.Sleep(2000); | |
180 | + | |
181 | + lock (LOCKER_PLAY) | |
230 | 182 | { |
231 | 183 | if (this.loading) |
232 | 184 | { |
233 | 185 | if (stopLoading) |
234 | - stopAll(); | |
186 | + stop(); | |
235 | 187 | else |
236 | 188 | return false; |
237 | 189 | } |
238 | 190 | else if (this.playing) |
239 | 191 | { |
240 | 192 | if (stopPlaying) |
241 | - stopAnimations(); | |
193 | + stop(); | |
242 | 194 | |
243 | 195 | else if ( ! forceLoading) |
244 | 196 | return false; |
245 | 197 | } |
198 | + | |
199 | + lock (this.glossQueue) { this.glossQueue.Enqueue(new Gloss(gloss)); Debug.Log("Added (" + glossQueue.Count + ")"); } | |
200 | + StartCoroutine("LoadAndPlay"); | |
246 | 201 | } |
247 | 202 | |
248 | - StartCoroutine("loadAndPlay", gloss) | |
249 | 203 | return true; |
250 | 204 | } |
251 | 205 | |
252 | - private System.Object loadingLocker = new System.Object(); | |
253 | - | |
254 | - private IEnumerator loadAndPlay(string glossText) | |
206 | + private IEnumerator LoadAndPlay() | |
255 | 207 | { |
256 | - lock (this.loadingLocker) | |
208 | + lock (LOCKER_LOAD) | |
257 | 209 | { |
258 | - Gloss gloss = new Gloss(glossText); | |
259 | - this.glossQueue.Add(gloss); | |
260 | - | |
261 | - if ( ! gloss.loaded) | |
262 | - yield return gloss.load(); | |
263 | - | |
264 | - yield return gloss.handle(); | |
265 | - | |
210 | + Debug.Log("LoadAndPlay"); | |
266 | 211 | |
267 | - | |
268 | - | |
269 | - | |
270 | - | |
271 | - | |
272 | - this.randomAnimations.lockFor("loadAndPlay"); | |
212 | + this.randomAnimations.lockFor(RA_LOCKER_LOADANDPLAY); | |
273 | 213 | this.loading = true; |
274 | - // onPlayingStateChange(); | |
275 | - | |
276 | - string lastAnimationSubtitle = ""; | |
277 | - bool spelled = false; | |
214 | + onPlayingStateChange(); | |
278 | 215 | |
279 | - // Default | |
280 | - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", 2F); | |
216 | + lock (this.glossQueue) { this.lastGloss = this.glossQueue.Dequeue(); } | |
281 | 217 | |
282 | - if ( ! this.playing) | |
283 | - StartCoroutine("handleStates"); | |
218 | + Debug.Log(this.lastGloss.text); | |
284 | 219 | |
285 | - stringPos = gloss.Split(' '); | |
286 | - | |
287 | - foreach (string aniName in stringPos) | |
288 | - { | |
289 | - try { | |
290 | - if (String.IsNullOrEmpty(aniName)) continue; | |
291 | - } catch (Exception e) { | |
292 | - UnityEngine.Debug.Log(e + " :: NotNullNotEmpty"); | |
293 | - } | |
294 | - | |
295 | - bool nonexistent = nonexistentAssetBundles.Contains(aniName); | |
296 | - bool loaded = loadedAssetBundles.Contains(aniName); | |
297 | - | |
298 | - if ( ! nonexistent && ! loaded) | |
299 | - { | |
300 | - // Função loadAssetBundle é definida pela classe filha | |
301 | - WWW www = loadAssetBundle(aniName); | |
302 | - | |
303 | - if (www != null) | |
304 | - { | |
305 | - yield return www; | |
306 | - | |
307 | - AssetBundle bundle = null; | |
308 | - | |
309 | - if (www.error == null) | |
310 | - bundle = www.assetBundle; | |
311 | - | |
312 | - if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) | |
313 | - { | |
314 | - AnimationClip aniClip = bundle.mainAsset as AnimationClip; | |
315 | - bundle.Unload(false); | |
316 | - | |
317 | - if (aniClip) | |
318 | - { | |
319 | - COMPONENT_ANIMATION.AddClip(aniClip, aniName); | |
320 | - | |
321 | - loadedAssetBundles.Add(aniName); | |
322 | - loaded = true; | |
323 | - } | |
324 | - else UnityEngine.Debug.Log ("Sinal \"" + aniName + "\" não carregado corretamente."); | |
325 | - } | |
326 | - } | |
327 | - } | |
328 | - | |
329 | - // Reproduz palavra | |
330 | - if (loaded) | |
331 | - { | |
332 | - if (spelled) | |
333 | - { | |
334 | - // Default | |
335 | - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle); | |
336 | - spelled = false; | |
337 | - } | |
338 | - | |
339 | - if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) | |
340 | - { | |
341 | - lastAnimationSubtitle = ""; | |
342 | - playAnimation(Subtitle.TYPE_WORD, aniName, ""); | |
343 | - } | |
344 | - else | |
345 | - { | |
346 | - lastAnimationSubtitle = aniName; | |
347 | - playAnimation(Subtitle.TYPE_WORD, aniName); | |
348 | - } | |
349 | - } | |
350 | - | |
351 | - // Soletra palavra | |
352 | - else | |
353 | - { | |
354 | - // Se a animação não foi carregada e nem está marcada como não existente, | |
355 | - // adiciona ao set de animações não existentes | |
356 | - if ( ! nonexistent) | |
357 | - nonexistentAssetBundles.Add(aniName); | |
358 | - | |
359 | - UnityEngine.Debug.Log("~~ To spell: " + aniName); | |
360 | - | |
361 | - if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) | |
362 | - { | |
363 | - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", 1.6F); | |
364 | - continue; | |
365 | - } | |
366 | - | |
367 | - // Se já houve o soletramento de alguma palavra, reproduz animação default | |
368 | - if (spelled) | |
369 | - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, 1.6F); | |
370 | - else | |
371 | - spelled = true; | |
372 | - | |
373 | - lastAnimationSubtitle = spellWord(aniName); | |
374 | - } | |
375 | - } | |
376 | - | |
377 | - // Default | |
378 | - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, ""); | |
220 | + if ( ! this.lastGloss.isDone() && ! this.lastGloss.isLoading()) | |
221 | + yield return this.lastGloss.Load(true); | |
222 | + else | |
223 | + yield return this.lastGloss.Play(); | |
379 | 224 | |
380 | 225 | this.loading = false; |
381 | - // onPlayingStateChange(); | |
382 | - this.randomAnimations.unlockFor("loadAndPlay"); | |
226 | + onPlayingStateChange(); | |
227 | + this.randomAnimations.unlockFor(RA_LOCKER_LOADANDPLAY); | |
383 | 228 | } |
384 | 229 | } |
385 | 230 | |
386 | - private System.Object playingLocker = new System.Object(); | |
387 | - | |
388 | - /* Sincroniza as legendas com as animações. */ | |
389 | - IEnumerator handleStates() | |
231 | + private IEnumerator Play() | |
390 | 232 | { |
391 | - lock (this.playingLocker) | |
392 | - { | |
393 | - this.randomAnimations.lockFor("handleStates"); | |
394 | - | |
395 | - // this.playing = true; | |
396 | - | |
397 | - bool isNotEmpty; | |
233 | + this.randomAnimations.lockFor(RA_LOCKER_PLAY); | |
234 | + yield return this.lastGloss.Play(); | |
235 | + this.randomAnimations.unlockFor(RA_LOCKER_PLAY); | |
236 | + } | |
398 | 237 | |
399 | - lock (animQueue) { isNotEmpty = animQueue.Count > 0; } | |
238 | + public void loadIsDone() { | |
239 | + StartCoroutine("ParallelLoad"); | |
240 | + } | |
400 | 241 | |
401 | - // Enquanto estiver executando a rotina "loadAndPlay" | |
402 | - // ou existir animações na fila de reprodução | |
403 | - while (loading || isNotEmpty) | |
404 | - { | |
405 | - if (isNotEmpty) | |
406 | - { | |
407 | - AnimationReference reference; | |
408 | - lock (animQueue) { reference = animQueue.Peek(); } | |
409 | - | |
410 | - this.subtitles.setText(reference.subtitle); | |
411 | - | |
412 | - if (COMPONENT_ANIMATION.IsPlaying(reference.name)) | |
413 | - { | |
414 | - bool changing = false; | |
415 | - | |
416 | - if ( ! this.playing) | |
417 | - { | |
418 | - this.playing = true; | |
419 | - changing = true; | |
420 | - } | |
421 | - | |
422 | - if (this.intervalAnimations.Contains(reference.name)) | |
423 | - { | |
424 | - if ( ! this.playingIntervalAnimation) | |
425 | - { | |
426 | - this.playingIntervalAnimation = true; | |
427 | - changing = true; | |
428 | - } | |
429 | - } | |
430 | - else if (this.playingIntervalAnimation) | |
431 | - { | |
432 | - this.playingIntervalAnimation = false; | |
433 | - changing = true; | |
434 | - } | |
435 | - | |
436 | - if (changing) onPlayingStateChange(); | |
437 | - | |
438 | - // reference.playing = true; | |
439 | - do { yield return null; } | |
440 | - while (COMPONENT_ANIMATION.IsPlaying(reference.name)); | |
441 | - } | |
442 | - | |
443 | - if (reference.state == null) | |
444 | - lock (animQueue) { animQueue.Dequeue(); } | |
445 | - else | |
446 | - yield return null; | |
447 | - } | |
448 | - else yield return null; | |
449 | - | |
450 | - this.subtitles.setText(""); | |
451 | - | |
452 | - lock (animQueue) { isNotEmpty = animQueue.Count > 0; } | |
453 | - } | |
242 | + public IEnumerator ParallelLoad() | |
243 | + { | |
244 | + lock (LOCKER_PARALLEL_LOAD) | |
245 | + { | |
246 | + this.randomAnimations.lockFor("parallelLoading"); | |
247 | + this.loading = true; | |
454 | 248 | |
455 | - this.playing = false; | |
456 | - this.paused = false; | |
457 | - this.playingIntervalAnimation = false; | |
458 | - onPlayingStateChange(); | |
249 | + foreach (Gloss gloss in this.glossQueue) | |
250 | + if ( ! gloss.isDone() && ! gloss.isLoading()) | |
251 | + yield return gloss.Load(false); | |
459 | 252 | |
460 | - this.randomAnimations.unlockFor("handleStates"); | |
253 | + this.loading = true; | |
254 | + this.randomAnimations.unlockFor("parallelLoading"); | |
461 | 255 | } |
462 | 256 | } |
463 | 257 | ... | ... |
Assets/Scripts/Player Manager/Gloss.cs
... | ... | @@ -6,34 +6,79 @@ using System.Threading; |
6 | 6 | |
7 | 7 | public class Gloss { |
8 | 8 | |
9 | + // Começa a reproduzir as animações quando ao menos START_INDEX animações forem carregadas | |
10 | + // Se o numero de animações for menor que START_INDEX, então inicia quando carregar todas | |
11 | + private const int START_INDEX = 4; | |
12 | + private static System.Object LOCKER_PLAY = new System.Object(); | |
13 | + | |
9 | 14 | private GenericPlayerManager context = GenericPlayerManager.context; |
10 | 15 | |
11 | - private string gloss; | |
16 | + // Glosa em texto | |
17 | + public string text; | |
18 | + // Glosa partida em palavras | |
12 | 19 | private string[] tokens; |
20 | + // Número de animações carregadas | |
21 | + // -1 : carregamento não foi iniciado | |
22 | + // tokens.Length : carregamento foi concluído | |
23 | + // * : carregando | |
24 | + public int loaded = -1; | |
13 | 25 | |
26 | + // Fila de espera para fila de reprodução | |
14 | 27 | private Queue<AnimationReference> animations = new Queue<AnimationReference>(); |
28 | + // Fila de reprodução | |
29 | + private Queue<AnimationReference> playing = new Queue<AnimationReference>(); | |
15 | 30 | |
16 | - public bool loaded = false; | |
31 | + // Referencias para corotinas | |
32 | + private IEnumerator playCoroutine; | |
33 | + private IEnumerator handleCoroutine; | |
17 | 34 | |
18 | - public Gloss(string gloss) | |
35 | + public Gloss(string text) | |
19 | 36 | { |
20 | - this.gloss = gloss; | |
21 | - this.tokens = gloss.Split(' '); | |
37 | + this.text = text; | |
38 | + this.tokens = text.Split(' '); | |
39 | + } | |
40 | + | |
41 | + public bool isLoading() { | |
42 | + return this.loaded >= 0 && this.loaded < this.tokens.Length; | |
43 | + } | |
44 | + public bool isDone() { | |
45 | + return this.loaded == this.tokens.Length; | |
22 | 46 | } |
23 | 47 | |
48 | + /* Adiciona animação default na fila de espera */ | |
24 | 49 | private void addDefault() { |
25 | - this.animations.Add(new AnimationReference(context.DEFAULT_ANIMATION, "", Subtitle.TYPE_NONE, 2F)); | |
50 | + lock (this.animations) { | |
51 | + this.animations.Enqueue(new AnimationReference(context.DEFAULT_ANIMATION, "", Subtitle.TYPE_NONE, 2F)); | |
52 | + } | |
26 | 53 | } |
27 | 54 | |
28 | - public IEnumerator load() | |
55 | + /* Carrega e adiciona animações (tokens) na fila de espera */ | |
56 | + public IEnumerator Load(bool play) | |
29 | 57 | { |
30 | - loaded = true; | |
58 | + if (this.loaded >= 0) { | |
59 | + if (play) | |
60 | + { | |
61 | + this.playCoroutine = Play(); | |
62 | + context.StartCoroutine(this.playCoroutine); | |
63 | + } | |
64 | + else yield break; | |
65 | + } | |
66 | + | |
67 | + this.loaded = 0; | |
31 | 68 | addDefault(); |
32 | 69 | |
33 | 70 | bool spelled = false; |
34 | 71 | |
35 | 72 | foreach (string token in this.tokens) |
36 | 73 | { |
74 | + Debug.Log("loading " + token); | |
75 | + | |
76 | + if (play && this.loaded == START_INDEX) | |
77 | + { | |
78 | + this.playCoroutine = Play(); | |
79 | + context.StartCoroutine(this.playCoroutine); | |
80 | + } | |
81 | + | |
37 | 82 | if (String.IsNullOrEmpty(token) |
38 | 83 | || context.nonexistentAssetBundles.Contains(token) |
39 | 84 | || context.loadedAssetBundles.Contains(token)) |
... | ... | @@ -70,7 +115,9 @@ public class Gloss { |
70 | 115 | |
71 | 116 | string subtitle = context.flags.Contains(token) ? token : ""; |
72 | 117 | |
73 | - this.animations.Add(new AnimationReference(token, subtitle, Subtitle.TYPE_WORD)); | |
118 | + lock (this.animations) { | |
119 | + this.animations.Enqueue(new AnimationReference(token, subtitle, Subtitle.TYPE_WORD)); | |
120 | + } | |
74 | 121 | } |
75 | 122 | else error = "Error at Gloss.load(): clip from AssetBundle of " + token + " wasn't found"; |
76 | 123 | } |
... | ... | @@ -85,7 +132,7 @@ public class Gloss { |
85 | 132 | Debug.Log(error); |
86 | 133 | context.nonexistentAssetBundles.Add(token); |
87 | 134 | |
88 | - if (this.flags.Contains(aniName)) | |
135 | + if (context.flags.Contains(token)) | |
89 | 136 | { |
90 | 137 | addDefault(); |
91 | 138 | continue; |
... | ... | @@ -99,11 +146,23 @@ public class Gloss { |
99 | 146 | |
100 | 147 | spellWord(token); |
101 | 148 | } |
149 | + | |
150 | + this.loaded++; | |
102 | 151 | } |
103 | 152 | |
104 | 153 | addDefault(); |
154 | + | |
155 | + if (play) { | |
156 | + if (this.loaded <= START_INDEX) | |
157 | + { | |
158 | + this.playCoroutine = Play(); | |
159 | + context.StartCoroutine(this.playCoroutine); | |
160 | + } | |
161 | + context.loadIsDone(); | |
162 | + } | |
105 | 163 | } |
106 | 164 | |
165 | + /* Adiciona palavra de forma soletrada na fila de espera */ | |
107 | 166 | private void spellWord(string word) |
108 | 167 | { |
109 | 168 | // A reprodução da primeira letra deve ser longa para não ser cortada no fade |
... | ... | @@ -121,61 +180,145 @@ public class Gloss { |
121 | 180 | |
122 | 181 | last = letter; |
123 | 182 | |
124 | - // Se for uma letra | |
125 | - if (letter >= 65 && letter <= 90) | |
126 | - this.animations.Add(new AnimationReference( | |
127 | - animationName, | |
128 | - subtitle, | |
129 | - Subtitle.TYPE_LETTER | |
130 | - )); | |
131 | - | |
132 | - // Se for um número | |
133 | - else if (letter >= 48 && letter <= 57) | |
134 | - this.animations.Add(new AnimationReference( | |
135 | - animationName, | |
136 | - subtitle, | |
137 | - Subtitle.TYPE_NUMBER | |
138 | - )); | |
139 | - | |
140 | - // Se for uma vírgula | |
141 | - else if (letter == 44) | |
142 | - this.animations.Add(new AnimationReference( | |
143 | - animationName, | |
144 | - subtitle, | |
145 | - Subtitle.TYPE_WORD | |
146 | - )); | |
183 | + lock (this.animations) | |
184 | + { | |
185 | + // Se for uma letra | |
186 | + if (letter >= 65 && letter <= 90) | |
187 | + this.animations.Enqueue(new AnimationReference( | |
188 | + animationName, | |
189 | + subtitle, | |
190 | + Subtitle.TYPE_LETTER | |
191 | + )); | |
192 | + | |
193 | + // Se for um número | |
194 | + else if (letter >= 48 && letter <= 57) | |
195 | + this.animations.Enqueue(new AnimationReference( | |
196 | + animationName, | |
197 | + subtitle, | |
198 | + Subtitle.TYPE_NUMBER | |
199 | + )); | |
200 | + | |
201 | + // Se for uma vírgula | |
202 | + else if (letter == 44) | |
203 | + this.animations.Enqueue(new AnimationReference( | |
204 | + animationName, | |
205 | + subtitle, | |
206 | + Subtitle.TYPE_WORD | |
207 | + )); | |
208 | + } | |
147 | 209 | |
148 | 210 | context.subtitles.updateLetterSpeed(); |
149 | 211 | } |
150 | 212 | } |
151 | 213 | |
152 | - private IEnumerator play() | |
153 | - { | |
154 | - foreach (AnimationReference animation in this.animations) | |
155 | - animation.play(); | |
214 | + /* Verifica se há animações na fila de espera */ | |
215 | + private bool hasAnimations() { | |
216 | + lock (this.animations) { return this.animations.Count > 0; } | |
217 | + } | |
156 | 218 | |
157 | - while (this.animations.Count > 0) | |
219 | + /* Verifica se há animações na fila de reprodução */ | |
220 | + private bool hasPlaying() { | |
221 | + lock (this.playing) { return this.playing.Count > 0; } | |
222 | + } | |
223 | + | |
224 | + /* Transfere animações da fila de espera para a fila de reprodução */ | |
225 | + public IEnumerator Play() | |
226 | + { | |
227 | + lock (LOCKER_PLAY) | |
158 | 228 | { |
159 | - AnimationReference reference = this.animations.Peek(); | |
229 | + while (this.loaded < START_INDEX && this.loaded < this.tokens.Length) | |
230 | + yield return null; | |
160 | 231 | |
161 | - this.subtitles.setText(reference.subtitle); | |
232 | + this.handleCoroutine = Handle(); | |
233 | + context.StartCoroutine(this.handleCoroutine); | |
162 | 234 | |
163 | - while (COMPONENT_ANIMATION.IsPlaying(reference.name)) | |
164 | - yield return null; | |
235 | + context.playing = true; | |
236 | + context.onPlayingStateChange(); | |
237 | + | |
238 | + bool isPlaying = hasAnimations(); | |
165 | 239 | |
166 | - if (reference.state == null) | |
167 | - this.animations.Dequeue(); | |
168 | - else | |
240 | + while (isPlaying || this.loaded < this.tokens.Length) | |
241 | + { | |
242 | + if (isPlaying) | |
243 | + { | |
244 | + AnimationReference reference; | |
245 | + lock (this.animations) { reference = this.animations.Dequeue(); } | |
246 | + | |
247 | + reference.play(); | |
248 | + lock (this.playing) { this.playing.Enqueue(reference); } | |
249 | + } | |
250 | + | |
251 | + isPlaying = hasAnimations(); | |
169 | 252 | yield return null; |
253 | + } | |
254 | + | |
255 | + context.playing = false; | |
256 | + context.onPlayingStateChange(); | |
257 | + } | |
258 | + } | |
259 | + | |
260 | + /** Observa animações sendo reproduzidas | |
261 | + * Atualiza legenda e retira da fila de reprodução */ | |
262 | + private IEnumerator Handle() | |
263 | + { | |
264 | + bool notify = true; | |
265 | + bool isPlaying = hasPlaying(); | |
266 | + | |
267 | + while (isPlaying || hasAnimations() || isLoading()) { | |
268 | + if (isPlaying) | |
269 | + { | |
270 | + if (notify) | |
271 | + { | |
272 | + notify = false; | |
273 | + context.playing = true; | |
274 | + context.onPlayingStateChange(); | |
275 | + } | |
276 | + | |
277 | + AnimationReference reference = this.playing.Peek(); | |
278 | + | |
279 | + context.subtitles.setText(reference.subtitle); | |
280 | + | |
281 | + while (context.COMPONENT_ANIMATION.IsPlaying(reference.name)) | |
282 | + yield return null; | |
283 | + | |
284 | + if (reference.state == null) | |
285 | + lock (this.animations) { this.animations.Dequeue(); } | |
286 | + else | |
287 | + yield return null; | |
288 | + } | |
289 | + | |
290 | + isPlaying = hasPlaying(); | |
170 | 291 | } |
171 | 292 | |
172 | - this.subtitles.setText(""); | |
293 | + context.subtitles.setText(""); | |
294 | + | |
295 | + context.playing = true; | |
296 | + context.onPlayingStateChange(); | |
297 | + } | |
298 | + | |
299 | + /* Para animações (false) ou atualiza velocidade (true) */ | |
300 | + public void setPlayingState(bool active) | |
301 | + { | |
302 | + lock (this.animations) { | |
303 | + lock (this.playing) | |
304 | + { | |
305 | + foreach (AnimationReference reference in this.animations) | |
306 | + if (reference.type != Subtitle.TYPE_NONE && reference.state != null) | |
307 | + reference.state.speed = active ? context.subtitles.getSpeedByType(reference.type) : 0F; | |
308 | + } | |
309 | + } | |
310 | + } | |
311 | + | |
312 | + /* Atualiza velocidade */ | |
313 | + public void updateSpeed() { | |
314 | + setPlayingState(true); | |
173 | 315 | } |
174 | 316 | |
317 | + /* Termina glosa */ | |
175 | 318 | public void destroy() |
176 | 319 | { |
177 | - context.StopCoroutine("load"); | |
178 | - context.StopCoroutine("handle"); | |
320 | + context.StopCoroutine(this.playCoroutine); | |
321 | + context.StopCoroutine(this.handleCoroutine); | |
179 | 322 | } |
180 | 323 | |
181 | 324 | } | ... | ... |
Assets/Scripts/Player Manager/RandomAnimations.cs
... | ... | @@ -67,6 +67,7 @@ public class RandomAnimations : MonoBehaviour { |
67 | 67 | |
68 | 68 | if (isNotBlocked) |
69 | 69 | { |
70 | + Debug.Log("wait: " + this.time); | |
70 | 71 | yield return new WaitForSeconds(this.time); |
71 | 72 | |
72 | 73 | lock (this.blockingObjects) { |
... | ... | @@ -81,7 +82,25 @@ public class RandomAnimations : MonoBehaviour { |
81 | 82 | if (index == this.lastIndex) |
82 | 83 | index = sortIndex(); |
83 | 84 | |
84 | - this.playerManager.play(this.names[index], true, false, true); | |
85 | + this.playerManager.COMPONENT_ANIMATION.CrossFadeQueued( | |
86 | + this.playerManager.DEFAULT_ANIMATION, | |
87 | + this.playerManager.fadeLength, | |
88 | + QueueMode.CompleteOthers | |
89 | + ); | |
90 | + this.playerManager.COMPONENT_ANIMATION.CrossFadeQueued( | |
91 | + this.names[index], | |
92 | + this.playerManager.fadeLength, | |
93 | + QueueMode.CompleteOthers | |
94 | + ); | |
95 | + this.playerManager.COMPONENT_ANIMATION.CrossFadeQueued( | |
96 | + this.playerManager.DEFAULT_ANIMATION, | |
97 | + this.playerManager.fadeLength, | |
98 | + QueueMode.CompleteOthers | |
99 | + ); | |
100 | + | |
101 | + Debug.Log("wait: " + 4); | |
102 | + yield return new WaitForSeconds(4); | |
103 | + //this.playerManager.play(this.names[index], true, false, true); | |
85 | 104 | } |
86 | 105 | } |
87 | 106 | ... | ... |
Assets/Scripts/Player Manager/Subtitle.cs
... | ... | @@ -114,6 +114,17 @@ public class Subtitle { |
114 | 114 | this.NumberSpeed = this.DefaultNumberSpeed.getProportional(this.SliderPosition); |
115 | 115 | } |
116 | 116 | |
117 | + public float getSpeedByType(short type) | |
118 | + { | |
119 | + switch (type) | |
120 | + { | |
121 | + case TYPE_WORD: return this.wordSpeed; | |
122 | + case TYPE_LETTER: return this.letterSpeed; | |
123 | + case TYPE_NUMBER: return this.numberSpeed; | |
124 | + } | |
125 | + | |
126 | + return 2F; | |
127 | + } | |
117 | 128 | |
118 | 129 | /* Destaca caractere de uma string. */ |
119 | 130 | public static string highlight(string word, int index) | ... | ... |
Assets/Scripts/PlayerManager.cs
... | ... | @@ -53,15 +53,11 @@ public class PlayerManager : GenericPlayerManager { |
53 | 53 | TouchScreenKeyboard.hideInput = true; |
54 | 54 | } |
55 | 55 | |
56 | - public void start_play() { | |
57 | - base.play(); | |
58 | - } | |
59 | - | |
60 | 56 | // Stop loading, if loading |
61 | 57 | // Don't stop animations, if playing |
62 | 58 | // Load glosa, enqueue animations |
63 | - public void forcePlayFromCache() { | |
64 | - base.play(base.gloss, true, false, true); | |
59 | + public void forcePlay(string gloss) { | |
60 | + base.play(gloss, true, false, true); | |
65 | 61 | } |
66 | 62 | |
67 | 63 | public void start_play(string gloss) |
... | ... | @@ -69,13 +65,13 @@ public class PlayerManager : GenericPlayerManager { |
69 | 65 | if (gloss == null || String.IsNullOrEmpty(gloss.Trim())) |
70 | 66 | return; |
71 | 67 | |
72 | - base.gloss = gloss; | |
73 | - forcePlayFromCache(); | |
68 | + forcePlay(gloss); | |
74 | 69 | } |
75 | 70 | |
76 | 71 | public void playDict(string word) |
77 | 72 | { |
78 | - base.gloss = word; | |
73 | + Debug.Log(word); | |
74 | + | |
79 | 75 | base.play(word, true, true, true); |
80 | 76 | |
81 | 77 | this.screenManager.hideScreen(); |
... | ... | @@ -96,6 +92,11 @@ public class PlayerManager : GenericPlayerManager { |
96 | 92 | this.randomAnimations.unlockFor("translate"); |
97 | 93 | } |
98 | 94 | |
95 | + string gloss; | |
96 | + public void translationErrorPlay() { | |
97 | + start_play(gloss); | |
98 | + } | |
99 | + | |
99 | 100 | public Text debugText; |
100 | 101 | |
101 | 102 | public override WWW loadAssetBundle(string aniName) { |
... | ... | @@ -117,13 +118,11 @@ public class PlayerManager : GenericPlayerManager { |
117 | 118 | |
118 | 119 | private System.Object stateLocker = new System.Object(); |
119 | 120 | |
120 | - protected override void onPlayingStateChange() | |
121 | + public override void onPlayingStateChange() | |
121 | 122 | { |
122 | 123 | lock (this.stateLocker) |
123 | 124 | { |
124 | - //this.screenManager.setRepeatLayerState(base.isRepeatable() && ! base.isPlaying()); | |
125 | - | |
126 | - if (base.isPlaying() && ! base.isPlayingIntervalAnimation()) | |
125 | + if (base.isPlaying()) | |
127 | 126 | { |
128 | 127 | setPlayingState(true); |
129 | 128 | |
... | ... | @@ -138,7 +137,12 @@ public class PlayerManager : GenericPlayerManager { |
138 | 137 | this.screenManager.setPauseMenuState(false); |
139 | 138 | } |
140 | 139 | } |
141 | - else setPlayingState(false); | |
140 | + else | |
141 | + { | |
142 | + setPlayingState(false); | |
143 | + | |
144 | + // TODO repeat button | |
145 | + } | |
142 | 146 | } |
143 | 147 | } |
144 | 148 | |
... | ... | @@ -177,7 +181,7 @@ public class PlayerManager : GenericPlayerManager { |
177 | 181 | { |
178 | 182 | Debug.Log("Server answer: " + glossRequest.text); |
179 | 183 | |
180 | - base.playNext(glossRequest.text); | |
184 | + forcePlay(glossRequest.text); | |
181 | 185 | this.screenManager.setLoadingSnippetState(false); |
182 | 186 | base.randomAnimations.unlockFor("translate"); |
183 | 187 | |
... | ... | @@ -189,7 +193,7 @@ public class PlayerManager : GenericPlayerManager { |
189 | 193 | } |
190 | 194 | else Debug.Log ("Error at PlayerManager.translate: (WWW) glosaRequest is NULL."); |
191 | 195 | |
192 | - base.gloss = gloss.ToUpper(); | |
196 | + this.gloss = gloss.ToUpper(); | |
193 | 197 | |
194 | 198 | this.screenManager.setLoadingSnippetState(false); |
195 | 199 | this.screenManager.showConnectionErrorDialog(); | ... | ... |
Assets/Scripts/UI/ScreenManager.cs
... | ... | @@ -112,10 +112,10 @@ public class ScreenManager : MonoBehaviour { |
112 | 112 | |
113 | 113 | screen.SetActive(true); |
114 | 114 | |
115 | - if (playerManager.isPlayingIntervalAnimation()) | |
116 | - playerManager.stopAll(); | |
115 | + //if (playerManager.isPlayingIntervalAnimation()) | |
116 | + // playerManager.stopAll(); | |
117 | 117 | |
118 | - else if (playerManager.isPlaying()) | |
118 | + if (playerManager.isPlaying()) | |
119 | 119 | { |
120 | 120 | playerManager.setPauseState(true); |
121 | 121 | setPauseMenuState(true); | ... | ... |