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();
|
||||
|
||||
if (ImGui.InputText("##ScriptName", &buffer, buffer.Count))
|
||||
{
|
||||
search = StringView(&buffer);
|
||||
}
|
||||
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!() ?? "Select Script...";
|
||||
|
||||
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)
|
||||
{
|
||||
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
||||
@@ -457,8 +461,7 @@ namespace GlitchyEditor.EditWindows
|
||||
ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
/*T GetFieldValue<T>()
|
||||
@@ -473,17 +476,17 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
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)
|
||||
{
|
||||
value = scriptInstance.GetFieldValue<T>(scriptField.[Friend]_monoField);
|
||||
value = scriptInstance.GetFieldValue<T>(scriptField);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ class SharpClass : SharpType
|
||||
|
||||
if (sharpType == null)
|
||||
continue;
|
||||
|
||||
sharpType.ReleaseRef();
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
// 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
|
||||
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));
|
||||
|
||||
if (_sharpClasses.TryGetValue(typeName, let sharpType))
|
||||
return sharpType;
|
||||
return sharpType..AddRef();
|
||||
|
||||
Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(monoType);
|
||||
|
||||
|
||||
@@ -13,7 +13,13 @@ class ScriptInstance : RefCounter
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -40,6 +46,7 @@ class ScriptInstance : RefCounter
|
||||
public void InvokeOnCreate()
|
||||
{
|
||||
_scriptClass.OnCreate(_instance);
|
||||
_isCreated = true;
|
||||
}
|
||||
|
||||
public void InvokeOnUpdate(float deltaTime)
|
||||
@@ -52,21 +59,97 @@ class ScriptInstance : RefCounter
|
||||
_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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public bool InInstantiated => _instance?.IsInstatiated ?? false;
|
||||
public bool IsInitialized => _instance?.IsInitialized ?? false;
|
||||
|
||||
public bool IsCreated => _instance?.IsCreated ?? false;
|
||||
|
||||
public void Dispose() mut
|
||||
{
|
||||
|
||||
@@ -73,7 +73,6 @@ namespace GlitchyEngine.World
|
||||
|
||||
// TODO: perhaps use reflection and comptime
|
||||
// Copy components
|
||||
//CopyComponents<TransformComponent>(this, target); /* Parent will be copied below*/
|
||||
CopyComponents<MeshRendererComponent>(this, target);
|
||||
CopyComponents<MeshComponent>(this, target);
|
||||
CopyComponents<EditorComponent>(this, target);
|
||||
@@ -85,8 +84,8 @@ namespace GlitchyEngine.World
|
||||
CopyComponents<Rigidbody2DComponent>(this, target);
|
||||
CopyComponents<BoxCollider2DComponent>(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>())
|
||||
{
|
||||
Entity sourceEntity = .(sourceHandle, this);
|
||||
@@ -94,15 +93,16 @@ namespace GlitchyEngine.World
|
||||
Entity targetEntity = target.GetEntityByID(sourceEntity.UUID);
|
||||
ScriptComponent* targetComponent = targetEntity.AddComponent<ScriptComponent>();
|
||||
|
||||
// TODO: Do proper copy
|
||||
|
||||
targetComponent.Instance = new ScriptInstance(sourceComponent.Instance.ScriptClass);
|
||||
targetComponent.Instance..ReleaseRef();
|
||||
|
||||
// We need an instance so we can copy the variables to it
|
||||
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
||||
|
||||
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>())
|
||||
{
|
||||
Entity sourceEntity = Entity(sourceHandle, this);
|
||||
@@ -272,9 +272,10 @@ namespace GlitchyEngine.World
|
||||
// Run scripts
|
||||
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))
|
||||
script.Instance.InvokeOnCreate();
|
||||
|
||||
@@ -105,6 +105,9 @@ static class Mono
|
||||
[LinkName(.C)]
|
||||
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)]
|
||||
public static extern void* mono_object_unbox(MonoObject* obj);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace GlitchyEngine.Core;
|
||||
|
||||
public class EngineObject
|
||||
public abstract class EngineObject
|
||||
{
|
||||
protected internal UUID _uuid;
|
||||
|
||||
@@ -12,8 +14,7 @@ public class EngineObject
|
||||
/// <summary>
|
||||
/// Empty constructor not used. Do NOT USE!
|
||||
/// </summary>
|
||||
protected EngineObject()
|
||||
{}
|
||||
protected EngineObject() { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new EngineObject with the given ID.
|
||||
|
||||
Reference in New Issue
Block a user