mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Script default values after init, Fix memory leak, Copy Script values on Play
This commit is contained in:
@@ -437,13 +437,17 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
StringView search = StringView();
|
StringView search = StringView();
|
||||||
|
|
||||||
if (ImGui.InputText("##ScriptName", &buffer, buffer.Count))
|
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!() ?? "Select Script...";
|
||||||
{
|
|
||||||
search = StringView(&buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginCombo("##Type", scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!()))
|
if (ImGui.Button(scriptLabel))
|
||||||
|
ImGui.OpenPopup("SelectScript");
|
||||||
|
|
||||||
|
if (ImGui.BeginPopup("SelectScript"))
|
||||||
{
|
{
|
||||||
|
ImGui.InputText("##ScriptSearch", &buffer, buffer.Count);
|
||||||
|
|
||||||
|
search = StringView(&buffer);
|
||||||
|
|
||||||
for (let (className, script) in ScriptEngine.EntityClasses)
|
for (let (className, script) in ScriptEngine.EntityClasses)
|
||||||
{
|
{
|
||||||
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
||||||
@@ -457,8 +461,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ScriptEngine.InitializeInstance(entity, scriptComponent);
|
ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImGui.EndPopup();
|
||||||
ImGui.EndCombo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*T GetFieldValue<T>()
|
/*T GetFieldValue<T>()
|
||||||
@@ -473,17 +476,17 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
T GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField)
|
T GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField)
|
||||||
{
|
{
|
||||||
return scriptInstance.GetFieldValue<T>(scriptField.[Friend]_monoField);
|
return scriptInstance.GetFieldValue<T>(scriptField);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, out T value)
|
void GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, out T value)
|
||||||
{
|
{
|
||||||
value = scriptInstance.GetFieldValue<T>(scriptField.[Friend]_monoField);
|
value = scriptInstance.GetFieldValue<T>(scriptField);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, in T value)
|
void SetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, in T value)
|
||||||
{
|
{
|
||||||
scriptInstance.SetFieldValue<T>(scriptField.[Friend]_monoField, value);
|
scriptInstance.SetFieldValue<T>(scriptField, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -618,7 +621,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (scriptComponent.Instance?.IsInstatiated == true)
|
if (scriptComponent.Instance?.IsInitialized == true)
|
||||||
{
|
{
|
||||||
ShowClassFields(scriptComponent.Instance.ScriptClass, scriptComponent.Instance);
|
ShowClassFields(scriptComponent.Instance.ScriptClass, scriptComponent.Instance);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ class SharpClass : SharpType
|
|||||||
|
|
||||||
if (sharpType == null)
|
if (sharpType == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
sharpType.ReleaseRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(type);
|
//Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(type);
|
||||||
@@ -182,6 +184,11 @@ class ScriptClass : SharpClass
|
|||||||
{
|
{
|
||||||
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
||||||
|
|
||||||
|
// TODO: I think this is a bit dirty
|
||||||
|
// Invoke empty constructor to fill fields
|
||||||
|
Mono.mono_runtime_object_init(instance);
|
||||||
|
|
||||||
|
// Invoke constructor with UUID
|
||||||
#unwarn
|
#unwarn
|
||||||
ScriptEngine.[Friend]s_EngineObject.Invoke(ScriptEngine.[Friend]s_EngineObject._constructor, instance, &uuid);
|
ScriptEngine.[Friend]s_EngineObject.Invoke(ScriptEngine.[Friend]s_EngineObject._constructor, instance, &uuid);
|
||||||
|
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ static class ScriptEngine
|
|||||||
StringView typeName = StringView(Mono.mono_type_get_name(monoType));
|
StringView typeName = StringView(Mono.mono_type_get_name(monoType));
|
||||||
|
|
||||||
if (_sharpClasses.TryGetValue(typeName, let sharpType))
|
if (_sharpClasses.TryGetValue(typeName, let sharpType))
|
||||||
return sharpType;
|
return sharpType..AddRef();
|
||||||
|
|
||||||
Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(monoType);
|
Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(monoType);
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,13 @@ class ScriptInstance : RefCounter
|
|||||||
|
|
||||||
public ScriptClass ScriptClass => _scriptClass;
|
public ScriptClass ScriptClass => _scriptClass;
|
||||||
|
|
||||||
public bool IsInstatiated => _instance != null;
|
/// Gets whether or not the instance has ben initialized.
|
||||||
|
public bool IsInitialized => _instance != null;
|
||||||
|
|
||||||
|
/// Gets whether or not the Create-Method of this instance has been called before.
|
||||||
|
public bool IsCreated => _isCreated;
|
||||||
|
|
||||||
|
private bool _isCreated = false;
|
||||||
|
|
||||||
public this(ScriptClass scriptClass)
|
public this(ScriptClass scriptClass)
|
||||||
{
|
{
|
||||||
@@ -40,6 +46,7 @@ class ScriptInstance : RefCounter
|
|||||||
public void InvokeOnCreate()
|
public void InvokeOnCreate()
|
||||||
{
|
{
|
||||||
_scriptClass.OnCreate(_instance);
|
_scriptClass.OnCreate(_instance);
|
||||||
|
_isCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeOnUpdate(float deltaTime)
|
public void InvokeOnUpdate(float deltaTime)
|
||||||
@@ -52,21 +59,97 @@ class ScriptInstance : RefCounter
|
|||||||
_scriptClass.OnDestroy(_instance);
|
_scriptClass.OnDestroy(_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetFieldValue<T>(MonoClassField* field)
|
public T GetFieldValue<T>(ScriptField field)
|
||||||
{
|
{
|
||||||
return _scriptClass.GetFieldValue<T>(_instance, field);
|
return _scriptClass.GetFieldValue<T>(_instance, field.[Friend]_monoField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFieldValue<T>(MonoClassField* field, in T value)
|
public void SetFieldValue<T>(ScriptField field, in T value)
|
||||||
{
|
{
|
||||||
_scriptClass.SetFieldValue<T>(_instance, field, value);
|
_scriptClass.SetFieldValue<T>(_instance, field.[Friend]_monoField, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyEditorFieldsTo(ScriptInstance target)
|
public void CopyEditorFieldsTo(ScriptInstance target)
|
||||||
{
|
{
|
||||||
for (let (fieldName, field) in ScriptClass.Fields)
|
for (let (fieldName, field) in ScriptClass.Fields)
|
||||||
{
|
{
|
||||||
|
switch (field.FieldType)
|
||||||
|
{
|
||||||
|
case .Bool:
|
||||||
|
var value = GetFieldValue<bool>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
|
||||||
|
case .SByte:
|
||||||
|
var value = GetFieldValue<int8>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
case .Short:
|
||||||
|
var value = GetFieldValue<int16>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
case .Int:
|
||||||
|
var value = GetFieldValue<int32>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
case .Long:
|
||||||
|
var value = GetFieldValue<int64>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
|
||||||
|
case .Byte:
|
||||||
|
var value = GetFieldValue<uint8>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
case .UShort:
|
||||||
|
var value = GetFieldValue<uint16>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
case .UInt:
|
||||||
|
var value = GetFieldValue<uint32>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
case .ULong:
|
||||||
|
var value = GetFieldValue<uint64>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
|
||||||
|
case .Float:
|
||||||
|
var value = GetFieldValue<float>(field);
|
||||||
|
target.SetFieldValue(field, value);
|
||||||
|
|
||||||
|
/*case .Vector2:
|
||||||
|
GetFieldValue<Vector2>(field, var value);
|
||||||
|
if (ImGui.EditVector2(fieldName, ref value))
|
||||||
|
SetFieldValue(field, value);
|
||||||
|
case .Vector3:
|
||||||
|
GetFieldValue<Vector3>(field, var value);
|
||||||
|
if (ImGui.EditVector3(fieldName, ref value))
|
||||||
|
SetFieldValue(field, value);
|
||||||
|
case .Vector4:
|
||||||
|
GetFieldValue<Vector4>(field, var value);
|
||||||
|
if (ImGui.EditVector4(fieldName, ref value))
|
||||||
|
SetFieldValue(field, value);
|
||||||
|
|
||||||
|
case .Double:
|
||||||
|
var value = GetFieldValue<double>(field);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
||||||
|
SetFieldValue(field, value);
|
||||||
|
|
||||||
|
case .Entity:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
case .Class:
|
||||||
|
// TODO!
|
||||||
|
case .Enum:
|
||||||
|
// TODO!
|
||||||
|
case .Struct:
|
||||||
|
// TODO!*/
|
||||||
|
/*case .Struct:
|
||||||
|
ShowStructFields();
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8[128] bla = ?;
|
||||||
|
GetFieldValue<uint8[128]>(scriptField);
|
||||||
|
|
||||||
|
Mono.MonoObject* dings = (Mono.MonoObject*)&bla;
|
||||||
|
|
||||||
|
//ShowFields
|
||||||
|
}*/
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error($"Unhandled field type {field.FieldType}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,7 +457,9 @@ namespace GlitchyEngine.World
|
|||||||
set mut => SetReference!(_instance, value);
|
set mut => SetReference!(_instance, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool InInstantiated => _instance?.IsInstatiated ?? false;
|
public bool IsInitialized => _instance?.IsInitialized ?? false;
|
||||||
|
|
||||||
|
public bool IsCreated => _instance?.IsCreated ?? false;
|
||||||
|
|
||||||
public void Dispose() mut
|
public void Dispose() mut
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ namespace GlitchyEngine.World
|
|||||||
|
|
||||||
// TODO: perhaps use reflection and comptime
|
// TODO: perhaps use reflection and comptime
|
||||||
// Copy components
|
// Copy components
|
||||||
//CopyComponents<TransformComponent>(this, target); /* Parent will be copied below*/
|
|
||||||
CopyComponents<MeshRendererComponent>(this, target);
|
CopyComponents<MeshRendererComponent>(this, target);
|
||||||
CopyComponents<MeshComponent>(this, target);
|
CopyComponents<MeshComponent>(this, target);
|
||||||
CopyComponents<EditorComponent>(this, target);
|
CopyComponents<EditorComponent>(this, target);
|
||||||
@@ -85,8 +84,8 @@ namespace GlitchyEngine.World
|
|||||||
CopyComponents<Rigidbody2DComponent>(this, target);
|
CopyComponents<Rigidbody2DComponent>(this, target);
|
||||||
CopyComponents<BoxCollider2DComponent>(this, target);
|
CopyComponents<BoxCollider2DComponent>(this, target);
|
||||||
CopyComponents<CircleCollider2DComponent>(this, target);
|
CopyComponents<CircleCollider2DComponent>(this, target);
|
||||||
//CopyComponents<ScriptComponent>(this, target);
|
|
||||||
|
|
||||||
|
// Copy ScriptComponents... needs extra handling for the script instances
|
||||||
for (let (sourceHandle, sourceComponent) in _ecsWorld.Enumerate<ScriptComponent>())
|
for (let (sourceHandle, sourceComponent) in _ecsWorld.Enumerate<ScriptComponent>())
|
||||||
{
|
{
|
||||||
Entity sourceEntity = .(sourceHandle, this);
|
Entity sourceEntity = .(sourceHandle, this);
|
||||||
@@ -94,15 +93,16 @@ namespace GlitchyEngine.World
|
|||||||
Entity targetEntity = target.GetEntityByID(sourceEntity.UUID);
|
Entity targetEntity = target.GetEntityByID(sourceEntity.UUID);
|
||||||
ScriptComponent* targetComponent = targetEntity.AddComponent<ScriptComponent>();
|
ScriptComponent* targetComponent = targetEntity.AddComponent<ScriptComponent>();
|
||||||
|
|
||||||
// TODO: Do proper copy
|
|
||||||
|
|
||||||
targetComponent.Instance = new ScriptInstance(sourceComponent.Instance.ScriptClass);
|
targetComponent.Instance = new ScriptInstance(sourceComponent.Instance.ScriptClass);
|
||||||
targetComponent.Instance..ReleaseRef();
|
targetComponent.Instance..ReleaseRef();
|
||||||
|
|
||||||
|
// We need an instance so we can copy the variables to it
|
||||||
|
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
||||||
|
|
||||||
sourceComponent.Instance.CopyEditorFieldsTo(targetComponent.Instance);
|
sourceComponent.Instance.CopyEditorFieldsTo(targetComponent.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy transforms
|
// Copy transforms... needs special handling for the Parent<->Child relations
|
||||||
for (let (sourceHandle, sourceTransform) in _ecsWorld.Enumerate<TransformComponent>())
|
for (let (sourceHandle, sourceTransform) in _ecsWorld.Enumerate<TransformComponent>())
|
||||||
{
|
{
|
||||||
Entity sourceEntity = Entity(sourceHandle, this);
|
Entity sourceEntity = Entity(sourceHandle, this);
|
||||||
@@ -272,9 +272,10 @@ namespace GlitchyEngine.World
|
|||||||
// Run scripts
|
// Run scripts
|
||||||
for (var (entity, script) in _ecsWorld.Enumerate<ScriptComponent>())
|
for (var (entity, script) in _ecsWorld.Enumerate<ScriptComponent>())
|
||||||
{
|
{
|
||||||
if (!script.InInstantiated)
|
if (!script.IsCreated)
|
||||||
{
|
{
|
||||||
ScriptEngine.InitializeInstance(Entity(entity, this), script);
|
if (!script.IsInitialized)
|
||||||
|
ScriptEngine.InitializeInstance(Entity(entity, this), script);
|
||||||
|
|
||||||
if (mode.HasFlag(.Runtime))
|
if (mode.HasFlag(.Runtime))
|
||||||
script.Instance.InvokeOnCreate();
|
script.Instance.InvokeOnCreate();
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ static class Mono
|
|||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoObject* mono_runtime_invoke(MonoMethod* method, void* obj, void** param, MonoObject** exc);
|
public static extern MonoObject* mono_runtime_invoke(MonoMethod* method, void* obj, void** param, MonoObject** exc);
|
||||||
|
|
||||||
|
[LinkName(.C)]
|
||||||
|
public static extern MonoMethod* mono_object_get_virtual_method(MonoObject* obj, MonoMethod* method);
|
||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern void* mono_object_unbox(MonoObject* obj);
|
public static extern void* mono_object_unbox(MonoObject* obj);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace GlitchyEngine.Core;
|
namespace GlitchyEngine.Core;
|
||||||
|
|
||||||
public class EngineObject
|
public abstract class EngineObject
|
||||||
{
|
{
|
||||||
protected internal UUID _uuid;
|
protected internal UUID _uuid;
|
||||||
|
|
||||||
@@ -12,8 +14,7 @@ public class EngineObject
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Empty constructor not used. Do NOT USE!
|
/// Empty constructor not used. Do NOT USE!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected EngineObject()
|
protected EngineObject() { }
|
||||||
{}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new EngineObject with the given ID.
|
/// Creates a new EngineObject with the given ID.
|
||||||
|
|||||||
Reference in New Issue
Block a user