mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Don't instantiate scripts for Editor + ScriptComponent Serialzation + Don't crash when scene loading failed
This commit is contained in:
@@ -464,7 +464,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
search = StringView(&buffer);
|
search = StringView(&buffer);
|
||||||
|
|
||||||
for (let (className, script) in ScriptEngine.EntityClasses)
|
for (let (className, scriptClass) in ScriptEngine.EntityClasses)
|
||||||
{
|
{
|
||||||
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
||||||
continue;
|
continue;
|
||||||
@@ -472,9 +472,14 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if (ImGui.Selectable(className.ToScopeCStr!(),
|
if (ImGui.Selectable(className.ToScopeCStr!(),
|
||||||
className == scriptComponent.Instance?.ScriptClass.FullName))
|
className == scriptComponent.Instance?.ScriptClass.FullName))
|
||||||
{
|
{
|
||||||
scriptComponent.Instance = new ScriptInstance(script);
|
//scriptComponent.Instance = new ScriptInstance(scriptClass);
|
||||||
scriptComponent.Instance.ReleaseRef();
|
// decrement refCount to 1 (scriptComponent.Instance increments its)
|
||||||
ScriptEngine.InitializeInstance(entity, scriptComponent);
|
//scriptComponent.Instance.ReleaseRef();
|
||||||
|
//ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||||
|
|
||||||
|
scriptComponent.ScriptClass = scriptClass;
|
||||||
|
|
||||||
|
ScriptEngine.CreateScriptFieldMap(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
@@ -505,9 +510,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
scriptInstance.SetFieldValue<T>(scriptField, value);
|
scriptInstance.SetFieldValue<T>(scriptField, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scriptComponent.Instance?.IsInitialized == true)
|
||||||
void ShowClassFields(SharpClass sharpClass, ScriptInstance scriptInstance)
|
|
||||||
{
|
{
|
||||||
|
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
||||||
|
ScriptInstance scriptInstance = scriptComponent.Instance;
|
||||||
|
|
||||||
for (let (fieldName, scriptField) in sharpClass.Fields)
|
for (let (fieldName, scriptField) in sharpClass.Fields)
|
||||||
{
|
{
|
||||||
var monoField = scriptField.[Friend]_monoField;
|
var monoField = scriptField.[Friend]_monoField;
|
||||||
@@ -579,67 +586,124 @@ namespace GlitchyEditor.EditWindows
|
|||||||
case .Entity:
|
case .Entity:
|
||||||
// TODO!
|
// TODO!
|
||||||
|
|
||||||
case .Class:
|
|
||||||
// TODO!
|
|
||||||
case .Enum:
|
case .Enum:
|
||||||
// TODO!
|
// TODO!
|
||||||
case .Struct:
|
case .Struct:
|
||||||
// TODO!
|
// TODO!
|
||||||
/*case .Struct:
|
|
||||||
ShowStructFields();
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8[128] bla = ?;
|
|
||||||
GetFieldValue<uint8[128]>(scriptInstance, scriptField);
|
|
||||||
|
|
||||||
Mono.MonoObject* dings = (Mono.MonoObject*)&bla;
|
|
||||||
|
|
||||||
//ShowFields
|
|
||||||
}*/
|
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*void ShowStructFields(SharpClass sharpClass, ScriptInstance scriptInstance)
|
else if (scriptComponent.ScriptClass != null)
|
||||||
{
|
{
|
||||||
for (let (fieldName, scriptField) in sharpClass.Fields)
|
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
{
|
|
||||||
var monoField = scriptField.[Friend]_monoField;
|
|
||||||
|
|
||||||
switch (scriptField.FieldType)
|
for (var (name, field) in ref scriptFields)
|
||||||
{
|
{
|
||||||
|
switch (field.Field.FieldType)
|
||||||
|
{
|
||||||
|
case .Bool:
|
||||||
|
var value = field.GetData<bool>();
|
||||||
|
if (ImGui.Checkbox(name.ToScopeCStr!(), &value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .SByte:
|
||||||
|
var value = field.GetData<int8>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .S8, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Short:
|
||||||
|
var value = field.GetData<int16>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .S16, &value))
|
||||||
|
field.SetData(value);
|
||||||
case .Int:
|
case .Int:
|
||||||
int32 value = GetFieldValue<int32>(scriptInstance, scriptField);
|
var value = field.GetData<int32>();
|
||||||
if (ImGui.DragInt(fieldName.ToScopeCStr!(), &value))
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .S32, &value))
|
||||||
SetFieldValue(scriptInstance, scriptField, value);
|
field.SetData(value);
|
||||||
|
case .Int2:
|
||||||
|
var value = field.GetData<int2>();
|
||||||
|
if (ImGui.DragScalarN(name.ToScopeCStr!(), .S32, &value, 2))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Int3:
|
||||||
|
var value = field.GetData<int3>();
|
||||||
|
if (ImGui.DragScalarN(name.ToScopeCStr!(), .S32, &value, 3))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Int4:
|
||||||
|
var value = field.GetData<int4>();
|
||||||
|
if (ImGui.DragScalarN(name.ToScopeCStr!(), .S32, &value, 4))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Long:
|
||||||
|
var value = field.GetData<int64>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .S64, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .Byte:
|
||||||
|
var value = field.GetData<uint8>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .U8, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .UShort:
|
||||||
|
var value = field.GetData<uint16>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .U16, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .UInt:
|
||||||
|
var value = field.GetData<uint32>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .U32, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .ULong:
|
||||||
|
var value = field.GetData<uint64>();
|
||||||
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .U64, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
case .Float:
|
case .Float:
|
||||||
float value = GetFieldValue<int32>(scriptInstance, scriptField);
|
var value = field.GetData<float>();
|
||||||
if (ImGui.DragFloat(fieldName.ToScopeCStr!(), &value))
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .Float, &value))
|
||||||
SetFieldValue(scriptInstance, scriptField, value);
|
field.SetData(value);
|
||||||
|
case .float2:
|
||||||
|
var value = field.GetData<float2>();
|
||||||
|
if (ImGui.Editfloat2(name, ref value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .float3:
|
||||||
|
var value = field.GetData<float3>();
|
||||||
|
if (ImGui.Editfloat3(name, ref value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .float4:
|
||||||
|
var value = field.GetData<float4>();
|
||||||
|
if (ImGui.Editfloat4(name, ref value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
case .Double:
|
case .Double:
|
||||||
double value = GetFieldValue<double>(scriptInstance, scriptField);
|
var value = field.GetData<double>();
|
||||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
if (ImGui.DragScalar(name.ToScopeCStr!(), .Double, &value))
|
||||||
SetFieldValue(scriptInstance, scriptField, value);
|
field.SetData(value);
|
||||||
/*case .Struct:
|
case .Double2:
|
||||||
{
|
var value = field.GetData<double2>();
|
||||||
|
if (ImGui.DragScalarN(name.ToScopeCStr!(), .Double, &value, 2))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Double3:
|
||||||
|
var value = field.GetData<double3>();
|
||||||
|
if (ImGui.DragScalarN(name.ToScopeCStr!(), .Double, &value, 3))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Double4:
|
||||||
|
var value = field.GetData<double4>();
|
||||||
|
if (ImGui.DragScalarN(name.ToScopeCStr!(), .Double, &value, 4))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
uint8[128] bla = ?;
|
case .Enum:
|
||||||
GetFieldValue<uint8[128]>(scriptInstance, scriptField);
|
// TODO!
|
||||||
|
|
||||||
Mono.MonoObject* dings = (Mono.MonoObject*)&bla;
|
//case .String:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
case .Entity:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
case .Struct:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
//ShowFields
|
|
||||||
}*/
|
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
Log.EngineLogger.Error($"Unhandled field type {field.Field.FieldType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
if (scriptComponent.Instance?.IsInitialized == true)
|
|
||||||
{
|
|
||||||
ShowClassFields(scriptComponent.Instance.ScriptClass, scriptComponent.Instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -620,17 +620,27 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SceneFilePath = scope String(filename);
|
SceneFilePath = scope String(filename);
|
||||||
|
|
||||||
_editorScene.ReleaseRef();
|
using (Scene newScene = new Scene())
|
||||||
_editorScene = new Scene();
|
{
|
||||||
_editor.CurrentScene = _editorScene;
|
|
||||||
var vpSize = _editor.SceneViewportWindow.ViewportSize;
|
var vpSize = _editor.SceneViewportWindow.ViewportSize;
|
||||||
_editorScene.OnViewportResize((.)vpSize.X, (.)vpSize.Y);
|
newScene.OnViewportResize((.)vpSize.X, (.)vpSize.Y);
|
||||||
|
|
||||||
SceneSerializer serializer = scope .(_editorScene);
|
SceneSerializer serializer = scope .(newScene);
|
||||||
serializer.Deserialize(SceneFilePath);
|
let result = serializer.Deserialize(SceneFilePath);
|
||||||
|
|
||||||
|
// Make sure we actually loaded something!
|
||||||
|
if (result case .Ok)
|
||||||
|
{
|
||||||
|
SetReference!(_editorScene, newScene);
|
||||||
|
_editor.CurrentScene = _editorScene;
|
||||||
SetReference!(_activeScene, _editorScene);
|
SetReference!(_activeScene, _editorScene);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error("Failed to load scene file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawOpenRecentProjectMenu()
|
private void DrawOpenRecentProjectMenu()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,32 @@ public struct ScriptField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ScriptFieldInstance
|
||||||
|
{
|
||||||
|
public ScriptField Field;
|
||||||
|
// TODO: I hate this, but we need to be able to store an entire matrix
|
||||||
|
internal uint8[sizeof(GlitchyEngine.Math.Matrix)] _data;
|
||||||
|
|
||||||
|
public this(ScriptField field)
|
||||||
|
{
|
||||||
|
Field = field;
|
||||||
|
_data = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetData<T>()
|
||||||
|
{
|
||||||
|
#unwarn
|
||||||
|
return *(T*)&_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetData<T>(T value) mut
|
||||||
|
{
|
||||||
|
*(T*)&_data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public typealias ScriptFieldMap = Dictionary<StringView, ScriptFieldInstance>;
|
||||||
|
|
||||||
abstract class SharpType : RefCounter
|
abstract class SharpType : RefCounter
|
||||||
{
|
{
|
||||||
protected String _namespace ~ delete _;
|
protected String _namespace ~ delete _;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ enum ScriptFieldType
|
|||||||
|
|
||||||
SByte,
|
SByte,
|
||||||
Short,
|
Short,
|
||||||
Int,// int2, int3, int4,
|
Int, Int2, Int3, Int4,
|
||||||
Long,
|
Long,
|
||||||
Byte,
|
Byte,
|
||||||
UShort,
|
UShort,
|
||||||
@@ -31,11 +31,69 @@ enum ScriptFieldType
|
|||||||
ULong,
|
ULong,
|
||||||
// Half, Half2, Half3, Half4,
|
// Half, Half2, Half3, Half4,
|
||||||
Float, float2, float3, float4,
|
Float, float2, float3, float4,
|
||||||
Double, // Double2, Double3, Double4,
|
Double, Double2, Double3, Double4,
|
||||||
|
|
||||||
Entity
|
Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension ScriptFieldType
|
||||||
|
{
|
||||||
|
public Type GetBeefType()
|
||||||
|
{
|
||||||
|
switch(this)
|
||||||
|
{
|
||||||
|
case .Bool:
|
||||||
|
return typeof(bool);
|
||||||
|
|
||||||
|
case .SByte:
|
||||||
|
return typeof(int8);
|
||||||
|
case .Short:
|
||||||
|
return typeof(int16);
|
||||||
|
case .Int:
|
||||||
|
return typeof(int32);
|
||||||
|
case .Int2:
|
||||||
|
return typeof(int2);
|
||||||
|
case .Int3:
|
||||||
|
return typeof(int3);
|
||||||
|
case .Int4:
|
||||||
|
return typeof(int4);
|
||||||
|
case .Long:
|
||||||
|
return typeof(int64);
|
||||||
|
|
||||||
|
|
||||||
|
case .Byte:
|
||||||
|
return typeof(uint8);
|
||||||
|
case .UShort:
|
||||||
|
return typeof(uint16);
|
||||||
|
case .UInt:
|
||||||
|
return typeof(uint32);
|
||||||
|
case .ULong:
|
||||||
|
return typeof(uint64);
|
||||||
|
|
||||||
|
case .Float:
|
||||||
|
return typeof(float);
|
||||||
|
case .float2:
|
||||||
|
return typeof(float2);
|
||||||
|
case .float3:
|
||||||
|
return typeof(float3);
|
||||||
|
case .float4:
|
||||||
|
return typeof(float4);
|
||||||
|
|
||||||
|
case .Double:
|
||||||
|
return typeof(double);
|
||||||
|
case .Double2:
|
||||||
|
return typeof(double2);
|
||||||
|
case .Double3:
|
||||||
|
return typeof(double3);
|
||||||
|
case .Double4:
|
||||||
|
return typeof(double4);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static sealed class ScriptEngineHelper
|
static sealed class ScriptEngineHelper
|
||||||
{
|
{
|
||||||
private static Dictionary<StringView, ScriptFieldType> _scriptFieldTypes = new Dictionary<StringView, ScriptFieldType>()
|
private static Dictionary<StringView, ScriptFieldType> _scriptFieldTypes = new Dictionary<StringView, ScriptFieldType>()
|
||||||
@@ -53,9 +111,10 @@ static sealed class ScriptEngineHelper
|
|||||||
("System.UInt64", .ULong),
|
("System.UInt64", .ULong),
|
||||||
|
|
||||||
("System.Single", .Float),
|
("System.Single", .Float),
|
||||||
("GlitchyEngine.Math.float2", .float2),
|
// TODO: We probably want to switch the C#-Library to use the superior floatN-Names
|
||||||
("GlitchyEngine.Math.float3", .float3),
|
("GlitchyEngine.Math.Vector2", .float2),
|
||||||
("GlitchyEngine.Math.float4", .float4),
|
("GlitchyEngine.Math.Vector3", .float3),
|
||||||
|
("GlitchyEngine.Math.Vector4", .float4),
|
||||||
|
|
||||||
("System.Double", .Double),
|
("System.Double", .Double),
|
||||||
|
|
||||||
@@ -102,6 +161,8 @@ static class ScriptEngine
|
|||||||
|
|
||||||
public static Scene Context => s_Context;
|
public static Scene Context => s_Context;
|
||||||
|
|
||||||
|
private static Dictionary<UUID, ScriptFieldMap> _entityFields = new .() ~ DeleteDictionaryAndValues!(_);
|
||||||
|
|
||||||
internal static class Attributes
|
internal static class Attributes
|
||||||
{
|
{
|
||||||
internal static MonoClass* s_ShowInEditorAttribute;
|
internal static MonoClass* s_ShowInEditorAttribute;
|
||||||
@@ -148,6 +209,22 @@ static class ScriptEngine
|
|||||||
//_entityScriptInstances[entity.UUID] = script.Instance..AddRef();
|
//_entityScriptInstances[entity.UUID] = script.Instance..AddRef();
|
||||||
|
|
||||||
script.Instance.Instantiate(entity.UUID);
|
script.Instance.Instantiate(entity.UUID);
|
||||||
|
|
||||||
|
CopyEditorFieldsToInstance(entity, script);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CopyEditorFieldsToInstance(Entity entity, ScriptComponent* script)
|
||||||
|
{
|
||||||
|
// Technically the map is for a different entity (namely the editor-entity),
|
||||||
|
// however the UUID is the same, so we get the correct field map
|
||||||
|
let fiels = GetScriptFieldMap(entity);
|
||||||
|
|
||||||
|
for (var (fieldName, field) in fiels)
|
||||||
|
{
|
||||||
|
// TODO: a litte assertion maybe?
|
||||||
|
|
||||||
|
script.Instance.SetFieldValue(field.Field, field._data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MonoAssembly* LoadCSharpAssembly(StringView assemblyPath)
|
private static MonoAssembly* LoadCSharpAssembly(StringView assemblyPath)
|
||||||
@@ -290,7 +367,39 @@ static class ScriptEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CreateScriptFieldMap(Entity entity)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(entity.IsValid);
|
||||||
|
|
||||||
|
if (_entityFields.TryGetValue(entity.UUID, var entityFields))
|
||||||
|
{
|
||||||
|
entityFields.Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entityFields = new Dictionary<StringView, ScriptFieldInstance>();
|
||||||
|
_entityFields.Add(entity.UUID, entityFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
let scriptComponent = entity.GetComponent<ScriptComponent>();
|
||||||
|
|
||||||
|
for (let (fieldName, field) in scriptComponent.ScriptClass.Fields)
|
||||||
|
{
|
||||||
|
entityFields.Add(fieldName, ScriptFieldInstance(field));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScriptFieldMap GetScriptFieldMap(Entity entity)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(entity.IsValid);
|
||||||
|
|
||||||
|
let uuid = entity.UUID;
|
||||||
|
|
||||||
|
// TODO: Entites bekommen noch kein Eintrag hier!!
|
||||||
|
Log.EngineLogger.AssertDebug(_entityFields.ContainsKey(uuid));
|
||||||
|
|
||||||
|
return _entityFields[uuid];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,88 +68,4 @@ class ScriptInstance : RefCounter
|
|||||||
{
|
{
|
||||||
_scriptClass.SetFieldValue<T>(_instance, field.[Friend]_monoField, 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 .float2:
|
|
||||||
GetFieldValue<float2>(field, var value);
|
|
||||||
if (ImGui.Editfloat2(fieldName, ref value))
|
|
||||||
SetFieldValue(field, value);
|
|
||||||
case .float3:
|
|
||||||
GetFieldValue<float3>(field, var value);
|
|
||||||
if (ImGui.Editfloat3(fieldName, ref value))
|
|
||||||
SetFieldValue(field, value);
|
|
||||||
case .float4:
|
|
||||||
GetFieldValue<float4>(field, var value);
|
|
||||||
if (ImGui.Editfloat4(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}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -507,8 +507,16 @@ namespace GlitchyEngine.World
|
|||||||
|
|
||||||
struct ScriptComponent : IDisposableComponent
|
struct ScriptComponent : IDisposableComponent
|
||||||
{
|
{
|
||||||
|
private ScriptClass _scriptClass = null;
|
||||||
|
|
||||||
private ScriptInstance _instance = null;
|
private ScriptInstance _instance = null;
|
||||||
|
|
||||||
|
public ScriptClass ScriptClass
|
||||||
|
{
|
||||||
|
get => _scriptClass;
|
||||||
|
set mut => SetReference!(_scriptClass, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ScriptInstance Instance
|
public ScriptInstance Instance
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
@@ -517,12 +525,16 @@ namespace GlitchyEngine.World
|
|||||||
set mut => SetReference!(_instance, value);
|
set mut => SetReference!(_instance, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets whether or not this script component has a script assigned (that means ScriptClass isn't null).
|
||||||
|
public bool HasScript => _scriptClass != null;
|
||||||
|
|
||||||
public bool IsInitialized => _instance?.IsInitialized ?? false;
|
public bool IsInitialized => _instance?.IsInitialized ?? false;
|
||||||
|
|
||||||
public bool IsCreated => _instance?.IsCreated ?? false;
|
public bool IsCreated => _instance?.IsCreated ?? false;
|
||||||
|
|
||||||
public void Dispose() mut
|
public void Dispose() mut
|
||||||
{
|
{
|
||||||
|
ReleaseRefAndNullify!(_scriptClass);
|
||||||
ReleaseRefAndNullify!(_instance);
|
ReleaseRefAndNullify!(_instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,13 +93,11 @@ 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>();
|
||||||
|
|
||||||
targetComponent.Instance = new ScriptInstance(sourceComponent.Instance.ScriptClass);
|
targetComponent.Instance = new ScriptInstance(sourceComponent.ScriptClass);
|
||||||
targetComponent.Instance..ReleaseRef();
|
targetComponent.Instance..ReleaseRef();
|
||||||
|
|
||||||
// We need an instance so we can copy the variables to it
|
// Initializes the created instance
|
||||||
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
||||||
|
|
||||||
sourceComponent.Instance.CopyEditorFieldsTo(targetComponent.Instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy transforms... needs special handling for the Parent<->Child relations
|
// Copy transforms... needs special handling for the Parent<->Child relations
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using GlitchyEngine.Core;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using GlitchyEngine.Renderer;
|
using GlitchyEngine.Renderer;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEngine.Scripting;
|
||||||
|
|
||||||
namespace GlitchyEngine.World;
|
namespace GlitchyEngine.World;
|
||||||
|
|
||||||
@@ -185,6 +186,28 @@ class SceneSerializer
|
|||||||
{
|
{
|
||||||
Serialize.Value(writer, "Material", component.Material);
|
Serialize.Value(writer, "Material", component.Material);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
SerializeComponent<ScriptComponent>(writer, entity, "ScriptComponent", scope (component) =>
|
||||||
|
{
|
||||||
|
Serialize.Value(writer, "ScriptClass", component.ScriptClass?.FullName);
|
||||||
|
|
||||||
|
if (component.HasScript)
|
||||||
|
{
|
||||||
|
let fields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
|
|
||||||
|
for (var (fieldName, fieldInstance) in fields)
|
||||||
|
{
|
||||||
|
switch (fieldInstance.Field.FieldType)
|
||||||
|
{
|
||||||
|
case .Entity, .Enum, .Class, .Struct:
|
||||||
|
// TODO: implement
|
||||||
|
default:
|
||||||
|
writer.Identifier(fieldName);
|
||||||
|
Serialize.Value(writer, ValueView(fieldInstance.Field.FieldType.GetBeefType(), &fieldInstance.[Friend]_data), gBonEnv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.EntryEnd();
|
writer.EntryEnd();
|
||||||
@@ -512,6 +535,73 @@ class SceneSerializer
|
|||||||
|
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}));
|
}));
|
||||||
|
case "ScriptComponent":
|
||||||
|
Try!(DeserializeComponent<ScriptComponent>(reader, entity, scope (component) =>
|
||||||
|
{
|
||||||
|
String scriptClassName = null;
|
||||||
|
|
||||||
|
Try!(Deserialize.Value(reader, "ScriptClass", out scriptClassName));
|
||||||
|
|
||||||
|
if (scriptClassName != null)
|
||||||
|
{
|
||||||
|
if (ScriptEngine.EntityClasses.TryGetValue(scriptClassName, let scriptClass))
|
||||||
|
{
|
||||||
|
component.ScriptClass = scriptClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete scriptClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.HasScript)
|
||||||
|
{
|
||||||
|
// This whole operation is technically a bit junk, because we are not guaranteed to successfully deserialize the scene,
|
||||||
|
// however we are editing the ScriptEngine because it doesn't care about which scene is active right now.
|
||||||
|
// The UUID should be unique enough, however if they do overlap (e.g. loading the current scene or simply because we are unlucky)
|
||||||
|
// we will replace the fields of the active scene, even if deserialization fails...
|
||||||
|
// But that is a bug for me to rediscover in the distant future, so in case this bug occurred and it took ages for you to
|
||||||
|
// figure out what happened: You are welcome :)
|
||||||
|
|
||||||
|
ScriptEngine.CreateScriptFieldMap(entity);
|
||||||
|
|
||||||
|
var fields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
|
|
||||||
|
Try!(reader.EntryEnd());
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
while (reader.ObjectHasMore())
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
Try!(reader.EntryEnd());
|
||||||
|
|
||||||
|
// TODO: We could think about doing the Try! a little smarter...
|
||||||
|
// However we always might just fail to deserialize, so it doesn't really matter.
|
||||||
|
|
||||||
|
StringView fieldName = Try!(reader.Identifier());
|
||||||
|
|
||||||
|
if (fields.ContainsKey(fieldName))
|
||||||
|
{
|
||||||
|
var field = ref fields[fieldName];
|
||||||
|
|
||||||
|
void* data = &field.[Friend]_data;
|
||||||
|
|
||||||
|
Try!(Deserialize.Value(reader, ValueView(field.Field.FieldType.GetBeefType(), data), gBonEnv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}));
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
SerializeComponent<ScriptComponent>(writer, entity, "ScriptComponent", scope (component) =>
|
||||||
|
{
|
||||||
|
Serialize.Value(writer, "ScriptClass", component.ScriptClass?.FullName);
|
||||||
|
});
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
Log.EngineLogger.AssertDebug(false, "Unknown component type");
|
Log.EngineLogger.AssertDebug(false, "Unknown component type");
|
||||||
//return .Err;
|
//return .Err;
|
||||||
|
|||||||
Reference in New Issue
Block a user