Commit 68012fb0dc73866ffa1103764ebeca834d56010f

Authored by Mateus Lustosa
1 parent 315b1e1e
Exists in devel

Fix concurrence problem

Assets/Scripts/PlayerManager.cs
... ... @@ -5,21 +5,30 @@ using System.IO;
5 5 using System.Threading;
6 6 using System.Collections;
7 7 using System.Collections.Generic;
8   -using System.Runtime.InteropServices;
9   -using System.Net.Sockets;
10   -using System.Diagnostics;
11 8  
12 9 public class PlayerManager : GenericPlayerManager {
13 10  
14 11 private Server server = null;
15   - private Semaphore serverSemaphore = null;
16   -
17 12 private volatile Queue<Message> messages = new Queue<Message>();
18   - private volatile bool toFinalize = false;
  13 +
  14 + private readonly Semaphore finalizationLocker = new Semaphore(0, 1);
  15 + private readonly object messageQueueLocker = new object();
  16 +
  17 + public Semaphore FinalizationLocker {
  18 + get { return this.finalizationLocker; }
  19 + }
  20 +
  21 + public object MessageQueueLocker {
  22 + get { return this.messageQueueLocker; }
  23 + }
19 24  
20 25 public override void Start()
21 26 {
22 27 base.Start();
  28 + Screen.SetResolution(800, 600, false);
  29 +
  30 + Debug.Log("PM.S(): Setting args");
  31 +
23 32 string[] args = Environment.GetCommandLineArgs();
24 33  
25 34 if (args.Length >= 5)
... ... @@ -56,57 +65,65 @@ public class PlayerManager : GenericPlayerManager {
56 65 );
57 66 }
58 67  
59   - serverSemaphore = new Semaphore(0, 1);
60   - server = new Server(serverSemaphore, this);
61   - Thread t = new Thread(new ThreadStart(server.startServer));
62   - t.Start();
  68 + Debug.Log("PM.S(): Setting lockers");
63 69  
64   - serverSemaphore.WaitOne();
  70 + // Starts thread to wait for app finalization
  71 + new Thread(new ThreadStart(waitFinalize)).Start();
65 72  
66   - //UnityEngine.Debug.Log("Datapath: " + Application.dataPath);
  73 + Debug.Log("PM.S(): Starting server");
67 74  
68   - Screen.SetResolution(800, 600, false);
69   - }
  75 + // Start server
  76 + server = new Server(this);
  77 + new Thread(new ThreadStart(server.StartCommunication)).Start();
