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,21 +5,30 @@ using System.IO; | ||
5 | using System.Threading; | 5 | using System.Threading; |
6 | using System.Collections; | 6 | using System.Collections; |
7 | using System.Collections.Generic; | 7 | using System.Collections.Generic; |
8 | -using System.Runtime.InteropServices; | ||
9 | -using System.Net.Sockets; | ||
10 | -using System.Diagnostics; | ||
11 | 8 | ||
12 | public class PlayerManager : GenericPlayerManager { | 9 | public class PlayerManager : GenericPlayerManager { |
13 | 10 | ||
14 | private Server server = null; | 11 | private Server server = null; |
15 | - private Semaphore serverSemaphore = null; | ||
16 | - | ||
17 | private volatile Queue<Message> messages = new Queue<Message>(); | 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 | public override void Start() | 25 | public override void Start() |
21 | { | 26 | { |
22 | base.Start(); | 27 | base.Start(); |
28 | + Screen.SetResolution(800, 600, false); | ||
29 | + | ||
30 | + Debug.Log("PM.S(): Setting args"); | ||
31 | + | ||
23 | string[] args = Environment.GetCommandLineArgs(); | 32 | string[] args = Environment.GetCommandLineArgs(); |
24 | 33 | ||
25 | if (args.Length >= 5) | 34 | if (args.Length >= 5) |
@@ -56,57 +65,65 @@ public class PlayerManager : GenericPlayerManager { | @@ -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 | messages.Enqueue(message); | 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 | IEnumerator MessageChecker() | 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 | CameraCapture.capture = true; | 107 | CameraCapture.capture = true; |
92 | foreach (Message message in messages) | 108 | foreach (Message message in messages) |
93 | { | 109 | { |
94 | while ((CameraCapture.frameNumber * 1000) / CameraCapture.frameRate < message.Time) | 110 | while ((CameraCapture.frameNumber * 1000) / CameraCapture.frameRate < message.Time) |
95 | yield return null; | 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 | base.playQueued(message.Text); | 114 | base.playQueued(message.Text); |
99 | } | 115 | } |
100 | 116 | ||
101 | while (base.isPlaying() || base.isLoading()) | 117 | while (base.isPlaying() || base.isLoading()) |
102 | yield return null; | 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 | CameraCapture.capture = false; | 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 | public override WWW loadAssetBundle(string aniName) | 129 | public override WWW loadAssetBundle(string aniName) |
Assets/Scripts/PlayerManager/GenericPlayerManager.cs
@@ -18,17 +18,23 @@ | @@ -18,17 +18,23 @@ | ||
18 | * - Reprodução | 18 | * - Reprodução |
19 | * Quando não há acesso aos bundles dos sinais de pontuação, eles são ignorados. | 19 | * Quando não há acesso aos bundles dos sinais de pontuação, eles são ignorados. |
20 | * Ç adicionado como TYPE_WORD. | 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 | //Log Dir http://docs.unity3d.com/Manual/LogFiles.html | 32 | //Log Dir http://docs.unity3d.com/Manual/LogFiles.html |
33 | + | ||
24 | using UnityEngine; | 34 | using UnityEngine; |
25 | using System.Collections; | 35 | using System.Collections; |
26 | using System.Collections.Generic; | 36 | using System.Collections.Generic; |
27 | using System; | 37 | using System; |
28 | -using System.Threading; | ||
29 | -using System.IO; | ||
30 | -using System.Text; | ||
31 | -using System.Runtime.InteropServices; | ||
32 | using UnityEngine.UI; | 38 | using UnityEngine.UI; |
33 | 39 | ||
34 | public abstract class GenericPlayerManager : MonoBehaviour { | 40 | public abstract class GenericPlayerManager : MonoBehaviour { |
@@ -66,6 +72,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -66,6 +72,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
66 | // True quando é chamada a função de pausa | 72 | // True quando é chamada a função de pausa |
67 | private volatile bool paused = false; | 73 | private volatile bool paused = false; |
68 | 74 | ||
75 | + private IEnumerator subtitlesSynchronizer; | ||
76 | + | ||
69 | // Se diferente de null, não está reproduzindo animação de intervalo | 77 | // Se diferente de null, não está reproduzindo animação de intervalo |
70 | private AnimationState intervalAnimationState = null; | 78 | private AnimationState intervalAnimationState = null; |
71 | // Usado para pausar quando comandado | 79 | // Usado para pausar quando comandado |
@@ -87,6 +95,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -87,6 +95,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
87 | subtitles.DefaultLetterSpeed = new DefaultSignSpeed(3F, 4.3F); | 95 | subtitles.DefaultLetterSpeed = new DefaultSignSpeed(3F, 4.3F); |
88 | subtitles.DefaultNumberSpeed = new DefaultSignSpeed(1.5F, 2.9F); | 96 | subtitles.DefaultNumberSpeed = new DefaultSignSpeed(1.5F, 2.9F); |
89 | 97 | ||
98 | + subtitlesSynchronizer = SubtitlesSynchronizer(); | ||
99 | + | ||
90 | AVATAR = GameObject.FindGameObjectWithTag("avatar"); | 100 | AVATAR = GameObject.FindGameObjectWithTag("avatar"); |
91 | COMPONENT_ANIMATION = AVATAR.GetComponent<Animation>(); | 101 | COMPONENT_ANIMATION = AVATAR.GetComponent<Animation>(); |
92 | 102 | ||
@@ -175,8 +185,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -175,8 +185,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
175 | /* Para carregamento e animações */ | 185 | /* Para carregamento e animações */ |
176 | public void stopAll() | 186 | public void stopAll() |
177 | { | 187 | { |
178 | - StopCoroutine("loadAndPlay"); | ||
179 | - this.randomAnimations.unlockFor("loadAndPlay"); | 188 | + StopCoroutine("LoadAndPlay"); |
189 | + this.randomAnimations.unlockFor("GPM.LoadAndPlay"); | ||
180 | loading = false; | 190 | loading = false; |
181 | 191 | ||
182 | stopAnimations(); | 192 | stopAnimations(); |
@@ -185,8 +195,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -185,8 +195,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
185 | /* Para animações */ | 195 | /* Para animações */ |
186 | public void stopAnimations() | 196 | public void stopAnimations() |
187 | { | 197 | { |
188 | - StopCoroutine("handleStates"); | ||
189 | - this.randomAnimations.unlockFor("handleStates"); | 198 | + StopCoroutine(subtitlesSynchronizer); |
199 | + this.randomAnimations.unlockFor("GPM.SubtitlesSynchronizer"); | ||
190 | this.subtitles.setText(""); | 200 | this.subtitles.setText(""); |
191 | 201 | ||
192 | lock (this.animQueue) { this.animQueue.Clear(); } | 202 | lock (this.animQueue) { this.animQueue.Clear(); } |
@@ -294,62 +304,39 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -294,62 +304,39 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
294 | setPauseState( ! this.paused); | 304 | setPauseState( ! this.paused); |
295 | } | 305 | } |
296 | 306 | ||
297 | - private System.Object LOCKER_PLAY = new System.Object(); | ||
298 | - | ||
299 | /* Play if anything loading or playing */ | 307 | /* Play if anything loading or playing */ |
300 | public bool playIfEmpty(string gloss) | 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 | return true; | 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 | public void playQueued(string gloss) | 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 | /* Stop all and play */ | 325 | /* Stop all and play */ |
330 | public void playNow(string gloss) | 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 | /* Reproduz animação de intervalo */ | 333 | /* Reproduz animação de intervalo */ |
341 | public bool playIntervalAnimation(string name) | 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 | return true; | 340 | return true; |
354 | } | 341 | } |
355 | 342 | ||
@@ -443,7 +430,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -443,7 +430,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
443 | return lastAnimationSubtitle; | 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 | private struct ToPlay | 434 | private struct ToPlay |
448 | { | 435 | { |
449 | private short type; | 436 | private short type; |
@@ -469,239 +456,229 @@ public abstract class GenericPlayerManager : MonoBehaviour { | @@ -469,239 +456,229 @@ public abstract class GenericPlayerManager : MonoBehaviour { | ||
469 | context.playAnimation(this.type, this.name, this.subtitle, this.speed); | 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 | /* Carrega animações e reproduz */ | 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 | else onConnectionError(gloss, aniName); | 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 | else | 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 | toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); | 572 | toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); |
583 | - spelled = false; | ||
584 | - } | ||
585 | else | 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 | /* Sincroniza as legendas com as animações. */ | 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 | public void resetStates() | 684 | public void resetStates() |
Assets/Scripts/Server.cs
@@ -15,116 +15,119 @@ using System; | @@ -15,116 +15,119 @@ using System; | ||
15 | using System.IO; | 15 | using System.IO; |
16 | using System.Net; | 16 | using System.Net; |
17 | using System.Net.Sockets; | 17 | using System.Net.Sockets; |
18 | -using System.Text; | ||
19 | -using System.Threading; | ||
20 | 18 | ||
21 | public class Server { | 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 | Debug.Log(e); | 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 | try | 67 | try |
68 | { | 68 | { |
69 | Byte[] bytes = new Byte[1024]; | 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 | stream.Write(sendToCore, 0, sendToCore.Length); | 78 | stream.Write(sendToCore, 0, sendToCore.Length); |
86 | 79 | ||
87 | Message message = new Message(data); | 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 | if (message.Text.Equals("FINALIZE")) | 84 | if (message.Text.Equals("FINALIZE")) |
92 | { | 85 | { |
93 | - inspector.finishConnection(); | 86 | + isReady = true; |
94 | break; | 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 | catch (Exception e) | 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 | stream.Write(sendToCore, 0, sendToCore.Length); | 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 | try { | 118 | try { |
116 | client.Close(); | 119 | client.Close(); |
117 | stream.Close(); | 120 | stream.Close(); |
118 | server.Stop(); | 121 | server.Stop(); |
119 | } | 122 | } |
120 | - catch(SocketException e){ | 123 | + catch (SocketException e) { |
121 | Debug.Log(e); | 124 | Debug.Log(e); |
122 | - closeConnections(); | 125 | + CloseConnections(); |
123 | } | 126 | } |
124 | - catch(IOException e){ | 127 | + catch (IOException e) { |
125 | Debug.Log(e); | 128 | Debug.Log(e); |
126 | - closeConnections(); | 129 | + CloseConnections(); |
127 | } | 130 | } |
128 | - } // closeConnections | 131 | + } |
129 | 132 | ||
130 | } | 133 | } |
131 | \ No newline at end of file | 134 | \ No newline at end of file |