using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using MongoDB.Bson.Serialization.Attributes; namespace Model { [BsonIgnoreExtraElements] public class Entity : Disposer, ISupportInitialize { [BsonIgnore] public Entity Parent { get; set; } [BsonElement] [BsonIgnoreIfNull] private HashSet components; [BsonIgnore] private Dictionary componentDict = new Dictionary(); protected Entity() { this.Id = IdGenerater.GenerateId(); } protected Entity(long id) { this.Id = id; } public override void Dispose() { if (this.Id == 0) { return; } base.Dispose(); foreach (Component component in this.GetComponents()) { try { component.Dispose(); } catch (Exception e) { Log.Error(e.ToString()); } } } public K AddComponent() where K : Component, new() { K component = ComponentFactory.Create(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(); } if (component is ComponentDB) { this.components.Add(component); } this.componentDict.Add(component.GetType(), component); return component; } public K AddComponent(P1 p1) where K : Component, new() { K component = ComponentFactory.Create(this, p1); 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(); } if (component is ComponentDB) { this.components.Add(component); } this.componentDict.Add(component.GetType(), component); return component; } public K AddComponent(P1 p1, P2 p2) where K : Component, new() { K component = ComponentFactory.Create(this, p1, p2); 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(); } if (component is ComponentDB) { this.components.Add(component); } this.componentDict.Add(component.GetType(), component); return component; } public K AddComponent(P1 p1, P2 p2, P3 p3) where K : Component, new() { K component = ComponentFactory.Create(this, p1, p2, p3); 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(); } if (component is ComponentDB) { this.components.Add(component); } this.componentDict.Add(component.GetType(), component); return component; } 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 != null && this.components.Count == 0) { this.components = null; } component.Dispose(); } public void RemoveComponent(Type type) { Component component; if (!this.componentDict.TryGetValue(type, out component)) { return; } this.components?.Remove(component); this.componentDict.Remove(type); if (this.components != null && 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 this.componentDict.Values.ToArray(); } public virtual void BeginInit() { this.components = new HashSet(); this.componentDict = new Dictionary(); } public virtual void EndInit() { ObjectEvents.Instance.Add(this); if (this.components != null && this.components.Count == 0) { this.components = null; } if (this.components != null) { foreach (Component component in this.components) { component.Entity = this; this.componentDict.Add(component.GetType(), component); } } } #if AOT private void AvoidAot() { EnumSerializer e = new EnumSerializer(); } #endif } }