Commit 68012fb0dc73866ffa1103764ebeca834d56010f
1 parent
315b1e1e
Exists in
devel
Fix concurrence problem
Showing
3 changed files
with
307 additions
and
310 deletions
Show diff stats
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 | ... | ... |