diff --git a/src/scenes/entities/ShadowBallManager.tscn b/src/scenes/entities/SBallManager.tscn similarity index 54% rename from src/scenes/entities/ShadowBallManager.tscn rename to src/scenes/entities/SBallManager.tscn index ec6c6d1..c0dc867 100644 --- a/src/scenes/entities/ShadowBallManager.tscn +++ b/src/scenes/entities/SBallManager.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://scripts/scenes/entities/ShadowBallManager.cs" type="Script" id=1] +[ext_resource path="res://scripts/scenes/entities/SBallManager.cs" type="Script" id=1] [node name="ShadowBallManager" type="Spatial"] script = ExtResource( 1 ) diff --git a/src/scenes/entities/StalkerCore.tscn b/src/scenes/entities/StalkerCore.tscn index 0b870b8..41d6eed 100644 --- a/src/scenes/entities/StalkerCore.tscn +++ b/src/scenes/entities/StalkerCore.tscn @@ -3,7 +3,7 @@ [ext_resource path="res://scenes/levels/test.escn" type="PackedScene" id=1] [ext_resource path="res://scripts/scenes/entities/StalkerCore.cs" type="Script" id=2] [ext_resource path="res://scenes/entities/StalkerCamera.tscn" type="PackedScene" id=3] -[ext_resource path="res://scenes/entities/ShadowBallManager.tscn" type="PackedScene" id=4] +[ext_resource path="res://scenes/entities/SBallManager.tscn" type="PackedScene" id=4] [node name="StalkerCore" type="Spatial"] script = ExtResource( 2 ) diff --git a/src/scripts/cores/BStalkerContext.cs b/src/scripts/cores/BStalkerContext.cs index 56ec986..f0dd6e4 100644 --- a/src/scripts/cores/BStalkerContext.cs +++ b/src/scripts/cores/BStalkerContext.cs @@ -16,13 +16,18 @@ namespace BallanceStalker.Cores { private BStalkerContext() { mLogManager = new Managers.LogManager(); + mPresentManager = new Managers.PresentManager(mLogManager); } public void Dispose() { + mPresentManager.Dispose(); + + // logger will be released at the last position mLogManager.Dispose(); } public Managers.LogManager mLogManager; + public Managers.PresentManager mPresentManager; } } diff --git a/src/scripts/cores/managers/MultiplayManager.cs b/src/scripts/cores/managers/MultiplayManager.cs deleted file mode 100644 index 813be1b..0000000 --- a/src/scripts/cores/managers/MultiplayManager.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BallanceStalker.Cores.Managers { - public class MultiplayManager { - } -} diff --git a/src/scripts/cores/managers/PresentManager.cs b/src/scripts/cores/managers/PresentManager.cs new file mode 100644 index 0000000..33a893e --- /dev/null +++ b/src/scripts/cores/managers/PresentManager.cs @@ -0,0 +1,55 @@ +using BallanceStalker.Cores.Rec; +using BallanceStalker.Cores.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BallanceStalker.Cores.Managers { + public class PresentManager : IDisposable { + public PresentManager(LogManager logger) { + mLogger = logger; + } + + private LogManager mLogger; + + public event Action RecAdded; + public event Action RecRemoved; + public event Action MultiplayAdded; + public event Action MultiplayRemoved; + + private Dictionary mRecDict = new Dictionary(); + private Dictionary mMultiplayDict = new Dictionary(); + + public void AddSpiritTrailRec(string rec_folder, SpiritTrailRecType t) { + Guid g = Guid.NewGuid(); + var entity = new SpiritTrailRec(rec_folder, t); + entity.RecSetGuid(g); + mRecDict.Add(g, entity); + + RecAdded?.Invoke(g, entity); + } + public IRec GetRec(Guid uuid) { + if (mRecDict.TryGetValue(uuid, out IRec v)) { + return v; + } else return null; + } + public void RemoveRec(Guid uuid) { + if (mRecDict.TryGetValue(uuid, out IRec v)) { + mRecDict.Remove(uuid); + RecRemoved?.Invoke(uuid, v); + } + } + + public void Dispose() { + // free rec + foreach(var pair in mRecDict) { + RecRemoved?.Invoke(pair.Key, pair.Value); + } + mRecDict.Clear(); + + // todo: add multiplay free here + } + } +} diff --git a/src/scripts/cores/managers/RecManager.cs b/src/scripts/cores/managers/RecManager.cs deleted file mode 100644 index d973540..0000000 --- a/src/scripts/cores/managers/RecManager.cs +++ /dev/null @@ -1,29 +0,0 @@ -using BallanceStalker.Cores.Utils; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BallanceStalker.Cores.Managers { - public class RecManager { - - public event Action RecAdded; - public event Action RecRemoved; - - private Dictionary mRecDict = new Dictionary(); - - public Guid AddSpiritTrailRec(string rec_folder) { - - } - - public void RemoveRec(Guid uuid) { - - } - - public void Tick(float delta) { - - } - - } -} diff --git a/src/scripts/cores/rec/SpiritTrailRec.cs b/src/scripts/cores/rec/SpiritTrailRec.cs index 34d3d07..f5a0b3e 100644 --- a/src/scripts/cores/rec/SpiritTrailRec.cs +++ b/src/scripts/cores/rec/SpiritTrailRec.cs @@ -36,10 +36,20 @@ namespace BallanceStalker.Cores.Rec { mRecStateCursor = mRecTrafoCursor = 0; mRecRemainDelta = 0f; + + mGuid = Guid.Empty; } - public event Action RecRegisterBall; - public event Action RecUnregisterBall; + Guid mGuid; + public Guid RecGetGuid() { + return mGuid; + } + public void RecSetGuid(Guid g) { + mGuid = g; + } + + public event Action RecRegisterBall; + public event Action RecUnregisterBall; public event Action RecNewBallState; public event Action> RecNewBallStates; @@ -134,7 +144,7 @@ namespace BallanceStalker.Cores.Rec { public void Startup() { - RecRegisterBall?.Invoke(0, Path.GetFileName(mFileFolder)); + RecRegisterBall?.Invoke(0uL, Path.GetFileName(mFileFolder)); Task.Run(() => { LoadData(); @@ -142,7 +152,7 @@ namespace BallanceStalker.Cores.Rec { } public void Shutdown() { - RecUnregisterBall?.Invoke(0); + RecUnregisterBall?.Invoke(0uL); } public void Pause() { @@ -203,7 +213,7 @@ namespace BallanceStalker.Cores.Rec { RecNewBallState?.Invoke(new RecBallStateReport() { BallState = mRecStates[mRecStateCursor].Slerp(mRecStates[mRecStateCursor + 1], mRecRemainDelta / REC_DELTA), BallType = mRecTrafos[mRecTrafoCursor].TrafoType, - Identifier = 0 + Identifier = 0uL }); } @@ -217,5 +227,6 @@ SubRec HS/SR: {mRecHSScore}/{mRecSRScore} SubRec state/trafo size: {mRecStates?.Length}/{mRecTrafos?.Length}"; } } + } } diff --git a/src/scripts/cores/utils/BallStates.cs b/src/scripts/cores/utils/BallStates.cs index 0af3618..282660d 100644 --- a/src/scripts/cores/utils/BallStates.cs +++ b/src/scripts/cores/utils/BallStates.cs @@ -136,7 +136,7 @@ namespace BallanceStalker.Cores.Utils { } public struct RecBallStateReport { - public long Identifier; + public ulong Identifier; public VxBallType BallType; public VxBallState BallState; } diff --git a/src/scripts/cores/utils/CmdLexer.cs b/src/scripts/cores/utils/CmdLexer.cs deleted file mode 100644 index 97467e0..0000000 --- a/src/scripts/cores/utils/CmdLexer.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BallanceStalker.Cores.Utils { - - public class CmdLexer { - - public static List DoLexer(string command) { - var result = new List(); - - CmdLexerState current = CmdLexerState.Space, previous = CmdLexerState.Space; - StringBuilder itemCache = new StringBuilder(); - - #region processor - - void SpaceProcessor(char chr) { - switch (chr) { - case '\'': - current = CmdLexerState.Single; - break; - case '"': - current = CmdLexerState.Double; - break; - case '\\': - current = CmdLexerState.Shift; - previous = CmdLexerState.Normal; - break; - case ' ': - ;//keep - break; - default: - itemCache.Append(chr); - current = CmdLexerState.Normal; - break; - } - } - - void NormalProcessor(char chr) { - switch (chr) { - case '\'': - itemCache.Append('\''); - break; - case '"': - itemCache.Append('"'); - break; - case '\\': - previous = CmdLexerState.Normal; - current = CmdLexerState.Shift; - break; - case ' ': - result.Add(itemCache.ToString()); - itemCache.Clear(); - current = CmdLexerState.Space; - break; - default: - itemCache.Append(chr); - break; - } - } - - void SingleProcessor(char chr) { - switch (chr) { - case '\'': - current = CmdLexerState.Normal; - break; - case '"': - itemCache.Append('"'); - break; - case '\\': - previous = CmdLexerState.Single; - current = CmdLexerState.Shift; - break; - case ' ': - itemCache.Append(' '); - break; - default: - itemCache.Append(chr); - break; - } - } - - void DoubleProcessor(char chr) { - switch (chr) { - case '\'': - itemCache.Append('\''); - break; - case '"': - current = CmdLexerState.Normal; - break; - case '\\': - previous = CmdLexerState.Double; - current = CmdLexerState.Shift; - break; - case ' ': - itemCache.Append(' '); - break; - default: - itemCache.Append(chr); - break; - } - } - - void ShiftProcessor(char chr) { - switch (chr) { - case '\'': - itemCache.Append('\''); - break; - case '"': - itemCache.Append('"'); - break; - case '\\': - itemCache.Append('\\'); - break; - case ' ': - throw new ArgumentException(); - default: - throw new ArgumentException(); - } - current = previous; - } - - - #endregion - - try { - foreach (var item in command) { - switch (current) { - case CmdLexerState.Space: - SpaceProcessor(item); - break; - case CmdLexerState.Normal: - NormalProcessor(item); - break; - case CmdLexerState.Single: - SingleProcessor(item); - break; - case CmdLexerState.Double: - DoubleProcessor(item); - break; - case CmdLexerState.Shift: - ShiftProcessor(item); - break; - } - } - - switch (current) { - case CmdLexerState.Space: - break; - case CmdLexerState.Normal: - //add the last one - result.Add(itemCache.ToString()); - break; - case CmdLexerState.Single: - case CmdLexerState.Double: - case CmdLexerState.Shift: - throw new ArgumentException(); - } - } catch { - // when raise a error, clean list - // and return null - result.Clear(); - return null; - } - - return result; - } - - private enum CmdLexerState { - Space, - Normal, - Single, - Double, - Shift - } - - } - -} diff --git a/src/scripts/cores/utils/IRec.cs b/src/scripts/cores/utils/IRec.cs index 5113f4d..0f81046 100644 --- a/src/scripts/cores/utils/IRec.cs +++ b/src/scripts/cores/utils/IRec.cs @@ -6,19 +6,22 @@ using System.Threading.Tasks; namespace BallanceStalker.Cores.Utils { public interface IRec { + Guid RecGetGuid(); + void RecSetGuid(Guid g); + void Startup(); void Shutdown(); void Play(); void Pause(); void Seek(float sec); void Tick(float delta_sec); - string GetProfile(); + string GetProfile(); // todo: in future return a Dict and serialized by PresentManager /// /// register a ball /// long is identifier, string is name /// - event Action RecRegisterBall; + event Action RecRegisterBall; event Action RecNewBallState; event Action> RecNewBallStates; //event Action RecPlaying; @@ -27,6 +30,6 @@ namespace BallanceStalker.Cores.Utils { /// unregister a ball /// long is identifier /// - event Action RecUnregisterBall; + event Action RecUnregisterBall; } } diff --git a/src/scripts/scenes/entities/SBallManager.cs b/src/scripts/scenes/entities/SBallManager.cs new file mode 100644 index 0000000..89064d7 --- /dev/null +++ b/src/scripts/scenes/entities/SBallManager.cs @@ -0,0 +1,138 @@ +using BallanceStalker.Cores.Utils; +using Godot; +using System; +using System.Collections.Generic; + +namespace BallanceStalker.Scenes.Entities { + + public class SBallManager : Spatial { + + private Dictionary mBallDict = new Dictionary(); + private PackedScene mTemplateShadowBall; + private BallanceStalker.Cores.Managers.PresentManager mPresentManager; + + public override void _Ready() { + // load template + mTemplateShadowBall = ResourceLoader.Load("res://scenes/entities/ShadowBall.tscn"); + + // add event hook + mPresentManager = BallanceStalker.Cores.BStalkerContext.Singleton.mPresentManager; + mPresentManager.RecAdded += Proc_PresentManager_RecAdded; + mPresentManager.RecRemoved += Proc_PresentManager_RecRemoved; + mPresentManager.MultiplayAdded += Proc_PresentManager_MultiplayAdded; + mPresentManager.MultiplayRemoved += Proc_PresentManager_MultiplayRemoved; + } + + private void Proc_PresentManager_MultiplayRemoved(Guid uuid, Cores.Utils.IMultiplay mp) { + if (mBallDict.TryGetValue(uuid, out PresentHandler hd)) { + mBallDict.Remove(uuid); + hd.Dispose(); + } + } + private void Proc_PresentManager_MultiplayAdded(Guid uuid, Cores.Utils.IMultiplay mp) { + mBallDict.Add(uuid, new PresentHandler(mTemplateShadowBall, this, mp)); + } + private void Proc_PresentManager_RecRemoved(Guid uuid, Cores.Utils.IRec rec) { + if (mBallDict.TryGetValue(uuid, out PresentHandler hd)) { + mBallDict.Remove(uuid); + hd.Dispose(); + } + } + private void Proc_PresentManager_RecAdded(Guid uuid, Cores.Utils.IRec rec) { + mBallDict.Add(uuid, new PresentHandler(mTemplateShadowBall, this, rec)); + } + + class PresentHandler : IDisposable { + bool mIsRec; + IRec mRec; + IMultiplay mMp; + Dictionary mBallDict; + Spatial mParent; + PackedScene mTemplate; + + public void Dispose() { + // remove event handler + if (mIsRec) { + mRec.RecRegisterBall -= Proc_Rec_RecRegisterBall; + mRec.RecUnregisterBall -= Proc_Rec_RecUnregisterBall; + mRec.RecNewBallState -= Proc_Rec_RecNewBallState; + mRec.RecNewBallStates -= Proc_Rec_RecNewBallStates; + } else { + // todo: add mp event deleter + } + mRec = null; + mMp = null; + + // remove all shadow balls + foreach (var ball in mBallDict.Values) { + mParent.RemoveChild(ball); + ball.QueueFree(); + } + mBallDict.Clear(); + } + + #region rec + public PresentHandler(PackedScene template, Spatial parent, IRec rec) { + mTemplate = template; + mParent = parent; + mBallDict = new Dictionary(); + mIsRec = true; + mRec = rec; + mMp = null; + + rec.RecRegisterBall += Proc_Rec_RecRegisterBall; + rec.RecUnregisterBall += Proc_Rec_RecUnregisterBall; + rec.RecNewBallState += Proc_Rec_RecNewBallState; + rec.RecNewBallStates += Proc_Rec_RecNewBallStates; + } + + private void Proc_Rec_RecNewBallStates(List reports) { + foreach (var report in reports) { + if (mBallDict.TryGetValue(report.Identifier, out ShadowBall ball)) { + ball.SetBallState(report.BallState, report.BallType); + } + } + } + + private void Proc_Rec_RecNewBallState(RecBallStateReport report) { + if (mBallDict.TryGetValue(report.Identifier, out ShadowBall ball)) { + ball.SetBallState(report.BallState, report.BallType); + } + } + + private void Proc_Rec_RecUnregisterBall(ulong raw_uuid) { + if (mBallDict.TryGetValue(raw_uuid, out ShadowBall ball)) { + mBallDict.Remove(raw_uuid); + mParent.RemoveChild(ball); + ball.QueueFree(); + } + } + + private void Proc_Rec_RecRegisterBall(ulong raw_uuid, string name) { + var instance = mTemplate.Instance(); + mParent.AddChild(instance); + instance.SetPlayerName(name); + mBallDict.Add(raw_uuid, instance); + } + #endregion + + #region multiply + + public PresentHandler(PackedScene template, Spatial parent, IMultiplay mp) { + mTemplate = template; + mParent = parent; + mBallDict = new Dictionary(); + mIsRec = false; + mRec = null; + mMp = mp; + + // todo: add mp event handler + } + + #endregion + + } + + } + +} diff --git a/src/scripts/scenes/entities/ShadowBall.cs b/src/scripts/scenes/entities/ShadowBall.cs index 21ba442..8e93fcc 100644 --- a/src/scripts/scenes/entities/ShadowBall.cs +++ b/src/scripts/scenes/entities/ShadowBall.cs @@ -4,13 +4,7 @@ using System; // Reference: https://github.com/godotengine/godot-demo-projects/blob/master/3d/waypoints namespace BallanceStalker.Scenes.Entities { - - public enum ShadowBallType : UInt32 { - Stone, - Wood, - Paper - } - + public class ShadowBall : Spatial { static readonly float MARGIN = 16f; // set it as half of arrow image @@ -24,7 +18,7 @@ namespace BallanceStalker.Scenes.Entities { Label mPlayername; Camera mSpectatorCamera = null; MeshInstance mMeshWood, mMeshStone, mMeshPaper; - ShadowBallType mOldState = ShadowBallType.Wood; + Cores.Utils.VxBallType mOldState = Cores.Utils.VxBallType.Wood; public override void _Ready() { mCtl2D = GetNode("TextArchor/Ctl2D"); @@ -42,30 +36,31 @@ namespace BallanceStalker.Scenes.Entities { mPlayername.Text = new_name; } - public void SetBallState(Vector3 pos, Quat quad, ShadowBallType btype) { - this.Translation = pos; - mModelArchor.Rotation = quad.GetEuler(); + public void SetBallState(Cores.Utils.VxBallState bstate, Cores.Utils.VxBallType btype) { + // set z weight of pos and quat to minus, for converting it into godot coordinate system. + this.Translation = new Vector3(bstate.Pos.X, bstate.Pos.Y, -bstate.Pos.Z); + mModelArchor.Rotation = new Quat(bstate.Quat.X, bstate.Quat.Y, -bstate.Quat.Z, bstate.Quat.W).GetEuler(); if (mOldState != btype) { switch (mOldState) { - case ShadowBallType.Stone: + case Cores.Utils.VxBallType.Stone: mMeshStone.Visible = false; break; - case ShadowBallType.Wood: + case Cores.Utils.VxBallType.Wood: mMeshWood.Visible = false; break; - case ShadowBallType.Paper: + case Cores.Utils.VxBallType.Paper: mMeshPaper.Visible = false; break; } switch (btype) { - case ShadowBallType.Stone: + case Cores.Utils.VxBallType.Stone: mMeshStone.Visible = true; break; - case ShadowBallType.Wood: + case Cores.Utils.VxBallType.Wood: mMeshWood.Visible = true; break; - case ShadowBallType.Paper: + case Cores.Utils.VxBallType.Paper: mMeshPaper.Visible = true; break; } diff --git a/src/scripts/scenes/entities/ShadowBallManager.cs b/src/scripts/scenes/entities/ShadowBallManager.cs deleted file mode 100644 index 31f1405..0000000 --- a/src/scripts/scenes/entities/ShadowBallManager.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Godot; -using System; -using System.Collections.Generic; - -namespace BallanceStalker.Scenes.Entities { - - public class ShadowBallManager : Spatial { - private Dictionary mBallDict = new Dictionary(); - private PackedScene mTemplateShadowBall; - - public override void _Ready() { - mTemplateShadowBall = ResourceLoader.Load("res://scenes/entities/ShadowBall.tscn"); - - } - - public Guid AddBall() { - var guid = Guid.NewGuid(); - var instance = mTemplateShadowBall.Instance(); - - AddChild(instance); - mBallDict.Add(guid, instance); - return guid; - } - - public void SetBallName(Guid ballid, string new_name) { - if (mBallDict.TryGetValue(ballid, out ShadowBall entity)) { - entity.SetPlayerName(new_name); - } - } - - public void SetBallState(Guid ballid, Vector3 pos, Quat quad, ShadowBallType btype) { - if (mBallDict.TryGetValue(ballid, out ShadowBall entity)) { - entity.SetBallState(pos, quad, btype); - } - } - - public void RemoveBall(Guid ballid) { - if (mBallDict.TryGetValue(ballid, out ShadowBall entity)) { - RemoveChild(entity); - entity.QueueFree(); - mBallDict.Remove(ballid); - } - } - - } - -}