70 78  
71   - protected void Update() {
72   - if (toFinalize)
73   - {
74   - UnityEngine.Debug.Log("PM.U(): Update -> toFinalize == " + toFinalize);
75   - Application.Quit();
76   - }
  79 + // Starts communication thread and wait for finalize
  80 + StartCoroutine(MessageChecker());
77 81 }
78 82  
79   - public void enqueueMessage(Message message) {
80   - //UnityEngine.Debug.Log("PlayerManager.enqueueMessage( " + message.Text + " )");
  83 + public void enqueueMessage(Message message)
  84 + {
  85 + UnityEngine.Debug.Log("PM.eM(): " + message.Text + ", " + message.Time);
81 86 messages.Enqueue(message);
82 87 }
83 88  
84   - public void finishConnection() {
85   - //UnityEngine.Debug.Log("PlayerManager.finishConnection()");
86   - StartCoroutine(MessageChecker());
  89 + private void waitFinalize()
  90 + {
  91 + Debug.Log("PM.WF(): START");
  92 + FinalizationLocker.WaitOne();
  93 + Debug.Log("PM.WF(): Finalize command received");
  94 +
  95 + Application.Quit();
87 96 }
88 97  
89 98 IEnumerator MessageChecker()
90 99 {
  100 + Debug.Log("PM.MC(): START");
  101 +
  102 + while (server.IsNotReady)
  103 + yield return null;
  104 +
  105 + Debug.Log("PM.MC(): Starting to read messages");
  106 +
91 107 CameraCapture.capture = true;
92 108 foreach (Message message in messages)
93 109 {
94 110 while ((CameraCapture.frameNumber * 1000) / CameraCapture.frameRate < message.Time)
95 111 yield return null;
96 112  
97   - UnityEngine.Debug.Log("PM.MS(): Loading " + message.Text);
  113 + UnityEngine.Debug.Log("PM.MC(): Loading " + message.Text);
98 114 base.playQueued(message.Text);
99 115 }
100 116  
101 117 while (base.isPlaying() || base.isLoading())
102 118 yield return null;
103 119  
104   - UnityEngine.Debug.Log("PM.MS(): ALL DONE!");
105   - server.sendFinalizeToCore();
  120 + UnityEngine.Debug.Log("PM.MC(): All done!");
  121 +
  122 + server.SendFinalizeToCore();
106 123 CameraCapture.capture = false;
107   - UnityEngine.Debug.Log("PM.MS(): CameraCapture.capture == " + CameraCapture.capture);
108   - toFinalize = true;
109   - UnityEngine.Debug.Log("PM.MS(): toFinalize == " + toFinalize);
  124 + UnityEngine.Debug.Log("PM.MC(): CameraCapture.capture == " + CameraCapture.capture);
  125 +
  126 + Application.Quit();
110 127 }
111 128  
112 129 public override WWW loadAssetBundle(string aniName)
... ...
Assets/Scripts/PlayerManager/GenericPlayerManager.cs
... ... @@ -18,17 +18,23 @@
18 18 * - Reprodução
19 19 * Quando não há acesso aos bundles dos sinais de pontuação, eles são ignorados.
20 20 * Ç adicionado como TYPE_WORD.
  21 + *
  22 + * Versão 2.5
  23 + * - Sincronização
  24 + * Retira os LOCKERs.
  25 + * Os LOCKERs não impedem que duas Coroutines entrem na mesma sessão crítica.
  26 + * A soluação utiliza o estado loading na coroutine LoadAndPlay.
  27 + * - Código
  28 + * Retira namespaces não utilizados.
  29 + * Adiciona logs.
21 30 */
22 31  
23 32 //Log Dir http://docs.unity3d.com/Manual/LogFiles.html
  33 +
24 34 using UnityEngine;
25 35 using System.Collections;
26 36 using System.Collections.Generic;
27 37 using System;
28   -using System.Threading;
29   -using System.IO;
30   -using System.Text;
31   -using System.Runtime.InteropServices;
32 38 using UnityEngine.UI;
33 39  
34 40 public abstract class GenericPlayerManager : MonoBehaviour {
... ... @@ -66,6 +72,8 @@ public abstract class GenericPlayerManager : MonoBehaviour {
66 72 // True quando é chamada a função de pausa
67 73 private volatile bool paused = false;
68 74  
  75 + private IEnumerator subtitlesSynchronizer;
  76 +
69 77 // Se diferente de null, não está reproduzindo animação de intervalo
70 78 private AnimationState intervalAnimationState = null;
71 79 // Usado para pausar quando comandado
... ... @@ -87,6 +95,8 @@ public abstract class GenericPlayerManager : MonoBehaviour {
87 95 subtitles.DefaultLetterSpeed = new DefaultSignSpeed(3F, 4.3F);
88 96 subtitles.DefaultNumberSpeed = new DefaultSignSpeed(1.5F, 2.9F);
89 97  
  98 + subtitlesSynchronizer = SubtitlesSynchronizer();
  99 +
90 100 AVATAR = GameObject.FindGameObjectWithTag("avatar");
91 101 COMPONENT_ANIMATION = AVATAR.GetComponent<Animation>();
92 102  
... ... @@ -175,8 +185,8 @@ public abstract class GenericPlayerManager : MonoBehaviour {
175 185 /* Para carregamento e animações */
176 186 public void stopAll()
177 187 {
178   - StopCoroutine("loadAndPlay");
179   - this.randomAnimations.unlockFor("loadAndPlay");
  188 + StopCoroutine("LoadAndPlay");
  189 + this.randomAnimations.unlockFor("GPM.LoadAndPlay");
180 190 loading = false;
181 191  
182 192 stopAnimations();
... ... @@ -185,8 +195,8 @@ public abstract class GenericPlayerManager : MonoBehaviour {
185 195 /* Para animações */
186 196 public void stopAnimations()
187 197 {
188   - StopCoroutine("handleStates");
189   - this.randomAnimations.unlockFor("handleStates");
  198 + StopCoroutine(subtitlesSynchronizer);
  199 + this.randomAnimations.unlockFor("GPM.SubtitlesSynchronizer");
190 200 this.subtitles.setText("");
191 201  
192 202 lock (this.animQueue) { this.animQueue.Clear(); }
... ... @@ -294,62 +304,39 @@ public abstract class GenericPlayerManager : MonoBehaviour {
294 304 setPauseState( ! this.paused);
295 305 }
296 306  
297   - private System.Object LOCKER_PLAY = new System.Object();
298   -
299 307 /* Play if anything loading or playing */
300 308 public bool playIfEmpty(string gloss)
301 309 {
302   - lock (LOCKER_PLAY)
303   - {
304   - if (this.loading || this.playing)
305   - return false;
  310 + if (this.loading || this.playing)
  311 + return false;
306 312  
307   - StartCoroutine("loadAndPlay", gloss);
308   - }
  313 + StartCoroutine(LoadAndPlay(gloss));
309 314  
310 315 return true;
311 316 }
312 317  
313   - private System.Object LOCKER_GLOSS_WATING = new System.Object();
314   - private int numGlossWating = 0;
315   - public void setGlossWaiting(bool inc) { lock (LOCKER_GLOSS_WATING) { numGlossWating += inc ? 1 : -1; } }
316   - public bool hasGlossWaiting() { lock (LOCKER_GLOSS_WATING) { return this.numGlossWating > 0; } }
317   -
318   - /* Enqueue animations for playing */
  318 + /* Enqueue animations */
319 319 public void playQueued(string gloss)
320 320 {
321   - lock (LOCKER_PLAY)
322   - {
323   - Debug.Log("GPM.pQ(" + gloss + ")");
324   - setGlossWaiting(true);
325   - StartCoroutine("loadAndPlay", gloss);
326   - }
  321 + Debug.Log("GPM.pQ(" + gloss + ")");
  322 + StartCoroutine(LoadAndPlay(gloss));
327 323 }
328 324  
329 325 /* Stop all and play */
330 326 public void playNow(string gloss)
331 327 {
332   - lock (LOCKER_PLAY)
333   - {
334   - Debug.Log("GPM.pN(" + gloss + ")");
335   - stopAll();
336   - StartCoroutine("loadAndPlay", gloss);
337   - }
  328 + Debug.Log("GPM.pN(" + gloss + ")");
  329 + stopAll();
  330 + StartCoroutine(LoadAndPlay(gloss));
338 331 }
339 332  
340 333 /* Reproduz animação de intervalo */
341 334 public bool playIntervalAnimation(string name)
342 335 {
343   - if ( ! Monitor.TryEnter(LOCKER_PLAY))
344   - return false;
345   -
346   - lock (LOCKER_PLAY)
347   - {
348   - playDefaultAnimation(true);
349   - this.intervalAnimationState = COMPONENT_ANIMATION.CrossFadeQueued(name, fadeLength, QueueMode.CompleteOthers);
350   - playDefaultAnimation(false);
351   - }
352   -
  336 + playDefaultAnimation(true);
  337 + this.intervalAnimationState = COMPONENT_ANIMATION.CrossFadeQueued(name, fadeLength, QueueMode.CompleteOthers);
  338 + playDefaultAnimation(false);
  339 +
353 340 return true;
354 341 }
355 342  
... ... @@ -443,7 +430,7 @@ public abstract class GenericPlayerManager : MonoBehaviour {
443 430 return lastAnimationSubtitle;
444 431 }
445 432  
446   - /* Instruções para reprodução de aninmação */
  433 + /* Instruções para reprodução de animação */
447 434 private struct ToPlay
448 435 {
449 436 private short type;
... ... @@ -469,239 +456,229 @@ public abstract class GenericPlayerManager : MonoBehaviour {
469 456 context.playAnimation(this.type, this.name, this.subtitle, this.speed);
470 457 }
471 458 }
472   -
473   - private System.Object LOCKER_LOADING = new System.Object();
474   -
  459 +
475 460 /* Carrega animações e reproduz */
476   - private IEnumerator loadAndPlay(string gloss)
  461 + private IEnumerator LoadAndPlay(string gloss)
477 462 {
478   - lock (LOCKER_LOADING)
479   - {
480   - Debug.Log("GPM.lAP(" + gloss + ")");
  463 + Debug.Log("GPM.LAP(" + gloss + ")");
481 464  
482   - this.randomAnimations.lockFor("loadAndPlay");
483   - this.loading = true;
484   - setGlossWaiting(false);
485   - // onPlayingStateChange();
  465 + while (loading) yield return null;
486 466  
487   - string lastAnimationSubtitle = "";
488   - bool spelled = false;
  467 + this.loading = true;
  468 + // onPlayingStateChange();
  469 + this.randomAnimations.lockFor("GPM.LoadAndPlay");
489 470  
490   - if ( ! this.playing)
491   - StartCoroutine("handleStates");
  471 + string lastAnimationSubtitle = "";
  472 + bool spelled = false;
492 473  
493   - String[] stringPos = gloss.Split(' ');
  474 + StartCoroutine(subtitlesSynchronizer);
494 475  
495   - Queue<ToPlay> toPlayQueue = new Queue<ToPlay>();
496   - int wordsCount = 0;
497   - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", this));
  476 + String[] stringPos = gloss.Split(' ');
498 477  
499   - foreach (string aniName in stringPos)
500   - {
501   - Debug.Log("GPM.lAP(" + gloss + "): Animation name: " + aniName);
  478 + Queue<ToPlay> toPlayQueue = new Queue<ToPlay>();
  479 + int wordsCount = 0;
  480 + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", this));
  481 +
  482 + foreach (string aniName in stringPos)
  483 + {
  484 + Debug.Log("GPM.LAP(" + gloss + "): Animation name: " + aniName);
  485 +
  486 + wordsCount++;
  487 + if (String.IsNullOrEmpty(aniName)) continue;
502 488  
503   - wordsCount++;
504   - if (String.IsNullOrEmpty(aniName)) continue;
  489 + bool nonexistent = nonexistentAssetBundles.Contains(aniName);
  490 + bool loaded = loadedAssetBundles.Contains(aniName);
505 491  
506   - bool nonexistent = nonexistentAssetBundles.Contains(aniName);
507   - bool loaded = loadedAssetBundles.Contains(aniName);
  492 + if ( ! nonexistent && ! loaded)
  493 + {
  494 + // Função loadAssetBundle é definida pela classe filha
  495 + WWW www = loadAssetBundle(aniName);
508 496  
509   - if ( ! nonexistent && ! loaded)
  497 + if (www != null)
510 498 {
511   - // Função loadAssetBundle é definida pela classe filha
512   - WWW www = loadAssetBundle(aniName);
  499 + Debug.Log("GPM:LAP(" + gloss + "): www != null");
  500 + yield return www;
513 501  
514   - if (www != null)
515   - {
516   - Debug.Log("GPM:lAP(" + gloss + "): www != null");
517   - yield return www;
  502 + AssetBundle bundle = null;
518 503  
519   - AssetBundle bundle = null;
  504 + if (www.error == null)
  505 + {
  506 + Debug.Log("GPM:LAP(" + gloss + "): www.error == null");
  507 + bundle = www.assetBundle;
520 508  
521   - if (www.error == null)
  509 + if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name))
522 510 {
523   - Debug.Log("GPM:lAP(" + gloss + "): www.error == null");
524   - bundle = www.assetBundle;
  511 + AnimationClip aniClip = bundle.mainAsset as AnimationClip;
  512 + bundle.Unload(false);
525 513  
526   - if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name))
  514 + if (aniClip)
527 515 {
528   - AnimationClip aniClip = bundle.mainAsset as AnimationClip;
529   - bundle.Unload(false);
530   -
531   - if (aniClip)
532   - {
533   - COMPONENT_ANIMATION.AddClip(aniClip, aniName);
  516 + COMPONENT_ANIMATION.AddClip(aniClip, aniName);
534 517  
535   - loadedAssetBundles.Add(aniName);
536   - loaded = true;
  518 + loadedAssetBundles.Add(aniName);
  519 + loaded = true;
537 520  
538   - Debug.Log("GPM:lAP(" + gloss + "): Bundle \"" + aniName + "\" loaded!");
539   - }
540   - else Debug.Log ("GPM:lAP(" + gloss + "): Sinal \"" + aniName + "\" foi não carregado corretamente.");
  521 + Debug.Log("GPM:LAP(" + gloss + "): Bundle \"" + aniName + "\" loaded!");
541 522 }
  523 + else Debug.Log ("GPM:lAP(" + gloss + "): Sinal \"" + aniName + "\" foi não carregado corretamente.");
542 524 }
543   - else onConnectionError(gloss, aniName);
544 525 }
545 526 else onConnectionError(gloss, aniName);
546 527 }
  528 + else onConnectionError(gloss, aniName);
  529 + }
547 530  
548   - // Reproduz palavra
549   - if (loaded)
  531 + // Reproduz palavra
  532 + if (loaded)
  533 + {
  534 + if (spelled)
550 535 {
551   - if (spelled)
552   - {
553   - // Default
554   - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, this));
555   - spelled = false;
556   - }
557   -
558   - if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName))
559   - {
560   - lastAnimationSubtitle = "";
561   - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, "", this));
562   - }
563   - else
564   - {
565   - lastAnimationSubtitle = aniName;
566   - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, this));
567   - }
  536 + // Default
  537 + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, this));
  538 + spelled = false;
568 539 }
569 540  
570   - // Soletra palavra
  541 + if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName))
  542 + {
  543 + lastAnimationSubtitle = "";
  544 + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, "", this));
  545 + }
