using System.Collections.Generic; using System.Linq; using Godot; using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity; using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity; namespace Babushka.scripts.CSharp.GameEntity.Management; /// /// Manages the lifecycle and interactions of all entities within the game, including their creation, retrieval, /// and organization. The EntityManager serves as a centralized hub for managing both standard and positional entities. /// public partial class EntityManager : Node { public static EntityManager Instance; [Export] private EntityNodeCreator _nodeCreator = null!; private EntitySceneContainer? _currentEntitySceneContainer; private readonly List _allEntities = new(); public IEnumerable AllEntities => _allEntities; public IEnumerable AllPositionalEntities => _allEntities.OfType(); public EntitySceneContainer? CurrentEntitySceneContainer => _currentEntitySceneContainer; public EntityNodeCreator NodeCreator => _nodeCreator; public override void _EnterTree() { Instance = this; } public override void _Input(InputEvent @event) { // for debugging purposes if (@event.IsActionPressed("DebugEntities")) { GD.Print("Entities:"); foreach (var entity in AllEntities) { GD.Print(entity.EntityType + " " + entity.id); } } } #region ENTITY MANAGEMENT /// /// Adds an entity to the list of managed entities. If the entity is a positional entity /// and its scene matches the current scene container, it is also instantiated in the scene. /// /// The entity to be added to the manager. public void AddEntity(Entity entity) { if (!_allEntities.Contains(entity)) _allEntities.Add(entity); if(entity is PositionalEntity positionalEntity && positionalEntity.sceneName == _currentEntitySceneContainer?.sceneName) InstantiatePositionalEntityNode(positionalEntity); } private void InstantiatePositionalEntityNode(PositionalEntity entity) { if(_currentEntitySceneContainer == null) return; entity.InstantiateEntityNode(_currentEntitySceneContainer); } /// /// Retrieves the first entity of the specified type from the list of managed entities. /// If no such entity exists, creates a new instance of the specified type, adds it to the manager, and returns it. /// /// The type of entity to retrieve or create. Must inherit from the Entity class and have a parameterless constructor. /// The first entity of the specified type or a newly created entity of that type if none were found. public T GetUniqueEntity() where T : Entity, new() { var result = AllEntities.OfType().FirstOrDefault(); if (result == null) { var newEntity = new T(); AddEntity(newEntity); result = newEntity; } return result; } #endregion #region SCENE CONTAINER ACCESS public void SetSceneContainer(EntitySceneContainer sceneContainer) { _currentEntitySceneContainer = sceneContainer; } public void UnsetSceneContainer() { _currentEntitySceneContainer = null; } #endregion }