Преглед изворни кода

World的Singleton分成两种,一种是Instance不会修改的继承Singleton,一种是会修改的需要继承SingletonLock

tanghai пре 2 година
родитељ
комит
43ef7a1eb8

+ 10 - 15
Unity/Assets/Scripts/Core/Entity/EntitySystemSingleton.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 
 namespace ET
 {
-    public class EntitySystemSingleton: Singleton<EntitySystemSingleton>, ISingletonAwake, ISingletonLoad
+    public class EntitySystemSingleton: SingletonLock<EntitySystemSingleton>, ISingletonAwake
     {
         public TypeSystems TypeSystems { get; private set; }
         
@@ -28,11 +28,6 @@ namespace ET
             }
         }
         
-        public ISingleton Load()
-        {
-            return new EntitySystemSingleton();
-        }
-        
         public void Serialize(Entity component)
         {
             if (component is not ISerialize)
@@ -40,7 +35,7 @@ namespace ET
                 return;
             }
             
-            List<object> iSerializeSystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (ISerializeSystem));
+            List<object> iSerializeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof (ISerializeSystem));
             if (iSerializeSystems == null)
             {
                 return;
@@ -71,7 +66,7 @@ namespace ET
                 return;
             }
             
-            List<object> iDeserializeSystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (IDeserializeSystem));
+            List<object> iDeserializeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof (IDeserializeSystem));
             if (iDeserializeSystems == null)
             {
                 return;
@@ -98,7 +93,7 @@ namespace ET
         // GetComponentSystem
         public void GetComponent(Entity entity, Entity component)
         {
-            List<object> iGetSystem = EntitySystemSingleton.Instance.TypeSystems.GetSystems(entity.GetType(), typeof (IGetComponentSystem));
+            List<object> iGetSystem = this.TypeSystems.GetSystems(entity.GetType(), typeof (IGetComponentSystem));
             if (iGetSystem == null)
             {
                 return;
@@ -125,7 +120,7 @@ namespace ET
         // AddComponentSystem
         public void AddComponent(Entity entity, Entity component)
         {
-            List<object> iAddSystem = EntitySystemSingleton.Instance.TypeSystems.GetSystems(entity.GetType(), typeof (IAddComponentSystem));
+            List<object> iAddSystem = this.TypeSystems.GetSystems(entity.GetType(), typeof (IAddComponentSystem));
             if (iAddSystem == null)
             {
                 return;
@@ -151,7 +146,7 @@ namespace ET
 
         public void Awake(Entity component)
         {
-            List<object> iAwakeSystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem));
+            List<object> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem));
             if (iAwakeSystems == null)
             {
                 return;
@@ -182,7 +177,7 @@ namespace ET
                 return;
             }
             
-            List<object> iAwakeSystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem<P1>));
+            List<object> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem<P1>));
             if (iAwakeSystems == null)
             {
                 return;
@@ -213,7 +208,7 @@ namespace ET
                 return;
             }
             
-            List<object> iAwakeSystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem<P1, P2>));
+            List<object> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem<P1, P2>));
             if (iAwakeSystems == null)
             {
                 return;
@@ -244,7 +239,7 @@ namespace ET
                 return;
             }
             
-            List<object> iAwakeSystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem<P1, P2, P3>));
+            List<object> iAwakeSystems = this.TypeSystems.GetSystems(component.GetType(), typeof (IAwakeSystem<P1, P2, P3>));
             if (iAwakeSystems == null)
             {
                 return;
@@ -275,7 +270,7 @@ namespace ET
                 return;
             }
             
-            List<object> iDestroySystems = EntitySystemSingleton.Instance.TypeSystems.GetSystems(component.GetType(), typeof (IDestroySystem));
+            List<object> iDestroySystems = this.TypeSystems.GetSystems(component.GetType(), typeof (IDestroySystem));
             if (iDestroySystems == null)
             {
                 return;

+ 13 - 2
Unity/Assets/Scripts/Core/Fiber/Fiber.cs

@@ -14,6 +14,8 @@ namespace ET
     
     public class Fiber: IDisposable
     {
+        public bool IsDisposed;
+        
         public int Id;
 
         public int Zone;
@@ -51,16 +53,18 @@ namespace ET
 
         public void Update()
         {
-            this.TimeInfo.Update();
+            this.IsRuning = true;
             
+            this.TimeInfo.Update();
             this.EntitySystem.Update();
         }
         
         public void LateUpdate()
         {
             this.EntitySystem.LateUpdate();
-
             FrameFinishUpdate();
+
+            this.IsRuning = false;
         }
 
         public async ETTask WaitFrameFinish()
@@ -74,6 +78,13 @@ namespace ET
 
         public void Dispose()
         {
+            if (this.IsDisposed)
+            {
+                return;
+            }
+
+            this.IsDisposed = true;
+            
             this.IsRuning = false;
         }
     }

+ 1 - 1
Unity/Assets/Scripts/Core/Network/NetServices.cs

@@ -21,7 +21,7 @@ namespace ET
         {
         }
 
-        public override void Destroy()
+        protected override void Destroy()
         {
             foreach (var kv in this.services)
             {

+ 1 - 6
Unity/Assets/Scripts/Core/Network/OpcodeType.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 
 namespace ET
 {
-    public class OpcodeType: Singleton<OpcodeType>, ISingletonAwake, ISingletonLoad
+    public class OpcodeType: SingletonLock<OpcodeType>, ISingletonAwake
     {
         // 初始化后不变,所以主线程,网络线程都可以读
         private readonly DoubleMap<Type, ushort> typeOpcode = new();
@@ -84,10 +84,5 @@ namespace ET
 
             return response;
         }
-
-        public ISingleton Load()
-        {
-            return new OpcodeType();
-        }
     }
 }

+ 1 - 7
Unity/Assets/Scripts/Core/World/Module/Actor/ActorMessageDispatcherComponent.cs

@@ -19,7 +19,7 @@ namespace ET
     /// <summary>
     /// Actor消息分发组件
     /// </summary>
-    public class ActorMessageDispatcherComponent: Singleton<ActorMessageDispatcherComponent>, ISingletonAwake, ISingletonLoad
+    public class ActorMessageDispatcherComponent: SingletonLock<ActorMessageDispatcherComponent>, ISingletonAwake
     {
         private readonly Dictionary<Type, List<ActorMessageDispatcherInfo>> ActorMessageHandlers = new();
 
@@ -40,12 +40,6 @@ namespace ET
             }
         }
         
-        
-        public ISingleton Load()
-        {
-            return new ActorMessageDispatcherComponent();
-        }
-
         private void Register(Type type)
         {
             object obj = Activator.CreateInstance(type);

+ 1 - 1
Unity/Assets/Scripts/Core/World/Module/Fiber/FiberManager.cs

@@ -44,7 +44,7 @@ namespace ET
             return Create(fiberId, zone, sceneType, name);
         }
         
-        // 不允许外部调用,只能由Schecher执行完成一帧调用,否则容易出现多线程问题
+        // 不允许外部调用,只能由Schecher执行完成一帧调用,否则容易出现多线程问题
         internal void Remove(int id)
         {
             if (this.fibers.Remove(id, out Fiber fiber))

+ 10 - 0
Unity/Assets/Scripts/Core/World/Module/Scheduler/MainThreadScheduler.cs

@@ -26,6 +26,11 @@ namespace ET
                 {
                     continue;
                 }
+                
+                if (fiber.IsDisposed)
+                {
+                    continue;
+                }
 
                 this.idQueue.Enqueue(id);
 
@@ -49,6 +54,11 @@ namespace ET
                     continue;
                 }
 
+                if (fiber.IsDisposed)
+                {
+                    continue;
+                }
+
                 this.idQueue.Enqueue(id);
 
                 fiber.LateUpdate();

+ 10 - 6
Unity/Assets/Scripts/Core/World/Module/Scheduler/ThreadPoolScheduler.cs

@@ -45,19 +45,23 @@ namespace ET
                     Fiber fiber = FiberManager.Instance.Get(id);
                     if (fiber == null)
                     {
-                        Thread.Sleep(1);
                         continue;
                     }
 
-                    // 执行过的或者正在执行的进程放到队尾
-                    if (fiber.IsRuning)
+                    if (fiber.IsDisposed)
+                    {
+                        continue;
+                    }
+                    
+                    this.idQueue.Enqueue(id);
+
+                    // 正在执行的就不执行了
+                    if (!fiber.IsRuning)
                     {
                         fiber.Update();
                         fiber.LateUpdate();
                     }
 
-                    this.idQueue.Enqueue(id);
-
                     Thread.Sleep(1);
                 }
                 catch (Exception e)