571 546 else
572 547 {
573   - // Se a animação não foi carregada e nem está marcada como não existente,
574   - // adiciona ao set de animações não existentes
575   - if ( ! nonexistent)
576   - nonexistentAssetBundles.Add(aniName);
  548 + lastAnimationSubtitle = aniName;
  549 + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, this));
  550 + }
  551 + }
  552 +
  553 + // Soletra palavra
  554 + else
  555 + {
  556 + // Se a animação não foi carregada e nem está marcada como não existente,
  557 + // adiciona ao set de animações não existentes
  558 + if ( ! nonexistent)
  559 + nonexistentAssetBundles.Add(aniName);
577 560  
578   - UnityEngine.Debug.Log("GPM:lAP(" + gloss + "): To spell: " + aniName);
  561 + UnityEngine.Debug.Log("GPM:lAP(" + gloss + "): To spell: " + aniName);
579 562  
580   - if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName))
581   - {
  563 + if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName))
  564 + {
  565 + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F));
  566 + spelled = false;
  567 + }
  568 + else
  569 + {
  570 + // Se já houve o soletramento de alguma palavra, reproduz animação default
  571 + if (spelled)
582 572 toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F));
583   - spelled = false;
584   - }
585 573 else
586   - {
587   - // Se já houve o soletramento de alguma palavra, reproduz animação default
588   - if (spelled)
589   - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F));
590   - else
591   - spelled = true;
  574 + spelled = true;
