Script default values after init, Fix memory leak, Copy Script values on Play

This commit is contained in:
Simon Lübeß
2023-05-31 14:38:07 +02:00
parent 6a59deb9e2
commit f4607a6210
8 changed files with 130 additions and 30 deletions
@@ -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);
+1 -1
View File
@@ -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);
+88 -5
View File
@@ -12,8 +12,14 @@ class ScriptInstance : RefCounter
private uint32 _gcHandle;
public ScriptClass ScriptClass => _scriptClass;
/// Gets whether or not the instance has ben initialized.
public bool IsInitialized => _instance != null;
public bool IsInstatiated => _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
{
+9 -8
View File
@@ -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();