mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
ScriptEngine cleanup
This commit is contained in:
@@ -8,77 +8,6 @@ namespace GlitchyEngine.Scripting;
|
|||||||
|
|
||||||
using internal GlitchyEngine.Scripting;
|
using internal GlitchyEngine.Scripting;
|
||||||
|
|
||||||
public struct ScriptField
|
|
||||||
{
|
|
||||||
public StringView Name;
|
|
||||||
internal MonoClassField* _monoField;
|
|
||||||
public bool IsStatic;
|
|
||||||
public ScriptFieldType FieldType;
|
|
||||||
public SharpType SharpType;
|
|
||||||
public int SizeInBytes;
|
|
||||||
|
|
||||||
internal this(StringView name, MonoClassField* monoField, bool isStatic, ScriptFieldType fieldType, int sizeInBytes, SharpType sharpType)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
_monoField = monoField;
|
|
||||||
IsStatic = isStatic;
|
|
||||||
FieldType = fieldType;
|
|
||||||
SharpType = sharpType;
|
|
||||||
SizeInBytes = sizeInBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsType(SharpClass otherClass, bool checkIfSubtype)
|
|
||||||
{
|
|
||||||
return IsType(otherClass.GetMonoType(), checkIfSubtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsType(MonoType* otherType, bool checkIfSubtype)
|
|
||||||
{
|
|
||||||
MonoType* myType = GetMonoType();
|
|
||||||
|
|
||||||
if (checkIfSubtype)
|
|
||||||
{
|
|
||||||
MonoClass* myClass = Mono.mono_type_get_class(myType);
|
|
||||||
MonoClass* otherClass = Mono.mono_type_get_class(otherType);
|
|
||||||
|
|
||||||
return Mono.mono_class_is_subclass_of(myClass, otherClass, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return myType == otherType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonoType* GetMonoType()
|
|
||||||
{
|
|
||||||
return Mono.mono_field_get_type(_monoField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct ScriptFieldInstance
|
|
||||||
{
|
|
||||||
public ScriptFieldType Type;
|
|
||||||
// TODO: I hate this, but we need to be able to store an entire matrix
|
|
||||||
internal uint8[sizeof(GlitchyEngine.Math.Matrix)] _data;
|
|
||||||
|
|
||||||
public this(ScriptFieldType type)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
_data = default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T GetData<T>()
|
|
||||||
{
|
|
||||||
#unwarn
|
|
||||||
return *(T*)&_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetData<T>(T value) mut
|
|
||||||
{
|
|
||||||
*(T*)&_data = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class SharpType : RefCounter
|
abstract class SharpType : RefCounter
|
||||||
{
|
{
|
||||||
protected String _namespace ~ delete _;
|
protected String _namespace ~ delete _;
|
||||||
@@ -86,15 +15,11 @@ abstract class SharpType : RefCounter
|
|||||||
protected String _fullName ~ delete _;
|
protected String _fullName ~ delete _;
|
||||||
protected ScriptFieldType _scriptType;
|
protected ScriptFieldType _scriptType;
|
||||||
|
|
||||||
protected Dictionary<StringView, ScriptField> _monoFields ~ delete _;
|
|
||||||
|
|
||||||
public StringView Namespace => _namespace;
|
public StringView Namespace => _namespace;
|
||||||
public StringView ClassName => _className;
|
public StringView ClassName => _className;
|
||||||
public StringView FullName => _fullName;
|
public StringView FullName => _fullName;
|
||||||
public ScriptFieldType ScriptType => _scriptType;
|
public ScriptFieldType ScriptType => _scriptType;
|
||||||
|
|
||||||
public Dictionary<StringView, ScriptField> Fields => _monoFields;
|
|
||||||
|
|
||||||
public this(StringView classNamespace, StringView className, ScriptFieldType scriptType)
|
public this(StringView classNamespace, StringView className, ScriptFieldType scriptType)
|
||||||
{
|
{
|
||||||
_namespace = new String(classNamespace);
|
_namespace = new String(classNamespace);
|
||||||
@@ -116,8 +41,6 @@ class SharpClass : SharpType
|
|||||||
_monoClass = Mono.mono_class_from_name(image, _namespace, _className);
|
_monoClass = Mono.mono_class_from_name(image, _namespace, _className);
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(_monoClass != null);
|
Log.EngineLogger.AssertDebug(_monoClass != null);
|
||||||
|
|
||||||
ExtractFields();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal this(MonoClass* monoClass, ScriptFieldType fieldType = .Class) :
|
internal this(MonoClass* monoClass, ScriptFieldType fieldType = .Class) :
|
||||||
@@ -126,8 +49,6 @@ class SharpClass : SharpType
|
|||||||
_monoClass = monoClass;
|
_monoClass = monoClass;
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(_monoClass != null);
|
Log.EngineLogger.AssertDebug(_monoClass != null);
|
||||||
|
|
||||||
ExtractFields();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal MonoType* GetMonoType()
|
internal MonoType* GetMonoType()
|
||||||
@@ -144,135 +65,6 @@ class SharpClass : SharpType
|
|||||||
{
|
{
|
||||||
return Mono.mono_class_is_subclass_of(_monoClass, @class, false);
|
return Mono.mono_class_is_subclass_of(_monoClass, @class, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExtractFields()
|
|
||||||
{
|
|
||||||
//_monoFields = new List<MonoClassField*>();´
|
|
||||||
_monoFields = new Dictionary<StringView, ScriptField>();
|
|
||||||
|
|
||||||
void* iterator = null;
|
|
||||||
MonoClassField* currentField = null;
|
|
||||||
while ((currentField = Mono.mono_class_get_fields(_monoClass, &iterator)) != null)
|
|
||||||
{
|
|
||||||
StringView name = StringView(Mono.mono_field_get_name(currentField));
|
|
||||||
|
|
||||||
MonoType* type = Mono.mono_field_get_type(currentField);
|
|
||||||
|
|
||||||
ScriptFieldType fieldType = ScriptEngineHelper.GetScriptFieldType(type);
|
|
||||||
|
|
||||||
SharpType sharpType = null;
|
|
||||||
|
|
||||||
// If field type is none the field might be a struct, class or enum
|
|
||||||
if (fieldType == .None)
|
|
||||||
{
|
|
||||||
sharpType = ScriptEngine.GetSharpType(type);
|
|
||||||
fieldType = sharpType?.ScriptType ?? .None;
|
|
||||||
|
|
||||||
if (sharpType == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sharpType.ReleaseRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(type);
|
|
||||||
|
|
||||||
FieldAttribute flags = (.)Mono.mono_field_get_flags(currentField);
|
|
||||||
|
|
||||||
MonoCustomAttrInfo* attributes = Mono.mono_custom_attrs_from_field(_monoClass, currentField);
|
|
||||||
|
|
||||||
if (flags.HasFlag(.Public) ||
|
|
||||||
(attributes != null &&
|
|
||||||
Mono.mono_custom_attrs_has_attr(attributes, ScriptEngine.Attributes.s_ShowInEditorAttribute)))
|
|
||||||
{
|
|
||||||
MonoClass* fieldClass = Mono.mono_type_get_class(type);
|
|
||||||
|
|
||||||
int sizeInBytes = 8;
|
|
||||||
|
|
||||||
if (fieldClass != null)
|
|
||||||
{
|
|
||||||
sizeInBytes = Mono.mono_class_instance_size(fieldClass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_monoFields[name] = .(name, currentField, flags.HasFlag(.Static), fieldType, sizeInBytes, sharpType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EnumValue
|
|
||||||
{
|
|
||||||
public StringView Name;
|
|
||||||
|
|
||||||
public uint64 Value;
|
|
||||||
|
|
||||||
public this(StringView name, uint64 value)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SharpEnum : SharpClass
|
|
||||||
{
|
|
||||||
private append Dictionary<uint64, EnumValue> _values = .();
|
|
||||||
|
|
||||||
public Dictionary<uint64, EnumValue> Values => _values;
|
|
||||||
|
|
||||||
private int _underlyingSize = 0;
|
|
||||||
|
|
||||||
public this(StringView classNamespace, StringView className, MonoImage* image)
|
|
||||||
: base(classNamespace, className, image, .Enum)
|
|
||||||
{
|
|
||||||
ExtractEnumValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractEnumValues()
|
|
||||||
{
|
|
||||||
_underlyingSize = Mono.mono_class_instance_size(_monoClass);
|
|
||||||
Log.EngineLogger.Assert(_underlyingSize != 0);
|
|
||||||
|
|
||||||
var vtable = Mono.mono_class_vtable(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
|
||||||
|
|
||||||
void* iterator = null;
|
|
||||||
MonoClassField* currentField = null;
|
|
||||||
while ((currentField = Mono.mono_class_get_fields(_monoClass, &iterator)) != null)
|
|
||||||
{
|
|
||||||
MonoType* fieldType = Mono.mono_field_get_type(currentField);
|
|
||||||
MonoClass* fieldClass = Mono.mono_type_get_class(fieldType);
|
|
||||||
|
|
||||||
FieldAttribute fieldFlags = (.)Mono.mono_field_get_flags(currentField);
|
|
||||||
|
|
||||||
if (fieldFlags.HasFlag(.Public) && fieldFlags.HasFlag(.Static) &&
|
|
||||||
fieldClass != null && Mono.mono_class_is_subclass_of(fieldClass, _monoClass, false))
|
|
||||||
{
|
|
||||||
StringView fieldName = StringView(Mono.mono_field_get_name(currentField));
|
|
||||||
|
|
||||||
uint64 value = 0;
|
|
||||||
Mono.mono_field_static_get_value(vtable, currentField, &value);
|
|
||||||
|
|
||||||
EnumValue enumValue = .(fieldName, value);
|
|
||||||
|
|
||||||
_values.Add(value, enumValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SharpStruct : SharpClass
|
|
||||||
{
|
|
||||||
protected int _size;
|
|
||||||
|
|
||||||
public int Size => _size;
|
|
||||||
|
|
||||||
public this(StringView classNamespace, StringView className, MonoImage* image)
|
|
||||||
: base(classNamespace, className, image)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScriptClass : SharpClass
|
class ScriptClass : SharpClass
|
||||||
@@ -289,16 +81,11 @@ class ScriptClass : SharpClass
|
|||||||
private OnUpdateMethod _onUpdate;
|
private OnUpdateMethod _onUpdate;
|
||||||
private OnDestroyMethod _onDestroy;
|
private OnDestroyMethod _onDestroy;
|
||||||
|
|
||||||
private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, Collision2D collision, MonoException** exception) _onCollisionEnter2D;
|
private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, MonoObject* collision2d, MonoException** exception) _onCollisionEnter2D;
|
||||||
private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, Collision2D collision, MonoException** exception) _onCollisionLeave2D;
|
private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, MonoObject* collision2d, MonoException** exception) _onCollisionLeave2D;
|
||||||
|
|
||||||
//private OnCollisionEnter2DMethod _onCollisionEnter2D;
|
public bool HasCollisionEnter2D => _onCollisionEnter2D != null;
|
||||||
//private OnDestroyMethod _onCollisionLeave2D;
|
public bool HasCollisionLeave2D => _onCollisionLeave2D != null;
|
||||||
private MonoMethod* _onCollisionEnter2DMethod;
|
|
||||||
private MonoMethod* _onCollisionLeave2DMethod;
|
|
||||||
|
|
||||||
public bool HasCollisionEnter2D => _onCollisionEnter2DMethod != null;
|
|
||||||
public bool HasCollisionLeave2D => _onCollisionLeave2DMethod != null;
|
|
||||||
|
|
||||||
public bool RunInEditMode => _runInEditMode;
|
public bool RunInEditMode => _runInEditMode;
|
||||||
|
|
||||||
@@ -311,9 +98,6 @@ class ScriptClass : SharpClass
|
|||||||
_onUpdate = (OnUpdateMethod)GetMethodThunk("OnUpdate", 1);
|
_onUpdate = (OnUpdateMethod)GetMethodThunk("OnUpdate", 1);
|
||||||
_onDestroy = (OnDestroyMethod)GetMethodThunk("OnDestroy");
|
_onDestroy = (OnDestroyMethod)GetMethodThunk("OnDestroy");
|
||||||
|
|
||||||
_onCollisionEnter2D = (.)GetMethodThunk("OnCollisionEnter2D", 1);
|
|
||||||
_onCollisionLeave2D = (.)GetMethodThunk("OnCollisionLeave2D", 1);
|
|
||||||
|
|
||||||
_onCollisionEnter2DMethod = GetMethod("OnCollisionEnter2D", 1);
|
_onCollisionEnter2DMethod = GetMethod("OnCollisionEnter2D", 1);
|
||||||
_onCollisionLeave2DMethod = GetMethod("OnCollisionLeave2D", 1);
|
_onCollisionLeave2DMethod = GetMethod("OnCollisionLeave2D", 1);
|
||||||
|
|
||||||
@@ -392,32 +176,22 @@ class ScriptClass : SharpClass
|
|||||||
{
|
{
|
||||||
exception = null;
|
exception = null;
|
||||||
|
|
||||||
// TODO: use method thunk
|
if (_onCollisionEnter2D != null)
|
||||||
if (_onCollisionEnter2DMethod != null)
|
|
||||||
{
|
{
|
||||||
#unwarn
|
MonoObject* monoObject = ScriptEngine.Classes.Collision2D.BoxValue(collision);
|
||||||
void*[1] args = .(&collision);
|
_onCollisionEnter2D(instance, monoObject, &exception);
|
||||||
|
|
||||||
Invoke(_onCollisionEnter2DMethod, instance, (.)&args);
|
|
||||||
}
|
}
|
||||||
// if (_onCollisionEnter2D != null)
|
|
||||||
// _onCollisionEnter2D(instance, collision, &exception);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnCollisionLeave2D(MonoObject* instance, Collision2D collision, out MonoException* exception)
|
public void OnCollisionLeave2D(MonoObject* instance, Collision2D collision, out MonoException* exception)
|
||||||
{
|
{
|
||||||
exception = null;
|
exception = null;
|
||||||
|
|
||||||
// TODO: use method thunk
|
if (_onCollisionEnter2D != null)
|
||||||
if (_onCollisionLeave2DMethod != null)
|
|
||||||
{
|
{
|
||||||
#unwarn
|
MonoObject* monoObject = ScriptEngine.Classes.Collision2D.BoxValue(collision);
|
||||||
void*[1] args = .(&collision);
|
_onCollisionLeave2D(instance, monoObject, &exception);
|
||||||
|
|
||||||
Invoke(_onCollisionLeave2DMethod, instance, (.)&args);
|
|
||||||
}
|
}
|
||||||
// if (_onCollisionEnter2D != null)
|
|
||||||
// _onCollisionEnter2D(instance, collision, &exception);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonoObject* CreateInstance(UUID uuid, out MonoException* exception)
|
public MonoObject* CreateInstance(UUID uuid, out MonoException* exception)
|
||||||
@@ -505,4 +279,14 @@ class ScriptClass : SharpClass
|
|||||||
{
|
{
|
||||||
Mono.mono_field_set_value(instance, field, value);
|
Mono.mono_field_set_value(instance, field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MonoObject* BoxValue<T>(in T value)
|
||||||
|
{
|
||||||
|
return Mono.mono_value_box(ScriptEngine.[Friend]s_AppDomain, _monoClass, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonoObject* BoxValue(void* value)
|
||||||
|
{
|
||||||
|
return Mono.mono_value_box(ScriptEngine.[Friend]s_AppDomain, _monoClass, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,45 +12,10 @@ namespace GlitchyEngine.Scripting;
|
|||||||
|
|
||||||
using internal GlitchyEngine.Scripting;
|
using internal GlitchyEngine.Scripting;
|
||||||
|
|
||||||
static sealed class ScriptEngineHelper
|
|
||||||
{
|
|
||||||
private static Dictionary<StringView, ScriptFieldType> _scriptFieldTypes = new Dictionary<StringView, ScriptFieldType>()
|
|
||||||
{
|
|
||||||
("System.String", .String),
|
|
||||||
|
|
||||||
("System.Boolean", .Bool),
|
|
||||||
("System.Char", .Char),
|
|
||||||
|
|
||||||
("System.SByte", .SByte),
|
|
||||||
("System.Int16", .Short),
|
|
||||||
("System.Int32", .Int),
|
|
||||||
("System.Int64", .Long),
|
|
||||||
|
|
||||||
("System.Byte", .Byte),
|
|
||||||
("System.UInt16", .UShort),
|
|
||||||
("System.UInt32", .UInt),
|
|
||||||
("System.UInt64", .ULong),
|
|
||||||
|
|
||||||
("System.Single", .Float),
|
|
||||||
("GlitchyEngine.Math.float2", .float2),
|
|
||||||
("GlitchyEngine.Math.float3", .float3),
|
|
||||||
("GlitchyEngine.Math.float4", .float4),
|
|
||||||
|
|
||||||
("System.Double", .Double),
|
|
||||||
|
|
||||||
("GlitchyEngine.Entity", .Entity),
|
|
||||||
} ~ delete _;
|
|
||||||
|
|
||||||
public static ScriptFieldType GetScriptFieldType(MonoType* monoType)
|
|
||||||
{
|
|
||||||
StringView typeName = StringView(Mono.mono_type_get_name(monoType));
|
|
||||||
|
|
||||||
return _scriptFieldTypes.TryGetValue(typeName, .. let scriptFieldType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EngineClasses
|
class EngineClasses
|
||||||
{
|
{
|
||||||
|
// TODO: Not all of there are actually ScriptClasses (actually none of them are...)
|
||||||
|
|
||||||
private ScriptClass s_ComponentRoot ~ _?.ReleaseRef();
|
private ScriptClass s_ComponentRoot ~ _?.ReleaseRef();
|
||||||
private ScriptClass s_EntityRoot ~ _?.ReleaseRef();
|
private ScriptClass s_EntityRoot ~ _?.ReleaseRef();
|
||||||
private ScriptClass s_EngineObject ~ _?.ReleaseRef();
|
private ScriptClass s_EngineObject ~ _?.ReleaseRef();
|
||||||
@@ -60,6 +25,8 @@ class EngineClasses
|
|||||||
private ScriptClass s_EntitySerializer ~ _?.ReleaseRef();
|
private ScriptClass s_EntitySerializer ~ _?.ReleaseRef();
|
||||||
private ScriptClass s_SerializationContext ~ _?.ReleaseRef();
|
private ScriptClass s_SerializationContext ~ _?.ReleaseRef();
|
||||||
|
|
||||||
|
private ScriptClass s_Collision2D ~ _?.ReleaseRef();
|
||||||
|
|
||||||
public ScriptClass ComponentRoot => s_ComponentRoot;
|
public ScriptClass ComponentRoot => s_ComponentRoot;
|
||||||
public ScriptClass EntityRoot => s_EntityRoot;
|
public ScriptClass EntityRoot => s_EntityRoot;
|
||||||
public ScriptClass EngineObject => s_EngineObject;
|
public ScriptClass EngineObject => s_EngineObject;
|
||||||
@@ -67,7 +34,8 @@ class EngineClasses
|
|||||||
public ScriptClass EntityEditor => s_EntityEditor;
|
public ScriptClass EntityEditor => s_EntityEditor;
|
||||||
|
|
||||||
public ScriptClass EntitySerializer => s_EntitySerializer;
|
public ScriptClass EntitySerializer => s_EntitySerializer;
|
||||||
//public ScriptClass SerializationContext => s_SerializationContext;
|
|
||||||
|
public ScriptClass Collision2D => s_Collision2D;
|
||||||
|
|
||||||
internal void ReleaseAndNullify()
|
internal void ReleaseAndNullify()
|
||||||
{
|
{
|
||||||
@@ -79,6 +47,8 @@ class EngineClasses
|
|||||||
|
|
||||||
ReleaseRefAndNullify!(s_EntitySerializer);
|
ReleaseRefAndNullify!(s_EntitySerializer);
|
||||||
ReleaseRefAndNullify!(s_SerializationContext);
|
ReleaseRefAndNullify!(s_SerializationContext);
|
||||||
|
|
||||||
|
ReleaseRefAndNullify!(s_Collision2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LoadClasses(MonoImage* image)
|
internal void LoadClasses(MonoImage* image)
|
||||||
@@ -93,7 +63,8 @@ class EngineClasses
|
|||||||
s_EntityEditor = new ScriptClass("GlitchyEngine.Editor", "EntityEditor", image, .Class);
|
s_EntityEditor = new ScriptClass("GlitchyEngine.Editor", "EntityEditor", image, .Class);
|
||||||
|
|
||||||
s_EntitySerializer = new ScriptClass("GlitchyEngine.Serialization", "EntitySerializer", image, .Class);
|
s_EntitySerializer = new ScriptClass("GlitchyEngine.Serialization", "EntitySerializer", image, .Class);
|
||||||
//s_SerializationContext = new ScriptClass("GlitchyEngine.Serialization", "EntitySerializer.SerializationContext", image, .Class);
|
|
||||||
|
s_Collision2D = new ScriptClass("GlitchyEngine.Physics", "Collision2D", image, .Struct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,11 +235,6 @@ static class ScriptEngine
|
|||||||
String directory = scope .();
|
String directory = scope .();
|
||||||
Path.GetDirectoryPath(_appAssemblyPath, directory);
|
Path.GetDirectoryPath(_appAssemblyPath, directory);
|
||||||
|
|
||||||
/*if (_userAssemblyWatcher != null) // _userAssemblyWatcher.Directory != directory
|
|
||||||
{
|
|
||||||
delete _userAssemblyWatcher;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
String fileName = scope .("*/");
|
String fileName = scope .("*/");
|
||||||
Path.GetFileName(_appAssemblyPath, fileName);
|
Path.GetFileName(_appAssemblyPath, fileName);
|
||||||
|
|
||||||
@@ -336,8 +302,6 @@ static class ScriptEngine
|
|||||||
/// Starts the script runtime and sets the context scene.
|
/// Starts the script runtime and sets the context scene.
|
||||||
public static void StartRuntime(Scene context)
|
public static void StartRuntime(Scene context)
|
||||||
{
|
{
|
||||||
/// At the moment only set the context.
|
|
||||||
|
|
||||||
Debug.Assert(s_Context == null, "StartRuntime was called twice without StopRuntime in between!");
|
Debug.Assert(s_Context == null, "StartRuntime was called twice without StopRuntime in between!");
|
||||||
Context = context;
|
Context = context;
|
||||||
|
|
||||||
@@ -416,117 +380,6 @@ static class ScriptEngine
|
|||||||
_entityScriptInstances.Remove(entityId);
|
_entityScriptInstances.Remove(entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an instance that can be used as a reference to the entity with the given ID in Scripts
|
|
||||||
private static MonoObject* GetOrCreateScriptReferenceInstance(UUID entityId)
|
|
||||||
{
|
|
||||||
MonoObject* referencedEntity = GetManagedInstance(entityId);
|
|
||||||
|
|
||||||
if (referencedEntity == null)
|
|
||||||
{
|
|
||||||
referencedEntity = Classes.EntityRoot.CreateInstance(entityId, let exception);
|
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException(exception, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return referencedEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates an instance of the given component class referencing the specified entity instance.
|
|
||||||
private static MonoObject* CreateComponentReferenceInstance(ScriptClass componentClass, UUID id)//MonoObject* entityReferenceInstance)
|
|
||||||
{
|
|
||||||
MonoObject* componentInstance = componentClass.CreateInstance();
|
|
||||||
|
|
||||||
MonoClassField* idField = Mono.mono_class_get_field_from_name(componentClass.[Friend]_monoClass, "_uuid");
|
|
||||||
|
|
||||||
Classes.ComponentRoot.SetFieldValue<UUID>(componentInstance, idField, id);
|
|
||||||
|
|
||||||
/*// TODO: We could cache the property, but this might be fine
|
|
||||||
MonoProperty* entityProperty = Mono.mono_class_get_property_from_name(componentClass.[Friend]_monoClass, "Entity");
|
|
||||||
|
|
||||||
MonoObject* exception = null;
|
|
||||||
|
|
||||||
//#unwarn
|
|
||||||
//Mono.mono_property_set_value(entityProperty, componentInstance, (void**)&entityReferenceInstance, &exception);
|
|
||||||
#unwarn
|
|
||||||
Mono.mono_property_set_value(entityProperty, componentInstance, (void**)&id, &exception);
|
|
||||||
|
|
||||||
if (exception != null)
|
|
||||||
ScriptEngine.HandleMonoException((MonoException*)exception, null);*/
|
|
||||||
|
|
||||||
return componentInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CopyFieldsToInstance(ScriptComponent* targetScript, ScriptComponent* sourceScript, Dictionary<UUID, UUID> sourceIdToTargetId)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileFunction!();
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(targetScript.Instance.ScriptClass == sourceScript.Instance.ScriptClass);
|
|
||||||
|
|
||||||
for (let (name, scriptField) in sourceScript.Instance.ScriptClass.Fields)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileScope!("Copy Field");
|
|
||||||
|
|
||||||
targetScript.Instance.CopyFieldValue(scriptField, sourceScript.Instance);
|
|
||||||
switch (scriptField.FieldType)
|
|
||||||
{
|
|
||||||
case .Entity:
|
|
||||||
let sourceEntityReference = sourceScript.Instance.GetFieldValue<MonoObject*>(scriptField);
|
|
||||||
|
|
||||||
MonoObject* referencedEntity = sourceEntityReference;
|
|
||||||
|
|
||||||
if (sourceEntityReference != null)
|
|
||||||
{
|
|
||||||
let idField = Mono.mono_class_get_field_from_name(Classes.EntityRoot._monoClass, "_uuid");
|
|
||||||
UUID sourceId = Classes.EntityRoot.GetFieldValue<UUID>(sourceEntityReference, idField);
|
|
||||||
|
|
||||||
// Check if we need to translate, copy otherwise
|
|
||||||
if (sourceIdToTargetId.TryGetValue(sourceId, let referencedId))
|
|
||||||
{
|
|
||||||
// On the C# side we actually differentiate between an Entity and the Script
|
|
||||||
// in the sense that getting an entity and a script yields two different results (one creates a new Entity-Class instance, the other returns the actual instance).
|
|
||||||
// But here its just easier to always use the script instance.
|
|
||||||
// Obviously breaks once we support multiple scripts per entity.
|
|
||||||
referencedEntity = GetOrCreateScriptReferenceInstance(referencedId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
targetScript.Instance.SetFieldValue(scriptField, referencedEntity);
|
|
||||||
case .Component:
|
|
||||||
|
|
||||||
let sourceComponentReference = sourceScript.Instance.GetFieldValue<MonoObject*>(scriptField);
|
|
||||||
|
|
||||||
MonoObject* componentInstance = sourceComponentReference;
|
|
||||||
|
|
||||||
// Get or create entity reference
|
|
||||||
if (sourceComponentReference != null)
|
|
||||||
{
|
|
||||||
let idField = Mono.mono_class_get_field_from_name(Classes.EngineObject._monoClass, "_uuid");
|
|
||||||
UUID sourceId = Classes.EntityRoot.GetFieldValue<UUID>(sourceComponentReference, idField);
|
|
||||||
|
|
||||||
MonoType* fieldMonoType = scriptField.GetMonoType();
|
|
||||||
|
|
||||||
SharpType componentType = ScriptEngine.GetSharpType(fieldMonoType);
|
|
||||||
|
|
||||||
var componentClass = ComponentClasses[componentType.FullName];
|
|
||||||
|
|
||||||
if (sourceIdToTargetId.TryGetValue(sourceId, let targetId))
|
|
||||||
{
|
|
||||||
// Create reference for translated id
|
|
||||||
componentInstance = CreateComponentReferenceInstance(componentClass, targetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentType.ReleaseRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
targetScript.Instance.SetFieldValue(scriptField, componentInstance);
|
|
||||||
|
|
||||||
default:
|
|
||||||
targetScript.Instance.CopyFieldValue(scriptField, sourceScript.Instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MonoAssembly* LoadCSharpAssembly(StringView assemblyPath, bool loadPDB = false)
|
private static MonoAssembly* LoadCSharpAssembly(StringView assemblyPath, bool loadPDB = false)
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileFunction!();
|
Debug.Profiler.ProfileFunction!();
|
||||||
@@ -728,78 +581,6 @@ static class ScriptEngine
|
|||||||
_sharpClasses.Add(sharpType.FullName, sharpType..AddRef());
|
_sharpClasses.Add(sharpType.FullName, sharpType..AddRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static SharpType GetSharpType(MonoType* monoType)
|
|
||||||
{
|
|
||||||
StringView typeName = StringView(Mono.mono_type_get_name(monoType));
|
|
||||||
|
|
||||||
if (_sharpClasses.TryGetValue(typeName, let sharpType))
|
|
||||||
return sharpType..AddRef();
|
|
||||||
|
|
||||||
Mono.MonoTypeEnum fieldType = Mono.Mono.mono_type_get_type(monoType);
|
|
||||||
|
|
||||||
MonoClass* monoClass = Mono.mono_class_from_mono_type(monoType);
|
|
||||||
|
|
||||||
if (monoClass == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
StringView className = StringView(Mono.mono_class_get_name(monoClass));
|
|
||||||
StringView classNamespace = StringView(Mono.mono_class_get_namespace(monoClass));
|
|
||||||
|
|
||||||
// TODO: at the moment only allow user-structs
|
|
||||||
//if (classNamespace.StartsWith("GlitchyEngine"))
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
ScriptFieldType scriptType = .None;
|
|
||||||
|
|
||||||
if (Mono.mono_class_is_enum(monoClass))
|
|
||||||
{
|
|
||||||
scriptType = .Enum;
|
|
||||||
|
|
||||||
return new SharpEnum(classNamespace, className, Mono.mono_class_get_image(monoClass));
|
|
||||||
}
|
|
||||||
else if (fieldType == .Class)
|
|
||||||
{
|
|
||||||
if (Mono.mono_class_is_subclass_of(monoClass, Classes.EntityRoot._monoClass, false))
|
|
||||||
{
|
|
||||||
scriptType = .Entity;
|
|
||||||
}
|
|
||||||
else if (Mono.mono_class_is_subclass_of(monoClass, Classes.ComponentRoot._monoClass, false))
|
|
||||||
{
|
|
||||||
scriptType = .Component;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scriptType = .Class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fieldType == .Valuetype)
|
|
||||||
{
|
|
||||||
scriptType = .Struct;
|
|
||||||
}
|
|
||||||
// TODO! ?!
|
|
||||||
else if (fieldType == .Genericinst)
|
|
||||||
{
|
|
||||||
scriptType = .GenericClass;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
//return new SharpClass(monoClass, scriptType);
|
|
||||||
}
|
|
||||||
else if (fieldType == .SzArray)
|
|
||||||
{
|
|
||||||
scriptType = .Array;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else if (fieldType == .Object)
|
|
||||||
{
|
|
||||||
// TODO: Help
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(scriptType != .None);
|
|
||||||
|
|
||||||
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the script instance or null.
|
/// Returns the script instance or null.
|
||||||
public static MonoObject* GetManagedInstance(UUID entityId)
|
public static MonoObject* GetManagedInstance(UUID entityId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,100 +9,8 @@ enum ScriptFieldType
|
|||||||
case None;
|
case None;
|
||||||
|
|
||||||
case Class;
|
case Class;
|
||||||
case Enum;
|
|
||||||
case Struct;
|
case Struct;
|
||||||
|
|
||||||
case GenericClass;
|
|
||||||
case Array;
|
|
||||||
|
|
||||||
case String;
|
|
||||||
|
|
||||||
case Bool, Bool2, Bool3, Bool4;
|
|
||||||
case Char;
|
|
||||||
|
|
||||||
case SByte;
|
|
||||||
case Short;
|
|
||||||
case Int, Int2, Int3, Int4;
|
|
||||||
case Long;
|
|
||||||
case Byte;
|
|
||||||
case UShort;
|
|
||||||
case UInt; // UInt2, UInt3, UInt4;
|
|
||||||
case ULong;
|
|
||||||
|
|
||||||
case Float, float2, float3, float4;
|
|
||||||
case Double, Double2, Double3, Double4;
|
|
||||||
|
|
||||||
case Entity;
|
case Entity;
|
||||||
case Component;
|
case Component;
|
||||||
|
|
||||||
public Type GetBeefType()
|
|
||||||
{
|
|
||||||
switch(this)
|
|
||||||
{
|
|
||||||
case .String:
|
|
||||||
return typeof(String);
|
|
||||||
|
|
||||||
case .Bool:
|
|
||||||
return typeof(bool);
|
|
||||||
case .Bool2:
|
|
||||||
return typeof(bool2);
|
|
||||||
case .Bool3:
|
|
||||||
return typeof(bool3);
|
|
||||||
case .Bool4:
|
|
||||||
return typeof(bool4);
|
|
||||||
|
|
||||||
case .Char:
|
|
||||||
return typeof(char16);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
case .Entity:
|
|
||||||
return typeof(UUID);
|
|
||||||
case .Component:
|
|
||||||
return typeof(UUID);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -116,23 +116,6 @@ class ScriptInstance : RefCounter
|
|||||||
ScriptEngine.HandleMonoException(exception, this);
|
ScriptEngine.HandleMonoException(exception, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetFieldValue<T>(ScriptField field)
|
|
||||||
{
|
|
||||||
return _scriptClass.GetFieldValue<T>(_instance, field.[Friend]_monoField);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetFieldValue<T>(ScriptField field, in T value)
|
|
||||||
{
|
|
||||||
_scriptClass.SetFieldValue<T>(_instance, field.[Friend]_monoField, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyFieldValue(ScriptField field, ScriptInstance sourceInstance)
|
|
||||||
{
|
|
||||||
// TODO: I hate this!
|
|
||||||
var data = sourceInstance.GetFieldValue<uint8[sizeof(GlitchyEngine.Math.Matrix)]>(field);
|
|
||||||
SetFieldValue(field, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new instance of the given component class and initializes it for the current entity.
|
/// Creates a new instance of the given component class and initializes it for the current entity.
|
||||||
public MonoObject* CreateComponentInstance(ScriptClass componentClassType)
|
public MonoObject* CreateComponentInstance(ScriptClass componentClassType)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user