Compare commits
21 Commits
main
...
feat/gameo
Author | SHA1 | Date |
---|---|---|
Syntriax | 1df5eee59d | |
Syntriax | 0148afea52 | |
Syntriax | 4faac1b5ca | |
Syntriax | 4c04e3d02f | |
Syntriax | 2f6fecdd78 | |
Syntriax | 7e48eb8f12 | |
Syntriax | 86b9206515 | |
Syntriax | 0708ba89cc | |
Syntriax | 361a7c53b9 | |
Syntriax | 2cf6135063 | |
Syntriax | be06575f91 | |
Syntriax | ed6975bf24 | |
Syntriax | d9660c08b1 | |
Syntriax | 3902f1caca | |
Syntriax | 14e3337daa | |
Syntriax | f729cdc0a8 | |
Syntriax | c767e1e856 | |
Syntriax | f96c58cbd4 | |
Syntriax | fed288859f | |
Syntriax | 6e4c9b0ef8 | |
Syntriax | b931abb735 |
|
@ -1,11 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
/// Represents the transformation properties of an object such as position, scale, and rotation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITransform
|
public interface ITransform : IAssignableGameObject, IEnumerable<ITransform>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
|
||||||
|
@ -23,17 +24,75 @@ public interface ITransform
|
||||||
Action<ITransform>? OnRotationChanged { get; set; }
|
Action<ITransform>? OnRotationChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The position of the <see cref="ITransform"/> in 2D space.
|
/// Event triggered when the <see cref="Parent"/> of the <see cref="ITransform"/> changes. The second parameter is the old <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
Action<ITransform, ITransform?>? OnParentChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when a new <see cref="ITransform"/> is added to the <see cref="Children"/>.
|
||||||
|
/// </summary>
|
||||||
|
Action<ITransform, ITransform>? OnChildrenAdded { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when an <see cref="ITransform"/> is removed from the <see cref="Children"/>.
|
||||||
|
/// </summary>
|
||||||
|
Action<ITransform, ITransform>? OnChildrenRemoved { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The world position of the <see cref="ITransform"/> in 2D space.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Vector2D Position { get; set; }
|
Vector2D Position { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The scale of the <see cref="ITransform"/>.
|
/// The world scale of the <see cref="ITransform"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Vector2D Scale { get; set; }
|
Vector2D Scale { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The rotation of the <see cref="ITransform"/> in degrees.
|
/// The world rotation of the <see cref="ITransform"/> in degrees.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
float Rotation { get; set; }
|
float Rotation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local position of the <see cref="ITransform"/> in 2D space.
|
||||||
|
/// </summary>
|
||||||
|
Vector2D LocalPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local scale of the <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
Vector2D LocalScale { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The local rotation of the <see cref="ITransform"/> in degrees.
|
||||||
|
/// </summary>
|
||||||
|
float LocalRotation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The parent <see cref="ITransform"/> of the <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
ITransform? Parent { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ITransform"/>s that have this <see cref="ITransform"/> as their <see cref="Parent"/>.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyList<ITransform> Children { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the parent <see cref="ITransform"/> of this <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The parent <see cref="ITransform"/> to set.</param>
|
||||||
|
void SetParent(ITransform? transform);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a child <see cref="ITransform"/> to this <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The child <see cref="ITransform"/> to add.</param>
|
||||||
|
void AddChild(ITransform transform);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a child <see cref="ITransform"/> from this <see cref="ITransform"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="transform">The child <see cref="ITransform"/> to remove.</param>
|
||||||
|
void RemoveChild(ITransform transform);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@ using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
public class BehaviourCollector<T> : IAssignableGameManager, IEnumerable<T>
|
||||||
{
|
{
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
||||||
|
|
||||||
public Action<BehaviourCacher<T>, T>? OnCached { get; set; } = null;
|
public Action<BehaviourCollector<T>, T>? OnCollected { get; set; } = null;
|
||||||
public Action<BehaviourCacher<T>, T>? OnUncached { get; set; } = null;
|
public Action<BehaviourCollector<T>, T>? OnRemoved { get; set; } = null;
|
||||||
|
|
||||||
private readonly List<T> _behaviours = new(32);
|
private readonly List<T> _behaviours = new(32);
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
||||||
|
|
||||||
public T this[Index index] => _behaviours[index];
|
public T this[Index index] => _behaviours[index];
|
||||||
|
|
||||||
public BehaviourCacher() { }
|
public BehaviourCollector() { }
|
||||||
public BehaviourCacher(IGameManager gameManager) => Assign(gameManager);
|
public BehaviourCollector(IGameManager gameManager) => Assign(gameManager);
|
||||||
|
|
||||||
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
|
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_behaviours.Add(tBehaviour);
|
_behaviours.Add(tBehaviour);
|
||||||
OnCached?.Invoke(this, tBehaviour);
|
OnCollected?.Invoke(this, tBehaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
||||||
|
@ -53,7 +53,7 @@ public class BehaviourCacher<T> : IAssignableGameManager, IEnumerable<T>
|
||||||
if (!_behaviours.Remove(tBehaviour))
|
if (!_behaviours.Remove(tBehaviour))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnUncached?.Invoke(this, tBehaviour);
|
OnRemoved?.Invoke(this, tBehaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Assign(IGameManager gameManager)
|
public bool Assign(IGameManager gameManager)
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
public static class BehaviourControllerExtensions
|
||||||
|
{
|
||||||
|
public static bool TryGetBehaviourInParent<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
||||||
|
{
|
||||||
|
behaviour = GetBehaviourInParent<T>(behaviourController);
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T? GetBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class
|
||||||
|
{
|
||||||
|
IBehaviourController? controller = behaviourController;
|
||||||
|
|
||||||
|
while (controller is not null)
|
||||||
|
{
|
||||||
|
if (behaviourController.GetBehaviour<T>() is T behaviour)
|
||||||
|
return behaviour;
|
||||||
|
|
||||||
|
controller = controller.GameObject.Transform.Parent?.GameObject.BehaviourController;
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetBehaviourInChildren<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
||||||
|
{
|
||||||
|
behaviour = GetBehaviourInChildren<T>(behaviourController);
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T? GetBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class
|
||||||
|
{
|
||||||
|
if (behaviourController.GetBehaviour<T>() is T localBehaviour)
|
||||||
|
return localBehaviour;
|
||||||
|
|
||||||
|
foreach (ITransform transform in behaviourController.GameObject.Transform)
|
||||||
|
if (GetBehaviourInChildren<T>(transform.GameObject.BehaviourController) is T behaviour)
|
||||||
|
return behaviour;
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,18 +7,22 @@ namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class BehaviourExtensions
|
public static class BehaviourExtensions
|
||||||
{
|
{
|
||||||
public static bool TryFindBehaviour<T>(this IEnumerable<IGameObject> gameObjects, [NotNullWhen(returnValue: true)] out T? behaviour)
|
public static T? FindBehaviour<T>(this IEnumerable<IGameObject> gameObjects) where T : class
|
||||||
{
|
{
|
||||||
behaviour = default;
|
|
||||||
|
|
||||||
foreach (IGameObject gameObject in gameObjects)
|
foreach (IGameObject gameObject in gameObjects)
|
||||||
if (gameObject.BehaviourController.TryGetBehaviour(out behaviour))
|
if (gameObject.BehaviourController.TryGetBehaviour(out T? behaviour))
|
||||||
return true;
|
return behaviour;
|
||||||
|
|
||||||
return false;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FindBehaviours<T>(this IEnumerable<IGameObject> gameObjects, List<T> behaviours)
|
public static bool TryFindBehaviour<T>(this IEnumerable<IGameObject> gameObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
||||||
|
{
|
||||||
|
behaviour = FindBehaviour<T>(gameObjects);
|
||||||
|
return behaviour is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FindBehaviours<T>(this IEnumerable<IGameObject> gameObjects, List<T> behaviours) where T : class
|
||||||
{
|
{
|
||||||
behaviours.Clear();
|
behaviours.Clear();
|
||||||
List<T> cache = [];
|
List<T> cache = [];
|
||||||
|
|
|
@ -4,11 +4,16 @@ namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
public static class TransformExtensions
|
public static class TransformExtensions
|
||||||
{
|
{
|
||||||
public static ITransform SetTransform(this ITransform transform, Vector2D? position = null, float? rotation = null, Vector2D? scale = null)
|
public static ITransform SetTransform(this ITransform transform,
|
||||||
|
Vector2D? position = null, float? rotation = null, Vector2D? scale = null,
|
||||||
|
Vector2D? localPosition = null, float? localRotation = null, Vector2D? localScale = null)
|
||||||
{
|
{
|
||||||
if (position.HasValue) transform.Position = position.Value;
|
if (position.HasValue) transform.Position = position.Value;
|
||||||
if (rotation.HasValue) transform.Rotation = rotation.Value;
|
if (rotation.HasValue) transform.Rotation = rotation.Value;
|
||||||
if (scale.HasValue) transform.Scale = scale.Value;
|
if (scale.HasValue) transform.Scale = scale.Value;
|
||||||
|
if (localPosition.HasValue) transform.LocalPosition = localPosition.Value;
|
||||||
|
if (localRotation.HasValue) transform.LocalRotation = localRotation.Value;
|
||||||
|
if (localScale.HasValue) transform.LocalScale = localScale.Value;
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ public class GameObjectFactory
|
||||||
behaviourController ??= TypeFactory.Get<BehaviourController>();
|
behaviourController ??= TypeFactory.Get<BehaviourController>();
|
||||||
stateEnable ??= TypeFactory.Get<StateEnable>();
|
stateEnable ??= TypeFactory.Get<StateEnable>();
|
||||||
|
|
||||||
|
if (!transform.Assign(gameObject))
|
||||||
|
throw AssignException.From(transform, gameObject);
|
||||||
|
|
||||||
if (!behaviourController.Assign(gameObject))
|
if (!behaviourController.Assign(gameObject))
|
||||||
throw AssignException.From(behaviourController, gameObject);
|
throw AssignException.From(behaviourController, gameObject);
|
||||||
if (!stateEnable.Assign(gameObject))
|
if (!stateEnable.Assign(gameObject))
|
||||||
|
|
|
@ -1,20 +1,35 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Factory;
|
namespace Syntriax.Engine.Core.Factory;
|
||||||
|
|
||||||
public static class TypeFactory
|
public static class TypeFactory
|
||||||
{
|
{
|
||||||
public static T Get<T>(params object?[]? args) where T : class
|
public static T Get<T>(params object?[]? args) where T : class
|
||||||
|
=> Get<T>(typeof(T), args);
|
||||||
|
|
||||||
|
public static Type Get(string typeName)
|
||||||
|
{
|
||||||
|
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
||||||
|
if (type.FullName?.Equals(typeName, StringComparison.OrdinalIgnoreCase) ?? false)
|
||||||
|
return type;
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Get<T>(string typeName, params object?[]? args) where T : class
|
||||||
|
=> Get<T>(Get(typeName), args);
|
||||||
|
|
||||||
|
public static T Get<T>(Type type, params object?[]? args) where T : class
|
||||||
{
|
{
|
||||||
T? result;
|
T? result;
|
||||||
|
|
||||||
if (args is not null && args.Length != 0)
|
if (args is not null && args.Length != 0)
|
||||||
result = Activator.CreateInstance(typeof(T), args) as T;
|
result = Activator.CreateInstance(type, args) as T;
|
||||||
else
|
else
|
||||||
result = Activator.CreateInstance(typeof(T)) as T;
|
result = Activator.CreateInstance(type) as T;
|
||||||
|
|
||||||
if (result is null)
|
if (result is null)
|
||||||
throw new Exception($"{typeof(T).Name} of type {typeof(T).Name} could not be created.");
|
throw new Exception($"{type.Name} could not be created or casted to {typeof(T).Name}.");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,42 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
namespace Syntriax.Engine.Core;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
[System.Diagnostics.DebuggerDisplay("Name: {GameObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
||||||
public class Transform : ITransform
|
public class Transform : ITransform
|
||||||
{
|
{
|
||||||
|
public Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; } = null;
|
||||||
|
|
||||||
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
|
|
||||||
public Action<ITransform>? OnPositionChanged { get; set; } = null;
|
public Action<ITransform>? OnPositionChanged { get; set; } = null;
|
||||||
public Action<ITransform>? OnScaleChanged { get; set; } = null;
|
public Action<ITransform>? OnScaleChanged { get; set; } = null;
|
||||||
public Action<ITransform>? OnRotationChanged { get; set; } = null;
|
public Action<ITransform>? OnRotationChanged { get; set; } = null;
|
||||||
|
|
||||||
|
public Action<ITransform, ITransform?>? OnParentChanged { get; set; } = null;
|
||||||
|
public Action<ITransform, ITransform>? OnChildrenAdded { get; set; } = null;
|
||||||
|
public Action<ITransform, ITransform>? OnChildrenRemoved { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
private Vector2D _position = Vector2D.Zero;
|
private Vector2D _position = Vector2D.Zero;
|
||||||
private Vector2D _scale = Vector2D.One;
|
private Vector2D _scale = Vector2D.One;
|
||||||
private float _rotation = 0f;
|
private float _rotation = 0f;
|
||||||
|
|
||||||
|
private Vector2D _localPosition = Vector2D.Zero;
|
||||||
|
private Vector2D _localScale = Vector2D.One;
|
||||||
|
private float _localRotation = 0f;
|
||||||
|
|
||||||
|
private readonly List<ITransform> _children = [];
|
||||||
|
|
||||||
|
public IGameObject GameObject { get; private set; } = null!;
|
||||||
|
public ITransform? Parent { get; private set; } = null;
|
||||||
|
|
||||||
|
public IReadOnlyList<ITransform> Children => _children;
|
||||||
|
|
||||||
public Vector2D Position
|
public Vector2D Position
|
||||||
{
|
{
|
||||||
get => _position;
|
get => _position;
|
||||||
|
@ -24,6 +46,7 @@ public class Transform : ITransform
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_position = value;
|
_position = value;
|
||||||
|
UpdateLocalPosition();
|
||||||
OnPositionChanged?.Invoke(this);
|
OnPositionChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +60,7 @@ public class Transform : ITransform
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_scale = value;
|
_scale = value;
|
||||||
|
UpdateLocalScale();
|
||||||
OnScaleChanged?.Invoke(this);
|
OnScaleChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +74,210 @@ public class Transform : ITransform
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_rotation = value;
|
_rotation = value;
|
||||||
|
UpdateLocalPosition();
|
||||||
OnRotationChanged?.Invoke(this);
|
OnRotationChanged?.Invoke(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2D LocalPosition
|
||||||
|
{
|
||||||
|
get => _localPosition;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _localPosition)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_localPosition = value;
|
||||||
|
UpdatePosition();
|
||||||
|
OnPositionChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2D LocalScale
|
||||||
|
{
|
||||||
|
get => _localScale;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _localScale)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_localScale = value;
|
||||||
|
UpdateScale();
|
||||||
|
OnScaleChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float LocalRotation
|
||||||
|
{
|
||||||
|
get => _localRotation;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _localRotation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_localRotation = value;
|
||||||
|
UpdateRotation();
|
||||||
|
OnRotationChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetParent(ITransform? transform)
|
||||||
|
{
|
||||||
|
if (transform == this || Parent == transform)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ITransform? previousParent = Parent;
|
||||||
|
if (previousParent is not null)
|
||||||
|
{
|
||||||
|
previousParent.RemoveChild(this);
|
||||||
|
previousParent.OnPositionChanged -= RecalculatePosition;
|
||||||
|
previousParent.OnScaleChanged -= RecalculateScale;
|
||||||
|
previousParent.OnRotationChanged -= RecalculateRotation;
|
||||||
|
previousParent.OnParentChanged -= NotifyChildrenOnParentChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parent = transform;
|
||||||
|
|
||||||
|
if (transform is not null)
|
||||||
|
{
|
||||||
|
transform.AddChild(this);
|
||||||
|
transform.OnPositionChanged += RecalculatePosition;
|
||||||
|
transform.OnScaleChanged += RecalculateScale;
|
||||||
|
transform.OnRotationChanged += RecalculateRotation;
|
||||||
|
transform.OnParentChanged += NotifyChildrenOnParentChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateLocalPosition();
|
||||||
|
UpdateLocalScale();
|
||||||
|
UpdateLocalRotation();
|
||||||
|
|
||||||
|
OnParentChanged?.Invoke(this, previousParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddChild(ITransform transform)
|
||||||
|
{
|
||||||
|
if (_children.Contains(transform))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_children.Add(transform);
|
||||||
|
transform.SetParent(this);
|
||||||
|
OnChildrenAdded?.Invoke(this, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveChild(ITransform transform)
|
||||||
|
{
|
||||||
|
if (!_children.Remove(transform))
|
||||||
|
return;
|
||||||
|
|
||||||
|
transform.SetParent(null);
|
||||||
|
OnChildrenRemoved?.Invoke(this, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<ITransform> GetEnumerator() => _children.GetEnumerator();
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator();
|
||||||
|
|
||||||
|
private void NotifyChildrenOnParentChange(ITransform transform, ITransform? previousParent)
|
||||||
|
{
|
||||||
|
// TODO No idea how logical this is to propagate this to the children the way I'm doing right now.
|
||||||
|
// I was originally gonna just call `child.OnParentChanged?.Invoke(child, child.Parent);` but seems an unnecessary call too?
|
||||||
|
foreach (var child in Children)
|
||||||
|
child.OnParentChanged?.Invoke(transform, previousParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculatePosition(ITransform _)
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdatePosition();
|
||||||
|
OnPositionChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculateScale(ITransform _)
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateScale();
|
||||||
|
OnScaleChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculateRotation(ITransform _)
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdatePosition();
|
||||||
|
UpdateRotation();
|
||||||
|
OnPositionChanged?.Invoke(this);
|
||||||
|
OnRotationChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLocalPosition()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_localPosition = Position;
|
||||||
|
else
|
||||||
|
_localPosition = Parent.Position.FromTo(Position).Scale(Parent.Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLocalScale()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_localScale = Scale;
|
||||||
|
else
|
||||||
|
_localScale = Scale.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLocalRotation()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_localRotation = Rotation;
|
||||||
|
else
|
||||||
|
_localRotation = Rotation - Parent.Rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePosition()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_position = LocalPosition.Scale(Vector2D.One).Rotate(0f * Math.DegreeToRadian);
|
||||||
|
else
|
||||||
|
_position = Parent.Position + LocalPosition.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y)).Rotate(Parent.Rotation * Math.DegreeToRadian);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateScale()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_scale = LocalScale;
|
||||||
|
else
|
||||||
|
_scale = Vector2D.Scale(Parent.Scale, LocalScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotation()
|
||||||
|
{
|
||||||
|
if (Parent is null)
|
||||||
|
_rotation = LocalRotation;
|
||||||
|
else
|
||||||
|
_rotation = Parent.Rotation + LocalRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Assign(IGameObject gameObject)
|
||||||
|
{
|
||||||
|
if (GameObject is not null && GameObject.Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GameObject = gameObject;
|
||||||
|
OnGameObjectAssigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Unassign()
|
||||||
|
{
|
||||||
|
if (GameObject is not null && GameObject.Initialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GameObject = null!;
|
||||||
|
OnUnassigned?.Invoke(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
||||||
|
|
||||||
protected override void OnInitialize()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
BehaviourController.TryGetBehaviour(out _rigidBody2D);
|
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
||||||
|
|
||||||
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
|
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
|
||||||
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
|
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
|
||||||
|
@ -45,6 +45,12 @@ public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
|
||||||
Transform.OnPositionChanged += SetNeedsRecalculation;
|
Transform.OnPositionChanged += SetNeedsRecalculation;
|
||||||
Transform.OnRotationChanged += SetNeedsRecalculation;
|
Transform.OnRotationChanged += SetNeedsRecalculation;
|
||||||
Transform.OnScaleChanged += SetNeedsRecalculation;
|
Transform.OnScaleChanged += SetNeedsRecalculation;
|
||||||
|
Transform.OnParentChanged += UpdateRigidBody2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRigidBody2D(ITransform _1, ITransform? _2)
|
||||||
|
{
|
||||||
|
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
|
private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Physics2D;
|
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
namespace Engine.Physics2D;
|
namespace Engine.Physics2D;
|
||||||
|
|
||||||
public static partial class Physics2D
|
public static partial class Physics2D
|
||||||
{
|
{
|
||||||
|
public static bool Overlaps(this Shape shape, Vector2D point) => Overlaps(shape, point, out var _);
|
||||||
|
public static bool Overlaps(this Shape shape, Vector2D point, out float depth)
|
||||||
|
{
|
||||||
|
depth = float.MaxValue;
|
||||||
|
var vertices = shape.Vertices;
|
||||||
|
int count = vertices.Count;
|
||||||
|
|
||||||
|
for (int indexProjection = 0; indexProjection < count; indexProjection++)
|
||||||
|
{
|
||||||
|
Vector2D projectionVector = vertices[indexProjection].FromTo(vertices[(indexProjection + 1) % count]).Perpendicular().Normalized;
|
||||||
|
|
||||||
|
Projection shapeProjection = shape.ToProjection(projectionVector);
|
||||||
|
float projectedPoint = point.Dot(projectionVector);
|
||||||
|
|
||||||
|
if (shapeProjection.Max < projectedPoint || shapeProjection.Min > projectedPoint)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
depth = Math.Min(depth, Math.Abs(Math.AbsMin(shapeProjection.Max - projectedPoint, shapeProjection.Min - projectedPoint)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool Overlaps(this Circle left, Circle right)
|
public static bool Overlaps(this Circle left, Circle right)
|
||||||
{
|
{
|
||||||
float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
|
float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
|
||||||
|
@ -27,7 +47,7 @@ public static partial class Physics2D
|
||||||
normal = distanceVector.Normalized;
|
normal = distanceVector.Normalized;
|
||||||
|
|
||||||
if (isOverlapping)
|
if (isOverlapping)
|
||||||
depth = MathF.Sqrt(radiusSumSquared - distanceSquared);
|
depth = Math.Sqrt(radiusSumSquared - distanceSquared);
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +64,7 @@ public static partial class Physics2D
|
||||||
normal = distanceVector.Normalized;
|
normal = distanceVector.Normalized;
|
||||||
|
|
||||||
if (isOverlapping)
|
if (isOverlapping)
|
||||||
depth = MathF.Sqrt(radiusSquared - distanceSquared);
|
depth = Math.Sqrt(radiusSquared - distanceSquared);
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Physics2D;
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
public class PhysicsEngine2DCollector : IPhysicsEngine2D, IAssignableGameManager
|
||||||
{
|
{
|
||||||
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
||||||
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
||||||
|
@ -17,8 +17,8 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
||||||
protected readonly ICollisionDetector2D collisionDetector = null!;
|
protected readonly ICollisionDetector2D collisionDetector = null!;
|
||||||
protected readonly ICollisionResolver2D collisionResolver = null!;
|
protected readonly ICollisionResolver2D collisionResolver = null!;
|
||||||
|
|
||||||
protected BehaviourCacher<IRigidBody2D> rigidBodyCacher = new();
|
protected BehaviourCollector<IRigidBody2D> rigidBodyCollector = new();
|
||||||
protected BehaviourCacher<ICollider2D> colliderCacher = new();
|
protected BehaviourCollector<ICollider2D> colliderCollector = new();
|
||||||
|
|
||||||
|
|
||||||
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
public int IterationPerStep { get => _iterationPerStep; set => _iterationPerStep = value < 1 ? 1 : value; }
|
||||||
|
@ -31,23 +31,23 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
||||||
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
for (int iterationIndex = 0; iterationIndex < IterationPerStep; iterationIndex++)
|
||||||
{
|
{
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var rigidBody in rigidBodyCacher)
|
foreach (var rigidBody in rigidBodyCollector)
|
||||||
StepRigidBody(rigidBody, intervalDeltaTime);
|
StepRigidBody(rigidBody, intervalDeltaTime);
|
||||||
|
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
foreach (var collider in colliderCacher)
|
foreach (var collider in colliderCollector)
|
||||||
collider.Recalculate();
|
collider.Recalculate();
|
||||||
|
|
||||||
// Can Parallel
|
// Can Parallel
|
||||||
for (int x = 0; x < colliderCacher.Behaviours.Count; x++)
|
for (int x = 0; x < colliderCollector.Behaviours.Count; x++)
|
||||||
{
|
{
|
||||||
ICollider2D? colliderX = colliderCacher.Behaviours[x];
|
ICollider2D? colliderX = colliderCollector.Behaviours[x];
|
||||||
if (!colliderX.IsActive)
|
if (!colliderX.IsActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int y = x + 1; y < colliderCacher.Behaviours.Count; y++)
|
for (int y = x + 1; y < colliderCollector.Behaviours.Count; y++)
|
||||||
{
|
{
|
||||||
ICollider2D? colliderY = colliderCacher.Behaviours[y];
|
ICollider2D? colliderY = colliderCollector.Behaviours[y];
|
||||||
|
|
||||||
if (!colliderY.IsActive)
|
if (!colliderY.IsActive)
|
||||||
return;
|
return;
|
||||||
|
@ -100,8 +100,8 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
||||||
if (GameManager is not null)
|
if (GameManager is not null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
colliderCacher.Assign(gameManager);
|
colliderCollector.Assign(gameManager);
|
||||||
rigidBodyCacher.Assign(gameManager);
|
rigidBodyCollector.Assign(gameManager);
|
||||||
|
|
||||||
GameManager = gameManager;
|
GameManager = gameManager;
|
||||||
OnGameManagerAssigned?.Invoke(this);
|
OnGameManagerAssigned?.Invoke(this);
|
||||||
|
@ -114,35 +114,35 @@ public class PhysicsEngine2DCacher : IPhysicsEngine2D, IAssignableGameManager
|
||||||
if (GameManager is null)
|
if (GameManager is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
colliderCacher.Unassign();
|
colliderCollector.Unassign();
|
||||||
rigidBodyCacher.Unassign();
|
rigidBodyCollector.Unassign();
|
||||||
|
|
||||||
GameManager = null!;
|
GameManager = null!;
|
||||||
OnUnassigned?.Invoke(this);
|
OnUnassigned?.Invoke(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher()
|
public PhysicsEngine2DCollector()
|
||||||
{
|
{
|
||||||
collisionDetector = new CollisionDetector2D();
|
collisionDetector = new CollisionDetector2D();
|
||||||
collisionResolver = new CollisionResolver2D();
|
collisionResolver = new CollisionResolver2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher(IGameManager gameManager)
|
public PhysicsEngine2DCollector(IGameManager gameManager)
|
||||||
{
|
{
|
||||||
Assign(gameManager);
|
Assign(gameManager);
|
||||||
collisionDetector = new CollisionDetector2D();
|
collisionDetector = new CollisionDetector2D();
|
||||||
collisionResolver = new CollisionResolver2D();
|
collisionResolver = new CollisionResolver2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher(IGameManager gameManager, ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
public PhysicsEngine2DCollector(IGameManager gameManager, ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
||||||
{
|
{
|
||||||
Assign(gameManager);
|
Assign(gameManager);
|
||||||
this.collisionDetector = collisionDetector;
|
this.collisionDetector = collisionDetector;
|
||||||
this.collisionResolver = collisionResolver;
|
this.collisionResolver = collisionResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsEngine2DCacher(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
public PhysicsEngine2DCollector(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver)
|
||||||
{
|
{
|
||||||
this.collisionDetector = collisionDetector;
|
this.collisionDetector = collisionDetector;
|
||||||
this.collisionResolver = collisionResolver;
|
this.collisionResolver = collisionResolver;
|
|
@ -0,0 +1,8 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public class BehaviourControllerDto : ClassInterchangeableDto
|
||||||
|
{
|
||||||
|
public Dictionary<string, object?> Behaviours { get; set; } = [];
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public class ClassInterchangeableDto : EntityDto
|
||||||
|
{
|
||||||
|
public string ClassType { get; set; } = null!;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public class EntityDto
|
||||||
|
{
|
||||||
|
public Dictionary<string, object?> Fields { get; set; } = [];
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public class GameObjectDto : ClassInterchangeableDto
|
||||||
|
{
|
||||||
|
string Id { get; set; } = null!;
|
||||||
|
string Name { get; set; } = null!;
|
||||||
|
TransformDto Transform { get; set; } = null!;
|
||||||
|
BehaviourControllerDto BehaviourController { get; set; } = null!;
|
||||||
|
StateEnableDto StateEnable { get; set; } = null!;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public class StateEnableDto : ClassInterchangeableDto
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public class TransformDto : ClassInterchangeableDto
|
||||||
|
{
|
||||||
|
string? ParentId { get; set; } = null;
|
||||||
|
Vector2D Position { get; set; } = Vector2D.Zero;
|
||||||
|
Vector2D Scale { get; set; } = Vector2D.Zero;
|
||||||
|
float Rotation { get; set; } = 0f;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>disable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="YamlDotNet" Version="15.1.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Engine.Core\Engine.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,85 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
using Syntriax.Engine.Core.Factory;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
public static class Serialization
|
||||||
|
{
|
||||||
|
private static readonly ISerializer defaultSerializer = new SerializerBuilder().;
|
||||||
|
|
||||||
|
public static string Serialize(object @object)
|
||||||
|
{
|
||||||
|
EntityDto dto = new();
|
||||||
|
BindingFlags bindingFlags = BindingFlags.Public |
|
||||||
|
BindingFlags.NonPublic |
|
||||||
|
BindingFlags.Instance;
|
||||||
|
|
||||||
|
Type type = @object.GetType();
|
||||||
|
FieldInfo[] fieldInfos = type.GetFields(bindingFlags);
|
||||||
|
List<(string Name, object?)> list = fieldInfos.Where(f => f.FieldType.IsValueType || f.FieldType == typeof(string)).Select(f => (f.Name, f.GetValue(@object))).ToList();
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static string SerializeGameObject(IGameObject gameObject) => Serialize(gameObject, defaultSerializer);
|
||||||
|
// public static T DeserializeGameObject<T>(StreamReader reader) where T : class, IGameObject
|
||||||
|
// {
|
||||||
|
// Dictionary<string, object?> gameObjectDTO = Deserialize<Dictionary<string, object?>>(reader, defaultSerializer);
|
||||||
|
// return CreateGameObject<T>(gameObjectDTO);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static T CreateGameObject<T>(Dictionary<string, object?> gameObject) where T : class, IGameObject
|
||||||
|
// {
|
||||||
|
// Type gameObjectType = gameObject.TryGetValue("ClassType", out var goType) ? TypeFactory.Get(goType?.ToString() ?? throw new Exception()) : typeof(GameObject);
|
||||||
|
// Type stateEnableType = gameObject.TryGetValue("StateEnable.ClassType", out var seType) ? TypeFactory.Get(seType?.ToString() ?? throw new Exception()) : typeof(Transform);
|
||||||
|
// Type transformType = gameObject.TryGetValue("Transform.ClassType", out var tType) ? TypeFactory.Get(tType?.ToString() ?? throw new Exception()) : typeof(Transform);
|
||||||
|
// Type behaviourControllerType = gameObject.TryGetValue("BehaviourController.ClassType", out var bcType) ? TypeFactory.Get(bcType?.ToString() ?? throw new Exception()) : typeof(Transform);
|
||||||
|
|
||||||
|
// ITransform transform = TypeFactory.Get<ITransform>(transformType);
|
||||||
|
// IStateEnable stateEnable = TypeFactory.Get<IStateEnable>(stateEnableType);
|
||||||
|
// IBehaviourController behaviourController = TypeFactory.Get<IBehaviourController>(behaviourControllerType);
|
||||||
|
// T t = new GameObjectFactory().Instantiate<T>(transform, behaviourController, stateEnable, gameObjectType);
|
||||||
|
|
||||||
|
// Dictionary<string, object?>? behaviours = gameObject["BehaviourController"] as Dictionary<string, object?> ?? throw new Exception();
|
||||||
|
|
||||||
|
// foreach ((var key, var value) in behaviours)
|
||||||
|
// {
|
||||||
|
// Dictionary<string, object?> values = value as Dictionary<string, object?> ?? throw new Exception();
|
||||||
|
|
||||||
|
// IBehaviour behaviour = TypeFactory.Get<IBehaviour>(values["ClassType"]);
|
||||||
|
// behaviourController.AddBehaviour(behaviour);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return t;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static string SerializeGameManager(IGameManager gameManager) => Serialize(gameManager, defaultSerializer);
|
||||||
|
// public static T DeserializeGameManager<T>(StreamReader reader) where T : class, IGameManager
|
||||||
|
// {
|
||||||
|
// GameManagerDTO gameManagerDto = Deserialize<GameManagerDTO>(reader, defaultSerializer);
|
||||||
|
|
||||||
|
// Type gameManagerType = (gameManagerDto.ClassType is not null) ? TypeFactory.Get(gameManagerDto.ClassType) : typeof(GameManager);
|
||||||
|
// T gameManager = TypeFactory.Get<T>(gameManagerType);
|
||||||
|
|
||||||
|
// foreach (var gameObjectDto in gameManagerDto.GameObjects)
|
||||||
|
// gameManager.RegisterGameObject(CreateGameObject<IGameObject>(gameObjectDto));
|
||||||
|
|
||||||
|
// return gameManager;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static string Serialize<T>(T @object) => Serialize(@object, defaultSerializer);
|
||||||
|
// public static string Serialize<T>(T @object, ISerializer serializer) => serializer.Serialize(@object);
|
||||||
|
|
||||||
|
// public static T Deserialize<T>(string serializedString) => Deserialize<T>(serializedString, defaultSerializer);
|
||||||
|
// public static T Deserialize<T>(string serializedString, ISerializer serializer) => serializer.Deserialize<T>(serializedString);
|
||||||
|
|
||||||
|
// public static T Deserialize<T>(StreamReader reader) => Deserialize<T>(reader, defaultSerializer);
|
||||||
|
// public static T Deserialize<T>(StreamReader reader, ISerializer serializer) => serializer.Deserialize<T>(reader);
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
using YamlDotNet.Core;
|
||||||
|
using YamlDotNet.Core.Events;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
|
||||||
|
namespace Engine.Serialization;
|
||||||
|
|
||||||
|
internal class Vector2DYamlConverter : IYamlTypeConverter
|
||||||
|
{
|
||||||
|
public bool Accepts(Type type) => type == typeof(Vector2D);
|
||||||
|
|
||||||
|
public object? ReadYaml(IParser parser, Type type)
|
||||||
|
{
|
||||||
|
if (parser.Current is not MappingStart)
|
||||||
|
throw new InvalidOperationException("Expected MappingStart");
|
||||||
|
|
||||||
|
parser.MoveNext();
|
||||||
|
float x = 0.0f;
|
||||||
|
float y = 0.0f;
|
||||||
|
|
||||||
|
while (parser.Current != null && parser.Current is not MappingEnd)
|
||||||
|
{
|
||||||
|
var propertyName = ((Scalar)parser.Current).Value;
|
||||||
|
parser.MoveNext();
|
||||||
|
switch (propertyName)
|
||||||
|
{
|
||||||
|
case nameof(Vector2D.X): x = float.Parse(((Scalar)parser.Current).Value); break;
|
||||||
|
case nameof(Vector2D.Y): y = float.Parse(((Scalar)parser.Current).Value); break;
|
||||||
|
}
|
||||||
|
parser.MoveNext();
|
||||||
|
}
|
||||||
|
return new Vector2D(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteYaml(IEmitter emitter, object? value, Type type)
|
||||||
|
{
|
||||||
|
var vector = (Vector2D)(value ?? throw new Exception());
|
||||||
|
emitter.Emit(new MappingStart());
|
||||||
|
emitter.Emit(new Scalar(nameof(Vector2D.X)));
|
||||||
|
emitter.Emit(new Scalar(vector.X.ToString()));
|
||||||
|
emitter.Emit(new Scalar(nameof(Vector2D.Y)));
|
||||||
|
emitter.Emit(new Scalar(vector.Y.ToString()));
|
||||||
|
emitter.Emit(new MappingEnd());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue