Просмотр исходного кода

1.Entity不再注册到Root中
2.之前actor使用Root.Get,现在改成放到ActorMessageDispatcherComponent中,挂载了MailboxComponent的Entity会注册进去
3.EventSystem中的Queue使用EntityRef,这样性能更好

tanghai 2 лет назад
Родитель
Сommit
e7d7a9a964

+ 1 - 6
Unity/Assets/Scripts/Core/Module/Entity/Entity.cs

@@ -73,13 +73,8 @@ namespace ET
                     this.status &= ~EntityStatus.IsRegister;
                 }
 
-                if (!value)
-                {
-                    Root.Instance.Remove(this.InstanceId);
-                }
-                else
+                if (value)
                 {
-                    Root.Instance.Add(this);
                     EventSystem.Instance.RegisterSystem(this);
                 }
 

+ 0 - 79
Unity/Assets/Scripts/Core/Module/Entity/Root.cs

@@ -8,9 +8,6 @@ namespace ET
     // 管理根部的Scene
     public class Root: Singleton<Root>, ISingletonAwake
     {
-        // 管理所有的Entity
-        private readonly Dictionary<long, Entity> allEntities = new();
-        
         public Scene Scene { get; private set; }
 
         public void Awake()
@@ -22,81 +19,5 @@ namespace ET
         {
             this.Scene.Dispose();
         }
-
-        public void Add(Entity entity)
-        {
-            this.allEntities.Add(entity.InstanceId, entity);
-        }
-        
-        public void Remove(long instanceId)
-        {
-            this.allEntities.Remove(instanceId);
-        }
-
-        public Entity Get(long instanceId)
-        {
-            Entity component = null;
-            this.allEntities.TryGetValue(instanceId, out component);
-            return component;
-        }
-        
-        public override string ToString()
-        {
-            StringBuilder sb = new();
-            HashSet<Type> noParent = new HashSet<Type>();
-            Dictionary<Type, int> typeCount = new Dictionary<Type, int>();
-
-            HashSet<Type> noDomain = new HashSet<Type>();
-
-            foreach (var kv in this.allEntities)
-            {
-                Type type = kv.Value.GetType();
-                if (kv.Value.Parent == null)
-                {
-                    noParent.Add(type);
-                }
-
-                if (kv.Value.Domain == null)
-                {
-                    noDomain.Add(type);
-                }
-
-                if (typeCount.ContainsKey(type))
-                {
-                    typeCount[type]++;
-                }
-                else
-                {
-                    typeCount[type] = 1;
-                }
-            }
-
-            sb.AppendLine("not set parent type: ");
-            foreach (Type type in noParent)
-            {
-                sb.AppendLine($"\t{type.Name}");
-            }
-
-            sb.AppendLine("not set domain type: ");
-            foreach (Type type in noDomain)
-            {
-                sb.AppendLine($"\t{type.Name}");
-            }
-
-            IOrderedEnumerable<KeyValuePair<Type, int>> orderByDescending = typeCount.OrderByDescending(s => s.Value);
-
-            sb.AppendLine("Entity Count: ");
-            foreach (var kv in orderByDescending)
-            {
-                if (kv.Value == 1)
-                {
-                    continue;
-                }
-
-                sb.AppendLine($"\t{kv.Key.Name}: {kv.Value}");
-            }
-
-            return sb.ToString();
-        }
     }
 }

+ 12 - 15
Unity/Assets/Scripts/Core/Module/EventSystem/EventSystem.cs

@@ -91,13 +91,13 @@ namespace ET
 
         private TypeSystems typeSystems;
 
-        private readonly Queue<long>[] queues = new Queue<long>[InstanceQueueIndex.Max];
+        private readonly Queue<EntityRef<Entity>>[] queues = new Queue<EntityRef<Entity>>[InstanceQueueIndex.Max];
 
         public EventSystem()
         {
             for (int i = 0; i < this.queues.Length; i++)
             {
-                this.queues[i] = new Queue<long>();
+                this.queues[i] = new Queue<EntityRef<Entity>>();
             }
         }
 
@@ -237,7 +237,7 @@ namespace ET
                 {
                     continue;
                 }
-                this.queues[i].Enqueue(component.InstanceId);
+                this.queues[i].Enqueue(component);
             }
         }
 