592 575  
593   - lastAnimationSubtitle = spellWord(toPlayQueue, aniName);
594   - }
  576 + lastAnimationSubtitle = spellWord(toPlayQueue, aniName);
595 577 }
596   -
597   - if (toPlayQueue.Count > 4 || wordsCount == stringPos.Length)
598   - while (toPlayQueue.Count > 0)
599   - toPlayQueue.Dequeue().play(this);
600 578 }
601 579  
602   - // Default
603   - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "");
604   -
605   - this.loading = false;
606   - // onPlayingStateChange();
607   - this.randomAnimations.unlockFor("loadAndPlay");
  580 + if (toPlayQueue.Count > 4 || wordsCount == stringPos.Length)
  581 + while (toPlayQueue.Count > 0)
  582 + toPlayQueue.Dequeue().play(this);
608 583 }
609   - }
610 584  
611   - private System.Object LOCKER_PLAYING = new System.Object();
  585 + // Default
  586 + playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "");
  587 +
  588 + this.randomAnimations.unlockFor("GPM.LoadAndPlay");
  589 + this.loading = false;
  590 + // onPlayingStateChange();
  591 + }
612 592  
613 593 /* Sincroniza as legendas com as animações. */
614   - IEnumerator handleStates()
  594 + private IEnumerator SubtitlesSynchronizer()
