From 1fc0eec1beba97e9b2c3f5cd1fafdd9999936aff Mon Sep 17 00:00:00 2001 From: Tim Sarbin Date: Sat, 1 Dec 2018 00:00:17 -0500 Subject: [PATCH] Added thread safety. --- OpenDiablo2.Common/Interfaces/IGameState.cs | 2 ++ .../Interfaces/MessageBus/ISessionManager.cs | 3 +- OpenDiablo2.Core/GameEngine.cs | 28 ++++++++++------- OpenDiablo2.Core/GameState/GameState.cs | 10 +++++- OpenDiablo2.ServiceBus/SessionManager.cs | 31 ++++++++++++++----- 5 files changed, 53 insertions(+), 21 deletions(-) diff --git a/OpenDiablo2.Common/Interfaces/IGameState.cs b/OpenDiablo2.Common/Interfaces/IGameState.cs index 4a4b5097..8be063cc 100644 --- a/OpenDiablo2.Common/Interfaces/IGameState.cs +++ b/OpenDiablo2.Common/Interfaces/IGameState.cs @@ -8,6 +8,8 @@ namespace OpenDiablo2.Common.Interfaces { public interface IGameState : IDisposable { + object ThreadLocker { get; } + int Act { get; } int Seed { get; } string MapName { get; } diff --git a/OpenDiablo2.Common/Interfaces/MessageBus/ISessionManager.cs b/OpenDiablo2.Common/Interfaces/MessageBus/ISessionManager.cs index 6e832818..aa3c33a8 100644 --- a/OpenDiablo2.Common/Interfaces/MessageBus/ISessionManager.cs +++ b/OpenDiablo2.Common/Interfaces/MessageBus/ISessionManager.cs @@ -11,6 +11,7 @@ namespace OpenDiablo2.Common.Interfaces { void Initialize(); void Stop(); - void JoinGame(string playerName); + + void JoinGame(string playerName, Action callback); } } diff --git a/OpenDiablo2.Core/GameEngine.cs b/OpenDiablo2.Core/GameEngine.cs index 47dc301f..93fb4dc7 100644 --- a/OpenDiablo2.Core/GameEngine.cs +++ b/OpenDiablo2.Core/GameEngine.cs @@ -111,20 +111,24 @@ namespace OpenDiablo2.Core lastTicks = curTicks; - getGameState().Update(ms); - getRenderWindow().Update(); - currentScene.Update(ms); - if (nextScene!= null) + lock (getGameState().ThreadLocker) { - currentScene = nextScene; - nextScene = null; - continue; + getGameState().Update(ms); + getRenderWindow().Update(); + currentScene.Update(ms); + + if (nextScene!= null) + { + currentScene = nextScene; + nextScene = null; + continue; + } + + renderWindow.Clear(); + currentScene.Render(); + + renderWindow.Sync(); } - - renderWindow.Clear(); - currentScene.Render(); - - renderWindow.Sync(); } } diff --git a/OpenDiablo2.Core/GameState/GameState.cs b/OpenDiablo2.Core/GameState/GameState.cs index b7b18c98..68570d27 100644 --- a/OpenDiablo2.Core/GameState/GameState.cs +++ b/OpenDiablo2.Core/GameState/GameState.cs @@ -21,6 +21,7 @@ namespace OpenDiablo2.Core.GameState_ private readonly Func getMapEngine; private readonly Func getSessionManager; + private Guid playerId; private float animationTime = 0f; private List mapInfo; private List mapDataLookup = new List(); @@ -35,6 +36,8 @@ namespace OpenDiablo2.Core.GameState_ public int Seed { get; internal set; } + public object ThreadLocker { get; } = new object(); + public GameState( ISceneManager sceneManager, IResourceManager resourceManager, @@ -65,7 +68,12 @@ namespace OpenDiablo2.Core.GameState_ mapInfo = new List(); sceneManager.ChangeScene("Game"); - sessionManager.JoinGame(characterName); // TODO: we need more attributes... + sessionManager.JoinGame(characterName, (id) => + { + log.Info("hoo"); + playerId = id; + }); // TODO: we need more attributes... + log.Info("woo"); } private void OnSetSeedEvent(object sender, int seed) diff --git a/OpenDiablo2.ServiceBus/SessionManager.cs b/OpenDiablo2.ServiceBus/SessionManager.cs index 5c417149..e9798f50 100644 --- a/OpenDiablo2.ServiceBus/SessionManager.cs +++ b/OpenDiablo2.ServiceBus/SessionManager.cs @@ -18,6 +18,7 @@ namespace OpenDiablo2.ServiceBus private readonly Func getSessionServer; private readonly eSessionType sessionType; private readonly Func getMessageFrame; + private readonly Func getGameState; private RequestSocket requestSocket; private AutoResetEvent resetEvent = new AutoResetEvent(false); @@ -28,11 +29,17 @@ namespace OpenDiablo2.ServiceBus public OnSetSeedEvent OnSetSeed { get; set; } public OnJoinGameEvent OnJoinGame { get; set; } - public SessionManager(eSessionType sessionType, Func getSessionServer, Func getMessageFrame) + public SessionManager( + eSessionType sessionType, + Func getSessionServer, + Func getMessageFrame, + Func getGameState + ) { this.getSessionServer = getSessionServer; this.sessionType = sessionType; this.getMessageFrame = getMessageFrame; + this.getGameState = getGameState; } public void Initialize() @@ -115,15 +122,25 @@ namespace OpenDiablo2.ServiceBus if (messageFrame.GetType() != typeof(T)) throw new ApplicationException("Recieved unexpected message frame!"); messageFrame.Data = frameData; - messageFrame.Process(requestSocket, this); + lock (getGameState().ThreadLocker) + { + messageFrame.Process(requestSocket, this); + } } - public void JoinGame(string playerName) + public void JoinGame(string playerName, Action callback) { - var mf = new MFJoinGame(playerName); - playerId = mf.PlayerId; - Send(mf); - ProcessMessageFrame(); + Task.Run(() => + { + var mf = new MFJoinGame(playerName); + playerId = mf.PlayerId; + Send(mf); + ProcessMessageFrame(); + lock (getGameState().ThreadLocker) + { + callback(playerId); + } + }); } } }