@@ -447,12 +447,11 @@ namespace ET
 
         public void Load()
         {
-            Queue<long> queue = this.queues[InstanceQueueIndex.Load];
+            Queue<EntityRef<Entity>> queue = this.queues[InstanceQueueIndex.Load];
             int count = queue.Count;
             while (count-- > 0)
             {
-                long instanceId = queue.Dequeue();
-                Entity component = Root.Instance.Get(instanceId);
+                Entity component = queue.Dequeue();
                 if (component == null)
                 {
                     continue;
@@ -474,7 +473,7 @@ namespace ET
                     continue;
                 }
 
-                queue.Enqueue(instanceId);
+                queue.Enqueue(component);
 
                 foreach (ILoadSystem iLoadSystem in iLoadSystems)
                 {
@@ -523,12 +522,11 @@ namespace ET
 
         public void Update()
         {
-            Queue<long> queue = this.queues[InstanceQueueIndex.Update];
+            Queue<EntityRef<Entity>> queue = this.queues[InstanceQueueIndex.Update];
             int count = queue.Count;
             while (count-- > 0)
             {
-                long instanceId = queue.Dequeue();
-                Entity component = Root.Instance.Get(instanceId);
+                Entity component = queue.Dequeue();
                 if (component == null)
                 {
                     continue;
@@ -550,7 +548,7 @@ namespace ET
                     continue;
                 }
 
-                queue.Enqueue(instanceId);
+                queue.Enqueue(component);
 
                 foreach (IUpdateSystem iUpdateSystem in iUpdateSystems)
                 {
@@ -568,12 +566,11 @@ namespace ET
 
         public void LateUpdate()
         {
-            Queue<long> queue = this.queues[InstanceQueueIndex.LateUpdate];
+            Queue<EntityRef<Entity>> queue = this.queues[InstanceQueueIndex.LateUpdate];
             int count = queue.Count;
             while (count-- > 0)
             {
-                long instanceId = queue.Dequeue();
-                Entity component = Root.Instance.Get(instanceId);
+                Entity component = queue.Dequeue();
                 if (component == null)
                 {
                     continue;
@@ -595,7 +592,7 @@ namespace ET
                     continue;
                 }
 
-                queue.Enqueue(instanceId);
+                queue.Enqueue(component);
 
                 foreach (ILateUpdateSystem iLateUpdateSystem in iLateUpdateSystems)
                 {

+ 3 - 5
Unity/Assets/Scripts/Hotfix/Server/Demo/Session/NetInnerComponentOnReadEvent.cs

@@ -14,7 +14,7 @@ namespace ET.Server
 
                 if (message is IActorResponse iActorResponse)
                 {
-                    ActorHandleHelper.HandleIActorResponse(iActorResponse);
+                    ActorMessageSenderComponent.Instance.HandleIActorResponse(iActorResponse);
                     return;
                 }
                 
@@ -28,12 +28,12 @@ namespace ET.Server
                 {
                     case IActorRequest iActorRequest:
                     {
-                        await ActorHandleHelper.HandleIActorRequest(fromProcess, realActorId, iActorRequest);
+                        await ActorMessageDispatcherComponent.Instance.HandleIActorRequest(fromProcess, realActorId, iActorRequest);
                         break;
                     }
                     case IActorMessage iActorMessage:
                     {
-                        await ActorHandleHelper.HandleIActorMessage(fromProcess, realActorId, iActorMessage);
+                        await ActorMessageDispatcherComponent.Instance.HandleIActorMessage(fromProcess, realActorId, iActorMessage);
                         break;
                     }
                 }
@@ -42,8 +42,6 @@ namespace ET.Server
             {
                 Log.Error($"InnerMessageDispatcher error: {args.Message.GetType().FullName}\n{e}");
             }
-
-            await ETTask.CompletedTask;
         }
     }
 }

+ 0 - 108
Unity/Assets/Scripts/Hotfix/Server/Module/Actor/ActorHandleHelper.cs

@@ -20,113 +20,5 @@ namespace ET.Server
             Session replySession = NetInnerComponent.Instance.Get(fromProcess);
             replySession.Send(response);
         }
-        
-        public static void HandleIActorResponse(IActorResponse response)
-        {
-            ActorMessageSenderComponent.Instance.HandleIActorResponse(response);
-        }
-        
-        /// <summary>
-        /// 分发actor消息
-        /// </summary>
-        [EnableAccessEntiyChild]
-        public static async ETTask HandleIActorRequest(int fromProcess, long actorId, IActorRequest iActorRequest)
-        {
-            Entity entity = Root.Instance.Get(actorId);
-            if (entity == null)
-            {
-                IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
-                Reply(fromProcess, response);
-                return;
-            }
-            
-            OpcodeHelper.LogMsg(entity.DomainScene(), iActorRequest);
-
-            MailBoxComponent mailBoxComponent = entity.GetComponent<MailBoxComponent>();
-            if (mailBoxComponent == null)
-            {
-                Log.Warning($"actor not found mailbox: {entity.GetType().FullName} {actorId} {iActorRequest}");
-                IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
-                Reply(fromProcess, response);
-                return;
-            }
-            
-            switch (mailBoxComponent.MailboxType)
-            {
-                case MailboxType.MessageDispatcher:
-                {
-                    using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Mailbox, actorId))
-                    {
-                        if (entity.InstanceId != actorId)
-                        {
-                            IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
-                            Reply(fromProcess, response);
-                            break;
-                        }
-                        await ActorMessageDispatcherComponent.Instance.Handle(entity, fromProcess, iActorRequest);
-                    }
-                    break;
-                }
-                case MailboxType.UnOrderMessageDispatcher:
-                {
-                    await ActorMessageDispatcherComponent.Instance.Handle(entity, fromProcess, iActorRequest);
-                    break;
-                }
-                default:
-                    throw new Exception($"no mailboxtype: {mailBoxComponent.MailboxType} {iActorRequest}");
-            }
-        }
-        
-        /// <summary>
-        /// 分发actor消息
-        /// </summary>
-        [EnableAccessEntiyChild]
-        public static async ETTask HandleIActorMessage(int fromProcess, long actorId, IActorMessage iActorMessage)
-        {
-            Entity entity = Root.Instance.Get(actorId);
-            if (entity == null)
-            {
-                Log.Error($"not found actor: {actorId} {iActorMessage}");
-                return;
-            }
-            
-            MailBoxComponent mailBoxComponent = entity.GetComponent<MailBoxComponent>();
-            if (mailBoxComponent == null)
-            {
-                Log.Error($"actor not found mailbox: {entity.GetType().FullName} {actorId} {iActorMessage}");
-                return;
-            }
-
-            switch (mailBoxComponent.MailboxType)
-            {
-                case MailboxType.MessageDispatcher:
-                {
-                    using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Mailbox, actorId))
-                    {
-                        if (entity.InstanceId != actorId)
-                        {
-                            break;
-                        }
-                        await ActorMessageDispatcherComponent.Instance.Handle(entity, fromProcess, iActorMessage);
-                    }
-                    break;
-                }
-                case MailboxType.UnOrderMessageDispatcher:
-                {
-                    await ActorMessageDispatcherComponent.Instance.Handle(entity, fromProcess, iActorMessage);
-                    break;
-                }
-                case MailboxType.GateSession:
-                {
-                    if (entity is PlayerSessionComponent playerSessionComponent)
-                    {
-                        playerSessionComponent.Session?.Send(iActorMessage);
-                    }
-                    break;
-                }
-                default:
-                    throw new Exception($"no mailboxtype: {mailBoxComponent.MailboxType} {iActorMessage}");
-            }
-        }
     }
 }

