using MongoDB.Bson.Serialization.Attributes; namespace KYFramework { [BsonIgnoreExtraElements] public class Entity : ComponentWithId { [BsonElement("C")] [BsonIgnoreIfNull] private HashSet components = new HashSet(); [BsonIgnore] private Dictionary componentDict = new Dictionary(); public Entity() { } protected Entity(long id) : base(id) { } public override void Dispose() { if (this.IsDisposed) { return; } base.Dispose(); foreach (Component component in this.componentDict.Values) { try { component.Dispose(); } catch (Exception e) { Log.Error(e); } } this.components.Clear(); this.componentDict.Clear(); } public virtual Component AddComponent(Component component) { Type type = component.GetType(); if (this.componentDict.ContainsKey(type)) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {type.Name}"); } component.Parent = this; this.componentDict.Add(type, component); if (component is ISerializeToEntity) { this.components.Add(component); } return component; } public virtual Component AddComponent(Type type) { if (this.componentDict.ContainsKey(type)) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {type.Name}"); } Component component = ComponentFactory.CreateWithParent(type, this, this.IsFromPool); this.componentDict.Add(type, component); if (component is ISerializeToEntity) { this.components.Add(component); } return component; } public virtual K AddComponent() where K : Component, new() { Type type = typeof(K); if (this.componentDict.ContainsKey(type)) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } K component = ComponentFactory.CreateWithParent(this, this.IsFromPool); this.componentDict.Add(type, component); if (component is ISerializeToEntity) { this.components.Add(component); } return component; } public virtual K AddComponent(P1 p1) where K : Component, new() { Type type = typeof(K); if (this.componentDict.ContainsKey(type)) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } K component = ComponentFactory.CreateWithParent(this, p1, this.IsFromPool); this.componentDict.Add(type, component); if (component is ISerializeToEntity) { this.components.Add(component); } return component; } public virtual K AddComponent(P1 p1, P2 p2) where K : Component, new() { Type type = typeof(K); if (this.componentDict.ContainsKey(type)) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } K component = ComponentFactory.CreateWithParent(this, p1, p2, this.IsFromPool); this.componentDict.Add(type, component); if (component is ISerializeToEntity) { this.components.Add(component); } return component; } public virtual K AddComponent(P1 p1, P2 p2, P3 p3) where K : Component, new() { Type type = typeof(K); if (this.componentDict.ContainsKey(type)) { throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}"); } K component = ComponentFactory.CreateWithParent(this, p1, p2, p3, this.IsFromPool); this.componentDict.Add(type, component); if (component is ISerializeToEntity) { this.components.Add(component); } return component; } public virtual void RemoveComponent() where K : Component { if (this.IsDisposed) { return; } Type type = typeof(K); Component component; if (!this.componentDict.TryGetValue(type, out component)) { return; } this.componentDict.Remove(type); this.components.Remove(component); component.Dispose(); } public virtual void RemoveComponent(Type type) { if (this.IsDisposed) { return; } Component component; if (!this.componentDict.TryGetValue(type, out component)) { return; } this.componentDict.Remove(type); this.components.Remove(component); 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 GetComponent(Type type) { Component component; if (!this.componentDict.TryGetValue(type, out component)) { return null; } return component; } public Component[] GetComponents() { return this.componentDict.Values.ToArray(); } public override void EndInit() { try { base.EndInit(); this.componentDict.Clear(); if (this.components != null) { foreach (Component component in this.components) { component.Parent = this; this.componentDict.Add(component.GetType(), component); } } } catch (Exception e) { Log.Error(e); } } } }