using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Xml.Linq; using GlitchyEngine.Core; using GlitchyEngine.Math; namespace GlitchyEngine; internal struct EntityHandle { public uint Version; public uint Index; } public class Entity : EngineObject { /// /// Empty constructor not used. Do NOT USE! /// protected Entity() { } internal Entity(UUID uuid) { _uuid = uuid; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool HasComponent() => HasComponent(typeof(T)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool HasComponent(Type type) => ScriptGlue.Entity_HasComponent(_uuid, type); /// /// Gets the component with the specified type. /// /// The type of the component to get. /// The component or null, if the entity doesn't have a component of the specified type. public T GetComponent() where T : Component, new() { if (HasComponent()) { return new T { Entity = this }; } return null; } /// /// Gets the component with the given type. /// /// The type of the component to get. /// The component or null, if the entity doesn't have a component of the given type. /// For performance reasons it is recommended to use if possible. public Component GetComponent(Type componentType) { // TODO: probably throw! if (!componentType.IsSubclassOf(typeof(Component))) return null; if (HasComponent(componentType)) { return Activator.CreateInstance(componentType) as Component; } return null; } /// /// Gets the component with the specified component type. /// /// The type of the component to add. /// The component. public T AddComponent() where T : Component, new() { ScriptGlue.Entity_AddComponent(_uuid, typeof(T)); return new T { Entity = this }; } /// /// Gets the component with the given component type. /// /// The type of the component to add. /// The component or null, if the given type is not a valid component type. /// For performance reasons it is recommended to use if possible. public Component AddComponent(Type componentType) { // TODO: probably throw! if (!componentType.IsSubclassOf(typeof(Component))) return null; ScriptGlue.Entity_AddComponent(_uuid, componentType); Component component = Activator.CreateInstance(componentType) as Component; return component; } /// /// Removes the component with the specified component type. /// /// The type of the component to remove. public void RemoveComponent() where T : Component, new() { ScriptGlue.Entity_RemoveComponent(_uuid, typeof(T)); } /// /// Removes the component with the given component type. /// /// The type of the component to remove. /// For performance reasons it is recommended to use if possible. public void RemoveComponent(Type componentType) { // TODO: probably throw! if (!componentType.IsSubclassOf(typeof(Component))) return; ScriptGlue.Entity_RemoveComponent(_uuid, componentType); } public Transform Transform => GetComponent(); //public Vector3 Translation //{ // get => Transform.Translation; // set => Transform.Translation = value; //} /// /// Returns the first entity with the given name. /// /// The name of the entity. /// The first entity with the given name, or null. public static Entity FindEntityWithName(string name) { ScriptGlue.Entity_FindEntityWithName(name, out UUID entityId); if (entityId == UUID.Zero) return null; return new Entity(entityId); } /// /// Returns the script of the given type, or null, if the entity has no script of the given type. /// /// The type of the script. /// The script instance or null. public T As() where T : Entity { object scriptInstance = ScriptGlue.Entity_GetScriptInstance(_uuid); return scriptInstance as T; } // Will be executed once after the entity as be created. // void OnCreate(); // Will be executed every frame. // void OnUpdate(GameTime); // Will be executed once when the entity is being destroyed. // void OnDestroy(); }