From 68012fb0dc73866ffa1103764ebeca834d56010f Mon Sep 17 00:00:00 2001 From: Mateus Pires Date: Mon, 4 Jul 2016 16:15:46 -0200 Subject: [PATCH] Fix concurrence problem --- Assets/Scripts/PlayerManager.cs | 79 ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- Assets/Scripts/PlayerManager/GenericPlayerManager.cs | 399 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Assets/Scripts/Server.cs | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------- 3 files changed, 307 insertions(+), 310 deletions(-) diff --git a/Assets/Scripts/PlayerManager.cs b/Assets/Scripts/PlayerManager.cs index 409d9c1..acdb9d4 100644 --- a/Assets/Scripts/PlayerManager.cs +++ b/Assets/Scripts/PlayerManager.cs @@ -5,21 +5,30 @@ using System.IO; using System.Threading; using System.Collections; using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Net.Sockets; -using System.Diagnostics; public class PlayerManager : GenericPlayerManager { private Server server = null; - private Semaphore serverSemaphore = null; - private volatile Queue messages = new Queue(); - private volatile bool toFinalize = false; + + private readonly Semaphore finalizationLocker = new Semaphore(0, 1); + private readonly object messageQueueLocker = new object(); + + public Semaphore FinalizationLocker { + get { return this.finalizationLocker; } + } + + public object MessageQueueLocker { + get { return this.messageQueueLocker; } + } public override void Start() { base.Start(); + Screen.SetResolution(800, 600, false); + + Debug.Log("PM.S(): Setting args"); + string[] args = Environment.GetCommandLineArgs(); if (args.Length >= 5) @@ -56,57 +65,65 @@ public class PlayerManager : GenericPlayerManager { ); } - serverSemaphore = new Semaphore(0, 1); - server = new Server(serverSemaphore, this); - Thread t = new Thread(new ThreadStart(server.startServer)); - t.Start(); + Debug.Log("PM.S(): Setting lockers"); - serverSemaphore.WaitOne(); + // Starts thread to wait for app finalization + new Thread(new ThreadStart(waitFinalize)).Start(); - //UnityEngine.Debug.Log("Datapath: " + Application.dataPath); + Debug.Log("PM.S(): Starting server"); - Screen.SetResolution(800, 600, false); - } + // Start server + server = new Server(this); + new Thread(new ThreadStart(server.StartCommunication)).Start(); - protected void Update() { - if (toFinalize) - { - UnityEngine.Debug.Log("PM.U(): Update -> toFinalize == " + toFinalize); - Application.Quit(); - } + // Starts communication thread and wait for finalize + StartCoroutine(MessageChecker()); } - public void enqueueMessage(Message message) { - //UnityEngine.Debug.Log("PlayerManager.enqueueMessage( " + message.Text + " )"); + public void enqueueMessage(Message message) + { + UnityEngine.Debug.Log("PM.eM(): " + message.Text + ", " + message.Time); messages.Enqueue(message); } - public void finishConnection() { - //UnityEngine.Debug.Log("PlayerManager.finishConnection()"); - StartCoroutine(MessageChecker()); + private void waitFinalize() + { + Debug.Log("PM.WF(): START"); + FinalizationLocker.WaitOne(); + Debug.Log("PM.WF(): Finalize command received"); + + Application.Quit(); } IEnumerator MessageChecker() { + Debug.Log("PM.MC(): START"); + + while (server.IsNotReady) + yield return null; + + Debug.Log("PM.MC(): Starting to read messages"); + CameraCapture.capture = true; foreach (Message message in messages) { while ((CameraCapture.frameNumber * 1000) / CameraCapture.frameRate < message.Time) yield return null; - UnityEngine.Debug.Log("PM.MS(): Loading " + message.Text); + UnityEngine.Debug.Log("PM.MC(): Loading " + message.Text); base.playQueued(message.Text); } while (base.isPlaying() || base.isLoading()) yield return null; - UnityEngine.Debug.Log("PM.MS(): ALL DONE!"); - server.sendFinalizeToCore(); + UnityEngine.Debug.Log("PM.MC(): All done!"); + + server.SendFinalizeToCore(); CameraCapture.capture = false; - UnityEngine.Debug.Log("PM.MS(): CameraCapture.capture == " + CameraCapture.capture); - toFinalize = true; - UnityEngine.Debug.Log("PM.MS(): toFinalize == " + toFinalize); + UnityEngine.Debug.Log("PM.MC(): CameraCapture.capture == " + CameraCapture.capture); + + Application.Quit(); } public override WWW loadAssetBundle(string aniName) diff --git a/Assets/Scripts/PlayerManager/GenericPlayerManager.cs b/Assets/Scripts/PlayerManager/GenericPlayerManager.cs index d0b88d0..c6233ce 100644 --- a/Assets/Scripts/PlayerManager/GenericPlayerManager.cs +++ b/Assets/Scripts/PlayerManager/GenericPlayerManager.cs @@ -18,17 +18,23 @@ * - Reprodução * Quando não há acesso aos bundles dos sinais de pontuação, eles são ignorados. * Ç adicionado como TYPE_WORD. + * + * Versão 2.5 + * - Sincronização + * Retira os LOCKERs. + * Os LOCKERs não impedem que duas Coroutines entrem na mesma sessão crítica. + * A soluação utiliza o estado loading na coroutine LoadAndPlay. + * - Código + * Retira namespaces não utilizados. + * Adiciona logs. */ //Log Dir http://docs.unity3d.com/Manual/LogFiles.html + using UnityEngine; using System.Collections; using System.Collections.Generic; using System; -using System.Threading; -using System.IO; -using System.Text; -using System.Runtime.InteropServices; using UnityEngine.UI; public abstract class GenericPlayerManager : MonoBehaviour { @@ -66,6 +72,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { // True quando é chamada a função de pausa private volatile bool paused = false; + private IEnumerator subtitlesSynchronizer; + // Se diferente de null, não está reproduzindo animação de intervalo private AnimationState intervalAnimationState = null; // Usado para pausar quando comandado @@ -87,6 +95,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { subtitles.DefaultLetterSpeed = new DefaultSignSpeed(3F, 4.3F); subtitles.DefaultNumberSpeed = new DefaultSignSpeed(1.5F, 2.9F); + subtitlesSynchronizer = SubtitlesSynchronizer(); + AVATAR = GameObject.FindGameObjectWithTag("avatar"); COMPONENT_ANIMATION = AVATAR.GetComponent(); @@ -175,8 +185,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { /* Para carregamento e animações */ public void stopAll() { - StopCoroutine("loadAndPlay"); - this.randomAnimations.unlockFor("loadAndPlay"); + StopCoroutine("LoadAndPlay"); + this.randomAnimations.unlockFor("GPM.LoadAndPlay"); loading = false; stopAnimations(); @@ -185,8 +195,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { /* Para animações */ public void stopAnimations() { - StopCoroutine("handleStates"); - this.randomAnimations.unlockFor("handleStates"); + StopCoroutine(subtitlesSynchronizer); + this.randomAnimations.unlockFor("GPM.SubtitlesSynchronizer"); this.subtitles.setText(""); lock (this.animQueue) { this.animQueue.Clear(); } @@ -294,62 +304,39 @@ public abstract class GenericPlayerManager : MonoBehaviour { setPauseState( ! this.paused); } - private System.Object LOCKER_PLAY = new System.Object(); - /* Play if anything loading or playing */ public bool playIfEmpty(string gloss) { - lock (LOCKER_PLAY) - { - if (this.loading || this.playing) - return false; + if (this.loading || this.playing) + return false; - StartCoroutine("loadAndPlay", gloss); - } + StartCoroutine(LoadAndPlay(gloss)); return true; } - private System.Object LOCKER_GLOSS_WATING = new System.Object(); - private int numGlossWating = 0; - public void setGlossWaiting(bool inc) { lock (LOCKER_GLOSS_WATING) { numGlossWating += inc ? 1 : -1; } } - public bool hasGlossWaiting() { lock (LOCKER_GLOSS_WATING) { return this.numGlossWating > 0; } } - - /* Enqueue animations for playing */ + /* Enqueue animations */ public void playQueued(string gloss) { - lock (LOCKER_PLAY) - { - Debug.Log("GPM.pQ(" + gloss + ")"); - setGlossWaiting(true); - StartCoroutine("loadAndPlay", gloss); - } + Debug.Log("GPM.pQ(" + gloss + ")"); + StartCoroutine(LoadAndPlay(gloss)); } /* Stop all and play */ public void playNow(string gloss) { - lock (LOCKER_PLAY) - { - Debug.Log("GPM.pN(" + gloss + ")"); - stopAll(); - StartCoroutine("loadAndPlay", gloss); - } + Debug.Log("GPM.pN(" + gloss + ")"); + stopAll(); + StartCoroutine(LoadAndPlay(gloss)); } /* Reproduz animação de intervalo */ public bool playIntervalAnimation(string name) { - if ( ! Monitor.TryEnter(LOCKER_PLAY)) - return false; - - lock (LOCKER_PLAY) - { - playDefaultAnimation(true); - this.intervalAnimationState = COMPONENT_ANIMATION.CrossFadeQueued(name, fadeLength, QueueMode.CompleteOthers); - playDefaultAnimation(false); - } - + playDefaultAnimation(true); + this.intervalAnimationState = COMPONENT_ANIMATION.CrossFadeQueued(name, fadeLength, QueueMode.CompleteOthers); + playDefaultAnimation(false); + return true; } @@ -443,7 +430,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { return lastAnimationSubtitle; } - /* Instruções para reprodução de aninmação */ + /* Instruções para reprodução de animação */ private struct ToPlay { private short type; @@ -469,239 +456,229 @@ public abstract class GenericPlayerManager : MonoBehaviour { context.playAnimation(this.type, this.name, this.subtitle, this.speed); } } - - private System.Object LOCKER_LOADING = new System.Object(); - + /* Carrega animações e reproduz */ - private IEnumerator loadAndPlay(string gloss) + private IEnumerator LoadAndPlay(string gloss) { - lock (LOCKER_LOADING) - { - Debug.Log("GPM.lAP(" + gloss + ")"); + Debug.Log("GPM.LAP(" + gloss + ")"); - this.randomAnimations.lockFor("loadAndPlay"); - this.loading = true; - setGlossWaiting(false); - // onPlayingStateChange(); + while (loading) yield return null; - string lastAnimationSubtitle = ""; - bool spelled = false; + this.loading = true; + // onPlayingStateChange(); + this.randomAnimations.lockFor("GPM.LoadAndPlay"); - if ( ! this.playing) - StartCoroutine("handleStates"); + string lastAnimationSubtitle = ""; + bool spelled = false; - String[] stringPos = gloss.Split(' '); + StartCoroutine(subtitlesSynchronizer); - Queue toPlayQueue = new Queue(); - int wordsCount = 0; - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", this)); + String[] stringPos = gloss.Split(' '); - foreach (string aniName in stringPos) - { - Debug.Log("GPM.lAP(" + gloss + "): Animation name: " + aniName); + Queue toPlayQueue = new Queue(); + int wordsCount = 0; + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", this)); + + foreach (string aniName in stringPos) + { + Debug.Log("GPM.LAP(" + gloss + "): Animation name: " + aniName); + + wordsCount++; + if (String.IsNullOrEmpty(aniName)) continue; - wordsCount++; - if (String.IsNullOrEmpty(aniName)) continue; + bool nonexistent = nonexistentAssetBundles.Contains(aniName); + bool loaded = loadedAssetBundles.Contains(aniName); - bool nonexistent = nonexistentAssetBundles.Contains(aniName); - bool loaded = loadedAssetBundles.Contains(aniName); + if ( ! nonexistent && ! loaded) + { + // Função loadAssetBundle é definida pela classe filha + WWW www = loadAssetBundle(aniName); - if ( ! nonexistent && ! loaded) + if (www != null) { - // Função loadAssetBundle é definida pela classe filha - WWW www = loadAssetBundle(aniName); + Debug.Log("GPM:LAP(" + gloss + "): www != null"); + yield return www; - if (www != null) - { - Debug.Log("GPM:lAP(" + gloss + "): www != null"); - yield return www; + AssetBundle bundle = null; - AssetBundle bundle = null; + if (www.error == null) + { + Debug.Log("GPM:LAP(" + gloss + "): www.error == null"); + bundle = www.assetBundle; - if (www.error == null) + if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) { - Debug.Log("GPM:lAP(" + gloss + "): www.error == null"); - bundle = www.assetBundle; + AnimationClip aniClip = bundle.mainAsset as AnimationClip; + bundle.Unload(false); - if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) + if (aniClip) { - AnimationClip aniClip = bundle.mainAsset as AnimationClip; - bundle.Unload(false); - - if (aniClip) - { - COMPONENT_ANIMATION.AddClip(aniClip, aniName); + COMPONENT_ANIMATION.AddClip(aniClip, aniName); - loadedAssetBundles.Add(aniName); - loaded = true; + loadedAssetBundles.Add(aniName); + loaded = true; - Debug.Log("GPM:lAP(" + gloss + "): Bundle \"" + aniName + "\" loaded!"); - } - else Debug.Log ("GPM:lAP(" + gloss + "): Sinal \"" + aniName + "\" foi não carregado corretamente."); + Debug.Log("GPM:LAP(" + gloss + "): Bundle \"" + aniName + "\" loaded!"); } + else Debug.Log ("GPM:lAP(" + gloss + "): Sinal \"" + aniName + "\" foi não carregado corretamente."); } - else onConnectionError(gloss, aniName); } else onConnectionError(gloss, aniName); } + else onConnectionError(gloss, aniName); + } - // Reproduz palavra - if (loaded) + // Reproduz palavra + if (loaded) + { + if (spelled) { - if (spelled) - { - // Default - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, this)); - spelled = false; - } - - if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) - { - lastAnimationSubtitle = ""; - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, "", this)); - } - else - { - lastAnimationSubtitle = aniName; - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, this)); - } + // Default + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, this)); + spelled = false; } - // Soletra palavra + if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) + { + lastAnimationSubtitle = ""; + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, "", this)); + } else { - // Se a animação não foi carregada e nem está marcada como não existente, - // adiciona ao set de animações não existentes - if ( ! nonexistent) - nonexistentAssetBundles.Add(aniName); + lastAnimationSubtitle = aniName; + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, aniName, this)); + } + } + + // Soletra palavra + else + { + // Se a animação não foi carregada e nem está marcada como não existente, + // adiciona ao set de animações não existentes + if ( ! nonexistent) + nonexistentAssetBundles.Add(aniName); - UnityEngine.Debug.Log("GPM:lAP(" + gloss + "): To spell: " + aniName); + UnityEngine.Debug.Log("GPM:lAP(" + gloss + "): To spell: " + aniName); - if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) - { + if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) + { + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); + spelled = false; + } + else + { + // Se já houve o soletramento de alguma palavra, reproduz animação default + if (spelled) toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); - spelled = false; - } else - { - // Se já houve o soletramento de alguma palavra, reproduz animação default - if (spelled) - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); - else - spelled = true; + spelled = true; - lastAnimationSubtitle = spellWord(toPlayQueue, aniName); - } + lastAnimationSubtitle = spellWord(toPlayQueue, aniName); } - - if (toPlayQueue.Count > 4 || wordsCount == stringPos.Length) - while (toPlayQueue.Count > 0) - toPlayQueue.Dequeue().play(this); } - // Default - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, ""); - - this.loading = false; - // onPlayingStateChange(); - this.randomAnimations.unlockFor("loadAndPlay"); + if (toPlayQueue.Count > 4 || wordsCount == stringPos.Length) + while (toPlayQueue.Count > 0) + toPlayQueue.Dequeue().play(this); } - } - private System.Object LOCKER_PLAYING = new System.Object(); + // Default + playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, ""); + + this.randomAnimations.unlockFor("GPM.LoadAndPlay"); + this.loading = false; + // onPlayingStateChange(); + } /* Sincroniza as legendas com as animações. */ - IEnumerator handleStates() + private IEnumerator SubtitlesSynchronizer() { - lock (LOCKER_PLAYING) - { - UnityEngine.Debug.Log("GPM:hS()"); + UnityEngine.Debug.Log("GPM.SS()"); - this.randomAnimations.lockFor("handleStates"); - this.playing = true; - onPlayingStateChange(); + this.randomAnimations.lockFor("GPM.SubtitlesSynchronizer"); + this.playing = true; + onPlayingStateChange(); - bool isNotEmpty; - lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; } + bool isNotEmpty; + lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; } - // Animação anterior a atual - AnimationReference endedAnimation = null; + // Animação anterior a atual + AnimationReference endedAnimation = null; - // Enquanto estiver executando a corotina "loadAndPlay" - // ou existir animações na fila de reprodução - while (loading || isNotEmpty) + // Enquanto estiver executando a corotina "loadAndPlay" + // ou existir animações na fila de reprodução + while (loading || isNotEmpty) + { + // Se não houver animações na fila, espera + if (isNotEmpty) { - // Se não houver animações na fila, espera - if (isNotEmpty) + // Pega primeira animação + AnimationReference reference; + lock (this.animQueue) { reference = this.animQueue.Peek(); } + + // Se estiver sendo reproduzida + if (COMPONENT_ANIMATION.IsPlaying(reference.name)) { - // Pega primeira animação - AnimationReference reference; - lock (this.animQueue) { reference = this.animQueue.Peek(); } + Debug.Log("GPM.SS(): Playing " + reference.name); + this.subtitles.setText(reference.subtitle); - // Se estiver sendo reproduzida - if (COMPONENT_ANIMATION.IsPlaying(reference.name)) + // Animação seguinte + AnimationReference next = null; + lock (this.animQueue) { - Debug.Log("GPM:hS(): Playing " + reference.name); - this.subtitles.setText(reference.subtitle); - - // Animação seguinte - AnimationReference next = null; - lock (this.animQueue) - { - this.animationPlaying = this.animQueue.Dequeue(); + this.animationPlaying = this.animQueue.Dequeue(); - if (this.animQueue.Count > 0) - next = this.animQueue.Peek(); - } + if (this.animQueue.Count > 0) + next = this.animQueue.Peek(); + } - while (true) + while (true) + { + // Se a próxima animação estiver sendo reproduzida (no fade) + if (next != null && COMPONENT_ANIMATION.IsPlaying(next.name)) { - // Se a próxima animação estiver sendo reproduzida (no fade) - if (next != null && COMPONENT_ANIMATION.IsPlaying(next.name)) - { - // Se a animação anterior a atual não tiver acabado, - // espera acabar e só então conta o tempo - if (endedAnimation != null) - while (COMPONENT_ANIMATION.IsPlaying(endedAnimation.name)) - yield return null; - - // Tempo para pular para a legenda da próxima animação - yield return new WaitForSeconds(0.4F); + // Se a animação anterior a atual não tiver acabado, + // espera acabar e só então conta o tempo + if (endedAnimation != null) + while (COMPONENT_ANIMATION.IsPlaying(endedAnimation.name)) + yield return null; - // Deprecated - // yield return WaitForContinuousMillis.Wait(this, 300); - - endedAnimation = reference; - break; - } + // Tempo para pular para a legenda da próxima animação + yield return new WaitForSeconds(0.4F); - else if (COMPONENT_ANIMATION.IsPlaying(reference.name)) - yield return null; + // Deprecated + // yield return WaitForContinuousMillis.Wait(this, 300); - else break; + endedAnimation = reference; + break; } - reference = null; + else if (COMPONENT_ANIMATION.IsPlaying(reference.name)) + yield return null; + + else break; } - // Se a animação não tiver sido liberada e seu AnimationState for nulo, - // a animação será liberada - if (reference != null && reference.state == null) - lock (this.animQueue) { this.animQueue.Dequeue(); } - else - yield return null; + reference = null; } - else yield return null; - lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; } + // Se a animação não tiver sido liberada e seu AnimationState for nulo, + // a animação será liberada + if (reference != null && reference.state == null) + lock (this.animQueue) { this.animQueue.Dequeue(); } + else + yield return null; } - UnityEngine.Debug.Log("GPM:sH(): All done."); - - this.subtitles.setText(""); + else yield return null; - resetStates(); - this.randomAnimations.unlockFor("handleStates"); + lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; } } + UnityEngine.Debug.Log("GPM.SS(): All done."); + + this.subtitles.setText(""); + + resetStates(); + this.randomAnimations.unlockFor("GPM.SubtitlesSynchronizer"); } public void resetStates() diff --git a/Assets/Scripts/Server.cs b/Assets/Scripts/Server.cs index 7701ec4..08b20e2 100644 --- a/Assets/Scripts/Server.cs +++ b/Assets/Scripts/Server.cs @@ -15,116 +15,119 @@ using System; using System.IO; using System.Net; using System.Net.Sockets; -using System.Text; -using System.Threading; public class Server { - TcpClient client; - NetworkStream stream; - TcpListener server; - Semaphore serverSemaphore; - PlayerManager inspector; - Int32 port = 5555; - - public Server(Semaphore ss, PlayerManager inspec){ - serverSemaphore = ss; - inspector = inspec; - } // constructor - - public void startServer(){ - try{ - IPAddress localAddr = IPAddress.Parse("0.0.0.0"); - server = new TcpListener (localAddr, port); - server.Start(); // Starts listening for incoming connection requests. - client = server.AcceptTcpClient(); // Accepts a pending connection request. - stream = client.GetStream(); + public readonly string ADDRESS = "0.0.0.0"; + public readonly Int32 PORT = 5555; - serverSemaphore.Release (); // Releases InspectorScript.Start() [Connection] - getPTSFromCore(); - } + private TcpClient client; + private NetworkStream stream; + private TcpListener server; + private bool isReady = false; - catch(SocketException e){ - Debug.Log(e); - closeConnections(); - Application.Quit(); - } - catch(IOException e){ - Debug.Log(e); - closeConnections(); - Application.Quit(); + private PlayerManager manager; + + public Server(PlayerManager manager) + { + this.manager = manager; + + try { + // Starts listening for incoming connection requests + server = new TcpListener(IPAddress.Parse(ADDRESS), PORT); + server.Start(); + + // Accepts a pending connection request + Debug.Log("S(): Waiting client"); + client = server.AcceptTcpClient(); + stream = client.GetStream(); } - catch(Exception e){ + catch (Exception e) + { Debug.Log(e); - closeConnections(); - Application.Quit(); + CloseConnections(); + manager.FinalizationLocker.Release(); + + throw e; } - } // startServer + } + + public bool IsNotReady { + get { return !isReady; } + } - // Receives glosa and pts from Core - void getPTSFromCore() + /** + * Starts receiving of glosa and time from server. + * Stops when receive "FINALIZE". + */ + public void StartCommunication() { + Debug.Log("S.SC()"); + try { Byte[] bytes = new Byte[1024]; - String data = null; - int i; - Byte[] sendToCore; - - /*Loop to receive all the data from Core - util get the string "FINALIZE\0" - '\0' for c++*/ - - Debug.Log("getPTSFromCore"); + int size; - while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) + while ((size = stream.Read(bytes, 0, bytes.Length)) != 0) { - data = System.Text.UTF8Encoding.UTF8.GetString(bytes, 0, i); + String data = System.Text.UTF8Encoding.UTF8.GetString(bytes, 0, size); - sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("OK\0"); // allows Core to send next stream + // Notify the core that the message was received + Byte[] sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("OK\0"); stream.Write(sendToCore, 0, sendToCore.Length); Message message = new Message(data); - Debug.Log("gPFC: received: " + message.Text); + Debug.Log("S.SC(): Received: " + message.Text); if (message.Text.Equals("FINALIZE")) { - inspector.finishConnection(); + isReady = true; break; } - else - inspector.enqueueMessage(message); + else manager.enqueueMessage(message); } - Debug.Log("~~ getPTSFromCore"); + Debug.Log("S.SC(): END"); } catch (Exception e) { - throw new Exception(e.Source); + Debug.Log(e); + + if (!this.isReady) + { + CloseConnections(); + manager.FinalizationLocker.Release(); + } + + throw e; } - } // getPTSFromCore + } - public void sendFinalizeToCore(){ - Byte[] sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("FINALIZE\0"); // ativar para o core + public void SendFinalizeToCore() + { + Byte[] sendToCore = System.Text.UTF8Encoding.UTF8.GetBytes("FINALIZE\0"); stream.Write(sendToCore, 0, sendToCore.Length); - //closeConnections(); - } - public void closeConnections(){ + CloseConnections(); + } + + private void CloseConnections() + { try { client.Close(); stream.Close(); server.Stop(); } - catch(SocketException e){ + catch (SocketException e) { Debug.Log(e); - closeConnections(); + CloseConnections(); } - catch(IOException e){ + catch (IOException e) { Debug.Log(e); - closeConnections(); + CloseConnections(); } - } // closeConnections + } } \ No newline at end of file -- libgit2 0.21.2