using System; using System.Collections.Generic; using System.Linq; using Base; using MongoDB.Bson.Serialization.Attributes; namespace Base { public abstract class Entity: Object where T : Entity { [BsonElement, BsonIgnoreIfNull] private HashSet> components = new HashSet>(); private Dictionary> componentDict = new Dictionary>(); [BsonIgnore] public T Parent { get; set; } public string Name { get; } [BsonElement, BsonIgnoreIfNull] private Dictionary idChildren; [BsonElement, BsonIgnoreIfNull] private Dictionary nameChildren; protected Entity() { this.Name = ""; ObjectManager.Add(this); } protected Entity(string name) { this.Name = name; ObjectManager.Add(this); } protected Entity(long id, string name): base(id) { this.Name = name; ObjectManager.Add(this); } public T Clone() { return MongoHelper.FromBson(MongoHelper.ToBson(this)); } public int Count { get { return this.idChildren.Count; } } public void Add(T t) { t.Parent = (T)this; if (this.idChildren == null) { this.idChildren = new Dictionary(); this.nameChildren = new Dictionary(); } this.idChildren.Add(t.Id, t); this.nameChildren.Add(t.Name, t); } private void Remove(T t) { this.idChildren.Remove(t.Id); this.nameChildren.Remove(t.Name); if (this.idChildren.Count == 0) { this.idChildren = null; this.nameChildren = null; } t.Dispose(); } public void Remove(long id) { T t; if (!this.idChildren.TryGetValue(id, out t)) { return; } this.Remove(t); } public void Remove(string name) { T t; if (!this.nameChildren.TryGetValue(name, out t)) { return; } this.Remove(t); } public override void Dispose() { if (this.Id == 0) { return; } base.Dispose(); foreach (T t in this.idChildren.Values.ToArray()) { t.Dispose(); } foreach (Component component in this.GetComponents()) { try { component.Dispose(); } catch (Exception e) { Log.Error(e.ToString()); } } this.Parent?.Remove(this.Id); ObjectManager.Remove(this.Id); } public K AddComponent() where K : Component, new() { K component = (K) Activator.CreateInstance(typeof (K)); component.Owner = (T) this; if (this.componentDict.ContainsKey(component.GetType())) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof (K).Name}"); } if (this.components == null) { this.components = new HashSet>(); } this.components.Add(component); this.componentDict.Add(component.GetType(), component); ObjectManager.Awake(component.Id); return component; } public K AddComponent(P1 p1) where K : Component, new() { K component = (K)Activator.CreateInstance(typeof(K)); component.Owner = (T)this; if (this.componentDict.ContainsKey(component.GetType())) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } if (this.components == null) { this.components = new HashSet>(); } this.components.Add(component); this.componentDict.Add(component.GetType(), component); ObjectManager.Awake(component.Id, p1); return component; } public K AddComponent(P1 p1, P2 p2) where K : Component, new() { K component = (K)Activator.CreateInstance(typeof(K)); component.Owner = (T)this; if (this.componentDict.ContainsKey(component.GetType())) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } if (this.components == null) { this.components = new HashSet>(); } this.components.Add(component); this.componentDict.Add(component.GetType(), component); ObjectManager.Awake(component.Id, p1, p2); return component; } public K AddComponent(P1 p1, P2 p2, P3 p3) where K : Component, new() { K component = (K)Activator.CreateInstance(typeof(K)); component.Owner = (T)this; if (this.componentDict.ContainsKey(component.GetType())) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } if (this.components == null) { this.components = new HashSet>(); } this.components.Add(component); this.componentDict.Add(component.GetType(), component); ObjectManager.Awake(component.Id, p1, p2, p3); return component; } public void AddComponent(Component component) { if (this.componentDict.ContainsKey(component.GetType())) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {component.GetType().Name}"); } if (this.components == null) { this.components = new HashSet>(); } this.components.Add(component); this.componentDict.Add(component.GetType(), component); ObjectManager.Awake(component.Id); } public void RemoveComponent() where K : Component { Component component; if (!this.componentDict.TryGetValue(typeof (K), out component)) { return; } this.components.Remove(component); this.componentDict.Remove(typeof (K)); if (this.components.Count == 0) { this.components = null; } component.Dispose(); } public K GetComponent() where K : Component { Component component; if (!this.componentDict.TryGetValue(typeof (K), out component)) { return default(K); } return (K) component; } public Component[] GetComponents() { return components.ToArray(); } public override void BeginInit() { base.BeginInit(); this.components = new HashSet>(); this.componentDict = new Dictionary>(); } public override void EndInit() { base.EndInit(); if (this.components.Count == 0) { this.components = null; return; } foreach (Component component in this.components) { component.Owner = (T) this; this.componentDict.Add(component.GetType(), component); } } } }