Managed the freeing of entityplacers. Also cleaned up EntityManager

pull/52/head
Katharina Ziolkowski 2 months ago
parent bcbc074c86
commit b65a3bbd6d

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Babushka.scripts.CSharp.GameEntity.Entities;
public class LoadedScenesEntity : Entity
{
private HashSet<string> _loadedScenes = new();
public override string EntityType => "LoadedScenesEntity";
public void AddScene(string sceneName) => _loadedScenes.Add(sceneName);
public bool WasSceneLoaded(string sceneName) => _loadedScenes.Contains(sceneName);
}

@ -28,6 +28,6 @@ public abstract class PositionalEntity : Entity
}
// Deals with Instantiation of the node
public abstract void AddEntity(Node2D parent);
public abstract void InstantiateEntityNode(Node2D parent);
}

@ -13,10 +13,10 @@ public class TrashEntity : PositionalEntity
{
}
public override void AddEntity(Node2D parent)
public override void InstantiateEntityNode(Node2D parent)
{
if(_creator == null) _creator = EntityManager.Instance.NodeCreator;
var entityNode = _creator.CreateNode2D(EntityType);
var entityNode = _creator.InstantiateNode(EntityType);
parent.AddChild(entityNode);
entityNode.GlobalPosition = position;
}

@ -9,10 +9,18 @@ public partial class TrashEntityPlacer : Node2D
private string _trashEntityType = TrashEntity.OWN_TYPE_NAME;
public override void _Ready()
{
string sceneName = EntityManager.Instance.CurrentEntitySceneContainer!.sceneName;
var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity<LoadedScenesEntity>();
if (!loadedScenesEntity.WasSceneLoaded(sceneName))
{
TrashEntity entity = new TrashEntity();
entity.sceneName = EntityManager.Instance.CurrentEntitySceneContainer!.sceneName;
entity.sceneName = sceneName;
entity.position = GlobalPosition;
EntityManager.Instance.AddEntity(entity);
}
QueueFree();
}
}

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Godot;
using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity;
@ -7,21 +6,23 @@ using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalE
namespace Babushka.scripts.CSharp.GameEntity.Management;
/// <summary>
/// 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.
/// </summary>
public partial class EntityManager : Node
{
[Export] private EntityNodeCreator _nodeCreator = null!;
public static EntityManager Instance;
public EntityNodeCreator NodeCreator => _nodeCreator;
[Export] private EntityNodeCreator _nodeCreator = null!;
private EntitySceneContainer? _currentEntitySceneContainer;
public static EntityManager Instance;
private readonly List<Entity> _allEntities = new();
public IEnumerable<Entity> AllEntities => _allEntities;
public IEnumerable<PositionalEntity> AllPositionalEntities => _allEntities.OfType<PositionalEntity>();
public EntitySceneContainer? CurrentEntitySceneContainer => _currentEntitySceneContainer;
public EntityNodeCreator NodeCreator => _nodeCreator;
public override void _EnterTree()
{
@ -30,6 +31,7 @@ public partial class EntityManager : Node
public override void _Input(InputEvent @event)
{
// for debugging purposes
if (@event.IsActionPressed("DebugEntities"))
{
GD.Print("Entities:");
@ -40,36 +42,48 @@ public partial class EntityManager : Node
}
}
public void UnloadScene()
{
if (_currentEntitySceneContainer == null) return;
_currentEntitySceneContainer = null;
}
public void LoadScene(EntitySceneContainer sceneContainer)
{
_currentEntitySceneContainer = sceneContainer;
foreach (var entity in AllPositionalEntities)
{
_currentEntitySceneContainer.AddIfNeeded(entity);
}
}
#region ENTITY MANAGEMENT
/// <summary>
/// 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.
/// </summary>
/// <param name="entity">The entity to be added to the manager.</param>
public void AddEntity(Entity entity)
{
if(!_allEntities.Contains(entity))
if (!_allEntities.Contains(entity))
_allEntities.Add(entity);
if(entity is PositionalEntity positionalEntity && positionalEntity.sceneName == _currentEntitySceneContainer?.sceneName)
CreateEntityNode(positionalEntity);
InstantiatePositionalEntityNode(positionalEntity);
}
public void CreateEntityNode(PositionalEntity entity)
private void InstantiatePositionalEntityNode(PositionalEntity entity)
{
if(_currentEntitySceneContainer == null) return;
entity.AddEntity(_currentEntitySceneContainer);
entity.InstantiateEntityNode(_currentEntitySceneContainer);
}
public EntitySceneContainer? CurrentEntitySceneContainer => _currentEntitySceneContainer;
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="T">The type of entity to retrieve or create. Must inherit from the Entity class and have a parameterless constructor.</typeparam>
/// <returns>The first entity of the specified type or a newly created entity of that type if none were found.</returns>
public T GetUniqueEntity<T>() where T : Entity, new()
{
var result = AllEntities.OfType<T>().FirstOrDefault();
if (result == null)
{
var newEntity = new T();
AddEntity(newEntity);
result = newEntity;
}
return result;
}
#endregion
#region SCENE CONTAINER ACCESS
public void SetSceneContainer(EntitySceneContainer sceneContainer)
{
@ -80,4 +94,7 @@ public partial class EntityManager : Node
{
_currentEntitySceneContainer = null;
}
#endregion
}

@ -1,4 +1,5 @@
using Godot;
using System;
using Godot;
using Godot.Collections;
namespace Babushka.scripts.CSharp.GameEntity.Management;
@ -7,8 +8,18 @@ public partial class EntityNodeCreator : Node
{
[Export] private Dictionary<string, PackedScene> _entityPrefabs;
public Node2D CreateNode2D(string type)
public Node2D InstantiateNode(string type)
{
if (string.IsNullOrEmpty(type))
{
throw new NullReferenceException("The type provided for Node instantiation cannot be null or empty.");
}
if (!_entityPrefabs.ContainsKey(type))
{
throw new Exception($"The type provided for Node instantiation ({type}) is not specified in the EntityNodeCreator dictionary.");
}
return _entityPrefabs[type].Instantiate<Node2D>();
}
}

@ -1,4 +1,5 @@
using System.Linq;
using Babushka.scripts.CSharp.GameEntity.Entities;
using Godot;
using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity;
@ -16,6 +17,8 @@ public partial class EntitySceneContainer : Node2D
public override void _ExitTree()
{
EntityManager.Instance.UnsetSceneContainer();
var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity<LoadedScenesEntity>();
loadedScenesEntity.AddScene(sceneName);
}
public override void _Ready()
@ -33,7 +36,7 @@ public partial class EntitySceneContainer : Node2D
public void AddEntity(PositionalEntity entity)
{
entity.AddEntity(this);
entity.InstantiateEntityNode(this);
}
}
Loading…
Cancel
Save