73 lines
2.0 KiB
C#
73 lines
2.0 KiB
C#
using Engine.Scene.Component;
|
|
|
|
namespace Engine.Scene;
|
|
|
|
public sealed class GameObject
|
|
{
|
|
public Guid Id { get; } = Guid.NewGuid();
|
|
public Transform Transform { get; }
|
|
|
|
private readonly Queue<Action> _componentActions = new();
|
|
|
|
private readonly List<Component.Component> _components = new();
|
|
private readonly ISet<Type> _addedComponentTypes = new HashSet<Type>();
|
|
|
|
public GameObject()
|
|
{
|
|
AddComponent<Transform>();
|
|
UpdateComponents();
|
|
|
|
Transform = GetComponent<Transform>()!;
|
|
}
|
|
|
|
public T? GetComponent<T>() where T : Component.Component
|
|
{
|
|
if (!_addedComponentTypes.Contains(typeof(T)))
|
|
return null;
|
|
|
|
return _components.OfType<T>().FirstOrDefault();
|
|
}
|
|
|
|
public void AddComponent<T>(params object?[] args) where T : Component.Component
|
|
{
|
|
if (_addedComponentTypes.Contains(typeof(T)))
|
|
return;
|
|
|
|
var newArgs = new object?[args.Length + 1];
|
|
newArgs[0] = this;
|
|
for (var i = 0; i < args.Length; i++)
|
|
newArgs[i + 1] = args[i];
|
|
|
|
var component = (T?)Activator.CreateInstance(typeof(T), newArgs);
|
|
if (component == null)
|
|
throw new InvalidOperationException($"Failed to create component of type {typeof(T)}");
|
|
|
|
_componentActions.Enqueue(() =>
|
|
{
|
|
_components.Add(component);
|
|
_addedComponentTypes.Add(typeof(T));
|
|
});
|
|
}
|
|
|
|
public void RemoveComponent<T>() where T : Component.Component
|
|
{
|
|
if (!_addedComponentTypes.Contains(typeof(T)) || typeof(T) == typeof(Transform))
|
|
return;
|
|
|
|
var component = GetComponent<T>();
|
|
if (component == null)
|
|
return;
|
|
|
|
_componentActions.Enqueue(() =>
|
|
{
|
|
_components.Remove(component);
|
|
_addedComponentTypes.Remove(typeof(T));
|
|
});
|
|
}
|
|
|
|
private void UpdateComponents()
|
|
{
|
|
while (_componentActions.TryDequeue(out var action))
|
|
action();
|
|
}
|
|
} |