615 595 {
616   - lock (LOCKER_PLAYING)
617   - {
618   - UnityEngine.Debug.Log("GPM:hS()");
  596 + UnityEngine.Debug.Log("GPM.SS()");
619 597  
620   - this.randomAnimations.lockFor("handleStates");
621   - this.playing = true;
622   - onPlayingStateChange();
  598 + this.randomAnimations.lockFor("GPM.SubtitlesSynchronizer");
  599 + this.playing = true;
  600 + onPlayingStateChange();
623 601  
624   - bool isNotEmpty;
625   - lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; }
  602 + bool isNotEmpty;
  603 + lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; }
626 604  
627   - // Animação anterior a atual
628   - AnimationReference endedAnimation = null;
  605 + // Animação anterior a atual
  606 + AnimationReference endedAnimation = null;
629 607  
630   - // Enquanto estiver executando a corotina "loadAndPlay"
631   - // ou existir animações na fila de reprodução
632   - while (loading || isNotEmpty)
  608 + // Enquanto estiver executando a corotina "loadAndPlay"
  609 + // ou existir animações na fila de reprodução
  610 + while (loading || isNotEmpty)
  611 + {
  612 + // Se não houver animações na fila, espera
  613 + if (isNotEmpty)
633 614 {
634   - // Se não houver animações na fila, espera
635   - if (isNotEmpty)
  615 + // Pega primeira animação
  616 + AnimationReference reference;
  617 + lock (this.animQueue) { reference = this.animQueue.Peek(); }
  618 +
  619 + // Se estiver sendo reproduzida
  620 + if (COMPONENT_ANIMATION.IsPlaying(reference.name))
636 621 {
637   - // Pega primeira animação
638   - AnimationReference reference;
639   - lock (this.animQueue) { reference = this.animQueue.Peek(); }
  622 + Debug.Log("GPM.SS(): Playing " + reference.name);
  623 + this.subtitles.setText(reference.subtitle);
640 624  
641   - // Se estiver sendo reproduzida
642   - if (COMPONENT_ANIMATION.IsPlaying(reference.name))
  625 + // Animação seguinte
  626 + AnimationReference next = null;
  627 + lock (this.animQueue)
643 628 {
644   - Debug.Log("GPM:hS(): Playing " + reference.name);
645   - this.subtitles.setText(reference.subtitle);
646   -
647   - // Animação seguinte
648   - AnimationReference next = null;
649   - lock (this.animQueue)
650   - {
651   - this.animationPlaying = this.animQueue.Dequeue();
  629 + this.animationPlaying = this.animQueue.Dequeue();
652 630  
653   - if (this.animQueue.Count > 0)
654   - next = this.animQueue.Peek();
655   - }
  631 + if (this.animQueue.Count > 0)
  632 + next = this.animQueue.Peek();
  633 + }
656 634  
657   - while (true)
  635 + while (true)
  636 + {
  637 + // Se a próxima animação estiver sendo reproduzida (no fade)
  638 + if (next != null && COMPONENT_ANIMATION.IsPlaying(next.name))
658 639 {
659   - // Se a próxima animação estiver sendo reproduzida (no fade)
660   - if (next != null && COMPONENT_ANIMATION.IsPlaying(next.name))
661   - {
662   - // Se a animação anterior a atual não tiver acabado,
663   - // espera acabar e só então conta o tempo
664   - if (endedAnimation != null)
665   - while (COMPONENT_ANIMATION.IsPlaying(endedAnimation.name))
666   - yield return null;
667   -
668   - // Tempo para pular para a legenda da próxima animação
669   - yield return new WaitForSeconds(0.4F);
  640 + // Se a animação anterior a atual não tiver acabado,
  641 + // espera acabar e só então conta o tempo
  642 + if (endedAnimation != null)
  643 + while (COMPONENT_ANIMATION.IsPlaying(endedAnimation.name))
  644 + yield return null;
670 645  
671   - // Deprecated
672   - // yield return WaitForContinuousMillis.Wait(this, 300);
673   -
674   - endedAnimation = reference;
675   - break;
676   - }
  646 + // Tempo para pular para a legenda da próxima animação
  647 + yield return new WaitForSeconds(0.4F);
677 648  
678   - else if (COMPONENT_ANIMATION.IsPlaying(reference.name))
679   - yield return null;
  649 + // Deprecated
  650 + // yield return WaitForContinuousMillis.Wait(this, 300);
680 651  
681   - else break;
  652 + endedAnimation = reference;
  653 + break;
682 654 }
683 655  
684   - reference = null;
  656 + else if (COMPONENT_ANIMATION.IsPlaying(reference.name))
  657 + yield return null;
  658 +
  659 + else break;
685 660 }
686 661  
687   - // Se a animação não tiver sido liberada e seu AnimationState for nulo,
688   - // a animação será liberada
689   - if (reference != null && reference.state == null)
690   - lock (this.animQueue) { this.animQueue.Dequeue(); }
691   - else
692   - yield return null;
  662 + reference = null;
693 663 }
694   - else yield return null;
695 664  
696   - lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; }
  665 + // Se a animação não tiver sido liberada e seu AnimationState for nulo,
  666 + // a animação será liberada
  667 + if (reference != null && reference.state == null)
  668 + lock (this.animQueue) { this.animQueue.Dequeue(); }
  669 + else
  670 + yield return null;
697 671 }
698   - UnityEngine.Debug.Log("GPM:sH(): All done.");
699   -
700   - this.subtitles.setText("");
  672 + else yield return null;
