mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
643 lines
21 KiB
Beef
643 lines
21 KiB
Beef
using Mono;
|
|
using System;
|
|
using GlitchLog;
|
|
using System.Reflection;
|
|
using GlitchyEngine.Events;
|
|
using GlitchyEngine.Math;
|
|
using GlitchyEngine.World;
|
|
using GlitchyEngine.Core;
|
|
using System.Collections;
|
|
using Box2D;
|
|
using GlitchyEngine.Scripting;
|
|
using GlitchyEngine.Serialization;
|
|
|
|
namespace GlitchyEngine.Scripting;
|
|
|
|
using internal GlitchyEngine.Scripting;
|
|
|
|
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 _;
|
|
|
|
struct RegisterCallAttribute : Attribute
|
|
{
|
|
public String MethodName;
|
|
|
|
public this(String methodName)
|
|
{
|
|
MethodName = methodName;
|
|
}
|
|
}
|
|
|
|
/* Adding this attribute to a method will log method entry and returned Result<T> errors */
|
|
[AttributeUsage(.Method)]
|
|
struct RegisterMethodAttribute : Attribute, IOnMethodInit
|
|
{
|
|
[Comptime]
|
|
public void OnMethodInit(MethodInfo method, Self* prev)
|
|
{
|
|
for (var methodInfo in typeof(ScriptGlue).GetMethods(.Static))
|
|
{
|
|
if (methodInfo.GetCustomAttribute<RegisterCallAttribute>() case .Ok(let attribute))
|
|
{
|
|
String functionType = scope $"{methodInfo.ReturnType}({methodInfo.GetParamsDecl(.. scope .())})";
|
|
|
|
String line = scope $"RegisterCall<function {functionType}>(\"{attribute.MethodName}\", => {methodInfo.Name});\n";
|
|
|
|
Compiler.EmitMethodEntry(method, line);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Init()
|
|
{
|
|
RegisterCalls();
|
|
|
|
RegisterMathFunctions();
|
|
}
|
|
|
|
public static void RegisterManagedComponents()
|
|
{
|
|
Debug.Profiler.ProfileFunction!();
|
|
|
|
s_AddComponentMethods.Clear();
|
|
s_HasComponentMethods.Clear();
|
|
s_RemoveComponentMethods.Clear();
|
|
|
|
RegisterComponent<TransformComponent>("GlitchyEngine.Core.Transform");
|
|
RegisterComponent<Rigidbody2DComponent>("GlitchyEngine.Physics.Rigidbody2D");
|
|
}
|
|
|
|
[RegisterMethod]
|
|
private static void RegisterCalls()
|
|
{
|
|
// Generated at CompTime
|
|
}
|
|
|
|
private static void RegisterComponent<T>(StringView cSharpClassName = "") where T : struct, new
|
|
{
|
|
String className;
|
|
|
|
if (cSharpClassName.IsWhiteSpace)
|
|
{
|
|
className = scope:: $"GlitchyEngine.";
|
|
typeof(T).GetName(className);
|
|
}
|
|
else
|
|
{
|
|
className = scope:: String(cSharpClassName);
|
|
}
|
|
|
|
className.EnsureNullTerminator();
|
|
|
|
MonoType* managedType = Mono.mono_reflection_type_from_name(className.CStr(), ScriptEngine.[Friend]s_CoreAssemblyImage);
|
|
|
|
if (managedType != null)
|
|
{
|
|
s_AddComponentMethods[managedType] = (entity) => entity.AddComponent<T>();
|
|
s_HasComponentMethods[managedType] = (entity) => entity.HasComponent<T>();
|
|
s_RemoveComponentMethods[managedType] = (entity) => entity.RemoveComponent<T>();
|
|
}
|
|
else
|
|
{
|
|
Log.EngineLogger.AssertDebug(managedType != null, scope $"No C# component with name \"{className}\" found for Beef type \"{typeof(T)}\"");
|
|
}
|
|
}
|
|
|
|
[RegisterCall("Log::LogMessage_Impl")]
|
|
static void Log(int32 logLevel, MonoString* message)
|
|
{
|
|
char8* utfMessage = Mono.mono_string_to_utf8(message);
|
|
|
|
Log.ClientLogger.Log((LogLevel)logLevel, StringView(utfMessage));
|
|
|
|
Mono.mono_free(utfMessage);
|
|
}
|
|
|
|
#region Input
|
|
|
|
[RegisterCall("Input::IsKeyPressed")]
|
|
static bool Input_IsKeyPressed(Key key) => Input.IsKeyPressed(key);
|
|
|
|
[RegisterCall("Input::IsKeyReleased")]
|
|
static bool Input_IsKeyReleased(Key key) => Input.IsKeyReleased(key);
|
|
|
|
[RegisterCall("Input::IsKeyToggled")]
|
|
static bool Input_IsKeyToggled(Key key) => Input.IsKeyToggled(key);
|
|
|
|
[RegisterCall("Input::IsKeyPressing")]
|
|
static bool Input_IsKeyPressing(Key key) => Input.IsKeyPressing(key);
|
|
|
|
[RegisterCall("Input::IsKeyReleasing")]
|
|
static bool Input_IsKeyReleasing(Key key) => Input.IsKeyReleasing(key);
|
|
|
|
|
|
[RegisterCall("Input::IsMouseButtonPressed")]
|
|
static bool Input_IsMouseButtonPressed(MouseButton mouseButton) => Input.IsMouseButtonPressed(mouseButton);
|
|
|
|
[RegisterCall("Input::IsMouseButtonReleased")]
|
|
static bool Input_IsMouseButtonReleased(MouseButton mouseButton) => Input.IsMouseButtonReleased(mouseButton);
|
|
|
|
[RegisterCall("Input::IsMouseButtonPressing")]
|
|
static bool Input_IsMouseButtonPressing(MouseButton mouseButton) => Input.IsMouseButtonPressing(mouseButton);
|
|
|
|
[RegisterCall("Input::IsMouseButtonReleasing")]
|
|
static bool Input_IsMouseButtonReleasing(MouseButton mouseButton) => Input.IsMouseButtonReleasing(mouseButton);
|
|
|
|
#endregion Input
|
|
|
|
#region Scene/Entity stuff
|
|
|
|
[RegisterCall("ScriptGlue::Entity_Create")]
|
|
static void Entity_Create(MonoObject* scriptInstance, MonoString* monoEntityName, MonoArray* componentTypes, out UUID entityId)
|
|
{
|
|
char8* entityName = Mono.mono_string_to_utf8(monoEntityName);
|
|
|
|
Entity entity = ScriptEngine.Context.CreateEntity(StringView(entityName));
|
|
|
|
Mono.mono_free(entityName);
|
|
|
|
entityId = entity.UUID;
|
|
|
|
// TODO: Script instance
|
|
|
|
if (componentTypes != null)
|
|
{
|
|
Entity_AddComponents(entityId, componentTypes);
|
|
}
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_Destroy")]
|
|
static void Entity_Destroy(UUID entityId)
|
|
{
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
ScriptEngine.Context.DestroyEntityDeferred(entity);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_CreateInstance")]
|
|
static void Entity_CreateInstance(UUID entityId, out UUID newEntityId)
|
|
{
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
Entity newEntity = ScriptEngine.Context.CreateInstance(entity);
|
|
|
|
newEntityId = newEntity.UUID;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_AddComponents")]
|
|
static void Entity_AddComponents(UUID entityId, MonoArray* componentTypes)
|
|
{
|
|
if (componentTypes == null)
|
|
return;
|
|
|
|
uint length = Mono.mono_array_length(componentTypes);
|
|
for (uint i < length)
|
|
{
|
|
MonoReflectionType* reflectionType = Mono.mono_array_get<MonoReflectionType*>(componentTypes, i);
|
|
|
|
if (reflectionType != null)
|
|
Entity_AddComponent(entityId, reflectionType);
|
|
}
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_AddComponent")]
|
|
static void Entity_AddComponent(UUID entityId, MonoReflectionType* componentType)
|
|
{
|
|
MonoType* type = Mono.mono_reflection_type_get_type(componentType);
|
|
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
if (s_AddComponentMethods.TryGetValue(type, let addMethod))
|
|
addMethod(entity);
|
|
else
|
|
Log.EngineLogger.AssertDebug(false, "No managed component with the given type registered.");
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_HasComponent")]
|
|
static bool Entity_HasComponent(UUID entityId, MonoReflectionType* componentType)
|
|
{
|
|
MonoType* type = Mono.mono_reflection_type_get_type(componentType);
|
|
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
if (s_HasComponentMethods.TryGetValue(type, let hasMethod))
|
|
return hasMethod(entity);
|
|
|
|
Log.EngineLogger.AssertDebug(false, "No managed component with the given type registered.");
|
|
|
|
return false;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_RemoveComponent")]
|
|
static void Entity_RemoveComponent(UUID entityId, MonoReflectionType* componentType)
|
|
{
|
|
MonoType* type = Mono.mono_reflection_type_get_type(componentType);
|
|
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
if (s_RemoveComponentMethods.TryGetValue(type, let removeMethod))
|
|
removeMethod(entity);
|
|
else
|
|
Log.EngineLogger.AssertDebug(false, "No managed component with the given type registered.");
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_FindEntityWithName")]
|
|
static void Entity_FindEntityWithName(MonoString* monoName, UUID* outUuid)
|
|
{
|
|
*outUuid = UUID(0);
|
|
|
|
char8* entityName = Mono.mono_string_to_utf8(monoName);
|
|
|
|
StringView nameString = StringView(entityName);
|
|
|
|
Result<Entity> entityResult = ScriptEngine.Context.GetEntityByName(nameString);
|
|
|
|
Mono.mono_free(entityName);
|
|
|
|
if (entityResult case .Ok(let entity))
|
|
*outUuid = entity.UUID;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_GetScriptInstance")]
|
|
static void Entity_GetScriptInstance(UUID entityId, out MonoObject* instance)
|
|
{
|
|
instance = ScriptEngine.GetManagedInstance(entityId);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_SetScript")]
|
|
static MonoObject* Entity_SetScript(UUID entityId, MonoReflectionType* scriptType)
|
|
{
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
|
|
if (!entity.HasComponent<ScriptComponent>())
|
|
{
|
|
entity.AddComponent<ScriptComponent>();
|
|
}
|
|
|
|
if (entity.TryGetComponent<ScriptComponent>(let scriptComponent))
|
|
{
|
|
scriptComponent.Instance = null;
|
|
|
|
MonoType* type = Mono.mono_reflection_type_get_type(scriptType);
|
|
|
|
scriptComponent.ScriptClassName = StringView(Mono.mono_type_full_name(type));
|
|
|
|
// Initializes the created instance
|
|
// TODO: this returns false, if no script with ScriptClassName exists, we have to handle this case correctly I think.
|
|
ScriptEngine.InitializeInstance(entity, scriptComponent);
|
|
|
|
return scriptComponent.Instance.MonoInstance;
|
|
}
|
|
|
|
Log.EngineLogger.AssertDebug(false, "Failed to set script.");
|
|
|
|
return null;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_RemoveScript")]
|
|
static void Entity_RemoveScript(UUID entityId)
|
|
{
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
|
|
if (entity.TryGetComponent<ScriptComponent>(let scriptComponent))
|
|
{
|
|
ScriptEngine.DestroyInstance(entity, scriptComponent);
|
|
|
|
entity.RemoveComponent<ScriptComponent>();
|
|
}
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_GetName")]
|
|
static MonoString* Entity_GetName(UUID entityId)
|
|
{
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
|
|
MonoString* name = Mono.mono_string_new_len(ScriptEngine.[Friend]s_AppDomain, entity.Name.Ptr, (.)entity.Name.Length);
|
|
|
|
return name;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Entity_SetName")]
|
|
static void Entity_SetName(UUID entityId, MonoString* name)
|
|
{
|
|
Entity entity = ScriptEngine.Context.GetEntityByID(entityId);
|
|
|
|
char8* rawName = Mono.mono_string_to_utf8(name);
|
|
|
|
entity.Name = StringView(rawName);
|
|
|
|
Mono.mono_free(rawName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region TransformComponent
|
|
|
|
[RegisterCall("ScriptGlue::Transform_GetTranslation")]
|
|
static void Transform_GetTranslation(UUID entityId, out float3 translation)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
translation = entity.Transform.Position;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Transform_SetTranslation")]
|
|
static void Transform_SetTranslation(UUID entityId, in float3 translation)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
entity.Transform.Position = translation;
|
|
|
|
// if necessary reposition Rigidbody2D
|
|
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
|
{
|
|
rigidbody2D.SetPosition(translation.XY);
|
|
}
|
|
}
|
|
|
|
#endregion TransformComponent
|
|
|
|
#region Rigidbody2D
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_ApplyForce")]
|
|
static void Rigidbody2D_ApplyForce(UUID entityId, in float2 force, in float2 point, bool wakeUp)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
Box2D.Body.ApplyForce(rigidBody.[Friend]RuntimeBody, force, point, wakeUp);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_ApplyForceToCenter")]
|
|
static void Rigidbody2D_ApplyForceToCenter(UUID entityId, in float2 force, bool wakeUp)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
Box2D.Body.ApplyForceToCenter(rigidBody.[Friend]RuntimeBody, force, wakeUp);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_SetPosition")]
|
|
static void Rigidbody2D_SetPosition(UUID entityId, in float2 position)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
rigidBody.SetPosition(position);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_GetPosition")]
|
|
static void Rigidbody2D_GetPosition(UUID entityId, out float2 position)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
position = rigidBody.GetPosition();
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_SetRotation")]
|
|
static void Rigidbody2D_SetRotation(UUID entityId, in float rotation)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
rigidBody.SetAngle(rotation);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_GetRotation")]
|
|
static void Rigidbody2D_GetRotation(UUID entityId, out float rotation)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
rotation = rigidBody.GetAngle();
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_GetLinearVelocity")]
|
|
static void Rigidbody2D_GetLinearVelocity(UUID entityId, out float2 velocity)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
velocity = rigidBody.GetLinearVelocity();
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_SetLinearVelocity")]
|
|
static void Rigidbody2D_SetLinearVelocity(UUID entityId, in float2 velocity)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
rigidBody.SetLinearVelocity(velocity);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_GetAngularVelocity")]
|
|
static void Rigidbody2D_GetAngularVelocity(UUID entityId, out float velocity)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
velocity = rigidBody.GetAngularVelocity();
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Rigidbody2D_SetAngularVelocity")]
|
|
static void Rigidbody2D_SetAngularVelocity(UUID entityId, in float velocity)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
Entity entity = scene.GetEntityByID(entityId);
|
|
|
|
var rigidBody = entity.GetComponent<Rigidbody2DComponent>();
|
|
rigidBody.SetAngularVelocity(velocity);
|
|
}
|
|
|
|
#endregion Rigidbody2D
|
|
|
|
#region Physics2D
|
|
|
|
// TODO: We need a wrapper class!
|
|
|
|
[RegisterCall("ScriptGlue::Physics2D_GetGravity")]
|
|
static void Physics2D_GetGravity(out float2 gravity)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
|
|
var box2DGravity = Box2D.World.GetGravity(scene.[Friend]_physicsWorld2D);
|
|
gravity = *(float2*)&box2DGravity;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Physics2D_SetGravity")]
|
|
static void Physics2D_SetGravity(in float2 gravity)
|
|
{
|
|
Scene scene = ScriptEngine.Context;
|
|
|
|
#unwarn
|
|
Box2D.World.SetGravity(scene.[Friend]_physicsWorld2D, gravity);
|
|
}
|
|
|
|
#endregion Physics2D
|
|
|
|
#region Math
|
|
|
|
private static void RegisterMathFunctions()
|
|
{
|
|
RegisterCall<function float(float, out float)>("ScriptGlue::modf_float", => GlitchyEngine.Math.modf);
|
|
RegisterCall<function float2(float2, out float2)>("ScriptGlue::modf_float2", => GlitchyEngine.Math.modf);
|
|
RegisterCall<function float3(float3, out float3)>("ScriptGlue::modf_float3", => GlitchyEngine.Math.modf);
|
|
RegisterCall<function float4(float4, out float4)>("ScriptGlue::modf_float4", => GlitchyEngine.Math.modf);
|
|
|
|
RegisterHalfFunctions();
|
|
}
|
|
|
|
private static void RegisterHalfFunctions()
|
|
{
|
|
RegisterCall<function void(float, out half)>("Math.Half::FromFloat32", (value, halfValue) => halfValue = GlitchyEngine.Math.half.FromFloat32(value));
|
|
RegisterCall<function void(half, out float)>("Math.Half::ToFloat32", (value, floatValue) => floatValue = GlitchyEngine.Math.half.ToFloat32(value));
|
|
|
|
RegisterCall<function void(half, half, out bool)>("Math.Half::LessThan_Impl", (left, right, result) => result = left < right);
|
|
RegisterCall<function void(half, half, out bool)>("Math.Half::LessThanOrEqual_Impl", (left, right, result) => result = left <= right);
|
|
RegisterCall<function void(half, half, out bool)>("Math.Half::GreaterThan_Impl", (left, right, result) => result = left > right);
|
|
RegisterCall<function void(half, half, out bool)>("Math.Half::GreaterThanOrEqual_Impl", (left, right, result) => result = left >= right);
|
|
|
|
RegisterCall<function void(half, half, out half)>("Math.Half::Add_Impl", (left, right, result) => result = left + right);
|
|
RegisterCall<function void(half, half, out half)>("Math.Half::Subtract_Impl", (left, right, result) => result = left - right);
|
|
RegisterCall<function void(half, half, out half)>("Math.Half::Multiply_Impl", (left, right, result) => result = left * right);
|
|
RegisterCall<function void(half, half, out half)>("Math.Half::Divide_Impl", (left, right, result) => result = left / right);
|
|
RegisterCall<function void(half, half, out half)>("Math.Half::Modulo_Impl", (left, right, result) => result = left % right);
|
|
RegisterCall<function void(half, out half)>("Math.Half::Negate_Impl", (value, result) => result = -value);
|
|
RegisterCall<function void(half, out half)>("Math.Half::Increment_Impl", (value, result) => result = ++value);
|
|
RegisterCall<function void(half, out half)>("Math.Half::Decrement_Impl", (value, result) => result = --value);
|
|
|
|
RegisterCall<function bool(half)>("Math.Half::IsNegative_Impl", (value) => value.IsNegative);
|
|
RegisterCall<function bool(half)>("Math.Half::IsFinite_Impl", (value) => value.IsFinite);
|
|
RegisterCall<function bool(half)>("Math.Half::IsInfinity_Impl", (value) => value.IsInfinity);
|
|
RegisterCall<function bool(half)>("Math.Half::IsNan_Impl", (value) => value.IsNaN);
|
|
RegisterCall<function bool(half)>("Math.Half::IsSubnormal_Impl", (value) => value.IsSubnormal);
|
|
}
|
|
|
|
#endregion
|
|
|
|
[RegisterCall("ScriptGlue::UUID_CreateNew")]
|
|
static void UUID_Create(out UUID id)
|
|
{
|
|
id = UUID.Create();
|
|
}
|
|
|
|
#region Application
|
|
|
|
[RegisterCall("ScriptGlue::Application_IsEditor")]
|
|
static bool Application_IsEditor()
|
|
{
|
|
return ScriptEngine.ApplicationInfo.IsEditor;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Application_IsPlayer")]
|
|
static bool Application_IsPlayer()
|
|
{
|
|
return ScriptEngine.ApplicationInfo.IsPlayer;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Application_IsInEditMode")]
|
|
static bool Application_IsInEditMode()
|
|
{
|
|
return ScriptEngine.ApplicationInfo.IsInEditMode;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Application_IsInPlayMode")]
|
|
static bool Application_IsInPlayMode()
|
|
{
|
|
return ScriptEngine.ApplicationInfo.IsInPlayMode;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Serialization
|
|
|
|
[RegisterCall("ScriptGlue::Serialization_SerializeField")]
|
|
static void Serialization_SerializeField(void* serializationContext, SerializationType type, MonoString* nameObject, MonoObject* valueObject, MonoString* fullTypeName)
|
|
{
|
|
SerializedObject context = Internal.UnsafeCastToObject(serializationContext) as SerializedObject;
|
|
|
|
Log.EngineLogger.AssertDebug(context != null);
|
|
|
|
char8* name = Mono.mono_string_to_utf8(nameObject);
|
|
|
|
context.AddField(StringView(name), type, valueObject, fullTypeName);
|
|
|
|
Mono.mono_free(name);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Serialization_CreateObject")]
|
|
static void Serialization_CreateObject(void* currentContext, MonoString* typeName, out void* newContext, out UUID newId)
|
|
{
|
|
SerializedObject context = Internal.UnsafeCastToObject(currentContext) as SerializedObject;
|
|
|
|
Log.EngineLogger.AssertDebug(context != null);
|
|
|
|
char8* rawTypeName = Mono.mono_string_to_utf8(typeName);
|
|
|
|
SerializedObject newObject = new SerializedObject(context.AllObjects, StringView(rawTypeName));
|
|
|
|
Mono.mono_free(rawTypeName);
|
|
|
|
newContext = Internal.UnsafeCastToPtr(newObject);
|
|
newId = newObject.Id;
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Serialization_DeserializeField")]
|
|
public static void Serialization_DeserializeField(void* internalContext, SerializationType expectedType, MonoString* fieldName, uint8* target, out SerializationType actualType)
|
|
{
|
|
SerializedObject context = Internal.UnsafeCastToObject(internalContext) as SerializedObject;
|
|
|
|
Log.EngineLogger.AssertDebug(context != null);
|
|
|
|
char8* name = Mono.mono_string_to_utf8(fieldName);
|
|
|
|
context.GetField(StringView(name), expectedType, target, out actualType);
|
|
|
|
Mono.mono_free(name);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Serialization_GetObject")]
|
|
public static void Serialization_GetObject(void* internalContext, UUID id, out void* objectContext)
|
|
{
|
|
SerializedObject context = Internal.UnsafeCastToObject(internalContext) as SerializedObject;
|
|
|
|
Log.EngineLogger.AssertDebug(context != null);
|
|
|
|
objectContext = null;
|
|
|
|
Log.EngineLogger.AssertDebug(context.AllObjects.ContainsKey(context.Id));
|
|
|
|
if (!context.AllObjects.TryGetValue(id, let foundObject))
|
|
return;
|
|
|
|
objectContext = Internal.UnsafeCastToPtr(foundObject);
|
|
}
|
|
|
|
[RegisterCall("ScriptGlue::Serialization_GetObjectTypeName")]
|
|
public static void Serialization_GetObjectTypeName(void* internalContext, out MonoString* fullTypeName)
|
|
{
|
|
SerializedObject context = Internal.UnsafeCastToObject(internalContext) as SerializedObject;
|
|
|
|
Log.EngineLogger.AssertDebug(context != null);
|
|
|
|
fullTypeName = Mono.mono_string_new(ScriptEngine.[Friend]s_AppDomain, context.TypeName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
private static void RegisterCall<T>(String name, T method) where T : var
|
|
{
|
|
Mono.mono_add_internal_call(scope $"GlitchyEngine.{name}", (void*)method);
|
|
}
|
|
} |