mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
ScriptEngine work and cleanup
This commit is contained in:
@@ -7,9 +7,9 @@ namespace GlitchyEngine.Scripting;
|
||||
|
||||
public struct ScriptFunctionPointers
|
||||
{
|
||||
public function void() OnCreate;
|
||||
public function void(float) OnUpdate;
|
||||
public function void() OnDestroy;
|
||||
public function void(UUID entityId) OnCreate;
|
||||
public function void(UUID entityId, float deltaTime) OnUpdate;
|
||||
public function void(UUID entityId, bool callEntity) OnDestroy;
|
||||
}
|
||||
|
||||
static class CoreClrHelper
|
||||
@@ -39,7 +39,7 @@ static class CoreClrHelper
|
||||
private function void ThrowExceptionFunc(char8* message);
|
||||
static ThrowExceptionFunc _throwException;
|
||||
|
||||
private function void RegisterComponentTypeFunc(StringView fullComponentTypeName, function void(UUID entityId) addComponent, function bool(UUID entityId) hasComponent, function void(UUID entityId) removeComponent);
|
||||
private function void RegisterComponentTypeFunc(char8* fullComponentTypeName, function void(UUID entityId) addComponent, function bool(UUID entityId) hasComponent, function void(UUID entityId) removeComponent);
|
||||
static RegisterComponentTypeFunc _registerComponentType;
|
||||
|
||||
public static ScriptFunctionPointers _entityScriptFunctions;
|
||||
@@ -180,7 +180,8 @@ static class CoreClrHelper
|
||||
return rc;
|
||||
}
|
||||
|
||||
public static int GetFunctionPointerUnmanagedCallersOnly<T>(StringView typeName, StringView methodName, out T outDelegate) where T: operator explicit void*
|
||||
|
||||
public static Result<void, int> GetFunctionPointerUnmanagedCallersOnly<T>(StringView typeName, StringView methodName, out T outDelegate) where T: operator explicit void*
|
||||
{
|
||||
void* funPtr = null;
|
||||
|
||||
@@ -189,7 +190,10 @@ static class CoreClrHelper
|
||||
|
||||
outDelegate = (T)funPtr;
|
||||
|
||||
return rc;
|
||||
if (rc == 0)
|
||||
return .Ok;
|
||||
|
||||
return .Err(rc);
|
||||
}
|
||||
|
||||
public static void ThrowException(StringView message)
|
||||
@@ -199,6 +203,6 @@ static class CoreClrHelper
|
||||
|
||||
public static void RegisterComponent(StringView fullComponentTypeName, function void(UUID entityId) addComponent, function bool(UUID entityId) hasComponent, function void(UUID entityId) removeComponent)
|
||||
{
|
||||
_registerComponentType(fullComponentTypeName, addComponent, hasComponent, removeComponent);
|
||||
_registerComponentType(fullComponentTypeName.Ptr, addComponent, hasComponent, removeComponent);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class EntityEditorWrapper : NewScriptClass
|
||||
private ShowEntityEditorFunc _showEntityEditorFunc;
|
||||
|
||||
[AllowAppend]
|
||||
public this() : base(FullName, .Empty, .None, false)
|
||||
public this() : base("GlitchyEngine.ScriptGlue.ShowEntityEditor", .Empty, .None, false)
|
||||
{
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "ShowEntityEditor", out _showEntityEditorFunc);
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Mono;
|
||||
using GlitchyEngine.Core;
|
||||
using GlitchyEngine.Serialization;
|
||||
|
||||
@@ -7,19 +6,19 @@ namespace GlitchyEngine.Scripting;
|
||||
|
||||
using internal GlitchyEngine.Scripting;
|
||||
|
||||
class EntitySerializerWrapper : ScriptClass
|
||||
class EntitySerializerWrapper : NewScriptClass
|
||||
{
|
||||
function void CreateSerializationContextMethod(void* serializerPtr, MonoException** exception);
|
||||
function void ClearSerializationContextMethod(void* serializerPtr, MonoException** exception);
|
||||
function void DestroySerializationContextMethod(void* serializerPtr, MonoException** exception);
|
||||
function void CreateSerializationContextMethod(void* serializerPtr);
|
||||
//function void ClearSerializationContextMethod(void* serializerPtr);
|
||||
function void DestroySerializationContextMethod(void* serializerPtr);
|
||||
|
||||
function void SerializeMethod(MonoObject* entity, void* serializedObjPtr, void* serializerPtr, MonoException** exception);
|
||||
function void DeserializeMethod(MonoObject* entity, void* serializedObjPtr, void* serializerPtr, MonoException** exception);
|
||||
function void SerializeStaticMethod(MonoReflectionType* type, void* serializedObjPtr, void* serializerPtr, MonoException** exception);
|
||||
function void DeserializeStaticMethod(MonoReflectionType* type, void* serializedObjPtr, void* serializerPtr, MonoException** exception);
|
||||
function void SerializeMethod(UUID entityId, void* serializedObjPtr, void* serializerPtr);
|
||||
function void DeserializeMethod(UUID entityId, void* serializedObjPtr, void* serializerPtr);
|
||||
function void SerializeStaticMethod(char8* fullTypeName, void* serializedObjPtr, void* serializerPtr);
|
||||
function void DeserializeStaticMethod(char8* fullTypeName, void* serializedObjPtr, void* serializerPtr);
|
||||
|
||||
private CreateSerializationContextMethod _createSerializationContextMethod;
|
||||
private ClearSerializationContextMethod _clearSerializationContextMethod;
|
||||
//private ClearSerializationContextMethod _clearSerializationContextMethod;
|
||||
private DestroySerializationContextMethod _destroySerializationContextMethod;
|
||||
|
||||
private SerializeMethod _serializeMethod;
|
||||
@@ -28,70 +27,24 @@ class EntitySerializerWrapper : ScriptClass
|
||||
private DeserializeStaticMethod _deserializeStaticMethod;
|
||||
|
||||
[AllowAppend]
|
||||
public this(StringView classNamespace, StringView className, MonoImage* image) : base(classNamespace, className, image)
|
||||
public this() : base("GlitchyEngine.Serialization.EntitySerializer", .Empty, .None, false)
|
||||
{
|
||||
_serializeMethod = (SerializeMethod)GetMethodThunk("Serialize", 3);
|
||||
|
||||
if (_serializeMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"Serialize\" method.");
|
||||
}
|
||||
|
||||
_deserializeMethod = (DeserializeMethod)GetMethodThunk("Deserialize", 3);
|
||||
|
||||
if (_serializeMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"Deserialize\" method.");
|
||||
}
|
||||
|
||||
_serializeStaticMethod = (SerializeStaticMethod)GetMethodThunk("SerializeStaticFields", 3);
|
||||
|
||||
if (_serializeStaticMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"SerializeStaticStatic\" method.");
|
||||
}
|
||||
|
||||
_deserializeStaticMethod = (SerializeStaticMethod)GetMethodThunk("DeserializeStaticFields", 3);
|
||||
|
||||
if (_deserializeStaticMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"DeserializeStaticStatic\" method.");
|
||||
}
|
||||
|
||||
_createSerializationContextMethod = (CreateSerializationContextMethod)GetMethodThunk("CreateSerializationContext", 1);
|
||||
|
||||
if (_createSerializationContextMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"CreateSerializationContext\" method.");
|
||||
}
|
||||
|
||||
_clearSerializationContextMethod = (ClearSerializationContextMethod)GetMethodThunk("ClearSerializationContext", 1);
|
||||
|
||||
if (_clearSerializationContextMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"ClearSerializationContext\" method.");
|
||||
}
|
||||
|
||||
_destroySerializationContextMethod = (DestroySerializationContextMethod)GetMethodThunk("DestroySerializationContext", 1);
|
||||
|
||||
if (_destroySerializationContextMethod == null)
|
||||
{
|
||||
Log.EngineLogger.Error("EntitySerializer has no \"DestroySerializationContext\" method.");
|
||||
}
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "CreateSerializationContext", out _createSerializationContextMethod);
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "DestroySerializationContext", out _destroySerializationContextMethod);
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "EntitySerializer_Serialize", out _serializeMethod);
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "EntitySerializer_Deserialize", out _deserializeMethod);
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "EntitySerializer_SerializeStaticFields", out _serializeStaticMethod);
|
||||
CoreClrHelper.GetFunctionPointerUnmanagedCallersOnly("GlitchyEngine.ScriptGlue, ScriptCore", "EntitySerializer_DeserializeStaticFields", out _deserializeStaticMethod);
|
||||
}
|
||||
|
||||
public void CreateSerializationContext(ScriptInstanceSerializer serializer)
|
||||
{
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializer);
|
||||
|
||||
MonoException* exception = null;
|
||||
_createSerializationContextMethod(serializerPtr, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, null);
|
||||
_createSerializationContextMethod(serializerPtr);
|
||||
}
|
||||
|
||||
public void ClearSerializationContext(ScriptInstanceSerializer serializer)
|
||||
/*public void ClearSerializationContext(ScriptInstanceSerializer serializer)
|
||||
{
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializer);
|
||||
|
||||
@@ -100,70 +53,44 @@ class EntitySerializerWrapper : ScriptClass
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, null);
|
||||
}
|
||||
}*/
|
||||
|
||||
public void DestroySerializationContext(ScriptInstanceSerializer serializer)
|
||||
{
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializer);
|
||||
|
||||
MonoException* exception = null;
|
||||
_destroySerializationContextMethod(serializerPtr, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, null);
|
||||
_destroySerializationContextMethod(serializerPtr);
|
||||
}
|
||||
|
||||
public void Serialize(ScriptInstance instance, SerializedObject serializedObject)
|
||||
public void Serialize(NewScriptInstance instance, SerializedObject serializedObject)
|
||||
{
|
||||
void* serializedObjectPtr = Internal.UnsafeCastToPtr(serializedObject);
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializedObject.Serializer);
|
||||
|
||||
MonoException* exception = null;
|
||||
_serializeMethod(instance.[Friend]_instance, serializedObjectPtr, serializerPtr, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, instance);
|
||||
_serializeMethod(instance.EntityId, serializedObjectPtr, serializerPtr);
|
||||
}
|
||||
|
||||
public void SerializeStatic(ScriptClass @class, SerializedObject serializedObject)
|
||||
public void SerializeStatic(NewScriptClass @class, SerializedObject serializedObject)
|
||||
{
|
||||
void* serializedObjectPtr = Internal.UnsafeCastToPtr(serializedObject);
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializedObject.Serializer);
|
||||
|
||||
MonoType* type = Mono.mono_class_get_type(@class.[Friend]_monoClass);
|
||||
MonoReflectionType* reflectionType = Mono.mono_type_get_object(ScriptEngine.[Friend]s_AppDomain, type);
|
||||
|
||||
MonoException* exception = null;
|
||||
_serializeStaticMethod(reflectionType, serializedObjectPtr, serializerPtr, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, null);
|
||||
_serializeStaticMethod(@class.FullName.CStr(), serializedObjectPtr, serializerPtr);
|
||||
}
|
||||
|
||||
public void Deserialize(ScriptInstance instance, SerializedObject serializedObject)
|
||||
public void Deserialize(NewScriptInstance instance, SerializedObject serializedObject)
|
||||
{
|
||||
void* serializedObjectPtr = Internal.UnsafeCastToPtr(serializedObject);
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializedObject.Serializer);
|
||||
|
||||
MonoException* exception = null;
|
||||
_deserializeMethod(instance.[Friend]_instance, serializedObjectPtr, serializerPtr, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, instance);
|
||||
_deserializeMethod(instance.EntityId, serializedObjectPtr, serializerPtr);
|
||||
}
|
||||
|
||||
public void DeserializeStatic(ScriptClass @class, SerializedObject serializedObject)
|
||||
public void DeserializeStatic(NewScriptClass @class, SerializedObject serializedObject)
|
||||
{
|
||||
void* serializedObjectPtr = Internal.UnsafeCastToPtr(serializedObject);
|
||||
void* serializerPtr = Internal.UnsafeCastToPtr(serializedObject.Serializer);
|
||||
|
||||
MonoType* type = Mono.mono_class_get_type(@class.[Friend]_monoClass);
|
||||
MonoReflectionType* reflectionType = Mono.mono_type_get_object(ScriptEngine.[Friend]s_AppDomain, type);
|
||||
|
||||
MonoException* exception = null;
|
||||
_deserializeStaticMethod(reflectionType, serializedObjectPtr, serializerPtr, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.[Friend]HandleMonoException(exception, null);
|
||||
_deserializeStaticMethod(@class.FullName.CStr(), serializedObjectPtr, serializerPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,13 +72,13 @@ class NewScriptInstance : RefCounter
|
||||
public void InvokeOnCreate()
|
||||
{
|
||||
if (_scriptClass.Methods.HasFlag(.OnCreate))
|
||||
CoreClrHelper._entityScriptFunctions.OnCreate();
|
||||
CoreClrHelper._entityScriptFunctions.OnCreate(_entityId);
|
||||
}
|
||||
|
||||
public void InvokeOnUpdate(float deltaTime)
|
||||
{
|
||||
if (_scriptClass.Methods.HasFlag(.OnUpdate))
|
||||
CoreClrHelper._entityScriptFunctions.OnUpdate(deltaTime);
|
||||
CoreClrHelper._entityScriptFunctions.OnUpdate(_entityId, deltaTime);
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
@@ -86,10 +86,11 @@ class NewScriptInstance : RefCounter
|
||||
if (!IsInitialized)
|
||||
return;
|
||||
|
||||
if (_scriptClass.Methods.HasFlag(.OnDestroy) && (ScriptEngine.ApplicationInfo.IsInPlayMode || ScriptClass.RunInEditMode))
|
||||
/*if (_scriptClass.Methods.HasFlag(.OnDestroy) && (ScriptEngine.ApplicationInfo.IsInPlayMode || ScriptClass.RunInEditMode))
|
||||
{
|
||||
CoreClrHelper._entityScriptFunctions.OnDestroy();
|
||||
}
|
||||
}*/
|
||||
CoreClrHelper._entityScriptFunctions.OnDestroy(_entityId, (ScriptEngine.ApplicationInfo.IsInPlayMode || ScriptClass.RunInEditMode));
|
||||
|
||||
IsInitialized = false;
|
||||
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
using Mono;
|
||||
using System;
|
||||
using GlitchyEngine.Core;
|
||||
using System.Collections;
|
||||
using GlitchyEngine.Scripting.Classes;
|
||||
|
||||
namespace GlitchyEngine.Scripting;
|
||||
|
||||
using internal GlitchyEngine.Scripting;
|
||||
|
||||
class SharpClass : RefCounter
|
||||
{
|
||||
protected String _fullName ~ delete _; // TODO APPEND
|
||||
|
||||
protected StringView _namespace;
|
||||
protected StringView _className;
|
||||
|
||||
protected internal MonoClass* _monoClass;
|
||||
|
||||
public StringView Namespace => _namespace;
|
||||
public StringView ClassName => _className;
|
||||
public StringView FullName => _fullName;
|
||||
|
||||
[AllowAppend]
|
||||
public this(StringView classNamespace, StringView className, MonoImage* image)
|
||||
{
|
||||
// TODO APPEND
|
||||
String fullName = new String(classNamespace.Length + 1 + className.Length);
|
||||
//append $"{classNamespace}.{className}";
|
||||
fullName.AppendF($"{classNamespace}.{className}");
|
||||
|
||||
_fullName = fullName;
|
||||
_namespace = _fullName.Substring(0, classNamespace.Length);
|
||||
_className = _fullName.Substring(classNamespace.Length + 1);
|
||||
|
||||
_monoClass = Mono.mono_class_from_name(image, _namespace.ToScopeCStr!(), _className.ToScopeCStr!());
|
||||
|
||||
Log.EngineLogger.AssertDebug(_monoClass != null);
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptClass : SharpClass
|
||||
{
|
||||
typealias OnCreateMethod = function MonoObject*(MonoObject* instance, MonoException** exception);
|
||||
typealias OnUpdateMethod = function MonoObject*(MonoObject* instance, float deltaTime, MonoException** exception);
|
||||
typealias OnDestroyMethod = function MonoObject*(MonoObject* instance, MonoException** exception);
|
||||
|
||||
private bool _runInEditMode;
|
||||
|
||||
private MonoMethod* _constructor;
|
||||
|
||||
private OnCreateMethod _onCreate;
|
||||
private OnUpdateMethod _onUpdate;
|
||||
private OnDestroyMethod _onDestroy;
|
||||
|
||||
private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, MonoObject* collision2d, MonoException** exception) _onCollisionEnter2D;
|
||||
private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, MonoObject* collision2d, MonoException** exception) _onCollisionLeave2D;
|
||||
|
||||
public bool HasCollisionEnter2D => _onCollisionEnter2D != null;
|
||||
public bool HasCollisionLeave2D => _onCollisionLeave2D != null;
|
||||
|
||||
public bool RunInEditMode => _runInEditMode;
|
||||
|
||||
[AllowAppend]
|
||||
public this(StringView classNamespace, StringView className, MonoImage* image) :
|
||||
base(classNamespace, className, image)
|
||||
{
|
||||
_constructor = FindConstructor();
|
||||
_onCreate = (OnCreateMethod)GetMethodThunk("OnCreate");
|
||||
_onUpdate = (OnUpdateMethod)GetMethodThunk("OnUpdate", 1);
|
||||
_onDestroy = (OnDestroyMethod)GetMethodThunk("OnDestroy");
|
||||
_onCollisionEnter2D = (.)GetMethodThunk("OnCollisionEnter2D", 1);
|
||||
_onCollisionLeave2D = (.)GetMethodThunk("OnCollisionLeave2D", 1);
|
||||
|
||||
DetermineRunInEditMode();
|
||||
}
|
||||
|
||||
/// Determines whether or not scripts of this class will be executed in edit mode.
|
||||
private void DetermineRunInEditMode()
|
||||
{
|
||||
// TODO: This is only relevant for the editor!
|
||||
MonoCustomAttrInfo* attributes = Mono.mono_custom_attrs_from_class(_monoClass);
|
||||
|
||||
//if (attributes != null && ScriptEngine.Classes.RunInEditModeAttribute != null)
|
||||
// _runInEditMode = Mono.mono_custom_attrs_has_attr(attributes, ScriptEngine.Classes.RunInEditModeAttribute._monoClass);
|
||||
}
|
||||
|
||||
private MonoMethod* FindConstructor()
|
||||
{
|
||||
MonoMethod* constructor = null;
|
||||
|
||||
MonoMethodDesc* constructorDesc = Mono.mono_method_desc_new(":.ctor(GlitchyEngine.Core.UUID)", true);
|
||||
|
||||
// Entities usually don't have a constructor that takes the UUID, so we have to look for it in the parents.
|
||||
for (MonoClass* @class = _monoClass; @class != null; @class = Mono.mono_class_get_parent(@class))
|
||||
{
|
||||
constructor = Mono.mono_method_desc_search_in_class(constructorDesc, @class);
|
||||
|
||||
if (constructor != null)
|
||||
break;
|
||||
}
|
||||
|
||||
Mono.mono_method_desc_free(constructorDesc);
|
||||
|
||||
return constructor;
|
||||
}
|
||||
|
||||
private void CallConstructorChain(MonoObject* instance, UUID uuid, out MonoException* exception)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
if (_constructor == null)
|
||||
return;
|
||||
|
||||
#unwarn
|
||||
void*[1] args = void*[](&uuid);
|
||||
|
||||
Mono.mono_runtime_invoke(_constructor, instance, &args, (.)&exception);
|
||||
}
|
||||
|
||||
public void OnCreate(MonoObject* instance, out MonoException* exception)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
if (_onCreate != null)
|
||||
_onCreate(instance, &exception);
|
||||
}
|
||||
|
||||
public void OnUpdate(MonoObject* instance, float deltaTime, out MonoException* exception)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
if (_onUpdate != null)
|
||||
_onUpdate(instance, deltaTime, &exception);
|
||||
}
|
||||
|
||||
public void OnDestroy(MonoObject* instance, out MonoException* exception)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
if (_onDestroy != null)
|
||||
_onDestroy(instance, &exception);
|
||||
}
|
||||
|
||||
public void OnCollisionEnter2D(MonoObject* instance, Collision2D collision, out MonoException* exception)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
if (_onCollisionEnter2D != null)
|
||||
{
|
||||
//MonoObject* monoObject = ScriptEngine.Classes.Collision2D.BoxValue(collision);
|
||||
//_onCollisionEnter2D(instance, monoObject, &exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCollisionLeave2D(MonoObject* instance, Collision2D collision, out MonoException* exception)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
if (_onCollisionEnter2D != null)
|
||||
{
|
||||
//MonoObject* monoObject = ScriptEngine.Classes.Collision2D.BoxValue(collision);
|
||||
//_onCollisionLeave2D(instance, monoObject, &exception);
|
||||
}
|
||||
}
|
||||
|
||||
public MonoObject* CreateInstance(UUID uuid, out MonoException* exception)
|
||||
{
|
||||
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
||||
|
||||
// Invoke empty constructor to initialize fields with default values specified in the script itself
|
||||
Mono.mono_runtime_object_init(instance);
|
||||
|
||||
// Invoke UUID Constructors:
|
||||
CallConstructorChain(instance, uuid, out exception);
|
||||
|
||||
// Invoke constructor with UUID
|
||||
//#unwarn
|
||||
//ScriptEngine.[Friend]s_EngineObject.Invoke(ScriptEngine.[Friend]s_EngineObject._constructor, instance, out exception, &uuid);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MonoObject* CreateInstance()
|
||||
{
|
||||
MonoObject* instance = Mono.mono_object_new(ScriptEngine.[Friend]s_AppDomain, _monoClass);
|
||||
|
||||
// Invoke empty constructor to fill fields
|
||||
Mono.mono_runtime_object_init(instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MonoMethod* GetMethod(StringView name, int argCount = 0)
|
||||
{
|
||||
return Mono.mono_class_get_method_from_name(_monoClass, name.ToScopeCStr!(), argCount);
|
||||
}
|
||||
|
||||
public void* GetMethodThunk(StringView name, int argCount = 0)
|
||||
{
|
||||
MonoMethod* method = GetMethod(name, argCount);
|
||||
|
||||
if (method == null)
|
||||
return null;
|
||||
|
||||
return Mono.mono_method_get_unmanaged_thunk(method);
|
||||
}
|
||||
|
||||
public MonoObject* Invoke(MonoMethod* method, MonoObject* instance, void** args = null)
|
||||
{
|
||||
MonoObject* exception = null;
|
||||
|
||||
MonoObject* result = Mono.mono_runtime_invoke(method, instance, args, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException((MonoException*)exception);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public MonoObject* Invoke(MonoMethod* method, MonoObject* instance, out MonoException* exception, params void*[] args)
|
||||
{
|
||||
exception = null;
|
||||
|
||||
MonoObject* result = Mono.mono_runtime_invoke(method, instance, args.Ptr, (.)&exception);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public T Invoke<T>(MonoMethod* method, MonoObject* instance, params void*[] args)
|
||||
{
|
||||
MonoObject* object = Invoke(method, instance, args.Ptr);
|
||||
return *(T*)Mono.mono_object_unbox(object);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using Mono;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
@@ -54,7 +53,7 @@ class EngineClasses
|
||||
|
||||
DeleteAndNullify!(s_EntityEditor);
|
||||
|
||||
ReleaseRefAndNullify!(s_EntitySerializer);
|
||||
DeleteAndNullify!(s_EntitySerializer);
|
||||
//ReleaseRefAndNullify!(s_SerializationContext);
|
||||
|
||||
DeleteAndNullify!(s_Collision2D);
|
||||
@@ -73,7 +72,7 @@ class EngineClasses
|
||||
// Editor classes
|
||||
s_EntityEditor = new EntityEditorWrapper();
|
||||
|
||||
//s_EntitySerializer = new EntitySerializerWrapper("GlitchyEngine.Serialization", "EntitySerializer");
|
||||
s_EntitySerializer = new EntitySerializerWrapper();
|
||||
|
||||
s_Collision2D = new NewScriptClass("GlitchyEngine.Physics.Collision2D", .Empty, .None);
|
||||
|
||||
@@ -84,15 +83,6 @@ class EngineClasses
|
||||
|
||||
static class ScriptEngine
|
||||
{
|
||||
private static MonoDomain* s_RootDomain;
|
||||
private static MonoDomain* s_AppDomain;
|
||||
|
||||
private static MonoAssembly* s_CoreAssembly;
|
||||
private static MonoImage* s_CoreAssemblyImage;
|
||||
|
||||
private static MonoAssembly* s_AppAssembly;
|
||||
private static MonoImage* s_AppAssemblyImage;
|
||||
|
||||
private static Scene s_Context ~ _?.ReleaseRef();
|
||||
|
||||
private static EngineClasses _classes = new .() ~ delete _;
|
||||
@@ -286,9 +276,12 @@ static class ScriptEngine
|
||||
static void LoadScriptAssemblies()
|
||||
{
|
||||
Debug.Profiler.ProfileFunction!();
|
||||
|
||||
// TODO: We should probably verify, that all required types actually exist.
|
||||
Classes.LoadClasses();
|
||||
|
||||
ScriptGlue.Init();
|
||||
|
||||
|
||||
// TODO: Check if files exist
|
||||
if (File.Exists(_appAssemblyPath))
|
||||
{
|
||||
@@ -415,9 +408,6 @@ static class ScriptEngine
|
||||
{
|
||||
Debug.Profiler.ProfileFunction!();
|
||||
|
||||
// TODO: We should probably verify, that all required types actually exist.
|
||||
Classes.LoadClasses();
|
||||
|
||||
CoreClrHelper.GetScriptClasses(let data, let entryCount);
|
||||
|
||||
Span<ScriptClassInfo> scriptClasses = .((.)data, entryCount);
|
||||
@@ -459,8 +449,7 @@ static class ScriptEngine
|
||||
{
|
||||
Debug.Profiler.ProfileScope!("Initialize Instances");
|
||||
|
||||
Log.EngineLogger.Error("Recreating and copying instances (ReloadAssemblies) not updated yet.");
|
||||
/*// We need to create a new instance for every entity
|
||||
// We need to create a new instance for every entity
|
||||
for (let (id, scriptInstance) in _entityScriptInstances)
|
||||
{
|
||||
if (Context.GetEntityByID(id) case .Ok(let entity))
|
||||
@@ -472,7 +461,7 @@ static class ScriptEngine
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(false, "Entities script was just serialized but the entity doesn't exist anymore.");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
contextSerializer.DeserializeScriptInstances();
|
||||
@@ -491,8 +480,9 @@ static class ScriptEngine
|
||||
s_RootDomain = null;*/
|
||||
}
|
||||
|
||||
// TODO: Do we still need this? It was only called by ScriptGlue
|
||||
/// Returns the script instance or null.
|
||||
public static MonoObject* GetManagedInstance(UUID entityId)
|
||||
public static void* GetManagedInstance(UUID entityId)
|
||||
{
|
||||
//if (_entityScriptInstances.TryGetValue(entityId, let scriptInstance))
|
||||
// return scriptInstance.MonoInstance;
|
||||
@@ -507,11 +497,6 @@ static class ScriptEngine
|
||||
return scriptClass;
|
||||
}
|
||||
|
||||
internal static void HandleException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal static void LogScriptException(ScriptException exception, UUID entityId)
|
||||
{
|
||||
String entityInfo = scope .();
|
||||
@@ -530,13 +515,8 @@ static class ScriptEngine
|
||||
|
||||
Log.ClientLogger.Error($"Mono Exception \"{exception.FullName}\": \"{exception.Message}\"{entityInfo}\nStackTrace:\n{exception.StackTrace}", exception);
|
||||
}
|
||||
|
||||
// TODO: This can go soon?
|
||||
internal static void HandleMonoException(MonoException* exception, ScriptInstance sourceInstance = null)
|
||||
{
|
||||
//LogScriptException(exception, sourceInstance?.EntityId ?? .Zero);
|
||||
}
|
||||
|
||||
// TODO: Wrap like the other classes
|
||||
public static void ShowScriptEditor(Entity entity, ScriptComponent* scriptComponent)
|
||||
{
|
||||
if (scriptComponent.Instance == null)
|
||||
|
||||
@@ -372,10 +372,6 @@ struct EngineFunctions
|
||||
|
||||
static class ScriptGlue
|
||||
{
|
||||
/*private static Dictionary<MonoType*, function void(Entity entityId)> s_AddComponentMethods = new .() ~ delete _;
|
||||
private static Dictionary<MonoType*, function bool(Entity entityId)> s_HasComponentMethods = new .() ~ delete _;
|
||||
private static Dictionary<MonoType*, function void(Entity entityId)> s_RemoveComponentMethods = new .() ~ delete _;*/
|
||||
|
||||
/* Adding this attribute to a method will log method entry and returned Result<T> errors */
|
||||
[AttributeUsage(.Method)]
|
||||
struct RegisterMethodAttribute : Attribute, IOnMethodInit
|
||||
@@ -408,9 +404,6 @@ static class ScriptGlue
|
||||
|
||||
public static Event<delegate void()> OnRegisterNativeCalls ~ _.Dispose();
|
||||
|
||||
/*private function void SetEngineFunctions(EngineFunctions* engineFunctions);
|
||||
private static SetEngineFunctions _setEngineFunctions;*/
|
||||
|
||||
private function void SetEngineFunctions(EngineFunctions* engineFunctions);
|
||||
private static SetEngineFunctions _setEngineFunctions;
|
||||
|
||||
@@ -423,17 +416,13 @@ static class ScriptGlue
|
||||
|
||||
RegisterCalls();
|
||||
|
||||
//RegisterMathFunctions();
|
||||
RegisterManagedComponents();
|
||||
}
|
||||
|
||||
public static void RegisterManagedComponents()
|
||||
{
|
||||
Debug.Profiler.ProfileFunction!();
|
||||
|
||||
/*s_AddComponentMethods.Clear();
|
||||
s_HasComponentMethods.Clear();
|
||||
s_RemoveComponentMethods.Clear();*/
|
||||
|
||||
RegisterComponent<TransformComponent>();
|
||||
RegisterComponent<Rigidbody2DComponent>();
|
||||
RegisterComponent<CameraComponent>();
|
||||
@@ -459,12 +448,10 @@ static class ScriptGlue
|
||||
|
||||
private static void RegisterComponent<T>() where T : struct, new
|
||||
{
|
||||
Log.EngineLogger.Error("ScriptGlue::RegisterComponent not updated yet.");
|
||||
|
||||
String fullComponentTypeName = scope String();
|
||||
typeof(T).GetFullName(fullComponentTypeName);
|
||||
|
||||
CoreClrHelper.RegisterComponent(fullComponentTypeName,
|
||||
CoreClrHelper.RegisterComponent(fullComponentTypeName..EnsureNullTerminator(),
|
||||
addComponent: (entityId) => {
|
||||
Entity entity = GetEntitySafe(entityId);
|
||||
entity.AddComponent<T>();
|
||||
@@ -1550,6 +1537,8 @@ static class ScriptGlue
|
||||
|
||||
Log.EngineLogger.AssertDebug(context != null);
|
||||
|
||||
Log.EngineLogger.Trace(StringView(fieldName));
|
||||
|
||||
context.AddField(StringView(fieldName), type, valueObject, StringView(fullTypeName));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
using Mono;
|
||||
using GlitchyEngine.Core;
|
||||
using System;
|
||||
using GlitchyEngine.Scripting.Classes;
|
||||
|
||||
namespace GlitchyEngine.Scripting;
|
||||
|
||||
using internal GlitchyEngine.Scripting;
|
||||
|
||||
class ScriptInstance : RefCounter
|
||||
{
|
||||
private ScriptClass _scriptClass;
|
||||
|
||||
private MonoObject* _instance;
|
||||
private uint32 _gcHandle;
|
||||
|
||||
private UUID _entityId;
|
||||
|
||||
public ScriptClass ScriptClass => _scriptClass;
|
||||
|
||||
/// 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;
|
||||
|
||||
internal MonoObject* MonoInstance => _instance;
|
||||
|
||||
public UUID EntityId => _entityId;
|
||||
|
||||
public this(UUID entityId, ScriptClass scriptClass)
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(scriptClass != null);
|
||||
|
||||
_entityId = entityId;
|
||||
_scriptClass = scriptClass..AddRef();
|
||||
}
|
||||
|
||||
private ~this()
|
||||
{
|
||||
Destroy();
|
||||
_scriptClass?.ReleaseRef();
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
if (ScriptEngine.ApplicationInfo.IsInPlayMode || ScriptClass.RunInEditMode)
|
||||
{
|
||||
InvokeOnDestroy();
|
||||
}
|
||||
|
||||
Mono.mono_gchandle_free(_gcHandle);
|
||||
_instance = null;
|
||||
|
||||
ScriptEngine.UnregisterScriptInstance(_entityId);
|
||||
}
|
||||
}
|
||||
|
||||
public void Instantiate(UUID uuid)
|
||||
{
|
||||
_instance = _scriptClass.CreateInstance(uuid, let exception);
|
||||
_gcHandle = Mono.mono_gchandle_new(_instance, true);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException(exception, this);
|
||||
}
|
||||
|
||||
public void InvokeOnCreate()
|
||||
{
|
||||
_scriptClass.OnCreate(_instance, let exception);
|
||||
_isCreated = true;
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException(exception, this);
|
||||
}
|
||||
|
||||
public void InvokeOnUpdate(float deltaTime)
|
||||
{
|
||||
_scriptClass.OnUpdate(_instance, deltaTime, let exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException(exception, this);
|
||||
}
|
||||
|
||||
public void InvokeOnDestroy()
|
||||
{
|
||||
_scriptClass.OnDestroy(_instance, let exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException(exception, this);
|
||||
}
|
||||
|
||||
public void InvokeOnCollisionEnter2D(Collision2D collision)
|
||||
{
|
||||
if (!_scriptClass.HasCollisionEnter2D)
|
||||
return;
|
||||
|
||||
_scriptClass.OnCollisionEnter2D(_instance, collision, let exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException(exception, this);
|
||||
}
|
||||
|
||||
public void InvokeOnCollisionLeave2D(Collision2D collision)
|
||||
{
|
||||
if (!_scriptClass.HasCollisionLeave2D)
|
||||
return;
|
||||
|
||||
_scriptClass.OnCollisionLeave2D(_instance, collision, let exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException(exception, this);
|
||||
}
|
||||
|
||||
/// Creates a new instance of the given component class and initializes it for the current entity.
|
||||
public MonoObject* CreateComponentInstance(ScriptClass componentClassType)
|
||||
{
|
||||
MonoObject* componentInstance = componentClassType.CreateInstance();
|
||||
|
||||
// TODO: We could cache the property, but this might be fine
|
||||
MonoProperty* entityProperty = Mono.mono_class_get_property_from_name(componentClassType.[Friend]_monoClass, "Entity");
|
||||
|
||||
MonoObject* exception = null;
|
||||
|
||||
Mono.mono_property_set_value(entityProperty, componentInstance, (void**)&_instance, &exception);
|
||||
|
||||
if (exception != null)
|
||||
ScriptEngine.HandleMonoException((MonoException*)exception, this);
|
||||
|
||||
return componentInstance;
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,12 @@ public class ScriptInstanceSerializer
|
||||
public void Clear()
|
||||
{
|
||||
ClearDictionaryAndDeleteValues!(_serializedData);
|
||||
//ScriptEngine.Classes.EntitySerializer.DestroySerializationContext(this);
|
||||
ScriptEngine.Classes.EntitySerializer.DestroySerializationContext(this);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
//ScriptEngine.Classes.EntitySerializer.CreateSerializationContext(this);
|
||||
ScriptEngine.Classes.EntitySerializer.CreateSerializationContext(this);
|
||||
}
|
||||
|
||||
/// Serializes all script instances that are currently managed by the ScriptEngine.
|
||||
@@ -36,11 +36,7 @@ public class ScriptInstanceSerializer
|
||||
{
|
||||
Debug.Profiler.ProfileFunction!();
|
||||
|
||||
Log.EngineLogger.Error("SerializeScriptInstances not implemented.");
|
||||
|
||||
return;
|
||||
|
||||
/*Init();
|
||||
Init();
|
||||
|
||||
for (let (id, scriptInstance) in ScriptEngine._entityScriptInstances)
|
||||
{
|
||||
@@ -50,18 +46,18 @@ public class ScriptInstanceSerializer
|
||||
for (let (name, scriptClass) in ScriptEngine.EntityClasses)
|
||||
{
|
||||
SerializeStaticScriptClassFields(scriptClass);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes the given script instance.
|
||||
public void SerializeScriptInstance(ScriptInstance script)
|
||||
public void SerializeScriptInstance(NewScriptInstance script)
|
||||
{
|
||||
SerializedObject object = new SerializedObject(this, false, script.ScriptClass.FullName, script.EntityId);
|
||||
object.Serialize(script);
|
||||
}
|
||||
|
||||
/// Serializes the given script instance.
|
||||
public void SerializeStaticScriptClassFields(ScriptClass scriptClass)
|
||||
public void SerializeStaticScriptClassFields(NewScriptClass scriptClass)
|
||||
{
|
||||
SerializedObject object = new SerializedObject(this, true, scriptClass.FullName, null);
|
||||
object.SerializeStaticFields(scriptClass);
|
||||
@@ -71,12 +67,8 @@ public class ScriptInstanceSerializer
|
||||
public void DeserializeScriptInstances()
|
||||
{
|
||||
Debug.Profiler.ProfileFunction!();
|
||||
|
||||
Log.EngineLogger.Error("SerializeScriptInstances not implemented.");
|
||||
|
||||
return;
|
||||
|
||||
/*Init();
|
||||
Init();
|
||||
|
||||
for (let (id, script) in ScriptEngine._entityScriptInstances)
|
||||
{
|
||||
@@ -86,12 +78,12 @@ public class ScriptInstanceSerializer
|
||||
for (let (name, scriptClass) in ScriptEngine.EntityClasses)
|
||||
{
|
||||
DeserializeStaticScriptClassFields(scriptClass);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes the data into the given script instance, if there is data available.
|
||||
/// @returns true if the script had serialized data; false otherwise.
|
||||
public bool DeserializeScriptInstance(UUID id, ScriptInstance script)
|
||||
public bool DeserializeScriptInstance(UUID id, NewScriptInstance script)
|
||||
{
|
||||
if (_serializedData.TryGetValue(id, let object))
|
||||
{
|
||||
@@ -103,7 +95,7 @@ public class ScriptInstanceSerializer
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DeserializeStaticScriptClassFields(ScriptClass scriptClass)
|
||||
public bool DeserializeStaticScriptClassFields(NewScriptClass scriptClass)
|
||||
{
|
||||
for (let object in _serializedData.Values)
|
||||
{
|
||||
|
||||
@@ -192,22 +192,22 @@ class SerializedObject
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(ScriptInstance scriptInstance)
|
||||
public void Serialize(NewScriptInstance scriptInstance)
|
||||
{
|
||||
ScriptEngine.Classes.EntitySerializer.Serialize(scriptInstance, this);
|
||||
}
|
||||
|
||||
public void Deserialize(ScriptInstance scriptInstance)
|
||||
public void Deserialize(NewScriptInstance scriptInstance)
|
||||
{
|
||||
ScriptEngine.Classes.EntitySerializer.Deserialize(scriptInstance, this);
|
||||
}
|
||||
|
||||
public void SerializeStaticFields(ScriptClass scriptClass)
|
||||
public void SerializeStaticFields(NewScriptClass scriptClass)
|
||||
{
|
||||
ScriptEngine.Classes.EntitySerializer.SerializeStatic(scriptClass, this);
|
||||
}
|
||||
|
||||
public void DeserializeStaticFields(ScriptClass scriptClass)
|
||||
public void DeserializeStaticFields(NewScriptClass scriptClass)
|
||||
{
|
||||
ScriptEngine.Classes.EntitySerializer.DeserializeStatic(scriptClass, this);
|
||||
}
|
||||
|
||||
@@ -956,7 +956,7 @@ namespace GlitchyEngine.World
|
||||
Dictionary<EcsEntity, EcsEntity> sourceToTargetEntity = scope .();
|
||||
Dictionary<UUID, UUID> sourceIdToTargetId = scope .();
|
||||
Dictionary<UUID, Entity> targetIdToSourceEntity = scope .();
|
||||
List<(UUID oldId, ScriptInstance scriptInstance)> newScripts = scope .();
|
||||
List<(UUID oldId, NewScriptInstance scriptInstance)> newScripts = scope .();
|
||||
|
||||
Entity CopyEntityAndChildren(Entity original, Entity? copyParent)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user