152 lines
5.2 KiB
C#
152 lines
5.2 KiB
C#
using Syntriax.Engine.Core.Abstract;
|
|
using Syntriax.Engine.Core.Exceptions;
|
|
|
|
namespace Syntriax.Engine.Core;
|
|
|
|
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
|
|
public class GameObject : BaseEntity, IGameObject
|
|
{
|
|
public event IHierarchyObject.OnEnteredHierarchyEventHandler? OnEnteredHierarchy = null;
|
|
public event IHierarchyObject.OnExitedHierarchyEventHandler? OnExitedHierarchy = null;
|
|
|
|
public event IAssignableTransform.OnTransformAssignedEventHandler? OnTransformAssigned = null;
|
|
public event IAssignableBehaviourController.OnBehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null;
|
|
|
|
public event INameable.OnNameChangedEventHandler? OnNameChanged = null;
|
|
|
|
public event IGameObject.OnUpdatedEventHandler? OnUpdated = null;
|
|
|
|
private ITransform _transform = null!;
|
|
private IBehaviourController _behaviourController = null!;
|
|
private IGameManager _gameManager = null!;
|
|
|
|
private string _name = nameof(GameObject);
|
|
|
|
public ITransform Transform => _transform;
|
|
public IBehaviourController BehaviourController => _behaviourController;
|
|
public IGameManager GameManager => _gameManager;
|
|
public bool IsInHierarchy => GameManager is not null;
|
|
|
|
public string Name
|
|
{
|
|
get => _name;
|
|
set
|
|
{
|
|
if (value == _name) return;
|
|
|
|
string previousName = _name;
|
|
_name = value;
|
|
OnNameChanged?.Invoke(this, previousName);
|
|
}
|
|
}
|
|
|
|
protected override void InitializeInternal()
|
|
{
|
|
base.InitializeInternal();
|
|
|
|
NotAssignedException.Check(this, _transform);
|
|
NotAssignedException.Check(this, _behaviourController);
|
|
|
|
if (!_behaviourController.Initialize())
|
|
throw new System.Exception($"Failed to Initialize {BehaviourController.GetType().Name} on {Transform.GameObject.Name}");
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (!StateEnable.Enabled)
|
|
return;
|
|
|
|
OnUpdated?.Invoke(this);
|
|
}
|
|
|
|
protected override void FinalizeInternal()
|
|
{
|
|
base.FinalizeInternal();
|
|
|
|
if (!_behaviourController.Finalize())
|
|
throw new System.Exception($"Failed to Finalize {BehaviourController.GetType().Name} on {Transform.GameObject.Name}");
|
|
}
|
|
|
|
public bool Assign(ITransform transform)
|
|
{
|
|
if (IsInitialized)
|
|
return false;
|
|
|
|
_transform = transform;
|
|
OnTransformAssigned?.Invoke(this);
|
|
transform.OnParentChanged += OnParentChangedInternal;
|
|
OnParentChangedInternal(transform, null, transform.Parent);
|
|
return true;
|
|
}
|
|
|
|
public bool Assign(IBehaviourController behaviourController)
|
|
{
|
|
if (IsInitialized)
|
|
return false;
|
|
|
|
_behaviourController = behaviourController;
|
|
OnBehaviourControllerAssigned?.Invoke(this);
|
|
return true;
|
|
}
|
|
|
|
protected override void UnassignInternal()
|
|
{
|
|
base.UnassignInternal();
|
|
|
|
_transform.OnParentChanged -= OnParentChangedInternal;
|
|
OnParentChangedInternal(_transform, _transform.Parent, null);
|
|
_transform = null!;
|
|
_behaviourController = null!;
|
|
_gameManager = null!;
|
|
}
|
|
|
|
public GameObject() { OnBehaviourControllerAssigned += ConnectBehaviourController; }
|
|
|
|
private void ConnectBehaviourController(IAssignableBehaviourController controller)
|
|
{
|
|
controller.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
|
|
controller.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
|
|
}
|
|
private void OnBehaviourRemoved(IBehaviourController _, IBehaviour behaviour) { if (IsInitialized) behaviour.Finalize(); }
|
|
private void OnBehaviourAdded(IBehaviourController _, IBehaviour behaviour) { if (!IsInitialized) behaviour.Initialize(); }
|
|
|
|
private void OnParentChangedInternal(ITransform sender, ITransform? previousParent, ITransform? newParent)
|
|
{
|
|
if (previousParent is not null)
|
|
{
|
|
previousParent.OnParentChanged -= OnParentChangedInternal;
|
|
previousParent.GameObject.OnEnteredHierarchy -= EnterHierarchyInternal;
|
|
previousParent.GameObject.OnExitedHierarchy -= ExitHierarchyInternal;
|
|
}
|
|
if (newParent is not null)
|
|
{
|
|
newParent.OnParentChanged += OnParentChangedInternal;
|
|
newParent.GameObject.OnEnteredHierarchy += EnterHierarchyInternal;
|
|
newParent.GameObject.OnExitedHierarchy += ExitHierarchyInternal;
|
|
}
|
|
}
|
|
|
|
private void EnterHierarchyInternal(IHierarchyObject sender, IGameManager gameManager) => ((IHierarchyObject)this).EnterHierarchy(gameManager);
|
|
private void ExitHierarchyInternal(IHierarchyObject sender, IGameManager gameManager) => ((IHierarchyObject)this).ExitHierarchy();
|
|
|
|
bool IHierarchyObject.EnterHierarchy(IGameManager gameManager)
|
|
{
|
|
if (IsInHierarchy)
|
|
return false;
|
|
|
|
_gameManager = gameManager;
|
|
OnEnteredHierarchy?.Invoke(this, gameManager);
|
|
return true;
|
|
}
|
|
|
|
bool IHierarchyObject.ExitHierarchy()
|
|
{
|
|
if (!IsInHierarchy || _gameManager is not IGameManager gameManager)
|
|
return false;
|
|
|
|
_gameManager = null!;
|
|
OnExitedHierarchy?.Invoke(this, gameManager);
|
|
return true;
|
|
}
|
|
}
|