701 673  
702   - resetStates();
703   - this.randomAnimations.unlockFor("handleStates");
  674 + lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; }
704 675 }
  676 + UnityEngine.Debug.Log("GPM.SS(): All done.");
  677 +
  678 + this.subtitles.setText("");
  679 +
  680 + resetStates();
  681 + this.randomAnimations.unlockFor("GPM.SubtitlesSynchronizer");
705 682 }
706 683  
707 684 public void resetStates()
... ...
Assets/Scripts/Server.cs
... ... @@ -15,116 +15,119 @@ using System;
15 15 using System.IO;
16 16 using System.Net;
17 17 using System.Net.Sockets;
18   -using System.Text;
19   -using System.Threading;
20 18  
21 19 public class Server {
22 20  
23   - TcpClient client;
24   - NetworkStream stream;
25   - TcpListener server;
26   - Semaphore serverSemaphore;
27   - PlayerManager inspector;
28   - Int32 port = 5555;
29   -
30   - public Server(Semaphore ss, PlayerManager inspec){
31   - serverSemaphore = ss;
32   - inspector = inspec;
33   - } // constructor
34   -
35   - public void startServer(){
36   - try{
37   - IPAddress localAddr = IPAddress.Parse("0.0.0.0");
38   - server = new TcpListener (localAddr, port);
39   - server.Start(); // Starts listening for incoming connection requests.
40   - client = server.AcceptTcpClient(); // Accepts a pending connection request.
41   - stream = client.GetStream();
  21 + public readonly string ADDRESS = "0.0.0.0";
  22 + public readonly Int32 PORT = 5555;
42 23  
43   - serverSemaphore.Release (); // Releases InspectorScript.Start() [Connection]
44   - getPTSFromCore();
45   - }
  24 + private TcpClient client;
  25 + private NetworkStream stream;
  26 + private TcpListener server;
  27 + private bool isReady = false;
46 28  
47   - catch(SocketException e){
48   - Debug.Log(e);
49   - closeConnections();
50   - Application.Quit();
51   - }
52   - catch(IOException e){
53   - Debug.Log(e);
54   - closeConnections();
55   - Application.Quit();
  29 + private PlayerManager manager;
  30 +
  31 + public Server(PlayerManager manager)
  32 + {
  33 + this.manager = manager;
  34 +
  35 + try {
  36 + // Starts listening for incoming connection requests
  37 + server = new TcpListener(IPAddress.Parse(ADDRESS), PORT);
  38 + server.Start();
  39 +
  40 + // Accepts a pending connection request
  41 + Debug.Log("S(): Waiting client");
  42 + client = server.AcceptTcpClient();
  43 + stream = client.GetStream();
56 44 }
57   - catch(Exception e){
  45 + catch (Exception e)
  46 + {
58 47 Debug.Log(e);
59   - closeConnections();
60   - Application.Quit();
  48 + CloseConnections();
  49 + manager.FinalizationLocker.Release();
  50 +
  51 + throw e;
61 52 }
62   - } // startServer
  53 + }
  54 +
  55 + public bool IsNotReady {
  56 + get { return !isReady; }
  57 + }
63 58  
64   - // Receives glosa and pts from Core
65   - void getPTSFromCore()
  59 + /**
  60 + * Starts receiving of glosa and time from server.
  61 + * Stops when receive "FINALIZE".
  62 + */
  63 + public void StartCommunication()
66 64 {
  65 + Debug.Log("S.SC()");
  66 +
67 67 try
68 68 {
69 69 Byte[] bytes = new Byte[1024];
70   - String data = null;
71   - int i;
72   - Byte[] sendToCore;
73   -
74   - /*Loop to receive all the data from Core
75   - util get the string "FINALIZE\0"
76   - '\0' for c++*/
77   -
78   - Debug.Log("getPTSFromCore");
  70 + int size;
79 71  
80   - while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
  72 + while ((size = stream.Read(bytes, 0, bytes.Length)) != 0)
81 73 {
82   - data = System.Text.UTF8Encoding.UTF8.GetString(bytes, 0, i);
  74 + String data = System.Text.UTF8Encoding.UTF8.GetString(bytes, 0, size);
83 75  
84   - sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("OK\0"); // allows Core to send next stream
  76 + // Notify the core that the message was received
  77 + Byte[] sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("OK\0");
85 78 stream.Write(sendToCore, 0, sendToCore.Length);
86 79  
87 80 Message message = new Message(data);
88 81  
89   - Debug.Log("gPFC: received: " + message.Text);
  82 + Debug.Log("S.SC(): Received: " + message.Text);
90 83  
91 84 if (message.Text.Equals("FINALIZE"))
92 85 {
93   - inspector.finishConnection();
  86 + isReady = true;
94 87 break;
95 88 }
96   - else
97   - inspector.enqueueMessage(message);
  89 + else manager.enqueueMessage(message);
98 90 }
99 91  
100   - Debug.Log("~~ getPTSFromCore");
  92 + Debug.Log("S.SC(): END");
101 93 }
102 94 catch (Exception e)
103 95 {
104   - throw new Exception(e.Source);
  96 + Debug.Log(e);
  97 +
  98 + if (!this.isReady)
  99 + {
  100 + CloseConnections();
  101 + manager.FinalizationLocker.Release();
  102 + }
  103 +
  104 + throw e;
105 105 }
106   - } // getPTSFromCore
  106 + }
107 107  
108   - public void sendFinalizeToCore(){
109   - Byte[] sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("FINALIZE\0"); // ativar para o core
  108 + public void SendFinalizeToCore()
  109 + {
  110 + Byte[] sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("FINALIZE\0");
110 111 stream.Write(sendToCore, 0, sendToCore.Length);
111   - //closeConnections();
112   - }
113   - public void closeConnections(){
114 112  
  113 + CloseConnections();
  114 + }
  115 +
  116 + private void CloseConnections()
  117 + {
115 118 try {
116 119 client.Close();
117 120 stream.Close();
118 121 server.Stop();
119 122 }
120   - catch(SocketException e){
  123 + catch (SocketException e) {
121 124 Debug.Log(e);
122   - closeConnections();
  125 + CloseConnections();
123 126 }
124   - catch(IOException e){
  127 + catch (IOException e) {
125 128 Debug.Log(e);
126   - closeConnections();
  129 + CloseConnections();
127 130 }
128   - } // closeConnections
  131 + }
129 132  
130 133 }
131 134 \ No newline at end of file
... ...