merge rec_manager and mp_manager into present_manager and add event handler
This commit is contained in:
		@ -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 )
 | 
			
		||||
@ -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 )
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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 {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								src/scripts/cores/managers/PresentManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/scripts/cores/managers/PresentManager.cs
									
									
									
									
									
										Normal file
									
								
							@ -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<Guid, IRec> RecAdded;
 | 
			
		||||
        public event Action<Guid, IRec> RecRemoved;
 | 
			
		||||
        public event Action<Guid, IMultiplay> MultiplayAdded;
 | 
			
		||||
        public event Action<Guid, IMultiplay> MultiplayRemoved;
 | 
			
		||||
 | 
			
		||||
        private Dictionary<Guid, IRec> mRecDict = new Dictionary<Guid, IRec>();
 | 
			
		||||
        private Dictionary<Guid, IMultiplay> mMultiplayDict = new Dictionary<Guid, IMultiplay>();
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -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<Guid, IRec> RecAdded;
 | 
			
		||||
        public event Action<Guid, IRec> RecRemoved;
 | 
			
		||||
 | 
			
		||||
        private Dictionary<Guid, IRec> mRecDict = new Dictionary<Guid, IRec>();
 | 
			
		||||
 | 
			
		||||
        public Guid AddSpiritTrailRec(string rec_folder) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveRec(Guid uuid) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Tick(float delta) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -36,10 +36,20 @@ namespace BallanceStalker.Cores.Rec {
 | 
			
		||||
 | 
			
		||||
            mRecStateCursor = mRecTrafoCursor = 0;
 | 
			
		||||
            mRecRemainDelta = 0f;
 | 
			
		||||
 | 
			
		||||
            mGuid = Guid.Empty;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public event Action<long, string> RecRegisterBall;
 | 
			
		||||
        public event Action<long> RecUnregisterBall;
 | 
			
		||||
        Guid mGuid;
 | 
			
		||||
        public Guid RecGetGuid() {
 | 
			
		||||
            return mGuid;
 | 
			
		||||
        }
 | 
			
		||||
        public void RecSetGuid(Guid g) {
 | 
			
		||||
            mGuid = g;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public event Action<ulong, string> RecRegisterBall;
 | 
			
		||||
        public event Action<ulong> RecUnregisterBall;
 | 
			
		||||
        public event Action<RecBallStateReport> RecNewBallState;
 | 
			
		||||
        public event Action<List<RecBallStateReport>> 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}";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -136,7 +136,7 @@ namespace BallanceStalker.Cores.Utils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public struct RecBallStateReport {
 | 
			
		||||
        public long Identifier;
 | 
			
		||||
        public ulong Identifier;
 | 
			
		||||
        public VxBallType BallType;
 | 
			
		||||
        public VxBallState BallState;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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<string> DoLexer(string command) {
 | 
			
		||||
            var result = new List<string>();
 | 
			
		||||
 | 
			
		||||
            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
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// register a ball
 | 
			
		||||
        /// long is identifier, string is name
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        event Action<long, string> RecRegisterBall;
 | 
			
		||||
        event Action<ulong, string> RecRegisterBall;
 | 
			
		||||
        event Action<RecBallStateReport> RecNewBallState;
 | 
			
		||||
        event Action<List<RecBallStateReport>> RecNewBallStates;
 | 
			
		||||
        //event Action RecPlaying;
 | 
			
		||||
@ -27,6 +30,6 @@ namespace BallanceStalker.Cores.Utils {
 | 
			
		||||
        /// unregister a ball
 | 
			
		||||
        /// long is identifier
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        event Action<long> RecUnregisterBall;
 | 
			
		||||
        event Action<ulong> RecUnregisterBall;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										138
									
								
								src/scripts/scenes/entities/SBallManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/scripts/scenes/entities/SBallManager.cs
									
									
									
									
									
										Normal file
									
								
							@ -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<Guid, PresentHandler> mBallDict = new Dictionary<Guid, PresentHandler>();
 | 
			
		||||
        private PackedScene mTemplateShadowBall;
 | 
			
		||||
        private BallanceStalker.Cores.Managers.PresentManager mPresentManager;
 | 
			
		||||
 | 
			
		||||
        public override void _Ready() {
 | 
			
		||||
            // load template
 | 
			
		||||
            mTemplateShadowBall = ResourceLoader.Load<PackedScene>("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<ulong, ShadowBall> 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<ulong, ShadowBall>();
 | 
			
		||||
                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<RecBallStateReport> 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<ShadowBall>();
 | 
			
		||||
                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<ulong, ShadowBall>();
 | 
			
		||||
                mIsRec = false;
 | 
			
		||||
                mRec = null;
 | 
			
		||||
                mMp = mp;
 | 
			
		||||
 | 
			
		||||
                // todo: add mp event handler
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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<Control>("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;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -1,47 +0,0 @@
 | 
			
		||||
using Godot;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace BallanceStalker.Scenes.Entities {
 | 
			
		||||
 | 
			
		||||
    public class ShadowBallManager : Spatial {
 | 
			
		||||
        private Dictionary<Guid, ShadowBall> mBallDict = new Dictionary<Guid, ShadowBall>();
 | 
			
		||||
        private PackedScene mTemplateShadowBall;
 | 
			
		||||
        
 | 
			
		||||
        public override void _Ready() {
 | 
			
		||||
            mTemplateShadowBall = ResourceLoader.Load<PackedScene>("res://scenes/entities/ShadowBall.tscn");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Guid AddBall() {
 | 
			
		||||
            var guid = Guid.NewGuid();
 | 
			
		||||
            var instance = mTemplateShadowBall.Instance<ShadowBall>();
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user