+ 123 - 1
Unity/Assets/Scripts/Hotfix/Server/Module/Actor/ActorMessageDispatcherComponentSystem.cs

@@ -93,7 +93,7 @@ namespace ET.Server
             self.ActorMessageHandlers[type].Add(handler);
         }
 
-        public static async ETTask Handle(this ActorMessageDispatcherComponent self, Entity entity, int fromProcess, object message)
+        private static async ETTask Handle(this ActorMessageDispatcherComponent self, Entity entity, int fromProcess, object message)
         {
             List<ActorMessageDispatcherInfo> list;
             if (!self.ActorMessageHandlers.TryGetValue(message.GetType(), out list))
@@ -111,5 +111,127 @@ namespace ET.Server
                 await actorMessageDispatcherInfo.IMActorHandler.Handle(entity, fromProcess, message);   
             }
         }
+
+
+        /// <summary>
+        /// 分发actor消息
+        /// </summary>
+        [EnableAccessEntiyChild]
+        public static async ETTask HandleIActorRequest(this ActorMessageDispatcherComponent self, int fromProcess, long actorId, IActorRequest iActorRequest)
+        {
+            Entity entity = self.Get(actorId);
+            if (entity == null)
+            {
+                IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
+                ActorHandleHelper.Reply(fromProcess, response);
+                return;
+            }
+            
+            OpcodeHelper.LogMsg(entity.DomainScene(), iActorRequest);
+
+            MailBoxComponent mailBoxComponent = entity.GetComponent<MailBoxComponent>();
+            if (mailBoxComponent == null)
+            {
+                Log.Warning($"actor not found mailbox: {entity.GetType().FullName} {actorId} {iActorRequest}");
+                IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
+                ActorHandleHelper.Reply(fromProcess, response);
+                return;
+            }
+            
+            switch (mailBoxComponent.MailboxType)
+            {
+                case MailboxType.MessageDispatcher:
+                {
+                    using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Mailbox, actorId))
+                    {
+                        if (entity.InstanceId != actorId)
+                        {
+                            IActorResponse response = ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor);
+                            ActorHandleHelper.Reply(fromProcess, response);
+                            break;
+                        }
+                        await self.Handle(entity, fromProcess, iActorRequest);
+                    }
+                    break;
+                }
+                case MailboxType.UnOrderMessageDispatcher:
+                {
+                    await self.Handle(entity, fromProcess, iActorRequest);
+                    break;
+                }
+                default:
+                    throw new Exception($"no mailboxtype: {mailBoxComponent.MailboxType} {iActorRequest}");
+            }
+        }
+        
+        /// <summary>
+        /// 分发actor消息
+        /// </summary>
+        [EnableAccessEntiyChild]
+        public static async ETTask HandleIActorMessage(this ActorMessageDispatcherComponent self, int fromProcess, long actorId, IActorMessage iActorMessage)
+        {
+            Entity entity = self.Get(actorId);
+            if (entity == null)
+            {
+                Log.Error($"not found actor: {actorId} {iActorMessage}");
+                return;
+            }
+            
+            MailBoxComponent mailBoxComponent = entity.GetComponent<MailBoxComponent>();
+            if (mailBoxComponent == null)
+            {
+                Log.Error($"actor not found mailbox: {entity.GetType().FullName} {actorId} {iActorMessage}");
+                return;
+            }
+
+            switch (mailBoxComponent.MailboxType)
+            {
+                case MailboxType.MessageDispatcher:
+                {
+                    using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Mailbox, actorId))
+                    {
+                        if (entity.InstanceId != actorId)
+                        {
+                            break;
+                        }
+                        await self.Handle(entity, fromProcess, iActorMessage);
+                    }
+                    break;
+                }
+                case MailboxType.UnOrderMessageDispatcher:
+                {
+                    await self.Handle(entity, fromProcess, iActorMessage);
+                    break;
+                }
+                case MailboxType.GateSession:
+                {
+                    if (entity is PlayerSessionComponent playerSessionComponent)
+                    {
+                        playerSessionComponent.Session?.Send(iActorMessage);
+                    }
+                    break;
+                }
+                default:
+                    throw new Exception($"no mailboxtype: {mailBoxComponent.MailboxType} {iActorMessage}");
+            }
+        }
+        
+        
+        public static void Add(this ActorMessageDispatcherComponent self, Entity entity)
+        {
+            self.mailboxEntities.Add(entity.InstanceId, entity);
+        }
+        
+        public static void Remove(this ActorMessageDispatcherComponent self, long instanceId)
+        {
+            self.mailboxEntities.Remove(instanceId);
+        }
+
+        private static Entity Get(this ActorMessageDispatcherComponent self, long instanceId)
+        {
+            Entity component = null;
+            self.mailboxEntities.TryGetValue(instanceId, out component);
+            return component;
+        }
     }
 }

