Commit 7b8cdd87995abd72ff8f8b45e3e6c9ecd1ccf1e1

Authored by Mateus Lustosa
1 parent b10df488
Exists in ui

Remake quase completo

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);
... ...