mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
ScriptCore: Cleanup and refactoring
A bit of nullable stuff
This commit is contained in:
@@ -196,7 +196,9 @@ static class ScriptGlue
|
|||||||
for (uint i < length)
|
for (uint i < length)
|
||||||
{
|
{
|
||||||
MonoReflectionType* reflectionType = Mono.mono_array_get<MonoReflectionType*>(componentTypes, i);
|
MonoReflectionType* reflectionType = Mono.mono_array_get<MonoReflectionType*>(componentTypes, i);
|
||||||
Entity_AddComponent(entityId, reflectionType);
|
|
||||||
|
if (reflectionType != null)
|
||||||
|
Entity_AddComponent(entityId, reflectionType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,6 +288,8 @@ static class ScriptGlue
|
|||||||
return scriptComponent.Instance.MonoInstance;
|
return scriptComponent.Instance.MonoInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(false, "Failed to set script.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,27 +532,6 @@ static class ScriptGlue
|
|||||||
id = UUID.Create();
|
id = UUID.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RegisterCall("ScriptGlue::Print_Decimal")]
|
|
||||||
static void Print_Decimal(MonoDecimal monoDecimal)
|
|
||||||
{
|
|
||||||
Log.ClientLogger.Info(scope $"{monoDecimal}");
|
|
||||||
}
|
|
||||||
|
|
||||||
[RegisterCall("ScriptGlue::Get_Decimal")]
|
|
||||||
static void Get_Decimal(MonoString* string, out MonoDecimal monoDecimal)
|
|
||||||
{
|
|
||||||
char8* str = Mono.mono_string_to_utf8(string);
|
|
||||||
|
|
||||||
Result<MonoDecimal> decimalo = MonoDecimal.Parse(StringView(str));
|
|
||||||
|
|
||||||
if (!(decimalo case .Ok(out monoDecimal)))
|
|
||||||
{
|
|
||||||
monoDecimal = default;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mono.mono_free(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Application
|
#region Application
|
||||||
|
|
||||||
[RegisterCall("ScriptGlue::Application_IsEditor")]
|
[RegisterCall("ScriptGlue::Application_IsEditor")]
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ namespace GlitchyEngine.Editor;
|
|||||||
[CustomEditor(typeof(Dictionary<,>))]
|
[CustomEditor(typeof(Dictionary<,>))]
|
||||||
public class DictionaryEditor
|
public class DictionaryEditor
|
||||||
{
|
{
|
||||||
private static object? dictionaryForNewValue = null;
|
private static object? _dictionaryForNewValue = null;
|
||||||
private static DictionaryEntry newDictionaryValue = new();
|
private static DictionaryEntry _newDictionaryValue = new();
|
||||||
private static object? keyLastCreated = null;
|
private static object? _keyLastCreated = null;
|
||||||
|
|
||||||
public static object? ShowEditor(object? reference, Type fieldType, string fieldName)
|
public static object? ShowEditor(object? reference, Type fieldType, string fieldName)
|
||||||
{
|
{
|
||||||
@@ -46,9 +46,9 @@ public class DictionaryEditor
|
|||||||
Debug.Assert(dictionary != null);
|
Debug.Assert(dictionary != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionaryForNewValue = dictionary;
|
_dictionaryForNewValue = dictionary;
|
||||||
|
|
||||||
newDictionaryValue = new DictionaryEntry();
|
_newDictionaryValue = new DictionaryEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiExtension.AttachTooltip("Add a new Entry to the dictionary.");
|
ImGuiExtension.AttachTooltip("Add a new Entry to the dictionary.");
|
||||||
@@ -67,11 +67,11 @@ public class DictionaryEditor
|
|||||||
id++;
|
id++;
|
||||||
ImGui.PushID(id);
|
ImGui.PushID(id);
|
||||||
|
|
||||||
if (entry.Key == keyLastCreated)
|
if (entry.Key == _keyLastCreated)
|
||||||
{
|
{
|
||||||
// The current key is the one that was last created. Open the tree node.
|
// The current key is the one that was last created. Open the tree node.
|
||||||
ImGui.SetNextItemOpen(true);
|
ImGui.SetNextItemOpen(true);
|
||||||
keyLastCreated = null;
|
_keyLastCreated = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEntryOpen = ImGui.TreeNode("");
|
bool isEntryOpen = ImGui.TreeNode("");
|
||||||
@@ -110,7 +110,7 @@ public class DictionaryEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ReferenceEquals(dictionaryForNewValue, dictionary))
|
if (ReferenceEquals(_dictionaryForNewValue, dictionary))
|
||||||
{
|
{
|
||||||
ImGui.PushID("NewEntry");
|
ImGui.PushID("NewEntry");
|
||||||
|
|
||||||
@@ -121,29 +121,29 @@ public class DictionaryEditor
|
|||||||
|
|
||||||
if (ImGui.SmallButton("-"))
|
if (ImGui.SmallButton("-"))
|
||||||
{
|
{
|
||||||
dictionaryForNewValue = null;
|
_dictionaryForNewValue = null;
|
||||||
newDictionaryValue = new();
|
_newDictionaryValue = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiExtension.AttachTooltip("Remove the Entry from the dictionary");
|
ImGuiExtension.AttachTooltip("Remove the Entry from the dictionary");
|
||||||
|
|
||||||
if (isEntryOpen)
|
if (isEntryOpen)
|
||||||
{
|
{
|
||||||
object newKey = EntityEditor.ShowFieldEditor(newDictionaryValue.Key, keyType, "Key");
|
object newKey = EntityEditor.ShowFieldEditor(_newDictionaryValue.Key, keyType, "Key");
|
||||||
|
|
||||||
if (newKey != EntityEditor.DidNotChange)
|
if (newKey != EntityEditor.DidNotChange)
|
||||||
{
|
{
|
||||||
newEntries.Add(new DictionaryEntry(newKey, newDictionaryValue.Value));
|
newEntries.Add(new DictionaryEntry(newKey, _newDictionaryValue.Value));
|
||||||
dictionaryForNewValue = null;
|
_dictionaryForNewValue = null;
|
||||||
newDictionaryValue = new();
|
_newDictionaryValue = new();
|
||||||
keyLastCreated = newKey;
|
_keyLastCreated = newKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
object newValue = EntityEditor.ShowFieldEditor(newDictionaryValue.Value, newDictionaryValue.Value?.GetType() ?? valueType, "Value");
|
object newValue = EntityEditor.ShowFieldEditor(_newDictionaryValue.Value, _newDictionaryValue.Value?.GetType() ?? valueType, "Value");
|
||||||
|
|
||||||
if (newValue != EntityEditor.DidNotChange)
|
if (newValue != EntityEditor.DidNotChange)
|
||||||
{
|
{
|
||||||
newDictionaryValue.Value = newValue;
|
_newDictionaryValue.Value = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
|
|||||||
+114
-99
@@ -4,6 +4,7 @@ using System.Reflection;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEngine.Extensions;
|
using GlitchyEngine.Extensions;
|
||||||
|
using GlitchyEngine.Physics;
|
||||||
|
|
||||||
namespace GlitchyEngine;
|
namespace GlitchyEngine;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ namespace GlitchyEngine;
|
|||||||
public class Entity : EngineObject
|
public class Entity : EngineObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the entity.
|
/// Gets or sets the name of the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
@@ -22,8 +23,8 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Only to be called by the engine. Don't call this constructor yourself, it will not result in a valid entity.
|
/// Only to be called by the engine. Don't call this constructor yourself, it will not result in a valid <see cref="Entity"/>.
|
||||||
/// If you want to create a new entity use <see cref="Entity(string)"/> or <see cref="Entity(string, Type[])"/>
|
/// If you want to create a new <see cref="Entity"/> use <see cref="Entity(string)"/> or <see cref="Entity(string, Type[])"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Entity()
|
protected Entity()
|
||||||
{
|
{
|
||||||
@@ -35,34 +36,23 @@ public class Entity : EngineObject
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new Entity.
|
/// Creates a new Entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the new entity.</param>
|
/// <param name="name">The name of the new <see cref="Entity"/>.</param>
|
||||||
public Entity(string name = null)
|
public Entity(string? name = null)
|
||||||
{
|
{
|
||||||
Create(name, null);
|
Create(name, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new Entity with the specified components attached to it.
|
/// Creates a new <see cref="Entity"/> with the specified components attached to it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the new entity.</param>
|
/// <param name="name">The name of the new <see cref="Entity"/>.</param>
|
||||||
/// <param name="components">The components that the entity shall have.</param>
|
/// <param name="components">The components that the <see cref="Entity"/> will be created with.</param>
|
||||||
public Entity(string name, params Type[] components)
|
public Entity(string? name, params Type[] components)
|
||||||
{
|
{
|
||||||
Create(name, components);
|
Create(name, components);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void PrintDecimal(decimal value)
|
private void Create(string? name, Type[]? components)
|
||||||
{
|
|
||||||
ScriptGlue.Print_Decimal(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected decimal GetDecimal(string value)
|
|
||||||
{
|
|
||||||
ScriptGlue.Get_Decimal(value, out var dec);
|
|
||||||
return dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Create(string name, Type[] components)
|
|
||||||
{
|
{
|
||||||
ScriptGlue.Entity_Create(this, name, components, out _uuid);
|
ScriptGlue.Entity_Create(this, name, components, out _uuid);
|
||||||
|
|
||||||
@@ -73,20 +63,22 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance that represents the Entity with the given id.
|
/// Creates an instance that represents the <see cref="Entity"/> with the given id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid">The ID of the entity that belongs to this instance.</param>
|
/// <param name="uuid">The ID of the <see cref="Entity"/> that belongs to this instance.</param>
|
||||||
internal Entity(UUID uuid) : base(uuid) { }
|
internal Entity(UUID uuid) : base(uuid) { }
|
||||||
|
|
||||||
|
#region Components
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns <see langword="true"/> if a component of the given type is attached to this entity.
|
/// Returns <see langword="true"/> if a component of the given type is attached to this <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the component.</typeparam>
|
/// <typeparam name="T">The type of the component.</typeparam>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool HasComponent<T>() => HasComponent(typeof(T));
|
public bool HasComponent<T>() => HasComponent(typeof(T));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns <see langword="true"/> if a component of the given type is attached to this entity.
|
/// Returns <see langword="true"/> if a component of the given type is attached to this <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of the component.</param>
|
/// <param name="type">The type of the component.</param>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -96,8 +88,8 @@ public class Entity : EngineObject
|
|||||||
/// Gets the component with the specified type.
|
/// Gets the component with the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the component to get.</typeparam>
|
/// <typeparam name="T">The type of the component to get.</typeparam>
|
||||||
/// <returns>The component or null, if the entity doesn't have a component of the specified type.</returns>
|
/// <returns>The component or null, if the <see cref="Entity"/> doesn't have a component of the specified type.</returns>
|
||||||
public T GetComponent<T>() where T : Component, new()
|
public T? GetComponent<T>() where T : Component, new()
|
||||||
{
|
{
|
||||||
if (HasComponent<T>())
|
if (HasComponent<T>())
|
||||||
{
|
{
|
||||||
@@ -114,32 +106,28 @@ public class Entity : EngineObject
|
|||||||
/// Gets the component with the given type.
|
/// Gets the component with the given type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="componentType">The type of the component to get.</param>
|
/// <param name="componentType">The type of the component to get.</param>
|
||||||
/// <returns>The component or null, if the entity doesn't have a component of the given type.</returns>
|
/// <returns>The component; or <see langword="null"/>, if the <see cref="Entity"/> doesn't have a component of the specified type or if <see cref="componentType"/> doesn't inherit from <see cref="Component"/>.</returns>
|
||||||
/// <remarks>For performance reasons it is recommended to use <see cref="GetComponent{T}"/> if possible.</remarks>
|
/// <remarks>For performance reasons it is recommended to use <see cref="GetComponent{T}"/> if possible as it might be slightly faster.</remarks>
|
||||||
public Component GetComponent(Type componentType)
|
public Component? GetComponent(Type componentType)
|
||||||
{
|
{
|
||||||
// TODO: probably throw!
|
if (!componentType.IsSubclassOf(typeof(Component)))
|
||||||
if (!componentType.IsSubclassOf(typeof(Component))) return null;
|
{
|
||||||
|
Log.Error($"{nameof(GetComponent)}: Invalid component type \"{componentType}\". Must be a subclass of \"{nameof(Component)}\".");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (HasComponent(componentType))
|
if (HasComponent(componentType))
|
||||||
{
|
{
|
||||||
Component component = Activator.CreateInstance(componentType, true) as Component;
|
return ActivatorExtension.CreateComponent(componentType, _uuid);
|
||||||
|
|
||||||
if (component != null)
|
|
||||||
component._uuid = _uuid;
|
|
||||||
|
|
||||||
return component;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Add Components
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the component with the specified type.
|
/// Attaches a component of the specified type to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the component to add.</typeparam>
|
/// <typeparam name="T">The type of the component to attach.</typeparam>
|
||||||
/// <returns>The component.</returns>
|
/// <returns>The component.</returns>
|
||||||
public T AddComponent<T>() where T : Component, new()
|
public T AddComponent<T>() where T : Component, new()
|
||||||
{
|
{
|
||||||
@@ -152,60 +140,63 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the component with the given type.
|
/// Attaches a component of the specified type to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="componentType">The type of the component to add.</param>
|
/// <param name="componentType">The type of the component to attach.</param>
|
||||||
/// <returns>The component or null, if the given type is not a valid component type.</returns>
|
/// <returns>The component that was attached to the <see cref="Entity"/>; or <see langword="null"/> if <see cref="componentType"/> doesn't inherit from <see cref="Component"/>.</returns>
|
||||||
/// <remarks>For performance reasons it is recommended to use <see cref="AddComponent{T}"/> if possible.</remarks>
|
/// <remarks>For performance reasons it is recommended to use <see cref="AddComponent{T}"/> if possible as it might be slightly faster.</remarks>
|
||||||
public Component AddComponent(Type componentType)
|
public Component? AddComponent(Type componentType)
|
||||||
{
|
{
|
||||||
if (!componentType.IsSubclassOf(typeof(Component)))
|
if (!componentType.IsSubclassOf(typeof(Component)))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Invalid component type \"{componentType}\". Must be a subclass of \"Component\".", nameof(componentType));
|
Log.Error($"{nameof(AddComponent)}: Invalid component type \"{componentType}\". Must be a subclass of \"{nameof(Component)}\".");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptGlue.Entity_AddComponent(_uuid, componentType);
|
ScriptGlue.Entity_AddComponent(_uuid, componentType);
|
||||||
|
|
||||||
Component component = Activator.CreateInstance(componentType) as Component;
|
return ActivatorExtension.CreateComponent(componentType, _uuid);
|
||||||
if (component != null)
|
|
||||||
{
|
|
||||||
component._uuid = _uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return component;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds components with the specified types to the entity.
|
/// Attaches components with the specified types to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="componentTypes">The types of the components to add.</param>
|
/// <param name="componentTypes">The types of the components to attach.</param>
|
||||||
/// <returns>An array containing the components.</returns>
|
/// <returns>An array containing the components that were attached. A component is <see langword="null"/>, if it's type doesn't inherit from <see cref="Component"/>.</returns>
|
||||||
public Component[] AddComponents(params Type[] componentTypes)
|
public Component?[] AddComponents(params Type[] componentTypes)
|
||||||
{
|
{
|
||||||
|
// Note: The elements in componentTypes are non-nullable externally, but internally we rely on nullability.
|
||||||
|
|
||||||
foreach ((Type componentType, int index) in componentTypes.WithIndex())
|
foreach ((Type componentType, int index) in componentTypes.WithIndex())
|
||||||
{
|
{
|
||||||
if (!componentType.IsSubclassOf(typeof(Component)))
|
if (!componentType.IsSubclassOf(typeof(Component)))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Invalid component type \"{componentType}\" at index {index}. Must be a subclass of \"Component\".", nameof(componentTypes));
|
Log.Error($"{nameof(AddComponents)}: Invalid component type \"{componentType}\" at index {index}. Must be a subclass of \"{nameof(Component)}\".");
|
||||||
|
|
||||||
|
// Setting null here is fine, the engine can handle it!
|
||||||
|
componentTypes[index] = null!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptGlue.Entity_AddComponents(_uuid, componentTypes);
|
ScriptGlue.Entity_AddComponents(_uuid, componentTypes);
|
||||||
|
|
||||||
Component[] components = new Component[componentTypes.Length];
|
Component?[] components = new Component[componentTypes.Length];
|
||||||
|
|
||||||
foreach ((Type componentType, int index) in componentTypes.WithIndex())
|
foreach ((Type componentType, int index) in componentTypes.WithIndex())
|
||||||
{
|
{
|
||||||
components[index] = Activator.CreateInstance(componentType) as Component;
|
// componentType is null, if it's type is invalid!
|
||||||
components[index]._uuid = _uuid;
|
if (componentType == null!)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
components[index] = ActivatorExtension.CreateComponent(componentType, _uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the specified components to the entity.
|
/// Attaches the specified components to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A tuple containing the added components.</returns>
|
/// <returns>A tuple containing the added components.</returns>
|
||||||
public (T1, T2) AddComponents<T1, T2>()
|
public (T1, T2) AddComponents<T1, T2>()
|
||||||
@@ -218,7 +209,7 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the specified components to the entity.
|
/// Attaches the specified components to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A tuple containing the added components.</returns>
|
/// <returns>A tuple containing the added components.</returns>
|
||||||
public (T1, T2, T3) AddComponents<T1, T2, T3>()
|
public (T1, T2, T3) AddComponents<T1, T2, T3>()
|
||||||
@@ -231,10 +222,8 @@ public class Entity : EngineObject
|
|||||||
return (new T1 { _uuid = _uuid }, new T2 { _uuid = _uuid }, new T3 { _uuid = _uuid });
|
return (new T1 { _uuid = _uuid }, new T2 { _uuid = _uuid }, new T3 { _uuid = _uuid });
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Add Components
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the component with the specified component type.
|
/// Removes the component with the specified component type from the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the component to remove.</typeparam>
|
/// <typeparam name="T">The type of the component to remove.</typeparam>
|
||||||
public void RemoveComponent<T>() where T : Component, new()
|
public void RemoveComponent<T>() where T : Component, new()
|
||||||
@@ -243,32 +232,35 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the component with the given component type.
|
/// Removes the component with the given component type from the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="componentType">The type of the component to remove.</param>
|
/// <param name="componentType">The type of the component to remove.</param>
|
||||||
/// <remarks>For performance reasons it is recommended to use <see cref="RemoveComponent{T}"/> if possible.</remarks>
|
|
||||||
public void RemoveComponent(Type componentType)
|
public void RemoveComponent(Type componentType)
|
||||||
{
|
{
|
||||||
if (!componentType.IsSubclassOf(typeof(Component)))
|
if (!componentType.IsSubclassOf(typeof(Component)))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Invalid component type \"{componentType}\". Must be a subclass of \"Component\".", nameof(componentType));
|
Log.Error($"{nameof(RemoveComponent)}: Invalid component type \"{componentType}\". Must be a subclass of \"{nameof(Component)}\".");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptGlue.Entity_RemoveComponent(_uuid, componentType);
|
ScriptGlue.Entity_RemoveComponent(_uuid, componentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Components
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the script of the entity to the specified type.
|
/// Sets the script of the <see cref="Entity"/> to the specified type.
|
||||||
/// If necessary removes the existing script.
|
/// If necessary removes the existing script.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the script.</typeparam>
|
/// <typeparam name="T">The type of the script.</typeparam>
|
||||||
public T SetScript<T>() where T : Entity
|
/// <returns>A reference to the new script or <see langword="null"/>, if the operation failed.</returns>
|
||||||
|
public T? SetScript<T>() where T : Entity
|
||||||
{
|
{
|
||||||
return ScriptGlue.Entity_SetScript(_uuid, typeof(T)) as T;
|
return ScriptGlue.Entity_SetScript(_uuid, typeof(T)) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the script from the entity.
|
/// Removes the script from the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RemoveScript()
|
public void RemoveScript()
|
||||||
{
|
{
|
||||||
@@ -278,14 +270,14 @@ public class Entity : EngineObject
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="Core.Transform"/> <see cref="Component"/> of this <see cref="Entity"/>.
|
/// Gets the <see cref="Core.Transform"/> <see cref="Component"/> of this <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Transform Transform => GetComponent<Transform>();
|
public Transform Transform => GetComponent<Transform>()!; // Transform always exists!
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the first entity with the given name.
|
/// Returns the first <see cref="Entity"/> with the given name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the entity.</param>
|
/// <param name="name">The name of the <see cref="Entity"/>.</param>
|
||||||
/// <returns>The first entity with the given name, or null.</returns>
|
/// <returns>The first <see cref="Entity"/> with the given name, or <see langword="null"/> if no such entity exists.</returns>
|
||||||
public static Entity FindEntityWithName(string name)
|
public static Entity? FindEntityWithName(string name)
|
||||||
{
|
{
|
||||||
ScriptGlue.Entity_FindEntityWithName(name, out UUID entityId);
|
ScriptGlue.Entity_FindEntityWithName(name, out UUID entityId);
|
||||||
|
|
||||||
@@ -296,59 +288,82 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the entity has a script component of the given type; false if the entity either has no script or the script is not of the specified type.
|
/// Returns whether or not the <see cref="Entity"/> has a script of the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the script.</typeparam>
|
/// <typeparam name="T">The type of the script.</typeparam>
|
||||||
|
/// <returns><see langword="true"/> if the <see cref="Entity"/> has a script component of the given type; or <see langword="false"/> if the <see cref="Entity"/> either has no script or the script is not of the specified type.</returns>
|
||||||
public bool Is<T>() where T : Entity
|
public bool Is<T>() where T : Entity
|
||||||
{
|
{
|
||||||
ScriptGlue.Entity_GetScriptInstance(_uuid, out object scriptInstance);
|
ScriptGlue.Entity_GetScriptInstance(_uuid, out object? scriptInstance);
|
||||||
|
|
||||||
return scriptInstance is T;
|
return scriptInstance is T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the script of the given type, or null, if the entity has no script of the given type.
|
/// Returns whether or not the <see cref="Entity"/> has a script of the specified type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type of the script.</param>
|
||||||
|
/// <returns><see langword="true"/> if the <see cref="Entity"/> has a script component of the given type; or <see langword="false"/> if the <see cref="Entity"/> either has no script or the script is not of the specified type.</returns>
|
||||||
|
public bool Is(Type type)
|
||||||
|
{
|
||||||
|
if (!type.IsSubclassOf(typeof(Entity)))
|
||||||
|
{
|
||||||
|
Log.Warning($"{nameof(Is)}: Invalid script type \"{type}\". Must be a subclass of \"{nameof(Entity)}\".");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptGlue.Entity_GetScriptInstance(_uuid, out object? scriptInstance);
|
||||||
|
|
||||||
|
return type.IsInstanceOfType(scriptInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the script instance of the given type that is attached to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the script.</typeparam>
|
/// <typeparam name="T">The type of the script.</typeparam>
|
||||||
/// <returns>The script instance or null.</returns>
|
/// <returns>The script instance of the given type; or <see langword="null"/> if the <see cref="Entity"/> has no script of the given type.</returns>
|
||||||
public T As<T>() where T : Entity
|
public T? As<T>() where T : Entity
|
||||||
{
|
{
|
||||||
ScriptGlue.Entity_GetScriptInstance(_uuid, out object scriptInstance);
|
ScriptGlue.Entity_GetScriptInstance(_uuid, out object? scriptInstance);
|
||||||
|
|
||||||
return scriptInstance as T;
|
return scriptInstance as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the script of the given type, or null, if the entity has no script of the given type.
|
/// Returns the script instance of the given type that is attached to the <see cref="Entity"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of the script.</param>
|
/// <param name="type">The type of the script.</param>
|
||||||
/// <returns>The script instance or null.</returns>
|
/// <returns>The script instance of the given type; or <see langword="null"/> if the <see cref="Entity"/> has no script of the given type.</returns>
|
||||||
public object As(Type type)
|
public object? As(Type type)
|
||||||
{
|
{
|
||||||
Debug.Assert(type.IsSubclassOf(typeof(Entity)));
|
if (!type.IsSubclassOf(typeof(Entity)))
|
||||||
|
{
|
||||||
|
Log.Error($"{nameof(As)}: Invalid script type \"{type}\". Must be a subclass of \"{nameof(Entity)}\".");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
ScriptGlue.Entity_GetScriptInstance(_uuid, out object scriptInstance);
|
ScriptGlue.Entity_GetScriptInstance(_uuid, out object? scriptInstance);
|
||||||
|
|
||||||
return scriptInstance;
|
return scriptInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the script of the given type, or null, if the entity has no script of the given type.
|
/// Returns the script instance of the given type that is attached to the <see cref="Entity"/> with the given <see cref="id"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The id of the entity whose script instance shall be returned.</param>
|
/// <param name="id">The id of the <see cref="Entity"/> whose script instance shall be returned.</param>
|
||||||
/// <param name="type">The type of the script.</param>
|
/// <param name="type">The type of the script.</param>
|
||||||
/// <returns>The script instance or null.</returns>
|
/// <returns>The script instance of the given type; or <see langword="null"/> if the <see cref="Entity"/> with the given <see cref="id"/> has no script of the given type.</returns>
|
||||||
internal static Entity GetScriptReference(UUID id, Type type)
|
internal static Entity? GetScriptReference(UUID id, Type type)
|
||||||
{
|
{
|
||||||
Debug.Assert(typeof(Entity).IsAssignableFrom(type));
|
Debug.Assert(typeof(Entity).IsAssignableFrom(type));
|
||||||
|
|
||||||
ScriptGlue.Entity_GetScriptInstance(id, out object scriptInstance);
|
ScriptGlue.Entity_GetScriptInstance(id, out object? scriptInstance);
|
||||||
|
|
||||||
return scriptInstance as Entity;
|
return scriptInstance as Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Destroys the entity and all it's children.
|
/// Destroys the <see cref="Entity"/> and all it's children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The destruction will not take place immediately. It will happen at the end of the current frame.
|
/// The destruction will not take place immediately. It will happen at the end of the current frame.
|
||||||
@@ -359,10 +374,10 @@ public class Entity : EngineObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates a copy of the given entity and it's children.
|
/// Instantiates a copy of the given <see cref="Entity"/> and all of it's children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The entity to copy.</param>
|
/// <param name="entity">The <see cref="Entity"/> to copy.</param>
|
||||||
/// <returns>The new entity.</returns>
|
/// <returns>The new <see cref="Entity"/>.</returns>
|
||||||
public static Entity CreateInstance(Entity entity)
|
public static Entity CreateInstance(Entity entity)
|
||||||
{
|
{
|
||||||
ScriptGlue.Entity_CreateInstance(entity.UUID, out UUID newEntityId);
|
ScriptGlue.Entity_CreateInstance(entity.UUID, out UUID newEntityId);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using GlitchyEngine.Core;
|
||||||
|
|
||||||
namespace GlitchyEngine.Extensions;
|
namespace GlitchyEngine.Extensions;
|
||||||
|
|
||||||
@@ -49,4 +50,20 @@ public static class ActivatorExtension
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an instance of the given component type and sets it's entities id.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="componentType">The type of the component.</param>
|
||||||
|
/// <param name="entityId">The entities id.</param>
|
||||||
|
/// <returns>An instance of the component type; or <see langword="null"/> if the creation failed.</returns>
|
||||||
|
internal static Component? CreateComponent(Type componentType, UUID entityId)
|
||||||
|
{
|
||||||
|
Component? component = (Component?)CreateInstanceSafe(componentType);
|
||||||
|
|
||||||
|
if (component != null)
|
||||||
|
component._uuid = entityId;
|
||||||
|
|
||||||
|
return component;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ internal static class ScriptGlue
|
|||||||
#region Entity
|
#region Entity
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void Entity_Create(object scriptInstance, string entityName, Type[] componentTypes, out UUID entityId);
|
internal static extern void Entity_Create(object scriptInstance, string? entityName, Type[]? componentTypes, out UUID entityId);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void Entity_Destroy(UUID entityId);
|
internal static extern void Entity_Destroy(UUID entityId);
|
||||||
@@ -38,7 +38,7 @@ internal static class ScriptGlue
|
|||||||
internal static extern void Entity_FindEntityWithName(string name, out UUID uuid);
|
internal static extern void Entity_FindEntityWithName(string name, out UUID uuid);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void Entity_GetScriptInstance(UUID entityId, out object instance);
|
internal static extern void Entity_GetScriptInstance(UUID entityId, out object? instance);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern object Entity_SetScript(UUID entityId, Type scriptType);
|
internal static extern object Entity_SetScript(UUID entityId, Type scriptType);
|
||||||
@@ -122,12 +122,6 @@ internal static class ScriptGlue
|
|||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern float4 modf_float4(float4 x, out float4 integerPart);
|
internal static extern float4 modf_float4(float4 x, out float4 integerPart);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void Print_Decimal(decimal value);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void Get_Decimal(string str, out decimal value);
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
@@ -152,7 +146,7 @@ internal static class ScriptGlue
|
|||||||
#region Serialization
|
#region Serialization
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void Serialization_SerializeField(IntPtr serializationContext, SerializationType type, string name, object value, string fullTypeName = null);
|
internal static extern void Serialization_SerializeField(IntPtr serializationContext, SerializationType type, string name, object? value, string? fullTypeName = null);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void Serialization_CreateObject(IntPtr currentContext, string fullTypeName, out IntPtr context, out UUID id);
|
internal static extern void Serialization_CreateObject(IntPtr currentContext, string fullTypeName, out IntPtr context, out UUID id);
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ public class DeserializationObject
|
|||||||
|
|
||||||
private Stack<string> _structScope = new();
|
private Stack<string> _structScope = new();
|
||||||
|
|
||||||
private string _structScopeName;
|
private string _structScopeName = "";
|
||||||
|
|
||||||
public Dictionary<UUID, DeserializationObject> DeserializedClasses;
|
public Dictionary<UUID, DeserializationObject> DeserializedClasses;
|
||||||
|
|
||||||
private object _instance;
|
private object? _instance;
|
||||||
|
|
||||||
private Dictionary<string, Type?> _fullNameToType = new();
|
private Dictionary<string, Type?> _fullNameToType = new();
|
||||||
|
|
||||||
@@ -317,72 +317,49 @@ public class DeserializationObject
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object DeserializeField(object fieldValue, Type fieldType, string fieldName)
|
public object? DeserializeField(object? fieldValue, Type fieldType, string fieldName)
|
||||||
{
|
{
|
||||||
|
if (TryCustomDeserializer(fieldName, fieldType, out object? deserializedValue))
|
||||||
|
{
|
||||||
|
return deserializedValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (fieldType.IsPrimitive)
|
if (fieldType.IsPrimitive)
|
||||||
{
|
{
|
||||||
return DeserializePrimitive(fieldName, fieldType);
|
return DeserializePrimitive(fieldName, fieldType);
|
||||||
}
|
}
|
||||||
else if (fieldType == typeof(string))
|
if (fieldType == typeof(string))
|
||||||
{
|
{
|
||||||
return GetFieldValue(fieldName, SerializationType.String);
|
return GetFieldValue(fieldName, SerializationType.String);
|
||||||
}
|
}
|
||||||
else if (fieldType.IsEnum)
|
if (fieldType.IsEnum)
|
||||||
{
|
{
|
||||||
return DeserializeEnum(fieldName, fieldType);
|
return DeserializeEnum(fieldName, fieldType);
|
||||||
}
|
}
|
||||||
else if (fieldType.IsArray)
|
if (fieldType.IsArray)
|
||||||
{
|
{
|
||||||
return DeserializeList(fieldName, fieldType, fieldType.GetElementType());
|
Type? elementType = fieldType.GetElementType();
|
||||||
}
|
|
||||||
else if (fieldType.IsGenericType)
|
|
||||||
{
|
|
||||||
if (TryCustomDeserializer(fieldName, fieldType, out object deserializedValue))
|
|
||||||
{
|
|
||||||
return deserializedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldType.GetGenericTypeDefinition() == typeof(List<>))
|
if (elementType == null)
|
||||||
{
|
return NoValueDeserialized;
|
||||||
return DeserializeList(fieldName, fieldType, fieldType.GetGenericArguments()[0]);
|
|
||||||
}
|
|
||||||
//else if (fieldType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
|
|
||||||
//{
|
|
||||||
// ImGui.Text($"{fieldName} Dictionary");
|
|
||||||
//}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: what to do?
|
|
||||||
Log.Error($"Generic class serialization not yet implemented");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fieldType.IsValueType)
|
|
||||||
{
|
|
||||||
if (TryCustomDeserializer(fieldName, fieldType, out object deserializedValue))
|
|
||||||
{
|
|
||||||
return deserializedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return DeserializeList(fieldName, fieldType, elementType);
|
||||||
|
}
|
||||||
|
if (fieldType.IsValueType)
|
||||||
|
{
|
||||||
return DeserializeStruct(fieldName, fieldValue);
|
return DeserializeStruct(fieldName, fieldValue);
|
||||||
}
|
}
|
||||||
else if (fieldType.IsClass)
|
if (fieldType.IsClass)
|
||||||
{
|
{
|
||||||
if (TryCustomDeserializer(fieldName, fieldType, out object deserializedValue))
|
|
||||||
{
|
|
||||||
return deserializedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DeserializeClass(fieldName, fieldType);
|
return DeserializeClass(fieldName, fieldType);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
Log.Error($"Encountered unhandled type \"{fieldType}\" while serializing.");
|
||||||
Log.Error($"Encountered unhandled type \"{fieldType}\" while serializing.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NoValueDeserialized;
|
return NoValueDeserialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object DeserializePrimitive(string fieldName, Type fieldType)
|
public object? DeserializePrimitive(string fieldName, Type fieldType)
|
||||||
{
|
{
|
||||||
Debug.Assert(fieldType.IsPrimitive, $"{fieldType} is not a primitive type.");
|
Debug.Assert(fieldType.IsPrimitive, $"{fieldType} is not a primitive type.");
|
||||||
|
|
||||||
@@ -422,9 +399,9 @@ public class DeserializationObject
|
|||||||
return GetFieldValue(fieldName, expectedType);
|
return GetFieldValue(fieldName, expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object DeserializeList(string fieldName, Type fieldType, Type elementType)
|
public object? DeserializeList(string fieldName, Type fieldType, Type elementType)
|
||||||
{
|
{
|
||||||
UUID id = (UUID)GetFieldValue(fieldName, SerializationType.ObjectReference);
|
UUID id = (UUID)GetFieldValue(fieldName, SerializationType.ObjectReference)!;
|
||||||
|
|
||||||
if (id == UUID.Zero)
|
if (id == UUID.Zero)
|
||||||
return null;
|
return null;
|
||||||
@@ -442,8 +419,8 @@ public class DeserializationObject
|
|||||||
|
|
||||||
int count = deserializedObject.GetFieldValue<int>("Count", SerializationType.Int32);
|
int count = deserializedObject.GetFieldValue<int>("Count", SerializationType.Int32);
|
||||||
|
|
||||||
Array array = null;
|
Array? array = null;
|
||||||
IList list = null;
|
IList? list = null;
|
||||||
|
|
||||||
if (type.IsArray)
|
if (type.IsArray)
|
||||||
{
|
{
|
||||||
@@ -457,11 +434,11 @@ public class DeserializationObject
|
|||||||
|
|
||||||
if (type.GetGenericTypeDefinition() == typeof(List<>))
|
if (type.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
{
|
{
|
||||||
list = (IList)ActivatorExtension.CreateInstanceSafe(type, count);
|
list = (IList?)ActivatorExtension.CreateInstanceSafe(type, count);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
list = (IList)ActivatorExtension.CreateInstanceSafe(type);
|
list = (IList?)ActivatorExtension.CreateInstanceSafe(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list == null)
|
if (list == null)
|
||||||
@@ -479,17 +456,19 @@ public class DeserializationObject
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
object elementValue = ActivatorExtension.CreateInstanceSafe(elementType);
|
object? elementValue = ActivatorExtension.CreateInstanceSafe(elementType);
|
||||||
|
|
||||||
object newValue = deserializedObject.DeserializeField(elementValue, elementType, $"{i}");
|
object? newValue = deserializedObject.DeserializeField(elementValue, elementType, $"{i}");
|
||||||
|
|
||||||
if (newValue == NoValueDeserialized)
|
if (newValue == NoValueDeserialized)
|
||||||
newValue = elementValue;
|
newValue = elementValue;
|
||||||
|
|
||||||
if (array != null)
|
if (array != null)
|
||||||
array.SetValue(newValue, i);
|
array.SetValue(newValue, i);
|
||||||
else
|
else if (list != null)
|
||||||
list.Add(newValue);
|
list.Add(newValue);
|
||||||
|
else
|
||||||
|
Log.Error($"Deserialized element for field {fieldName}, but has no array or list to add it to.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return deserializedObject._instance;
|
return deserializedObject._instance;
|
||||||
@@ -523,8 +502,13 @@ public class DeserializationObject
|
|||||||
return changed ? targetInstance : NoValueDeserialized;
|
return changed ? targetInstance : NoValueDeserialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe object DeserializeClass(string fieldName, Type fieldType)
|
public unsafe object? DeserializeClass(string fieldName, Type fieldType)
|
||||||
{
|
{
|
||||||
|
if (fieldType.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
|
{
|
||||||
|
return DeserializeList(fieldName, fieldType, fieldType.GetGenericArguments()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
bool isEntity = typeof(Entity).IsAssignableFrom(fieldType);
|
bool isEntity = typeof(Entity).IsAssignableFrom(fieldType);
|
||||||
bool isComponent = fieldType.IsSubclassOf(typeof(Component));
|
bool isComponent = fieldType.IsSubclassOf(typeof(Component));
|
||||||
|
|
||||||
@@ -539,7 +523,7 @@ public class DeserializationObject
|
|||||||
|
|
||||||
string fullTypeName = Encoding.UTF8.GetString(data.FullTypeName, (int)data.FullTypeNameLength);
|
string fullTypeName = Encoding.UTF8.GetString(data.FullTypeName, (int)data.FullTypeNameLength);
|
||||||
|
|
||||||
Type type = GetTypeFromName(fullTypeName);
|
Type? type = GetTypeFromName(fullTypeName);
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return NoValueDeserialized;
|
return NoValueDeserialized;
|
||||||
@@ -562,21 +546,30 @@ public class DeserializationObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UUID id = (UUID)GetFieldValue(fieldName, SerializationType.ObjectReference);
|
UUID id = (UUID)GetFieldValue(fieldName, SerializationType.ObjectReference)!;
|
||||||
|
|
||||||
if (id == UUID.Zero)
|
if (id == UUID.Zero)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Get serialization container for the instance
|
// Get serialization container for the instance
|
||||||
DeserializationObject deserializedObject = GetDeserializedObject(id);
|
DeserializationObject? deserializedObject = GetDeserializedObject(id);
|
||||||
|
|
||||||
Type type = deserializedObject.StoredType;
|
if (deserializedObject == null)
|
||||||
|
return NoValueDeserialized;
|
||||||
|
|
||||||
|
Type? type = deserializedObject.StoredType;
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return null;
|
return NoValueDeserialized;
|
||||||
|
|
||||||
deserializedObject._instance = ActivatorExtension.CreateInstanceSafe(type);
|
deserializedObject._instance = ActivatorExtension.CreateInstanceSafe(type);
|
||||||
|
|
||||||
|
if (deserializedObject._instance == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Failed to create instance of type {type} for field {fieldName}");
|
||||||
|
return NoValueDeserialized;
|
||||||
|
}
|
||||||
|
|
||||||
deserializedObject.DeserializeFields(deserializedObject._instance);
|
deserializedObject.DeserializeFields(deserializedObject._instance);
|
||||||
|
|
||||||
return deserializedObject._instance;
|
return deserializedObject._instance;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class SerializedObject
|
|||||||
_structScopeName = _structScopeName.Remove(_structScopeName.Length - scopeToRemove.Length - 1);
|
_structScopeName = _structScopeName.Remove(_structScopeName.Length - scopeToRemove.Length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddField(string fieldName, SerializationType serializationType, object value, string fullTypeName = null)
|
public void AddField(string fieldName, SerializationType serializationType, object value, string? fullTypeName = null)
|
||||||
{
|
{
|
||||||
string completeFieldName = $"{_structScopeName}{fieldName}";
|
string completeFieldName = $"{_structScopeName}{fieldName}";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user