@@ -67,7 +71,7 @@ namespace ET
             }
         }
 
-        public override void Destroy()
+        protected override void Destroy()
         {
             this.isStart = false;
             foreach (Thread thread in this.threads)

+ 8 - 2
Unity/Assets/Scripts/Core/World/Module/Scheduler/ThreadScheduler.cs

@@ -10,7 +10,7 @@ namespace ET
     {
         private bool isStart;
 
-        private readonly ConcurrentDictionary<Fiber, Thread> dictionary = new();
+        private readonly ConcurrentDictionary<int, Thread> dictionary = new();
 
         public void Awake()
         {
@@ -29,6 +29,12 @@ namespace ET
             {
                 try
                 {
+                    if (fiber.IsDisposed)
+                    {
+                        this.dictionary.Remove(fiberId, out _);
+                        return;
+                    }
+                    
                     fiber.Update();
                     fiber.LateUpdate();
 
@@ -41,7 +47,7 @@ namespace ET
             }
         }
 
-        public override void Destroy()
+        protected override void Destroy()
         {
             this.isStart = false;
             foreach (var kv in this.dictionary)

+ 67 - 19
Unity/Assets/Scripts/Core/World/Singleton.cs

@@ -6,6 +6,7 @@ namespace ET
     public interface ISingleton: IDisposable
     {
         void Register();
+        
     }
     
     public abstract class Singleton<T>: ISingleton where T: Singleton<T>, new()
@@ -15,8 +16,57 @@ namespace ET
         [StaticField]
         private static T instance;
         
+        public static T Instance
+        {
+            get
+            {
+                return instance;
+            }
+            private set
+            {
+                instance = value;
+            }
+        }
+
+        public virtual void Register()
+        {
+            Instance = (T)this;
+        }
+
+        public bool IsDisposed()
+        {
+            return this.isDisposed;
+        }
+
+        protected virtual void Destroy()
+        {
+            
+        }
+
+        void IDisposable.Dispose()
+        {
+            if (this.isDisposed)
+            {
+                return;
+            }
+            
+            this.isDisposed = true;
+
+            Instance = null;
+            
+            this.Destroy();
+        }
+    }
+    
+    public abstract class SingletonLock<T>: ISingleton, ISingletonLoad where T: SingletonLock<T>, new()
+    {
+        private bool isDisposed;
+        
+        [StaticField]
+        private static T instance;
+        
         [StaticField]
-        private static readonly object lockObj = new();
+        private static object lockObj = new();
 
         public static T Instance
         {
@@ -24,10 +74,10 @@ namespace ET
             {
                 lock (lockObj)
                 {
-                    return instance; 
+                    return instance;
                 }
             }
-            set
+            private set
             {
                 lock (lockObj)
                 {
@@ -43,33 +93,31 @@ namespace ET
 
         public bool IsDisposed()
         {
-            lock (lockObj)
-            {
-                return this.isDisposed;
-            }
+            return this.isDisposed;
         }
 
-        public virtual void Destroy()
+        protected virtual void Destroy()
         {
             
         }
 
         void IDisposable.Dispose()
         {
-            T t;
-            lock (lockObj)
+            if (this.isDisposed)
             {
-                if (this.isDisposed)
-                {
-                    return;
-                }
-                this.isDisposed = true;
-                
-                t = instance;
-                instance = null;
+                return;
             }
             
-            t.Destroy();
+            this.isDisposed = true;
+
+            Instance = null;
+            
+            this.Destroy();
+        }
+
+        public virtual ISingleton Load()
+        {
+            return new T();
         }
     }
 }

+ 19 - 33
Unity/Assets/Scripts/Core/World/World.cs

@@ -7,7 +7,7 @@ namespace ET
         [StaticField]
         public static World Instance = new();
 
-        private readonly List<ISingleton> list = new();
+        private readonly Stack<Type> stack = new();
         private readonly Dictionary<Type, ISingleton> singletons = new();
         
         private World()
@@ -18,14 +18,15 @@ namespace ET
         {
             lock (this)
             {
-                for (int i = this.list.Count - 1; i >= 0; --i)
+                while (this.stack.Count > 0)
                 {
-                    this.list[i].Dispose();
+                    Type type = this.stack.Pop();
+                    this.singletons[type].Dispose();
                 }
             }
         }
 
-        public T AddSingleton<T>() where T : Singleton<T>, ISingletonAwake, new()
+        public T AddSingleton<T>() where T : class, ISingleton, ISingletonAwake, new()
         {
             T singleton = new();
             singleton.Awake();
@@ -34,7 +35,7 @@ namespace ET
             return singleton;
         }
         
-        public T AddSingleton<T, A>(A a) where T : Singleton<T>, ISingletonAwake<A>, new()
+        public T AddSingleton<T, A>(A a) where T : class, ISingleton, ISingletonAwake<A>, new()
         {
             T singleton = new();
             singleton.Awake(a);
@@ -43,7 +44,7 @@ namespace ET
             return singleton;
         }
         
-        public T AddSingleton<T, A, B>(A a, B b) where T : Singleton<T>, ISingletonAwake<A, B>, new()
+        public T AddSingleton<T, A, B>(A a, B b) where T : class, ISingleton, ISingletonAwake<A, B>, new()
         {
             T singleton = new();
             singleton.Awake(a, b);
@@ -52,7 +53,7 @@ namespace ET
             return singleton;
         }
         
-        public T AddSingleton<T, A, B, C>(A a, B b, C c) where T : Singleton<T>, ISingletonAwake<A, B, C>, new()
+        public T AddSingleton<T, A, B, C>(A a, B b, C c) where T : class, ISingleton, ISingletonAwake<A, B, C>, new()
         {
             T singleton = new();
             singleton.Awake(a, b, c);
@@ -65,45 +66,30 @@ namespace ET
         {
             lock (this)
             {
-                if (this.singletons.Remove(singleton.GetType(), out ISingleton removed))
-                {
-                    this.list.Remove(removed);
-                }
-                list.Add(singleton);
-                singletons.Add(singleton.GetType(), singleton);
+                Type type = singleton.GetType();
+                this.stack.Push(type);
+                singletons.Add(type, singleton);
             }
 
             singleton.Register();
         }
         
-        private void AddSingletonNoLock(ISingleton singleton)
-        {
-            if (this.singletons.Remove(singleton.GetType(), out ISingleton removed))
-            {
-                this.list.Remove(removed);
-            }
-            list.Add(singleton);
-            singletons.Add(singleton.GetType(), singleton);
-
-            singleton.Register();
-        }
-
         public void Load()
         {
             lock (this)
             {
-                ISingleton[] array = this.list.ToArray();
-                this.list.Clear();
-                this.singletons.Clear();
-                
-                foreach (ISingleton singleton in array)
+                foreach (Type type in this.stack)
                 {
-                    if (singleton is not ISingletonLoad singletonLoad)
+                    ISingleton singleton = this.singletons[type];
+
+                    if (singleton is not ISingletonLoad iSingletonLoad)
                     {
-                        this.AddSingletonNoLock(singleton);
                         continue;
                     }
-                    this.AddSingletonNoLock(singletonLoad.Load());
+                    
+                    singleton = iSingletonLoad.Load();
+                    this.singletons[type] = singleton;
+                    singleton.Register();
                 }
             }
         }

+ 1 - 6
Unity/Assets/Scripts/Model/Share/LockStep/LSEntitySystemSingleton.cs

@@ -11,7 +11,7 @@ namespace ET
         public const int Max = 1;
     }
     
-    public class LSEntitySystemSingleton: Singleton<LSEntitySystemSingleton>, ISingletonAwake, ISingletonLoad
+    public class LSEntitySystemSingleton: SingletonLock<LSEntitySystemSingleton>, ISingletonAwake
     {
         public TypeSystems TypeSystems { get; private set; }
         
@@ -37,11 +37,6 @@ namespace ET
             }
         }
         
-        public ISingleton Load()
-        {
-            return new LSEntitySystemSingleton();
-        }
-        
         public TypeSystems.OneTypeSystems GetOneTypeSystems(Type type)
         {
             return this.TypeSystems.GetOneTypeSystems(type);

+ 1 - 6
Unity/Assets/Scripts/Model/Share/Module/AI/AIDispatcherComponent.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 
 namespace ET
 {
-    public class AIDispatcherComponent: Singleton<AIDispatcherComponent>, ISingletonAwake, ISingletonLoad
+    public class AIDispatcherComponent: SingletonLock<AIDispatcherComponent>, ISingletonAwake
     {
         private readonly Dictionary<string, AAIHandler> aiHandlers = new();
         
@@ -22,11 +22,6 @@ namespace ET
             }
         }
 
-        public ISingleton Load()
-        {
-            return new AIDispatcherComponent();
-        }
-
         public AAIHandler Get(string key)
         {
             this.aiHandlers.TryGetValue(key, out var aaiHandler);

+ 1 - 6
Unity/Assets/Scripts/Model/Share/Module/Message/MessageDispatcherComponent.cs

@@ -15,7 +15,7 @@ namespace ET
         }
     }
     
-    public class MessageDispatcherComponent: Singleton<MessageDispatcherComponent>, ISingletonAwake, ISingletonLoad
+    public class MessageDispatcherComponent: SingletonLock<MessageDispatcherComponent>, ISingletonAwake
     {
         private readonly Dictionary<ushort, List<MessageDispatcherInfo>> handlers = new();
         
@@ -53,11 +53,6 @@ namespace ET
             }
         }
         
-        public ISingleton Load()
-        {
-            return new MessageDispatcherComponent();
-        }
-        
         private void RegisterHandler(ushort opcode, MessageDispatcherInfo handler)
         {
             if (!this.handlers.ContainsKey(opcode))

+ 1 - 6
Unity/Assets/Scripts/Model/Share/Module/Numeric/NumericWatcherComponent.cs

@@ -18,7 +18,7 @@ namespace ET
     /// <summary>
     /// 监视数值变化组件,分发监听
     /// </summary>
-    public class NumericWatcherComponent : Singleton<NumericWatcherComponent>, ISingletonAwake, ISingletonLoad
+    public class NumericWatcherComponent : SingletonLock<NumericWatcherComponent>, ISingletonAwake
     {
         private readonly Dictionary<int, List<NumericWatcherInfo>> allWatchers = new();
         
@@ -42,11 +42,6 @@ namespace ET
                 }
             }
         }
-
-        public ISingleton Load()
-        {
-            return new NumericWatcherComponent();
-        }
         
         public void Run(Unit unit, EventType.NumbericChange args)
         {

+ 1 - 6
Unity/Assets/Scripts/ModelView/Client/Module/UI/UIEventComponent.cs

@@ -7,7 +7,7 @@ namespace ET.Client
 	/// <summary>
 	/// 管理所有UI GameObject
 	/// </summary>
-	public class UIEventComponent: Singleton<UIEventComponent>, ISingletonAwake, ISingletonLoad
+	public class UIEventComponent: SingletonLock<UIEventComponent>, ISingletonAwake
 	{
 		public Dictionary<string, AUIEvent> UIEvents { get; } = new();
 		
@@ -27,10 +27,5 @@ namespace ET.Client
                 this.UIEvents.Add(uiEventAttribute.UIType, aUIEvent);
             }
         }
-
-        public ISingleton Load()
-        {
-	        return new UIEventComponent();
-        }
 	}
 }