+ 13 - 0
Unity/Assets/Scripts/Hotfix/Server/Module/Actor/MailBoxComponentSystem.cs

@@ -8,6 +8,8 @@ namespace ET.Server
         protected override void Awake(MailBoxComponent self)
         {
             self.MailboxType = MailboxType.MessageDispatcher;
+            self.ParentInstanceId = self.Parent.InstanceId;
+            ActorMessageDispatcherComponent.Instance.Add(self.Parent);
         }
     }
 
@@ -17,6 +19,17 @@ namespace ET.Server
         protected override void Awake(MailBoxComponent self, MailboxType mailboxType)
         {
             self.MailboxType = mailboxType;
+            self.ParentInstanceId = self.Parent.InstanceId;
+            ActorMessageDispatcherComponent.Instance.Add(self.Parent);
+        }
+    }
+
+    [ObjectSystem]
+    public class DestroySystem: DestroySystem<MailBoxComponent>
+    {
+        protected override void Destroy(MailBoxComponent self)
+        {
+            ActorMessageDispatcherComponent.Instance.Remove(self.ParentInstanceId);
         }
     }
 }

+ 2 - 0
Unity/Assets/Scripts/Model/Server/Module/Actor/ActorMessageDispatcherComponent.cs

@@ -26,5 +26,7 @@ namespace ET.Server
         public static ActorMessageDispatcherComponent Instance;
 
         public readonly Dictionary<Type, List<ActorMessageDispatcherInfo>> ActorMessageHandlers = new();
+        
+        public readonly Dictionary<long, Entity> mailboxEntities = new();
     }
 }

+ 2 - 1
Unity/Assets/Scripts/Model/Server/Module/Actor/MailBoxComponent.cs

@@ -4,8 +4,9 @@
     /// 挂上这个组件表示该Entity是一个Actor,接收的消息将会队列处理
     /// </summary>
     [ComponentOf]
-    public class MailBoxComponent: Entity, IAwake, IAwake<MailboxType>
+    public class MailBoxComponent: Entity, IAwake, IAwake<MailboxType>, IDestroy
     {
+        public long ParentInstanceId;
         // Mailbox的类型
         public MailboxType MailboxType { get; set; }
     }