Add support for compiling and running engine without C# scripting
(configurable via `EngineConfiguration.UseCSharp` in Flax.Build)
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include "GameCooker.h"
|
#include "GameCooker.h"
|
||||||
#include "FlaxEngine.Gen.h"
|
#include "FlaxEngine.Gen.h"
|
||||||
#include "Engine/Scripting/MainThreadManagedInvokeAction.h"
|
#include "Engine/Scripting/MainThreadManagedInvokeAction.h"
|
||||||
|
#include "Engine/Scripting/ManagedCLR/MTypes.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
#include "Engine/Scripting/Scripting.h"
|
#include "Engine/Scripting/Scripting.h"
|
||||||
#include "Engine/Scripting/ScriptingType.h"
|
#include "Engine/Scripting/ScriptingType.h"
|
||||||
@@ -450,7 +451,7 @@ void GameCookerImpl::OnCollectAssets(HashSet<Guid>& assets)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MCore::AttachThread();
|
MCore::AttachThread();
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
auto list = (MonoArray*)Internal_OnCollectAssets->Invoke(nullptr, nullptr, &exception);
|
auto list = (MonoArray*)Internal_OnCollectAssets->Invoke(nullptr, nullptr, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -486,7 +487,7 @@ bool GameCookerImpl::Build()
|
|||||||
Steps.Add(New<PostProcessStep>());
|
Steps.Add(New<PostProcessStep>());
|
||||||
}
|
}
|
||||||
|
|
||||||
MCore::Instance()->AttachThread();
|
MCore::AttachThread();
|
||||||
|
|
||||||
// Build Started
|
// Build Started
|
||||||
CallEvent(GameCooker::EventType::BuildStarted);
|
CallEvent(GameCooker::EventType::BuildStarted);
|
||||||
|
|||||||
@@ -11,5 +11,7 @@ class CustomEditorsUtil
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
static MonoReflectionType* GetCustomEditor(MonoReflectionType* refType);
|
static MonoReflectionType* GetCustomEditor(MonoReflectionType* refType);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ void OnVisualScriptingDebugFlow()
|
|||||||
flowInfo.ScriptInstance = stack->Instance ? stack->Instance->GetOrCreateManagedInstance() : nullptr;
|
flowInfo.ScriptInstance = stack->Instance ? stack->Instance->GetOrCreateManagedInstance() : nullptr;
|
||||||
flowInfo.NodeId = stack->Node->ID;
|
flowInfo.NodeId = stack->Node->ID;
|
||||||
flowInfo.BoxId = stack->Box->ID;
|
flowInfo.BoxId = stack->Box->ID;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = &flowInfo;
|
params[0] = &flowInfo;
|
||||||
Internal_OnVisualScriptingDebugFlow->Invoke(nullptr, params, &exception);
|
Internal_OnVisualScriptingDebugFlow->Invoke(nullptr, params, &exception);
|
||||||
@@ -191,7 +191,7 @@ void ManagedEditor::Init()
|
|||||||
{
|
{
|
||||||
LOG(Fatal, "Failed to create editor instance.");
|
LOG(Fatal, "Failed to create editor instance.");
|
||||||
}
|
}
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
bool isHeadless = CommandLine::Options.Headless.IsTrue();
|
bool isHeadless = CommandLine::Options.Headless.IsTrue();
|
||||||
bool skipCompile = CommandLine::Options.SkipCompile.IsTrue();
|
bool skipCompile = CommandLine::Options.SkipCompile.IsTrue();
|
||||||
bool newProject = CommandLine::Options.NewProject.IsTrue();
|
bool newProject = CommandLine::Options.NewProject.IsTrue();
|
||||||
@@ -259,7 +259,7 @@ void ManagedEditor::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call update
|
// Call update
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
UpdateMethod->Invoke(instance, nullptr, &exception);
|
UpdateMethod->Invoke(instance, nullptr, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -291,7 +291,7 @@ void ManagedEditor::Exit()
|
|||||||
{
|
{
|
||||||
LOG(Fatal, "Invalid Editor assembly!");
|
LOG(Fatal, "Invalid Editor assembly!");
|
||||||
}
|
}
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
exitMethod->Invoke(instance, nullptr, &exception);
|
exitMethod->Invoke(instance, nullptr, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -456,7 +456,7 @@ void ScriptsBuilderImpl::CallCompileEvent(EventData& data)
|
|||||||
LOG(Fatal, "Invalid Editor assembly!");
|
LOG(Fatal, "Invalid Editor assembly!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*MonoObject* exception = nullptr;
|
/*MObject* exception = nullptr;
|
||||||
void* args[1];
|
void* args[1];
|
||||||
args[0] = &data.Type;
|
args[0] = &data.Type;
|
||||||
Internal_OnEvent->Invoke(nullptr, args, &exception);
|
Internal_OnEvent->Invoke(nullptr, args, &exception);
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
#include "Engine/Scripting/Scripting.h"
|
#include "Engine/Scripting/Scripting.h"
|
||||||
#include "Engine/Scripting/MException.h"
|
#include "Engine/Scripting/MException.h"
|
||||||
#include "Engine/Content/Assets/SkinnedModel.h"
|
#include "Engine/Content/Assets/SkinnedModel.h"
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
|
||||||
struct InternalInitData
|
struct InternalInitData
|
||||||
@@ -80,15 +83,20 @@ namespace AnimGraphInternal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void AnimGraphExecutor::initRuntime()
|
void AnimGraphExecutor::initRuntime()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_HasConnection", &AnimGraphInternal::HasConnection);
|
ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_HasConnection", &AnimGraphInternal::HasConnection);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetInputValue", &AnimGraphInternal::GetInputValue);
|
ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetInputValue", &AnimGraphInternal::GetInputValue);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData", &AnimGraphInternal::GetOutputImpulseData);
|
ADD_INTERNAL_CALL("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData", &AnimGraphInternal::GetOutputImpulseData);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value& value)
|
void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value& value)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto& context = Context.Get();
|
auto& context = Context.Get();
|
||||||
if (context.ValueCache.TryGet(boxBase, value))
|
if (context.ValueCache.TryGet(boxBase, value))
|
||||||
return;
|
return;
|
||||||
@@ -124,7 +132,7 @@ void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value&
|
|||||||
// Evaluate node
|
// Evaluate node
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = &internalContext;
|
params[0] = &internalContext;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
MonoObject* result = data.Evaluate->Invoke(obj, params, &exception);
|
MonoObject* result = data.Evaluate->Invoke(obj, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -136,6 +144,7 @@ void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value&
|
|||||||
// Extract result
|
// Extract result
|
||||||
value = MUtils::UnboxVariant(result);
|
value = MUtils::UnboxVariant(result);
|
||||||
context.ValueCache.Add(boxBase, value);
|
context.ValueCache.Add(boxBase, value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimGraph::IsReady() const
|
bool AnimGraph::IsReady() const
|
||||||
@@ -156,13 +165,16 @@ void AnimGraph::ClearCustomNode(Node* node)
|
|||||||
data.Evaluate = nullptr;
|
data.Evaluate = nullptr;
|
||||||
if (data.Handle)
|
if (data.Handle)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
mono_gchandle_free(data.Handle);
|
mono_gchandle_free(data.Handle);
|
||||||
|
#endif
|
||||||
data.Handle = 0;
|
data.Handle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimGraph::InitCustomNode(Node* node)
|
bool AnimGraph::InitCustomNode(Node* node)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Fetch the node logic controller type
|
// Fetch the node logic controller type
|
||||||
if (node->Values.Count() < 2 || node->Values[0].Type.Type != ValueType::String)
|
if (node->Values.Count() < 2 || node->Values[0].Type.Type != ValueType::String)
|
||||||
{
|
{
|
||||||
@@ -212,7 +224,7 @@ bool AnimGraph::InitCustomNode(Node* node)
|
|||||||
initData.BaseModel = BaseModel.GetManagedInstance();
|
initData.BaseModel = BaseModel.GetManagedInstance();
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = &initData;
|
params[0] = &initData;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
load->Invoke(obj, params, &exception);
|
load->Invoke(obj, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -227,7 +239,7 @@ bool AnimGraph::InitCustomNode(Node* node)
|
|||||||
auto& data = node->Data.Custom;
|
auto& data = node->Data.Custom;
|
||||||
data.Evaluate = evaluate;
|
data.Evaluate = evaluate;
|
||||||
data.Handle = handleGC;
|
data.Handle = handleGC;
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ void SceneAnimationPlayer::MapTrack(const StringView& from, const Guid& to)
|
|||||||
|
|
||||||
void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset)
|
void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Restore all tracks
|
// Restore all tracks
|
||||||
for (int32 j = 0; j < anim->Tracks.Count(); j++)
|
for (int32 j = 0; j < anim->Tracks.Count(); j++)
|
||||||
{
|
{
|
||||||
@@ -293,7 +294,7 @@ void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset)
|
|||||||
|| state.RestoreStateIndex == -1
|
|| state.RestoreStateIndex == -1
|
||||||
|| (state.Field == nullptr && state.Property == nullptr))
|
|| (state.Field == nullptr && state.Property == nullptr))
|
||||||
break;
|
break;
|
||||||
MonoObject* instance = _tracks[stateIndexOffset + parentTrack.TrackStateIndex].ManagedObject;
|
MObject* instance = _tracks[stateIndexOffset + parentTrack.TrackStateIndex].ManagedObject;
|
||||||
if (!instance)
|
if (!instance)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -318,7 +319,7 @@ void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset)
|
|||||||
{
|
{
|
||||||
if (state.Property)
|
if (state.Property)
|
||||||
{
|
{
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
state.ManagedObject = state.Property->GetValue(instance, &exception);
|
state.ManagedObject = state.Property->GetValue(instance, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -341,7 +342,7 @@ void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset)
|
|||||||
// Set the value
|
// Set the value
|
||||||
if (state.Property)
|
if (state.Property)
|
||||||
{
|
{
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
state.Property->SetValue(instance, value, &exception);
|
state.Property->SetValue(instance, value, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -353,16 +354,17 @@ void SceneAnimationPlayer::Restore(SceneAnimation* anim, int32 stateIndexOffset)
|
|||||||
{
|
{
|
||||||
state.Field->SetValue(instance, value);
|
state.Field->SetValue(instance, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexOffset, SceneAnimation* anim, float time, const SceneAnimation::Track& track, TrackInstance& state, void* target)
|
bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexOffset, SceneAnimation* anim, float time, const SceneAnimation::Track& track, TrackInstance& state, void* target)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
switch (track.Type)
|
switch (track.Type)
|
||||||
{
|
{
|
||||||
case SceneAnimation::Track::Types::KeyframesProperty:
|
case SceneAnimation::Track::Types::KeyframesProperty:
|
||||||
@@ -511,17 +513,18 @@ bool SceneAnimationPlayer::TickPropertyTrack(int32 trackIndex, int32 stateIndexO
|
|||||||
case SceneAnimation::Track::Types::ObjectProperty:
|
case SceneAnimation::Track::Types::ObjectProperty:
|
||||||
{
|
{
|
||||||
// Cache the sub-object pointer for the sub-tracks
|
// Cache the sub-object pointer for the sub-tracks
|
||||||
state.ManagedObject = *(MonoObject**)target;
|
state.ManagedObject = *(MObject**)target;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int32 stateIndexOffset, CallStack& callStack)
|
void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int32 stateIndexOffset, CallStack& callStack)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const float fps = anim->FramesPerSecond;
|
const float fps = anim->FramesPerSecond;
|
||||||
#if !BUILD_RELEASE || USE_EDITOR
|
#if !BUILD_RELEASE || USE_EDITOR
|
||||||
callStack.Add(anim);
|
callStack.Add(anim);
|
||||||
@@ -827,7 +830,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Skip if parent object is missing
|
// Skip if parent object is missing
|
||||||
MonoObject* instance = _tracks[stateIndexOffset + parentTrack.TrackStateIndex].ManagedObject;
|
MObject* instance = _tracks[stateIndexOffset + parentTrack.TrackStateIndex].ManagedObject;
|
||||||
if (!instance)
|
if (!instance)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -860,7 +863,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
{
|
{
|
||||||
if (state.Property)
|
if (state.Property)
|
||||||
{
|
{
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
auto boxed = state.Property->GetValue(instance, &exception);
|
auto boxed = state.Property->GetValue(instance, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -876,7 +879,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*(MonoObject**)value = boxed;
|
*(MObject**)value = boxed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -900,7 +903,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
}
|
}
|
||||||
case SceneAnimation::Track::Types::ObjectReferenceProperty:
|
case SceneAnimation::Track::Types::ObjectReferenceProperty:
|
||||||
{
|
{
|
||||||
auto obj = Scripting::FindObject(*(MonoObject**)value);
|
auto obj = Scripting::FindObject(*(MObject**)value);
|
||||||
auto id = obj ? obj->GetID() : Guid::Empty;
|
auto id = obj ? obj->GetID() : Guid::Empty;
|
||||||
_restoreData.Add((byte*)&id, sizeof(Guid));
|
_restoreData.Add((byte*)&id, sizeof(Guid));
|
||||||
break;
|
break;
|
||||||
@@ -922,7 +925,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
value = (void*)*(intptr*)value;
|
value = (void*)*(intptr*)value;
|
||||||
if (state.Property)
|
if (state.Property)
|
||||||
{
|
{
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
state.Property->SetValue(instance, value, &exception);
|
state.Property->SetValue(instance, value, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -995,7 +998,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
|
|
||||||
// Invoke the method
|
// Invoke the method
|
||||||
Variant result;
|
Variant result;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
mono_runtime_invoke((MonoMethod*)state.Method, instance, paramsData, &exception);
|
mono_runtime_invoke((MonoMethod*)state.Method, instance, paramsData, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -1064,6 +1067,7 @@ void SceneAnimationPlayer::Tick(SceneAnimation* anim, float time, float dt, int3
|
|||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneAnimationPlayer::Tick()
|
void SceneAnimationPlayer::Tick()
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ private:
|
|||||||
struct TrackInstance
|
struct TrackInstance
|
||||||
{
|
{
|
||||||
ScriptingObjectReference<ScriptingObject> Object;
|
ScriptingObjectReference<ScriptingObject> Object;
|
||||||
MonoObject* ManagedObject = nullptr;
|
MObject* ManagedObject = nullptr;
|
||||||
MProperty* Property = nullptr;
|
MProperty* Property = nullptr;
|
||||||
MField* Field = nullptr;
|
MField* Field = nullptr;
|
||||||
void* Method = nullptr;
|
void* Method = nullptr;
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Threading/MainThreadTask.h"
|
#include "Engine/Threading/MainThreadTask.h"
|
||||||
#include "Engine/Threading/ConcurrentTaskQueue.h"
|
#include "Engine/Threading/ConcurrentTaskQueue.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
AssetReferenceBase::~AssetReferenceBase()
|
AssetReferenceBase::~AssetReferenceBase()
|
||||||
{
|
{
|
||||||
@@ -202,7 +204,9 @@ void Asset::OnManagedInstanceDeleted()
|
|||||||
// Cleanup
|
// Cleanup
|
||||||
if (_gcHandle)
|
if (_gcHandle)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
mono_gchandle_free(_gcHandle);
|
mono_gchandle_free(_gcHandle);
|
||||||
|
#endif
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets managed instance object (or null if no asset set).
|
/// Gets managed instance object (or null if no asset set).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
FORCE_INLINE MonoObject* GetManagedInstance() const
|
FORCE_INLINE MObject* GetManagedInstance() const
|
||||||
{
|
{
|
||||||
return _asset ? _asset->GetOrCreateManagedInstance() : nullptr;
|
return _asset ? _asset->GetOrCreateManagedInstance() : nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,10 +310,17 @@ void VisualScriptExecutor::ProcessGroupTools(Box* box, Node* node, Value& value)
|
|||||||
const StringAsANSI<100> typeNameAnsi(typeName.Get(), typeName.Length());
|
const StringAsANSI<100> typeNameAnsi(typeName.Get(), typeName.Length());
|
||||||
if (StringUtils::Compare(typeNameAnsi.Get(), obj.Type.GetTypeName()) != 0)
|
if (StringUtils::Compare(typeNameAnsi.Get(), obj.Type.GetTypeName()) != 0)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* klass = Scripting::FindClassNative(StringAnsiView(typeNameAnsi.Get(), typeName.Length()));
|
MonoClass* klass = Scripting::FindClassNative(StringAnsiView(typeNameAnsi.Get(), typeName.Length()));
|
||||||
MonoClass* objKlass = MUtils::GetClass(obj);
|
MonoClass* objKlass = MUtils::GetClass(obj);
|
||||||
if (!klass || !objKlass || mono_class_is_subclass_of(objKlass, klass, false) == 0)
|
if (!klass || !objKlass || mono_class_is_subclass_of(objKlass, klass, false) == 0)
|
||||||
obj = Value::Null;
|
obj = Value::Null;
|
||||||
|
#else
|
||||||
|
const ScriptingTypeHandle type = Scripting::FindScriptingType(StringAnsiView(typeNameAnsi.Get(), typeName.Length()));
|
||||||
|
const ScriptingTypeHandle objType = Scripting::FindScriptingType(obj.Type.GetTypeName());
|
||||||
|
if (!type || !objType || objType.IsSubclassOf(type))
|
||||||
|
obj = Value::Null;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,6 +455,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Fallback to C#-only types
|
// Fallback to C#-only types
|
||||||
const auto mclass = Scripting::FindClass(StringAnsiView(typeNameAnsi.Get(), typeName.Length()));
|
const auto mclass = Scripting::FindClass(StringAnsiView(typeNameAnsi.Get(), typeName.Length()));
|
||||||
if (mclass)
|
if (mclass)
|
||||||
@@ -461,6 +469,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (typeName.HasChars())
|
if (typeName.HasChars())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets managed instance object (or null if no asset set).
|
/// Gets managed instance object (or null if no asset set).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
FORCE_INLINE MonoObject* GetManagedInstance() const
|
FORCE_INLINE MObject* GetManagedInstance() const
|
||||||
{
|
{
|
||||||
return _asset ? _asset->GetOrCreateManagedInstance() : nullptr;
|
return _asset ? _asset->GetOrCreateManagedInstance() : nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ VariantType::VariantType(Types type, _MonoClass* klass)
|
|||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
TypeName = nullptr;
|
TypeName = nullptr;
|
||||||
|
#if USE_MONO
|
||||||
if (klass)
|
if (klass)
|
||||||
{
|
{
|
||||||
MString typeName;
|
MString typeName;
|
||||||
@@ -72,6 +73,7 @@ VariantType::VariantType(Types type, _MonoClass* klass)
|
|||||||
TypeName = static_cast<char*>(Allocator::Allocate(length));
|
TypeName = static_cast<char*>(Allocator::Allocate(length));
|
||||||
Platform::MemoryCopy(TypeName, typeName.Get(), length);
|
Platform::MemoryCopy(TypeName, typeName.Get(), length);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantType::VariantType(const VariantType& other)
|
VariantType::VariantType(const VariantType& other)
|
||||||
@@ -517,12 +519,24 @@ Variant::Variant(Asset* v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
Variant::Variant(_MonoObject* v)
|
Variant::Variant(_MonoObject* v)
|
||||||
: Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr)
|
: Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr)
|
||||||
{
|
{
|
||||||
AsUint = v ? mono_gchandle_new(v, true) : 0;
|
AsUint = v ? mono_gchandle_new(v, true) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
Variant::Variant(_MonoObject* v)
|
||||||
|
: Type(VariantType::ManagedObject, nullptr)
|
||||||
|
{
|
||||||
|
AsUint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Variant::Variant(const StringView& v)
|
Variant::Variant(const StringView& v)
|
||||||
: Type(VariantType::String)
|
: Type(VariantType::String)
|
||||||
{
|
{
|
||||||
@@ -788,8 +802,8 @@ Variant::~Variant()
|
|||||||
case VariantType::Dictionary:
|
case VariantType::Dictionary:
|
||||||
Delete(AsDictionary);
|
Delete(AsDictionary);
|
||||||
break;
|
break;
|
||||||
#if USE_MONO
|
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
if (AsUint)
|
if (AsUint)
|
||||||
mono_gchandle_free(AsUint);
|
mono_gchandle_free(AsUint);
|
||||||
break;
|
break;
|
||||||
@@ -912,7 +926,9 @@ Variant& Variant::operator=(const Variant& other)
|
|||||||
AsDictionary = New<Dictionary<Variant, Variant>>(*other.AsDictionary);
|
AsDictionary = New<Dictionary<Variant, Variant>>(*other.AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
AsUint = other.AsUint ? mono_gchandle_new(mono_gchandle_get_target(other.AsUint), true) : 0;
|
AsUint = other.AsUint ? mono_gchandle_new(mono_gchandle_get_target(other.AsUint), true) : 0;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case VariantType::Null:
|
case VariantType::Null:
|
||||||
case VariantType::Void:
|
case VariantType::Void:
|
||||||
@@ -1015,9 +1031,6 @@ bool Variant::operator==(const Variant& other) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case VariantType::ManagedObject:
|
|
||||||
// TODO: invoke C# Equality logic?
|
|
||||||
return AsUint == other.AsUint || mono_gchandle_get_target(AsUint) == mono_gchandle_get_target(other.AsUint);
|
|
||||||
case VariantType::Typename:
|
case VariantType::Typename:
|
||||||
if (AsBlob.Data == nullptr && other.AsBlob.Data == nullptr)
|
if (AsBlob.Data == nullptr && other.AsBlob.Data == nullptr)
|
||||||
return true;
|
return true;
|
||||||
@@ -1026,6 +1039,11 @@ bool Variant::operator==(const Variant& other) const
|
|||||||
if (other.AsBlob.Data == nullptr)
|
if (other.AsBlob.Data == nullptr)
|
||||||
return false;
|
return false;
|
||||||
return AsBlob.Length == other.AsBlob.Length && StringUtils::Compare(static_cast<const char*>(AsBlob.Data), static_cast<const char*>(other.AsBlob.Data), AsBlob.Length - 1) == 0;
|
return AsBlob.Length == other.AsBlob.Length && StringUtils::Compare(static_cast<const char*>(AsBlob.Data), static_cast<const char*>(other.AsBlob.Data), AsBlob.Length - 1) == 0;
|
||||||
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
|
// TODO: invoke C# Equality logic?
|
||||||
|
return AsUint == other.AsUint || mono_gchandle_get_target(AsUint) == mono_gchandle_get_target(other.AsUint);
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1115,7 +1133,9 @@ Variant::operator bool() const
|
|||||||
case VariantType::Asset:
|
case VariantType::Asset:
|
||||||
return AsAsset != nullptr;
|
return AsAsset != nullptr;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
return AsUint != 0 && mono_gchandle_get_target(AsUint) != nullptr;
|
return AsUint != 0 && mono_gchandle_get_target(AsUint) != nullptr;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1461,7 +1481,9 @@ Variant::operator void*() const
|
|||||||
case VariantType::Blob:
|
case VariantType::Blob:
|
||||||
return AsBlob.Data;
|
return AsBlob.Data;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
return AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
|
return AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -1504,7 +1526,11 @@ Variant::operator ScriptingObject*() const
|
|||||||
|
|
||||||
Variant::operator _MonoObject*() const
|
Variant::operator _MonoObject*() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return Type.Type == VariantType::ManagedObject && AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
|
return Type.Type == VariantType::ManagedObject && AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Asset*() const
|
Variant::operator Asset*() const
|
||||||
@@ -2011,8 +2037,10 @@ void Variant::SetType(const VariantType& type)
|
|||||||
Delete(AsDictionary);
|
Delete(AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
if (AsUint)
|
if (AsUint)
|
||||||
mono_gchandle_free(AsUint);
|
mono_gchandle_free(AsUint);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
@@ -2105,8 +2133,10 @@ void Variant::SetType(VariantType&& type)
|
|||||||
Delete(AsDictionary);
|
Delete(AsDictionary);
|
||||||
break;
|
break;
|
||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
if (AsUint)
|
if (AsUint)
|
||||||
mono_gchandle_free(AsUint);
|
mono_gchandle_free(AsUint);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
@@ -2245,6 +2275,7 @@ void Variant::SetObject(ScriptingObject* object)
|
|||||||
|
|
||||||
void Variant::SetManagedObject(_MonoObject* object)
|
void Variant::SetManagedObject(_MonoObject* object)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (object)
|
if (object)
|
||||||
{
|
{
|
||||||
if (Type.Type != VariantType::ManagedObject)
|
if (Type.Type != VariantType::ManagedObject)
|
||||||
@@ -2257,6 +2288,7 @@ void Variant::SetManagedObject(_MonoObject* object)
|
|||||||
SetType(VariantType(VariantType::ManagedObject));
|
SetType(VariantType(VariantType::ManagedObject));
|
||||||
AsUint = 0;
|
AsUint = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::SetAsset(Asset* asset)
|
void Variant::SetAsset(Asset* asset)
|
||||||
@@ -2338,10 +2370,12 @@ String Variant::ToString() const
|
|||||||
return (*(Ray*)AsBlob.Data).ToString();
|
return (*(Ray*)AsBlob.Data).ToString();
|
||||||
case VariantType::Matrix:
|
case VariantType::Matrix:
|
||||||
return (*(Matrix*)AsBlob.Data).ToString();
|
return (*(Matrix*)AsBlob.Data).ToString();
|
||||||
case VariantType::ManagedObject:
|
|
||||||
return AsUint ? String(MUtils::ToString(mono_object_to_string(mono_gchandle_get_target(AsUint), nullptr))) : TEXT("null");
|
|
||||||
case VariantType::Typename:
|
case VariantType::Typename:
|
||||||
return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0);
|
return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0);
|
||||||
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
|
return AsUint ? String(MUtils::ToString(mono_object_to_string(mono_gchandle_get_target(AsUint), nullptr))) : TEXT("null");
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return String::Empty;
|
return String::Empty;
|
||||||
}
|
}
|
||||||
@@ -3110,6 +3144,7 @@ void Variant::AllocStructure()
|
|||||||
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
|
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
|
||||||
*((int16*)AsBlob.Data) = 0;
|
*((int16*)AsBlob.Data) = 0;
|
||||||
}
|
}
|
||||||
|
#if USE_MONO
|
||||||
else if (const auto mclass = Scripting::FindClass(typeName))
|
else if (const auto mclass = Scripting::FindClass(typeName))
|
||||||
{
|
{
|
||||||
// Fallback to C#-only types
|
// Fallback to C#-only types
|
||||||
@@ -3134,6 +3169,7 @@ void Variant::AllocStructure()
|
|||||||
AsBlob.Length = 0;
|
AsBlob.Length = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (typeName.Length() != 0)
|
if (typeName.Length() != 0)
|
||||||
@@ -3213,10 +3249,12 @@ uint32 GetHash(const Variant& key)
|
|||||||
return GetHash(*(Color*)key.AsData);
|
return GetHash(*(Color*)key.AsData);
|
||||||
case VariantType::Guid:
|
case VariantType::Guid:
|
||||||
return GetHash(*(Guid*)key.AsData);
|
return GetHash(*(Guid*)key.AsData);
|
||||||
case VariantType::ManagedObject:
|
|
||||||
return key.AsUint ? (uint32)mono_object_hash(mono_gchandle_get_target(key.AsUint)) : 0;
|
|
||||||
case VariantType::Typename:
|
case VariantType::Typename:
|
||||||
return GetHash((const char*)key.AsBlob.Data);
|
return GetHash((const char*)key.AsBlob.Data);
|
||||||
|
case VariantType::ManagedObject:
|
||||||
|
#if USE_MONO
|
||||||
|
return key.AsUint ? (uint32)mono_object_hash(mono_gchandle_get_target(key.AsUint)) : 0;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
#include "FlaxEngine.Gen.h"
|
#include "FlaxEngine.Gen.h"
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/exception.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/exception.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
|
||||||
@@ -61,8 +64,11 @@ bool CacheMethods()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void DebugLog::Log(LogType type, const StringView& message)
|
void DebugLog::Log(LogType type, const StringView& message)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (CacheMethods())
|
if (CacheMethods())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -77,34 +83,41 @@ void DebugLog::Log(LogType type, const StringView& message)
|
|||||||
params.AddParam(stackTrace, scriptsDomain->GetNative());
|
params.AddParam(stackTrace, scriptsDomain->GetNative());
|
||||||
#endif
|
#endif
|
||||||
MainThreadManagedInvokeAction::Invoke(Internal_SendLog, params);
|
MainThreadManagedInvokeAction::Invoke(Internal_SendLog, params);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::LogException(MonoObject* exceptionObject)
|
void DebugLog::LogException(MObject* exceptionObject)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (exceptionObject == nullptr || CacheMethods())
|
if (exceptionObject == nullptr || CacheMethods())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MainThreadManagedInvokeAction::ParamsBuilder params;
|
MainThreadManagedInvokeAction::ParamsBuilder params;
|
||||||
params.AddParam(exceptionObject);
|
params.AddParam(exceptionObject);
|
||||||
MainThreadManagedInvokeAction::Invoke(Internal_SendLogException, params);
|
MainThreadManagedInvokeAction::Invoke(Internal_SendLogException, params);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
String DebugLog::GetStackTrace()
|
String DebugLog::GetStackTrace()
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
|
#if USE_MONO
|
||||||
if (!CacheMethods())
|
if (!CacheMethods())
|
||||||
{
|
{
|
||||||
auto stackTraceObj = Internal_GetStackTrace->Invoke(nullptr, nullptr, nullptr);
|
auto stackTraceObj = Internal_GetStackTrace->Invoke(nullptr, nullptr, nullptr);
|
||||||
MUtils::ToString((MonoString*)stackTraceObj, result);
|
MUtils::ToString((MonoString*)stackTraceObj, result);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::ThrowException(const char* msg)
|
void DebugLog::ThrowException(const char* msg)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Throw exception to the C# world
|
// Throw exception to the C# world
|
||||||
auto ex = mono_exception_from_name_msg(mono_get_corlib(), "System", "Exception", msg);
|
auto ex = mono_exception_from_name_msg(mono_get_corlib(), "System", "Exception", msg);
|
||||||
mono_raise_exception(ex);
|
mono_raise_exception(ex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::ThrowNullReference()
|
void DebugLog::ThrowNullReference()
|
||||||
@@ -112,35 +125,45 @@ void DebugLog::ThrowNullReference()
|
|||||||
//LOG(Warning, "Invalid null reference.");
|
//LOG(Warning, "Invalid null reference.");
|
||||||
//LOG_STR(Warning, DebugLog::GetStackTrace());
|
//LOG_STR(Warning, DebugLog::GetStackTrace());
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
// Throw exception to the C# world
|
// Throw exception to the C# world
|
||||||
auto ex = mono_get_exception_null_reference();
|
auto ex = mono_get_exception_null_reference();
|
||||||
mono_raise_exception(ex);
|
mono_raise_exception(ex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::ThrowArgument(const char* arg, const char* msg)
|
void DebugLog::ThrowArgument(const char* arg, const char* msg)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Throw exception to the C# world
|
// Throw exception to the C# world
|
||||||
auto ex = mono_get_exception_argument(arg, msg);
|
auto ex = mono_get_exception_argument(arg, msg);
|
||||||
mono_raise_exception(ex);
|
mono_raise_exception(ex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::ThrowArgumentNull(const char* arg)
|
void DebugLog::ThrowArgumentNull(const char* arg)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Throw exception to the C# world
|
// Throw exception to the C# world
|
||||||
auto ex = mono_get_exception_argument_null(arg);
|
auto ex = mono_get_exception_argument_null(arg);
|
||||||
mono_raise_exception(ex);
|
mono_raise_exception(ex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::ThrowArgumentOutOfRange(const char* arg)
|
void DebugLog::ThrowArgumentOutOfRange(const char* arg)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Throw exception to the C# world
|
// Throw exception to the C# world
|
||||||
auto ex = mono_get_exception_argument_out_of_range(arg);
|
auto ex = mono_get_exception_argument_out_of_range(arg);
|
||||||
mono_raise_exception(ex);
|
mono_raise_exception(ex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLog::ThrowNotSupported(const char* msg)
|
void DebugLog::ThrowNotSupported(const char* msg)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Throw exception to the C# world
|
// Throw exception to the C# world
|
||||||
auto ex = mono_get_exception_not_supported(msg);
|
auto ex = mono_get_exception_not_supported(msg);
|
||||||
mono_raise_exception(ex);
|
mono_raise_exception(ex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
/// Logs a formatted exception message to the Flax Console.
|
/// Logs a formatted exception message to the Flax Console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="exceptionObject">Runtime Exception.</param>
|
/// <param name="exceptionObject">Runtime Exception.</param>
|
||||||
static void LogException(MonoObject* exceptionObject);
|
static void LogException(MObject* exceptionObject);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -605,7 +605,7 @@ void EngineImpl::InitMainWindow()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !USE_EDITOR
|
#if !USE_EDITOR && !COMPILE_WITHOUT_CSHARP
|
||||||
// Inform the managed runtime about the window (game can link GUI to it)
|
// Inform the managed runtime about the window (game can link GUI to it)
|
||||||
auto scriptingClass = Scripting::GetStaticClass();
|
auto scriptingClass = Scripting::GetStaticClass();
|
||||||
ASSERT(scriptingClass);
|
ASSERT(scriptingClass);
|
||||||
@@ -613,7 +613,7 @@ void EngineImpl::InitMainWindow()
|
|||||||
ASSERT(setWindowMethod);
|
ASSERT(setWindowMethod);
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = Engine::MainWindow->GetOrCreateManagedInstance();
|
params[0] = Engine::MainWindow->GetOrCreateManagedInstance();
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
setWindowMethod->Invoke(nullptr, params, &exception);
|
setWindowMethod->Invoke(nullptr, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
#include "Engine/Renderer/RenderList.h"
|
#include "Engine/Renderer/RenderList.h"
|
||||||
#include "Engine/Serialization/MemoryReadStream.h"
|
#include "Engine/Serialization/MemoryReadStream.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -106,6 +108,8 @@ namespace
|
|||||||
return mesh->UpdateMesh(vertexCount, triangleCount, (VB0ElementType*)vertices, vb1.Get(), vb2.HasItems() ? vb2.Get() : nullptr, triangles);
|
return mesh->UpdateMesh(vertexCount, triangleCount, (VB0ElementType*)vertices, vb1.Get(), vb2.HasItems() ? vb2.Get() : nullptr, triangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
bool UpdateMesh(Mesh* mesh, uint32 vertexCount, uint32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj)
|
bool UpdateMesh(Mesh* mesh, uint32 vertexCount, uint32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj)
|
||||||
{
|
{
|
||||||
@@ -132,6 +136,8 @@ namespace
|
|||||||
|
|
||||||
return mesh->UpdateTriangles(triangleCount, ib);
|
return mesh->UpdateTriangles(triangleCount, ib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mesh::HasVertexColors() const
|
bool Mesh::HasVertexColors() const
|
||||||
@@ -591,6 +597,8 @@ ScriptingObject* Mesh::GetParentModel()
|
|||||||
return _model;
|
return _model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
bool Mesh::UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj)
|
bool Mesh::UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj)
|
||||||
{
|
{
|
||||||
return ::UpdateMesh<uint32>(this, (uint32)vertexCount, (uint32)triangleCount, verticesObj, trianglesObj, normalsObj, tangentsObj, uvObj, colorsObj);
|
return ::UpdateMesh<uint32>(this, (uint32)vertexCount, (uint32)triangleCount, verticesObj, trianglesObj, normalsObj, tangentsObj, uvObj, colorsObj);
|
||||||
@@ -763,3 +771,5 @@ bool Mesh::DownloadBuffer(bool forceGpu, MonoArray* resultObj, int32 typeI)
|
|||||||
ConvertMeshData(mesh, type, resultObj, data.Get());
|
ConvertMeshData(mesh, type, resultObj, data.Get());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -404,9 +404,11 @@ private:
|
|||||||
|
|
||||||
// Internal bindings
|
// Internal bindings
|
||||||
API_FUNCTION(NoProxy) ScriptingObject* GetParentModel();
|
API_FUNCTION(NoProxy) ScriptingObject* GetParentModel();
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
API_FUNCTION(NoProxy) bool UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj);
|
API_FUNCTION(NoProxy) bool UpdateMeshUInt(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj);
|
||||||
API_FUNCTION(NoProxy) bool UpdateMeshUShort(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj);
|
API_FUNCTION(NoProxy) bool UpdateMeshUShort(int32 vertexCount, int32 triangleCount, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj, MonoArray* colorsObj);
|
||||||
API_FUNCTION(NoProxy) bool UpdateTrianglesUInt(int32 triangleCount, MonoArray* trianglesObj);
|
API_FUNCTION(NoProxy) bool UpdateTrianglesUInt(int32 triangleCount, MonoArray* trianglesObj);
|
||||||
API_FUNCTION(NoProxy) bool UpdateTrianglesUShort(int32 triangleCount, MonoArray* trianglesObj);
|
API_FUNCTION(NoProxy) bool UpdateTrianglesUShort(int32 triangleCount, MonoArray* trianglesObj);
|
||||||
API_FUNCTION(NoProxy) bool DownloadBuffer(bool forceGpu, MonoArray* resultObj, int32 typeI);
|
API_FUNCTION(NoProxy) bool DownloadBuffer(bool forceGpu, MonoArray* resultObj, int32 typeI);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
#include "Engine/Serialization/MemoryReadStream.h"
|
#include "Engine/Serialization/MemoryReadStream.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void SkinnedMesh::Init(SkinnedModel* model, int32 lodIndex, int32 index, int32 materialSlotIndex, const BoundingBox& box, const BoundingSphere& sphere)
|
void SkinnedMesh::Init(SkinnedModel* model, int32 lodIndex, int32 index, int32 materialSlotIndex, const BoundingBox& box, const BoundingSphere& sphere)
|
||||||
{
|
{
|
||||||
@@ -316,6 +318,8 @@ ScriptingObject* SkinnedMesh::GetParentModel()
|
|||||||
return _model;
|
return _model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
bool UpdateMesh(SkinnedMesh* mesh, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj)
|
bool UpdateMesh(SkinnedMesh* mesh, MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj)
|
||||||
{
|
{
|
||||||
@@ -561,3 +565,5 @@ bool SkinnedMesh::DownloadBuffer(bool forceGpu, MonoArray* resultObj, int32 type
|
|||||||
ConvertMeshData(mesh, type, resultObj, data.Get());
|
ConvertMeshData(mesh, type, resultObj, data.Get());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -258,7 +258,9 @@ private:
|
|||||||
|
|
||||||
// Internal bindings
|
// Internal bindings
|
||||||
API_FUNCTION(NoProxy) ScriptingObject* GetParentModel();
|
API_FUNCTION(NoProxy) ScriptingObject* GetParentModel();
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
API_FUNCTION(NoProxy) bool UpdateMeshUInt(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj);
|
API_FUNCTION(NoProxy) bool UpdateMeshUInt(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj);
|
||||||
API_FUNCTION(NoProxy) bool UpdateMeshUShort(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj);
|
API_FUNCTION(NoProxy) bool UpdateMeshUShort(MonoArray* verticesObj, MonoArray* trianglesObj, MonoArray* blendIndicesObj, MonoArray* blendWeightsObj, MonoArray* normalsObj, MonoArray* tangentsObj, MonoArray* uvObj);
|
||||||
API_FUNCTION(NoProxy) bool DownloadBuffer(bool forceGpu, MonoArray* resultObj, int32 typeI);
|
API_FUNCTION(NoProxy) bool DownloadBuffer(bool forceGpu, MonoArray* resultObj, int32 typeI);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,13 +20,17 @@
|
|||||||
#include "Engine/Scripting/Script.h"
|
#include "Engine/Scripting/Script.h"
|
||||||
#include "Engine/Scripting/BinaryModule.h"
|
#include "Engine/Scripting/BinaryModule.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
#include "Engine/Renderer/Lightmaps.h"
|
#include "Engine/Renderer/Lightmaps.h"
|
||||||
#else
|
#else
|
||||||
#include "Engine/Engine/Screen.h"
|
#include "Engine/Engine/Screen.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
// TODO: use API for events and remove this manual wrapper code
|
// TODO: use API for events and remove this manual wrapper code
|
||||||
class RenderContextInternal
|
class RenderContextInternal
|
||||||
{
|
{
|
||||||
@@ -53,6 +57,8 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Array<RenderTask*> RenderTask::Tasks;
|
Array<RenderTask*> RenderTask::Tasks;
|
||||||
CriticalSection RenderTask::TasksLocker;
|
CriticalSection RenderTask::TasksLocker;
|
||||||
int32 RenderTask::TasksDoneLastFrame;
|
int32 RenderTask::TasksDoneLastFrame;
|
||||||
@@ -174,7 +180,7 @@ void ManagedPostProcessEffect::FetchInfo()
|
|||||||
args[0] = Target->GetOrCreateManagedInstance();
|
args[0] = Target->GetOrCreateManagedInstance();
|
||||||
args[1] = &_location;
|
args[1] = &_location;
|
||||||
args[2] = &_useSingleTarget;
|
args[2] = &_useSingleTarget;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
FetchInfoManaged->Invoke(nullptr, args, &exception);
|
FetchInfoManaged->Invoke(nullptr, args, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
DebugLog::LogException(exception);
|
DebugLog::LogException(exception);
|
||||||
@@ -187,6 +193,7 @@ bool ManagedPostProcessEffect::IsLoaded() const
|
|||||||
|
|
||||||
void ManagedPostProcessEffect::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output)
|
void ManagedPostProcessEffect::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const auto context = GPUDevice::Instance->GetMainContext();
|
const auto context = GPUDevice::Instance->GetMainContext();
|
||||||
auto inputObj = ScriptingObject::ToManaged(input);
|
auto inputObj = ScriptingObject::ToManaged(input);
|
||||||
auto outputObj = ScriptingObject::ToManaged(output);
|
auto outputObj = ScriptingObject::ToManaged(output);
|
||||||
@@ -203,10 +210,11 @@ void ManagedPostProcessEffect::Render(RenderContext& renderContext, GPUTexture*
|
|||||||
params[1] = &tmp;
|
params[1] = &tmp;
|
||||||
params[2] = inputObj;
|
params[2] = inputObj;
|
||||||
params[3] = outputObj;
|
params[3] = outputObj;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
renderMethod->InvokeVirtual(Target->GetOrCreateManagedInstance(), params, &exception);
|
renderMethod->InvokeVirtual(Target->GetOrCreateManagedInstance(), params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
DebugLog::LogException(exception);
|
DebugLog::LogException(exception);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneRenderTask::SceneRenderTask(const SpawnParams& params)
|
SceneRenderTask::SceneRenderTask(const SpawnParams& params)
|
||||||
@@ -340,6 +348,8 @@ void SceneRenderTask::OnBegin(GPUContext* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get custom and global PostFx
|
// Get custom and global PostFx
|
||||||
|
CustomPostFx.Clear();
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// TODO: move postFx in SceneRenderTask from C# to C++
|
// TODO: move postFx in SceneRenderTask from C# to C++
|
||||||
static MMethod* GetPostFxManaged = GetStaticClass()->GetMethod("GetPostFx", 1);
|
static MMethod* GetPostFxManaged = GetStaticClass()->GetMethod("GetPostFx", 1);
|
||||||
if (GetPostFxManaged)
|
if (GetPostFxManaged)
|
||||||
@@ -347,7 +357,8 @@ void SceneRenderTask::OnBegin(GPUContext* context)
|
|||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = &count;
|
params[0] = &count;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
|
#if USE_MONO
|
||||||
const auto objects = (MonoArray*)GetPostFxManaged->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
const auto objects = (MonoArray*)GetPostFxManaged->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
DebugLog::LogException(exception);
|
DebugLog::LogException(exception);
|
||||||
@@ -359,9 +370,9 @@ void SceneRenderTask::OnBegin(GPUContext* context)
|
|||||||
if (postFx.Target)
|
if (postFx.Target)
|
||||||
postFx.FetchInfo();
|
postFx.FetchInfo();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
CustomPostFx.Clear();
|
|
||||||
|
|
||||||
// Setup render buffers for the output rendering resolution
|
// Setup render buffers for the output rendering resolution
|
||||||
if (Output)
|
if (Output)
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
#include "Engine/Serialization/Serialization.h"
|
#include "Engine/Serialization/Serialization.h"
|
||||||
#include "Engine/Animations/CurveSerialization.h"
|
#include "Engine/Animations/CurveSerialization.h"
|
||||||
#include "Engine/Core/Math/Matrix.h"
|
#include "Engine/Core/Math/Matrix.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
Spline::Spline(const SpawnParams& params)
|
Spline::Spline(const SpawnParams& params)
|
||||||
: Actor(params)
|
: Actor(params)
|
||||||
@@ -437,6 +439,8 @@ void Spline::UpdateSpline()
|
|||||||
SplineUpdated();
|
SplineUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
void Spline::GetKeyframes(MonoArray* data)
|
void Spline::GetKeyframes(MonoArray* data)
|
||||||
{
|
{
|
||||||
Platform::MemoryCopy(mono_array_addr_with_size(data, sizeof(Keyframe), 0), Curve.GetKeyframes().Get(), sizeof(Keyframe) * Curve.GetKeyframes().Count());
|
Platform::MemoryCopy(mono_array_addr_with_size(data, sizeof(Keyframe), 0), Curve.GetKeyframes().Get(), sizeof(Keyframe) * Curve.GetKeyframes().Count());
|
||||||
@@ -450,6 +454,8 @@ void Spline::SetKeyframes(MonoArray* data)
|
|||||||
UpdateSpline();
|
UpdateSpline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
#include "Engine/Debug/DebugDraw.h"
|
#include "Engine/Debug/DebugDraw.h"
|
||||||
|
|||||||
@@ -368,8 +368,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
// Internal bindings
|
// Internal bindings
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
API_FUNCTION(NoProxy) void GetKeyframes(MonoArray* data);
|
API_FUNCTION(NoProxy) void GetKeyframes(MonoArray* data);
|
||||||
API_FUNCTION(NoProxy) void SetKeyframes(MonoArray* data);
|
API_FUNCTION(NoProxy) void SetKeyframes(MonoArray* data);
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ void SceneObject::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
stream.Guid(_parent->GetID());
|
stream.Guid(_parent->GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Handle C# objects data serialization
|
// Handle C# objects data serialization
|
||||||
if (Flags & ObjectFlags::IsManagedType)
|
if (Flags & ObjectFlags::IsManagedType)
|
||||||
{
|
{
|
||||||
@@ -130,6 +131,7 @@ void SceneObject::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
ManagedSerialization::Serialize(stream, GetOrCreateManagedInstance());
|
ManagedSerialization::Serialize(stream, GetOrCreateManagedInstance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Handle custom scripting objects data serialization
|
// Handle custom scripting objects data serialization
|
||||||
if (Flags & ObjectFlags::IsCustomScriptingType)
|
if (Flags & ObjectFlags::IsCustomScriptingType)
|
||||||
@@ -146,6 +148,7 @@ void SceneObject::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
|
|||||||
// _prefabID is deserialized by Actor/Script impl
|
// _prefabID is deserialized by Actor/Script impl
|
||||||
DESERIALIZE_MEMBER(PrefabObjectID, _prefabObjectID);
|
DESERIALIZE_MEMBER(PrefabObjectID, _prefabObjectID);
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Handle C# objects data serialization
|
// Handle C# objects data serialization
|
||||||
if (Flags & ObjectFlags::IsManagedType)
|
if (Flags & ObjectFlags::IsManagedType)
|
||||||
{
|
{
|
||||||
@@ -155,6 +158,7 @@ void SceneObject::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
|
|||||||
ManagedSerialization::Deserialize(v->value, GetOrCreateManagedInstance());
|
ManagedSerialization::Deserialize(v->value, GetOrCreateManagedInstance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Handle custom scripting objects data serialization
|
// Handle custom scripting objects data serialization
|
||||||
if (Flags & ObjectFlags::IsCustomScriptingType)
|
if (Flags & ObjectFlags::IsCustomScriptingType)
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ CultureInfo::CultureInfo(int32 lcid)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#error "Missing CultureInfo implementation."
|
|
||||||
#endif
|
#endif
|
||||||
if (!_data)
|
if (!_data)
|
||||||
{
|
{
|
||||||
@@ -89,8 +87,6 @@ CultureInfo::CultureInfo(const StringAnsiView& name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#error "Missing CultureInfo implementation."
|
|
||||||
#endif
|
#endif
|
||||||
if (!_data)
|
if (!_data)
|
||||||
{
|
{
|
||||||
@@ -132,8 +128,6 @@ bool CultureInfo::IsRightToLeft() const
|
|||||||
const auto data = static_cast<CultureInfoEntry*>(_data);
|
const auto data = static_cast<CultureInfoEntry*>(_data);
|
||||||
if (data)
|
if (data)
|
||||||
return data->text_info.is_right_to_left ? true : false;
|
return data->text_info.is_right_to_left ? true : false;
|
||||||
#else
|
|
||||||
#error "Missing CultureInfo implementation."
|
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,11 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
// Helper macros for calling C# events
|
// Helper macros for calling C# events
|
||||||
#define BEGIN_INVOKE_EVENT(name, paramsCount) \
|
#define BEGIN_INVOKE_EVENT(name, paramsCount) \
|
||||||
auto managedInstance = GetManagedInstance(); \
|
auto managedInstance = GetManagedInstance(); \
|
||||||
@@ -42,7 +45,7 @@
|
|||||||
params[0] = param0; \
|
params[0] = param0; \
|
||||||
params[1] = param1; \
|
params[1] = param1; \
|
||||||
params[2] = param2; \
|
params[2] = param2; \
|
||||||
MonoObject* exception = nullptr; \
|
MObject* exception = nullptr; \
|
||||||
_method_##name->Invoke(managedInstance, params, &exception); \
|
_method_##name->Invoke(managedInstance, params, &exception); \
|
||||||
END_INVOKE_EVENT(name)
|
END_INVOKE_EVENT(name)
|
||||||
#define INVOKE_EVENT_PARAMS_3(name, param0, param1, param2) INVOKE_EVENT(name, 3, param0, param1, param2)
|
#define INVOKE_EVENT_PARAMS_3(name, param0, param1, param2) INVOKE_EVENT(name, 3, param0, param1, param2)
|
||||||
@@ -69,11 +72,19 @@
|
|||||||
for (int32 i = 0; i < outputData.Count(); i++) \
|
for (int32 i = 0; i < outputData.Count(); i++) \
|
||||||
*(MonoString**)mono_array_addr_with_size(outputDataMono, sizeof(MonoString*), i) = MUtils::ToString(outputData[i]); \
|
*(MonoString**)mono_array_addr_with_size(outputDataMono, sizeof(MonoString*), i) = MUtils::ToString(outputData[i]); \
|
||||||
params[2] = outputDataMono; \
|
params[2] = outputDataMono; \
|
||||||
MonoObject* exception = nullptr; \
|
MObject* exception = nullptr; \
|
||||||
auto resultObj = _method_##name->Invoke(GetManagedInstance(), params, &exception); \
|
auto resultObj = _method_##name->Invoke(GetManagedInstance(), params, &exception); \
|
||||||
if (resultObj) \
|
if (resultObj) \
|
||||||
result = (DragDropEffect)MUtils::Unbox<int32>(resultObj); \
|
result = (DragDropEffect)MUtils::Unbox<int32>(resultObj); \
|
||||||
END_INVOKE_EVENT(name)
|
END_INVOKE_EVENT(name)
|
||||||
|
#else
|
||||||
|
#define INVOKE_EVENT(name, paramsCount, param0, param1, param2)
|
||||||
|
#define INVOKE_EVENT_PARAMS_3(name, param0, param1, param2) INVOKE_EVENT(name, 3, param0, param1, param2)
|
||||||
|
#define INVOKE_EVENT_PARAMS_2(name, param0, param1) INVOKE_EVENT(name, 2, param0, param1, nullptr)
|
||||||
|
#define INVOKE_EVENT_PARAMS_1(name, param0) INVOKE_EVENT(name, 1, param0, nullptr, nullptr)
|
||||||
|
#define INVOKE_EVENT_PARAMS_0(name) INVOKE_EVENT(name, 0, nullptr, nullptr, nullptr)
|
||||||
|
#define INVOKE_DRAG_EVENT(name)
|
||||||
|
#endif
|
||||||
|
|
||||||
WindowBase::WindowBase(const CreateWindowSettings& settings)
|
WindowBase::WindowBase(const CreateWindowSettings& settings)
|
||||||
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
|
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ Delegate<ScriptingObject*, Span<Variant>, ScriptingTypeHandle, StringView> Scrip
|
|||||||
|
|
||||||
ManagedBinaryModule* GetBinaryModuleCorlib()
|
ManagedBinaryModule* GetBinaryModuleCorlib()
|
||||||
{
|
{
|
||||||
|
#if COMPILE_WITHOUT_CSHARP
|
||||||
|
return nullptr;
|
||||||
|
#else
|
||||||
static ManagedBinaryModule assembly("corlib", MAssemblyOptions(false)); // Don't precache all corlib classes
|
static ManagedBinaryModule assembly("corlib", MAssemblyOptions(false)); // Don't precache all corlib classes
|
||||||
return &assembly;
|
return &assembly;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptingTypeHandle::ScriptingTypeHandle(const ScriptingTypeInitializer& initializer)
|
ScriptingTypeHandle::ScriptingTypeHandle(const ScriptingTypeInitializer& initializer)
|
||||||
@@ -698,6 +702,8 @@ ScriptingObject* ManagedBinaryModule::ManagedObjectSpawn(const ScriptingObjectSp
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
MMethod* FindMethod(MClass* mclass, const MMethod* referenceMethod)
|
MMethod* FindMethod(MClass* mclass, const MMethod* referenceMethod)
|
||||||
@@ -719,6 +725,8 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature)
|
MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature)
|
||||||
{
|
{
|
||||||
if (!mclass)
|
if (!mclass)
|
||||||
@@ -726,6 +734,7 @@ MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMeth
|
|||||||
const auto& methods = mclass->GetMethods();
|
const auto& methods = mclass->GetMethods();
|
||||||
for (MMethod* method : methods)
|
for (MMethod* method : methods)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoMethodSignature* sig = mono_method_signature(method->GetNative());
|
MonoMethodSignature* sig = mono_method_signature(method->GetNative());
|
||||||
if (method->IsStatic() != signature.IsStatic ||
|
if (method->IsStatic() != signature.IsStatic ||
|
||||||
method->GetName() != signature.Name ||
|
method->GetName() != signature.Name ||
|
||||||
@@ -746,10 +755,13 @@ MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMeth
|
|||||||
}
|
}
|
||||||
if (isValid && MUtils::GetClass(signature.ReturnType) == mono_class_from_mono_type(mono_signature_get_return_type(sig)))
|
if (isValid && MUtils::GetClass(signature.ReturnType) == mono_class_from_mono_type(mono_signature_get_return_type(sig)))
|
||||||
return method;
|
return method;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
ManagedBinaryModule* ManagedBinaryModule::FindModule(MonoClass* klass)
|
ManagedBinaryModule* ManagedBinaryModule::FindModule(MonoClass* klass)
|
||||||
{
|
{
|
||||||
// TODO: consider caching lookup table MonoImage* -> ManagedBinaryModule*
|
// TODO: consider caching lookup table MonoImage* -> ManagedBinaryModule*
|
||||||
@@ -782,6 +794,8 @@ ScriptingTypeHandle ManagedBinaryModule::FindType(MonoClass* klass)
|
|||||||
return ScriptingTypeHandle();
|
return ScriptingTypeHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void ManagedBinaryModule::OnLoading(MAssembly* assembly)
|
void ManagedBinaryModule::OnLoading(MAssembly* assembly)
|
||||||
{
|
{
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
@@ -793,6 +807,7 @@ void ManagedBinaryModule::OnLoading(MAssembly* assembly)
|
|||||||
|
|
||||||
void ManagedBinaryModule::OnLoaded(MAssembly* assembly)
|
void ManagedBinaryModule::OnLoaded(MAssembly* assembly)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
ASSERT(ClassToTypeIndex.IsEmpty());
|
ASSERT(ClassToTypeIndex.IsEmpty());
|
||||||
|
|
||||||
@@ -849,10 +864,12 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly)
|
|||||||
InitType(mclass);
|
InitType(mclass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedBinaryModule::InitType(MClass* mclass)
|
void ManagedBinaryModule::InitType(MClass* mclass)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Skip if already initialized
|
// Skip if already initialized
|
||||||
const MString& typeName = mclass->GetFullName();
|
const MString& typeName = mclass->GetFullName();
|
||||||
if (TypeNameToTypeIndex.ContainsKey(typeName))
|
if (TypeNameToTypeIndex.ContainsKey(typeName))
|
||||||
@@ -992,6 +1009,7 @@ void ManagedBinaryModule::InitType(MClass* mclass)
|
|||||||
// Move to the next entry (table is null terminated)
|
// Move to the next entry (table is null terminated)
|
||||||
scriptVTable++;
|
scriptVTable++;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedBinaryModule::OnUnloading(MAssembly* assembly)
|
void ManagedBinaryModule::OnUnloading(MAssembly* assembly)
|
||||||
@@ -1020,7 +1038,9 @@ void ManagedBinaryModule::OnUnloading(MAssembly* assembly)
|
|||||||
type.Script.ScriptVTable = nullptr;
|
type.Script.ScriptVTable = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
ClassToTypeIndex.Clear();
|
ClassToTypeIndex.Clear();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const StringAnsi& ManagedBinaryModule::GetName() const
|
const StringAnsi& ManagedBinaryModule::GetName() const
|
||||||
@@ -1030,7 +1050,11 @@ const StringAnsi& ManagedBinaryModule::GetName() const
|
|||||||
|
|
||||||
bool ManagedBinaryModule::IsLoaded() const
|
bool ManagedBinaryModule::IsLoaded() const
|
||||||
{
|
{
|
||||||
|
#if COMPILE_WITHOUT_CSHARP
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
return Assembly->IsLoaded();
|
return Assembly->IsLoaded();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ManagedBinaryModule::FindMethod(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name, int32 numParams)
|
void* ManagedBinaryModule::FindMethod(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name, int32 numParams)
|
||||||
@@ -1047,6 +1071,7 @@ void* ManagedBinaryModule::FindMethod(const ScriptingTypeHandle& typeHandle, con
|
|||||||
|
|
||||||
bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Span<Variant> paramValues, Variant& result)
|
bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Span<Variant> paramValues, Variant& result)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const auto mMethod = (MMethod*)method;
|
const auto mMethod = (MMethod*)method;
|
||||||
MonoMethodSignature* signature = mono_method_signature(mMethod->GetNative());
|
MonoMethodSignature* signature = mono_method_signature(mMethod->GetNative());
|
||||||
void* signatureParams = nullptr;
|
void* signatureParams = nullptr;
|
||||||
@@ -1101,7 +1126,7 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the method
|
// Invoke the method
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
MonoObject* resultObject = withInterfaces ? mMethod->InvokeVirtual((MonoObject*)mInstance, params, &exception) : mMethod->Invoke(mInstance, params, &exception);
|
MonoObject* resultObject = withInterfaces ? mMethod->InvokeVirtual((MonoObject*)mInstance, params, &exception) : mMethod->Invoke(mInstance, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -1164,10 +1189,14 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedBinaryModule::GetMethodSignature(void* method, ScriptingTypeMethodSignature& signature)
|
void ManagedBinaryModule::GetMethodSignature(void* method, ScriptingTypeMethodSignature& signature)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const auto mMethod = (MMethod*)method;
|
const auto mMethod = (MMethod*)method;
|
||||||
signature.Name = mMethod->GetName();
|
signature.Name = mMethod->GetName();
|
||||||
signature.IsStatic = mMethod->IsStatic();
|
signature.IsStatic = mMethod->IsStatic();
|
||||||
@@ -1183,6 +1212,7 @@ void ManagedBinaryModule::GetMethodSignature(void* method, ScriptingTypeMethodSi
|
|||||||
param.Type = MoveTemp(MUtils::UnboxVariantType(((MonoType**)signatureParams)[paramIdx]));
|
param.Type = MoveTemp(MUtils::UnboxVariantType(((MonoType**)signatureParams)[paramIdx]));
|
||||||
param.IsOut = mono_signature_param_is_out(sig, paramIdx) != 0;
|
param.IsOut = mono_signature_param_is_out(sig, paramIdx) != 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ManagedBinaryModule::FindField(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name)
|
void* ManagedBinaryModule::FindField(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name)
|
||||||
@@ -1193,14 +1223,17 @@ void* ManagedBinaryModule::FindField(const ScriptingTypeHandle& typeHandle, cons
|
|||||||
|
|
||||||
void ManagedBinaryModule::GetFieldSignature(void* field, ScriptingTypeFieldSignature& fieldSignature)
|
void ManagedBinaryModule::GetFieldSignature(void* field, ScriptingTypeFieldSignature& fieldSignature)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const auto mField = (MField*)field;
|
const auto mField = (MField*)field;
|
||||||
fieldSignature.Name = mField->GetName();
|
fieldSignature.Name = mField->GetName();
|
||||||
fieldSignature.ValueType = MoveTemp(MUtils::UnboxVariantType(mField->GetType().GetNative()));
|
fieldSignature.ValueType = MoveTemp(MUtils::UnboxVariantType(mField->GetType().GetNative()));
|
||||||
fieldSignature.IsStatic = mField->IsStatic();
|
fieldSignature.IsStatic = mField->IsStatic();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Variant& result)
|
bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Variant& result)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const auto mField = (MField*)field;
|
const auto mField = (MField*)field;
|
||||||
|
|
||||||
// Get instance object
|
// Get instance object
|
||||||
@@ -1225,10 +1258,14 @@ bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Va
|
|||||||
MonoObject* resultObject = mField->GetValueBoxed(instanceObject);
|
MonoObject* resultObject = mField->GetValueBoxed(instanceObject);
|
||||||
result = MUtils::UnboxVariant(resultObject);
|
result = MUtils::UnboxVariant(resultObject);
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManagedBinaryModule::SetFieldValue(void* field, const Variant& instance, Variant& value)
|
bool ManagedBinaryModule::SetFieldValue(void* field, const Variant& instance, Variant& value)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
const auto mField = (MField*)field;
|
const auto mField = (MField*)field;
|
||||||
|
|
||||||
// Get instance object
|
// Get instance object
|
||||||
@@ -1253,6 +1290,9 @@ bool ManagedBinaryModule::SetFieldValue(void* field, const Variant& instance, Va
|
|||||||
bool failed = false;
|
bool failed = false;
|
||||||
mField->SetValue(instanceObject, MUtils::VariantToManagedArgPtr(value, mField->GetType(), failed));
|
mField->SetValue(instanceObject, MUtils::VariantToManagedArgPtr(value, mField->GetType(), failed));
|
||||||
return failed;
|
return failed;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedBinaryModule::Destroy(bool isReloading)
|
void ManagedBinaryModule::Destroy(bool isReloading)
|
||||||
|
|||||||
@@ -290,15 +290,19 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
MAssembly* Assembly;
|
MAssembly* Assembly;
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The scripting types cache that maps the managed class to the scripting type index. Build after assembly is loaded and scripting types get the managed classes information.
|
/// The scripting types cache that maps the managed class to the scripting type index. Build after assembly is loaded and scripting types get the managed classes information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Dictionary<MonoClass*, int32, HeapAllocation> ClassToTypeIndex;
|
Dictionary<MonoClass*, int32, HeapAllocation> ClassToTypeIndex;
|
||||||
|
#endif
|
||||||
|
|
||||||
static ScriptingObject* ManagedObjectSpawn(const ScriptingObjectSpawnParams& params);
|
static ScriptingObject* ManagedObjectSpawn(const ScriptingObjectSpawnParams& params);
|
||||||
static MMethod* FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature);
|
static MMethod* FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature);
|
||||||
|
#if USE_MONO
|
||||||
static ManagedBinaryModule* FindModule(MonoClass* klass);
|
static ManagedBinaryModule* FindModule(MonoClass* klass);
|
||||||
static ScriptingTypeHandle FindType(MonoClass* klass);
|
static ScriptingTypeHandle FindType(MonoClass* klass);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
#include "Engine/Debug/DebugLog.h"
|
#include "Engine/Debug/DebugLog.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
#include "ScriptingType.h"
|
#include "ScriptingType.h"
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
extern "C" FLAXENGINE_API void mono_add_internal_call(const char* name, const void* method);
|
extern "C" FLAXENGINE_API void mono_add_internal_call(const char* name, const void* method);
|
||||||
#define ADD_INTERNAL_CALL(fullName, method) mono_add_internal_call(fullName, (const void*)method)
|
#define ADD_INTERNAL_CALL(fullName, method) mono_add_internal_call(fullName, (const void*)method)
|
||||||
@@ -46,3 +49,13 @@ extern "C" FLAXENGINE_API void mono_add_internal_call(const char* name, const vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ADD_INTERNAL_CALL(fullName, method)
|
||||||
|
#define INTERNAL_CALL_CHECK(obj)
|
||||||
|
#define INTERNAL_CALL_CHECK_EXP(expression)
|
||||||
|
#define INTERNAL_CALL_CHECK_RETURN(obj, defaultValue)
|
||||||
|
#define INTERNAL_CALL_CHECK_EXP_RETURN(expression, defaultValue)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "Engine/Scripting/MException.h"
|
#include "Engine/Scripting/MException.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
namespace UtilsInternal
|
namespace UtilsInternal
|
||||||
{
|
{
|
||||||
MonoObject* ExtractArrayFromList(MonoObject* obj)
|
MonoObject* ExtractArrayFromList(MonoObject* obj)
|
||||||
@@ -70,9 +72,12 @@ namespace FlaxLogWriterInternal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void registerFlaxEngineInternalCalls()
|
void registerFlaxEngineInternalCalls()
|
||||||
{
|
{
|
||||||
AnimGraphExecutor::initRuntime();
|
AnimGraphExecutor::initRuntime();
|
||||||
|
#if USE_MONO
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCopy", &Platform::MemoryCopy);
|
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCopy", &Platform::MemoryCopy);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryClear", &Platform::MemoryClear);
|
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryClear", &Platform::MemoryClear);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCompare", &Platform::MemoryCompare);
|
ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCompare", &Platform::MemoryCompare);
|
||||||
@@ -81,4 +86,5 @@ void registerFlaxEngineInternalCalls()
|
|||||||
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal::Log);
|
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal::Log);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal::LogException);
|
ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal::LogException);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog", &FlaxLogWriterInternal::WriteStringToLog);
|
ADD_INTERNAL_CALL("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog", &FlaxLogWriterInternal::WriteStringToLog);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MField.h"
|
#include "Engine/Scripting/ManagedCLR/MField.h"
|
||||||
#include "Engine/Scripting/BinaryModule.h"
|
#include "Engine/Scripting/BinaryModule.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/debug-helpers.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/debug-helpers.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
struct ManagedBitArray
|
struct ManagedBitArray
|
||||||
{
|
{
|
||||||
template<typename AllocationType = HeapAllocation>
|
template<typename AllocationType = HeapAllocation>
|
||||||
static MonoObject* ToManaged(const BitArray<AllocationType>& data)
|
static MObject* ToManaged(const BitArray<AllocationType>& data)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// TODO: use actual System.Collections.BitArray for BitArray interop
|
// TODO: use actual System.Collections.BitArray for BitArray interop
|
||||||
@@ -53,3 +54,5 @@ struct ManagedBitArray
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MAssembly.h"
|
#include "Engine/Scripting/ManagedCLR/MAssembly.h"
|
||||||
#include "Engine/Scripting/MException.h"
|
#include "Engine/Scripting/MException.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
|
||||||
struct FLAXENGINE_API ManagedDictionary
|
struct FLAXENGINE_API ManagedDictionary
|
||||||
@@ -93,7 +94,7 @@ struct FLAXENGINE_API ManagedDictionary
|
|||||||
void* params[2];
|
void* params[2];
|
||||||
params[0] = genericType;
|
params[0] = genericType;
|
||||||
params[1] = genericArgs;
|
params[1] = genericArgs;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
auto dictionaryType = makeGenericMethod->Invoke(nullptr, params, &exception);
|
auto dictionaryType = makeGenericMethod->Invoke(nullptr, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -127,7 +128,7 @@ struct FLAXENGINE_API ManagedDictionary
|
|||||||
params[0] = Instance;
|
params[0] = Instance;
|
||||||
params[1] = key;
|
params[1] = key;
|
||||||
params[2] = value;
|
params[2] = value;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
mono_runtime_invoke(addDictionaryItemMethod->GetNative(), Instance, params, &exception);
|
mono_runtime_invoke(addDictionaryItemMethod->GetNative(), Instance, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -159,3 +160,5 @@ struct FLAXENGINE_API ManagedDictionary
|
|||||||
return mono_runtime_invoke(getItemMethod, Instance, params, nullptr);
|
return mono_runtime_invoke(getItemMethod, Instance, params, nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
#include "MException.h"
|
#include "MException.h"
|
||||||
#include "ManagedCLR/MUtils.h"
|
#include "ManagedCLR/MUtils.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
MException::MException(MonoObject* exception)
|
MException::MException(MObject* exception)
|
||||||
: InnerException(nullptr)
|
: InnerException(nullptr)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
ASSERT(exception);
|
ASSERT(exception);
|
||||||
|
|
||||||
MonoClass* exceptionClass = mono_object_get_class(exception);
|
MonoClass* exceptionClass = mono_object_get_class(exception);
|
||||||
@@ -25,6 +28,7 @@ MException::MException(MonoObject* exception)
|
|||||||
MonoObject* innerException = (MonoObject*)mono_runtime_invoke(innerExceptionGetter, exception, nullptr, nullptr);
|
MonoObject* innerException = (MonoObject*)mono_runtime_invoke(innerExceptionGetter, exception, nullptr, nullptr);
|
||||||
if (innerException)
|
if (innerException)
|
||||||
InnerException = New<MException>(innerException);
|
InnerException = New<MException>(innerException);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MException::~MException()
|
MException::~MException()
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MException"/> class.
|
/// Initializes a new instance of the <see cref="MException"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -38,12 +39,13 @@ public:
|
|||||||
: MException((MonoObject*)exception)
|
: MException((MonoObject*)exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MException"/> class.
|
/// Initializes a new instance of the <see cref="MException"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="exception">The exception object.</param>
|
/// <param name="exception">The exception object.</param>
|
||||||
explicit MException(MonoObject* exception);
|
explicit MException(MObject* exception);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disposes a instance of the <see cref="MException"/> class.
|
/// Disposes a instance of the <see cref="MException"/> class.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "Engine/Scripting/ScriptingCalls.h"
|
#include "Engine/Scripting/ScriptingCalls.h"
|
||||||
#include "MException.h"
|
#include "MException.h"
|
||||||
|
|
||||||
MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(MMethod* method, MonoObject* instance, LogType exceptionLevel)
|
MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(MMethod* method, MObject* instance, LogType exceptionLevel)
|
||||||
{
|
{
|
||||||
ASSERT_LOW_LAYER(method != nullptr);
|
ASSERT_LOW_LAYER(method != nullptr);
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(MMethod* me
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(MMethod* method, ParamsBuilder& params, MonoObject* instance, LogType exceptionLevel)
|
MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(MMethod* method, ParamsBuilder& params, MObject* instance, LogType exceptionLevel)
|
||||||
{
|
{
|
||||||
ASSERT_LOW_LAYER(method != nullptr);
|
ASSERT_LOW_LAYER(method != nullptr);
|
||||||
|
|
||||||
@@ -59,14 +59,14 @@ MainThreadManagedInvokeAction* MainThreadManagedInvokeAction::Invoke(void* metho
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainThreadManagedInvokeAction::InvokeNow(MMethod* method, ParamsBuilder& params, MonoObject* instance, LogType exceptionLevel)
|
void MainThreadManagedInvokeAction::InvokeNow(MMethod* method, ParamsBuilder& params, MObject* instance, LogType exceptionLevel)
|
||||||
{
|
{
|
||||||
ASSERT_LOW_LAYER(method != nullptr);
|
ASSERT_LOW_LAYER(method != nullptr);
|
||||||
|
|
||||||
void* paramsData[8];
|
void* paramsData[8];
|
||||||
params.GetParams(paramsData);
|
params.GetParams(paramsData);
|
||||||
|
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
method->Invoke(instance, paramsData, &exception);
|
method->Invoke(instance, paramsData, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -82,14 +82,13 @@ bool MainThreadManagedInvokeAction::Run()
|
|||||||
void* paramsData[8];
|
void* paramsData[8];
|
||||||
_params.GetParams(paramsData);
|
_params.GetParams(paramsData);
|
||||||
|
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
if (_method)
|
if (_method)
|
||||||
{
|
{
|
||||||
_method->Invoke(_instance, paramsData, &exception);
|
_method->Invoke(_instance, paramsData, &exception);
|
||||||
}
|
}
|
||||||
else
|
else if (_methodThunk)
|
||||||
{
|
{
|
||||||
ASSERT(_methodThunk);
|
|
||||||
switch (_params.Count)
|
switch (_params.Count)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public:
|
|||||||
AddParam(val);
|
AddParam(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
FORCE_INLINE void AddParam(const String& value)
|
FORCE_INLINE void AddParam(const String& value)
|
||||||
{
|
{
|
||||||
MonoString* val = MUtils::ToString(value);
|
MonoString* val = MUtils::ToString(value);
|
||||||
@@ -94,6 +95,7 @@ public:
|
|||||||
MonoString* val = MUtils::ToString(value, domain);
|
MonoString* val = MUtils::ToString(value, domain);
|
||||||
AddParam(val);
|
AddParam(val);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void GetParams(void* params[8])
|
void GetParams(void* params[8])
|
||||||
{
|
{
|
||||||
@@ -109,7 +111,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
MonoObject* _instance;
|
MObject* _instance;
|
||||||
MMethod* _method;
|
MMethod* _method;
|
||||||
void* _methodThunk;
|
void* _methodThunk;
|
||||||
LogType _exceptionLevel;
|
LogType _exceptionLevel;
|
||||||
@@ -117,7 +119,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MainThreadManagedInvokeAction(MonoObject* instance, MMethod* method, LogType exceptionLevel)
|
MainThreadManagedInvokeAction(MObject* instance, MMethod* method, LogType exceptionLevel)
|
||||||
: _instance(instance)
|
: _instance(instance)
|
||||||
, _method(method)
|
, _method(method)
|
||||||
, _methodThunk(nullptr)
|
, _methodThunk(nullptr)
|
||||||
@@ -126,7 +128,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MainThreadManagedInvokeAction(MonoObject* instance, MMethod* method, LogType exceptionLevel, const ParamsBuilder& params)
|
MainThreadManagedInvokeAction(MObject* instance, MMethod* method, LogType exceptionLevel, const ParamsBuilder& params)
|
||||||
: _instance(instance)
|
: _instance(instance)
|
||||||
, _method(method)
|
, _method(method)
|
||||||
, _methodThunk(nullptr)
|
, _methodThunk(nullptr)
|
||||||
@@ -153,7 +155,7 @@ public:
|
|||||||
/// <param name="instance">The managed instance object.</param>
|
/// <param name="instance">The managed instance object.</param>
|
||||||
/// <param name="exceptionLevel">The exception logging error level.</param>
|
/// <param name="exceptionLevel">The exception logging error level.</param>
|
||||||
/// <returns>The created task.</returns>
|
/// <returns>The created task.</returns>
|
||||||
static MainThreadManagedInvokeAction* Invoke(MMethod* method, MonoObject* instance = nullptr, LogType exceptionLevel = LogType::Error);
|
static MainThreadManagedInvokeAction* Invoke(MMethod* method, MObject* instance = nullptr, LogType exceptionLevel = LogType::Error);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the new task or invokes this action now if already running on a main thread.
|
/// Starts the new task or invokes this action now if already running on a main thread.
|
||||||
@@ -163,7 +165,7 @@ public:
|
|||||||
/// <param name="instance">The managed instance object.</param>
|
/// <param name="instance">The managed instance object.</param>
|
||||||
/// <param name="exceptionLevel">The exception logging error level.</param>
|
/// <param name="exceptionLevel">The exception logging error level.</param>
|
||||||
/// <returns>The created task.</returns>
|
/// <returns>The created task.</returns>
|
||||||
static MainThreadManagedInvokeAction* Invoke(MMethod* method, ParamsBuilder& params, MonoObject* instance = nullptr, LogType exceptionLevel = LogType::Error);
|
static MainThreadManagedInvokeAction* Invoke(MMethod* method, ParamsBuilder& params, MObject* instance = nullptr, LogType exceptionLevel = LogType::Error);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the new task or invokes this action now if already running on a main thread.
|
/// Starts the new task or invokes this action now if already running on a main thread.
|
||||||
@@ -181,7 +183,7 @@ public:
|
|||||||
/// <param name="params">The method parameters.</param>
|
/// <param name="params">The method parameters.</param>
|
||||||
/// <param name="instance">The managed instance object.</param>
|
/// <param name="instance">The managed instance object.</param>
|
||||||
/// <param name="exceptionLevel">The exception logging error level.</param>
|
/// <param name="exceptionLevel">The exception logging error level.</param>
|
||||||
static void InvokeNow(MMethod* method, ParamsBuilder& params, MonoObject* instance = nullptr, LogType exceptionLevel = LogType::Error);
|
static void InvokeNow(MMethod* method, ParamsBuilder& params, MObject* instance = nullptr, LogType exceptionLevel = LogType::Error);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MAssembly.h"
|
#include "MAssembly.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
#include "MDomain.h"
|
#include "MDomain.h"
|
||||||
#include "MUtils.h"
|
#include "MUtils.h"
|
||||||
@@ -19,14 +16,14 @@
|
|||||||
#include "Engine/Platform/File.h"
|
#include "Engine/Platform/File.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/assembly.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/assembly.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/tokentype.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/tokentype.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
MAssembly::MAssembly(MDomain* domain, const StringAnsiView& name, const MAssemblyOptions& options)
|
MAssembly::MAssembly(MDomain* domain, const StringAnsiView& name, const MAssemblyOptions& options)
|
||||||
: _monoAssembly(nullptr)
|
: _domain(domain)
|
||||||
, _monoImage(nullptr)
|
|
||||||
, _domain(domain)
|
|
||||||
, _isLoaded(false)
|
, _isLoaded(false)
|
||||||
, _isLoading(false)
|
, _isLoading(false)
|
||||||
, _isDependency(false)
|
, _isDependency(false)
|
||||||
@@ -83,6 +80,8 @@ bool MAssembly::Load(const String& assemblyPath)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
bool MAssembly::Load(MonoImage* monoImage)
|
bool MAssembly::Load(MonoImage* monoImage)
|
||||||
{
|
{
|
||||||
if (IsLoaded())
|
if (IsLoaded())
|
||||||
@@ -116,6 +115,8 @@ bool MAssembly::Load(MonoImage* monoImage)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void MAssembly::Unload(bool isReloading)
|
void MAssembly::Unload(bool isReloading)
|
||||||
{
|
{
|
||||||
if (!IsLoaded())
|
if (!IsLoaded())
|
||||||
@@ -125,6 +126,7 @@ void MAssembly::Unload(bool isReloading)
|
|||||||
Unloading(this);
|
Unloading(this);
|
||||||
|
|
||||||
// Close runtime
|
// Close runtime
|
||||||
|
#if USE_MONO
|
||||||
if (_monoImage)
|
if (_monoImage)
|
||||||
{
|
{
|
||||||
if (isReloading)
|
if (isReloading)
|
||||||
@@ -143,6 +145,7 @@ void MAssembly::Unload(bool isReloading)
|
|||||||
_monoAssembly = nullptr;
|
_monoAssembly = nullptr;
|
||||||
_monoImage = nullptr;
|
_monoImage = nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
_debugData.Resize(0);
|
_debugData.Resize(0);
|
||||||
@@ -190,6 +193,8 @@ MClass* MAssembly::GetClass(const StringAnsiView& fullname) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
MClass* MAssembly::GetClass(MonoClass* monoClass) const
|
MClass* MAssembly::GetClass(MonoClass* monoClass) const
|
||||||
{
|
{
|
||||||
if (monoClass == nullptr || !IsLoaded() || mono_class_get_image(monoClass) != _monoImage)
|
if (monoClass == nullptr || !IsLoaded() || mono_class_get_image(monoClass) != _monoImage)
|
||||||
@@ -226,11 +231,16 @@ MonoReflectionAssembly* MAssembly::GetNative() const
|
|||||||
return mono_assembly_get_object(mono_domain_get(), _monoAssembly);
|
return mono_assembly_get_object(mono_domain_get(), _monoAssembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
||||||
{
|
{
|
||||||
if (_hasCachedClasses || !IsLoaded())
|
if (_hasCachedClasses || !IsLoaded())
|
||||||
return _classes;
|
return _classes;
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
|
const auto startTime = DateTime::NowUTC();
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
#if TRACY_ENABLE
|
#if TRACY_ENABLE
|
||||||
const StringAnsiView monoImageName(mono_image_get_name(_monoImage));
|
const StringAnsiView monoImageName(mono_image_get_name(_monoImage));
|
||||||
ZoneText(*monoImageName, monoImageName.Length());
|
ZoneText(*monoImageName, monoImageName.Length());
|
||||||
@@ -239,9 +249,6 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
|||||||
if (_hasCachedClasses)
|
if (_hasCachedClasses)
|
||||||
return _classes;
|
return _classes;
|
||||||
ASSERT(_classes.IsEmpty());
|
ASSERT(_classes.IsEmpty());
|
||||||
|
|
||||||
const auto startTime = DateTime::NowUTC();
|
|
||||||
|
|
||||||
const int32 numRows = mono_image_get_table_rows(_monoImage, MONO_TABLE_TYPEDEF);
|
const int32 numRows = mono_image_get_table_rows(_monoImage, MONO_TABLE_TYPEDEF);
|
||||||
_classes.EnsureCapacity(numRows * 4);
|
_classes.EnsureCapacity(numRows * 4);
|
||||||
for (int32 i = 1; i < numRows; i++) // Skip <Module> class
|
for (int32 i = 1; i < numRows; i++) // Skip <Module> class
|
||||||
@@ -256,6 +263,7 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
|||||||
auto mclass = New<MClass>(this, klass, fullname);
|
auto mclass = New<MClass>(this, klass, fullname);
|
||||||
_classes.Add(fullname, mclass);
|
_classes.Add(fullname, mclass);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const auto endTime = DateTime::NowUTC();
|
const auto endTime = DateTime::NowUTC();
|
||||||
LOG(Info, "Caching classes for assembly {0} took {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds());
|
LOG(Info, "Caching classes for assembly {0} took {1}ms", String(_name), (int32)(endTime - startTime).GetTotalMilliseconds());
|
||||||
@@ -271,6 +279,7 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
|||||||
|
|
||||||
bool MAssembly::LoadDefault(const String& assemblyPath)
|
bool MAssembly::LoadDefault(const String& assemblyPath)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// With this method of loading we need to make sure, we won't try to load assembly again if its loaded somewhere.
|
// With this method of loading we need to make sure, we won't try to load assembly again if its loaded somewhere.
|
||||||
auto assembly = mono_domain_assembly_open(_domain->GetNative(), assemblyPath.ToStringAnsi().Get());
|
auto assembly = mono_domain_assembly_open(_domain->GetNative(), assemblyPath.ToStringAnsi().Get());
|
||||||
if (!assembly)
|
if (!assembly)
|
||||||
@@ -283,17 +292,18 @@ bool MAssembly::LoadDefault(const String& assemblyPath)
|
|||||||
mono_assembly_close(assembly);
|
mono_assembly_close(assembly);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register in domain
|
|
||||||
_domain->_assemblies[_name] = this;
|
|
||||||
|
|
||||||
// Set state
|
|
||||||
_monoAssembly = assembly;
|
_monoAssembly = assembly;
|
||||||
_monoImage = assemblyImage;
|
_monoImage = assemblyImage;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set state
|
||||||
_isDependency = false;
|
_isDependency = false;
|
||||||
_hasCachedClasses = false;
|
_hasCachedClasses = false;
|
||||||
_isFileLocked = true;
|
_isFileLocked = true;
|
||||||
_assemblyPath = assemblyPath;
|
_assemblyPath = assemblyPath;
|
||||||
|
|
||||||
|
// Register in domain
|
||||||
|
_domain->_assemblies[_name] = this;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -307,6 +317,7 @@ bool MAssembly::LoadWithImage(const String& assemblyPath)
|
|||||||
Array<byte> data;
|
Array<byte> data;
|
||||||
File::ReadAllBytes(assemblyPath, data);
|
File::ReadAllBytes(assemblyPath, data);
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
// Init Mono image
|
// Init Mono image
|
||||||
MonoImageOpenStatus status;
|
MonoImageOpenStatus status;
|
||||||
const auto name = assemblyPath.ToStringAnsi();
|
const auto name = assemblyPath.ToStringAnsi();
|
||||||
@@ -359,10 +370,11 @@ bool MAssembly::LoadWithImage(const String& assemblyPath)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set state
|
|
||||||
_monoAssembly = assembly;
|
_monoAssembly = assembly;
|
||||||
_monoImage = assemblyImage;
|
_monoImage = assemblyImage;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set state
|
||||||
_isDependency = false;
|
_isDependency = false;
|
||||||
_hasCachedClasses = false;
|
_hasCachedClasses = false;
|
||||||
_isFileLocked = false;
|
_isFileLocked = false;
|
||||||
@@ -379,7 +391,7 @@ void MAssembly::OnLoading()
|
|||||||
|
|
||||||
// Pick a domain
|
// Pick a domain
|
||||||
if (_domain == nullptr)
|
if (_domain == nullptr)
|
||||||
_domain = MCore::Instance()->GetActiveDomain();
|
_domain = MCore::GetActiveDomain();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MAssembly::OnLoaded(const DateTime& startTime)
|
void MAssembly::OnLoaded(const DateTime& startTime)
|
||||||
@@ -405,5 +417,3 @@ void MAssembly::OnLoadFailed()
|
|||||||
|
|
||||||
LoadFailed(this);
|
LoadFailed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
class FLAXENGINE_API MAssembly
|
class FLAXENGINE_API MAssembly
|
||||||
{
|
{
|
||||||
friend MDomain;
|
friend MDomain;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef Dictionary<MString, MClass*> ClassesDictionary;
|
typedef Dictionary<MString, MClass*> ClassesDictionary;
|
||||||
@@ -24,8 +23,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
MonoAssembly* _monoAssembly;
|
MonoAssembly* _monoAssembly = nullptr;
|
||||||
MonoImage* _monoImage;
|
MonoImage* _monoImage = nullptr;
|
||||||
#endif
|
#endif
|
||||||
MDomain* _domain;
|
MDomain* _domain;
|
||||||
|
|
||||||
@@ -98,7 +97,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if assembly is during loading state.
|
/// Returns true if assembly is during loading state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if is loading, otherwise false.</returns>
|
|
||||||
FORCE_INLINE bool IsLoading() const
|
FORCE_INLINE bool IsLoading() const
|
||||||
{
|
{
|
||||||
return _isLoading != 0;
|
return _isLoading != 0;
|
||||||
@@ -107,7 +105,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if assembly has been loaded.
|
/// Returns true if assembly has been loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if is loaded, otherwise false.</returns>
|
|
||||||
FORCE_INLINE bool IsLoaded() const
|
FORCE_INLINE bool IsLoaded() const
|
||||||
{
|
{
|
||||||
return _isLoaded != 0;
|
return _isLoaded != 0;
|
||||||
@@ -116,7 +113,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the assembly name.
|
/// Gets the assembly name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The assembly name.</returns>
|
|
||||||
FORCE_INLINE const MString& GetName() const
|
FORCE_INLINE const MString& GetName() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
@@ -125,7 +121,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the assembly name as string.
|
/// Gets the assembly name as string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The assembly name.</returns>
|
|
||||||
String ToString() const;
|
String ToString() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -134,7 +129,6 @@ public:
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If assembly was made from scratch (empty), path will return null.
|
/// If assembly was made from scratch (empty), path will return null.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>The assembly path.</returns>
|
|
||||||
FORCE_INLINE const String& GetAssemblyPath() const
|
FORCE_INLINE const String& GetAssemblyPath() const
|
||||||
{
|
{
|
||||||
return _assemblyPath;
|
return _assemblyPath;
|
||||||
@@ -143,20 +137,15 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the parent domain.
|
/// Gets the parent domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The domain object.</returns>
|
|
||||||
FORCE_INLINE MDomain* GetDomain() const
|
FORCE_INLINE MDomain* GetDomain() const
|
||||||
{
|
{
|
||||||
return _domain;
|
return _domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Mono assembly.
|
/// Gets the Mono assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The Mono assembly.</returns>
|
|
||||||
FORCE_INLINE MonoAssembly* GetMonoAssembly() const
|
FORCE_INLINE MonoAssembly* GetMonoAssembly() const
|
||||||
{
|
{
|
||||||
return _monoAssembly;
|
return _monoAssembly;
|
||||||
@@ -165,25 +154,22 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Mono image.
|
/// Gets the Mono image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The Mono image.</returns>
|
|
||||||
FORCE_INLINE MonoImage* GetMonoImage() const
|
FORCE_INLINE MonoImage* GetMonoImage() const
|
||||||
{
|
{
|
||||||
return _monoImage;
|
return _monoImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the options that assembly was created with.
|
/// Gets the options that assembly was created with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The options.</returns>
|
|
||||||
FORCE_INLINE const MAssemblyOptions& GetOptions() const
|
FORCE_INLINE const MAssemblyOptions& GetOptions() const
|
||||||
{
|
{
|
||||||
return _options;
|
return _options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads assembly for domain.
|
/// Loads assembly for domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -192,14 +178,12 @@ public:
|
|||||||
bool Load(const String& assemblyPath);
|
bool Load(const String& assemblyPath);
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads assembly for domain.
|
/// Loads assembly for domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoImage">The assembly image.</param>
|
/// <param name="monoImage">The assembly image.</param>
|
||||||
/// <returns>True if cannot load, otherwise false.</returns>
|
/// <returns>True if cannot load, otherwise false.</returns>
|
||||||
bool Load(MonoImage* monoImage);
|
bool Load(MonoImage* monoImage);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -218,7 +202,6 @@ public:
|
|||||||
MClass* GetClass(const StringAnsiView& typeName) const;
|
MClass* GetClass(const StringAnsiView& typeName) const;
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an internal mono representation of a class into engine class.
|
/// Converts an internal mono representation of a class into engine class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -231,7 +214,6 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The native assembly object.</returns>
|
/// <returns>The native assembly object.</returns>
|
||||||
MonoReflectionAssembly* GetNative() const;
|
MonoReflectionAssembly* GetNative() const;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -242,8 +224,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the assembly for domain.
|
/// Loads the assembly for domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -256,8 +236,6 @@ private:
|
|||||||
/// <returns>True if failed, otherwise false.</returns>
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
bool LoadWithImage(const String& assemblyPath);
|
bool LoadWithImage(const String& assemblyPath);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OnLoading();
|
void OnLoading();
|
||||||
void OnLoaded(const struct DateTime& startTime);
|
void OnLoaded(const struct DateTime& startTime);
|
||||||
void OnLoadFailed();
|
void OnLoadFailed();
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MType.h"
|
#include "MType.h"
|
||||||
#include "MTypes.h"
|
#include "MTypes.h"
|
||||||
#include "MField.h"
|
#include "MField.h"
|
||||||
@@ -11,16 +8,16 @@
|
|||||||
#include "MMethod.h"
|
#include "MMethod.h"
|
||||||
#include "MEvent.h"
|
#include "MEvent.h"
|
||||||
#include "Engine/Scripting/Scripting.h"
|
#include "Engine/Scripting/Scripting.h"
|
||||||
|
#include "Engine/Core/Log.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/attrdefs.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/attrdefs.h>
|
||||||
|
|
||||||
#define GET_CUSTOM_ATTR() (MonoCustomAttrInfo*)(_attrInfo ? _attrInfo : _attrInfo = mono_custom_attrs_from_class(_monoClass))
|
#define GET_CUSTOM_ATTR() (MonoCustomAttrInfo*)(_attrInfo ? _attrInfo : _attrInfo = mono_custom_attrs_from_class(_monoClass))
|
||||||
#include "Engine/Core/Log.h"
|
#endif
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
MClass::MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MString& fullname)
|
MClass::MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MString& fullname)
|
||||||
: _monoClass(monoClass)
|
: _assembly(parentAssembly)
|
||||||
, _attrInfo(nullptr)
|
|
||||||
, _assembly(parentAssembly)
|
|
||||||
, _fullname(fullname)
|
, _fullname(fullname)
|
||||||
, _visibility(MVisibility::Private)
|
, _visibility(MVisibility::Private)
|
||||||
, _hasCachedProperties(false)
|
, _hasCachedProperties(false)
|
||||||
@@ -33,9 +30,10 @@ MClass::MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MStr
|
|||||||
, _isAbstract(false)
|
, _isAbstract(false)
|
||||||
, _isInterface(false)
|
, _isInterface(false)
|
||||||
{
|
{
|
||||||
ASSERT(_monoClass);
|
_monoClass = monoClass;
|
||||||
|
ASSERT(monoClass);
|
||||||
|
|
||||||
const uint32_t flags = mono_class_get_flags(_monoClass);
|
const uint32_t flags = mono_class_get_flags(monoClass);
|
||||||
|
|
||||||
switch (flags & MONO_TYPE_ATTR_VISIBILITY_MASK)
|
switch (flags & MONO_TYPE_ATTR_VISIBILITY_MASK)
|
||||||
{
|
{
|
||||||
@@ -67,12 +65,14 @@ MClass::MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MStr
|
|||||||
_isAbstract = !_isStatic && (flags & MONO_TYPE_ATTR_ABSTRACT) == MONO_TYPE_ATTR_ABSTRACT;
|
_isAbstract = !_isStatic && (flags & MONO_TYPE_ATTR_ABSTRACT) == MONO_TYPE_ATTR_ABSTRACT;
|
||||||
_isInterface = (flags & MONO_TYPE_ATTR_CLASS_SEMANTIC_MASK) == MONO_TYPE_ATTR_INTERFACE;
|
_isInterface = (flags & MONO_TYPE_ATTR_CLASS_SEMANTIC_MASK) == MONO_TYPE_ATTR_INTERFACE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MClass::~MClass()
|
MClass::~MClass()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (_attrInfo)
|
if (_attrInfo)
|
||||||
mono_custom_attrs_free((MonoCustomAttrInfo*)_attrInfo);
|
mono_custom_attrs_free((MonoCustomAttrInfo*)_attrInfo);
|
||||||
|
#endif
|
||||||
_fields.ClearDelete();
|
_fields.ClearDelete();
|
||||||
_properties.ClearDelete();
|
_properties.ClearDelete();
|
||||||
_methods.ClearDelete();
|
_methods.ClearDelete();
|
||||||
@@ -80,11 +80,6 @@ MClass::~MClass()
|
|||||||
_events.ClearDelete();
|
_events.ClearDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoClass* MClass::GetNative() const
|
|
||||||
{
|
|
||||||
return _monoClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MClass::IsGeneric() const
|
bool MClass::IsGeneric() const
|
||||||
{
|
{
|
||||||
return _fullname.FindLast('`') != -1;
|
return _fullname.FindLast('`') != -1;
|
||||||
@@ -92,45 +87,63 @@ bool MClass::IsGeneric() const
|
|||||||
|
|
||||||
MType MClass::GetType() const
|
MType MClass::GetType() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return MType(mono_class_get_type(_monoClass));
|
return MType(mono_class_get_type(_monoClass));
|
||||||
|
#else
|
||||||
|
return MType();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MClass* MClass::GetBaseClass() const
|
MClass* MClass::GetBaseClass() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* monoBase = mono_class_get_parent(_monoClass);
|
MonoClass* monoBase = mono_class_get_parent(_monoClass);
|
||||||
if (monoBase == nullptr)
|
if (monoBase == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return Scripting::FindClass(monoBase);
|
return Scripting::FindClass(monoBase);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MClass::IsSubClassOf(const MClass* klass) const
|
bool MClass::IsSubClassOf(const MClass* klass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return klass && mono_class_is_subclass_of(_monoClass, klass->GetNative(), false) != 0;
|
return klass && mono_class_is_subclass_of(_monoClass, klass->GetNative(), false) != 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
bool MClass::IsSubClassOf(MonoClass* monoClass) const
|
bool MClass::IsSubClassOf(MonoClass* monoClass) const
|
||||||
{
|
{
|
||||||
return monoClass && mono_class_is_subclass_of(_monoClass, monoClass, true) != 0;
|
return monoClass && mono_class_is_subclass_of(_monoClass, monoClass, true) != 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool MClass::IsInstanceOfType(MonoObject* object) const
|
bool MClass::IsInstanceOfType(MObject* object) const
|
||||||
{
|
{
|
||||||
if (object == nullptr)
|
if (object == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* monoClass = mono_object_get_class(object);
|
MonoClass* monoClass = mono_object_get_class(object);
|
||||||
return mono_class_is_subclass_of(monoClass, _monoClass, false) != 0;
|
return mono_class_is_subclass_of(monoClass, _monoClass, false) != 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MClass::GetInstanceSize() const
|
uint32 MClass::GetInstanceSize() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
uint32 dummy = 0;
|
uint32 dummy = 0;
|
||||||
|
|
||||||
if (mono_class_is_valuetype(_monoClass))
|
if (mono_class_is_valuetype(_monoClass))
|
||||||
return mono_class_value_size(_monoClass, &dummy);
|
return mono_class_value_size(_monoClass, &dummy);
|
||||||
|
|
||||||
return mono_class_instance_size(_monoClass);
|
return mono_class_instance_size(_monoClass);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MMethod* MClass::FindMethod(const char* name, int32 numParams, bool checkBaseClasses)
|
MMethod* MClass::FindMethod(const char* name, int32 numParams, bool checkBaseClasses)
|
||||||
@@ -154,6 +167,7 @@ MMethod* MClass::GetMethod(const char* name, int32 numParams)
|
|||||||
return _methods[i];
|
return _methods[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
// Find Mono method
|
// Find Mono method
|
||||||
MonoMethod* monoMethod = mono_class_get_method_from_name(_monoClass, name, numParams);
|
MonoMethod* monoMethod = mono_class_get_method_from_name(_monoClass, name, numParams);
|
||||||
if (monoMethod == nullptr)
|
if (monoMethod == nullptr)
|
||||||
@@ -162,8 +176,10 @@ MMethod* MClass::GetMethod(const char* name, int32 numParams)
|
|||||||
// Create method
|
// Create method
|
||||||
auto method = New<MMethod>(monoMethod, name, this);
|
auto method = New<MMethod>(monoMethod, name, this);
|
||||||
_methods.Add(method);
|
_methods.Add(method);
|
||||||
|
|
||||||
return method;
|
return method;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MMethod*>& MClass::GetMethods()
|
const Array<MMethod*>& MClass::GetMethods()
|
||||||
@@ -171,6 +187,7 @@ const Array<MMethod*>& MClass::GetMethods()
|
|||||||
if (_hasCachedMethods)
|
if (_hasCachedMethods)
|
||||||
return _methods;
|
return _methods;
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
void* iter = nullptr;
|
void* iter = nullptr;
|
||||||
MonoMethod* curClassMethod;
|
MonoMethod* curClassMethod;
|
||||||
while ((curClassMethod = mono_class_get_methods(_monoClass, &iter)))
|
while ((curClassMethod = mono_class_get_methods(_monoClass, &iter)))
|
||||||
@@ -193,6 +210,7 @@ const Array<MMethod*>& MClass::GetMethods()
|
|||||||
_methods.Add(method);
|
_methods.Add(method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_hasCachedMethods = true;
|
_hasCachedMethods = true;
|
||||||
return _methods;
|
return _methods;
|
||||||
@@ -207,6 +225,7 @@ MField* MClass::GetField(const char* name)
|
|||||||
return _fields[i];
|
return _fields[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
// Find mono field
|
// Find mono field
|
||||||
MonoClassField* field = mono_class_get_field_from_name(_monoClass, name);
|
MonoClassField* field = mono_class_get_field_from_name(_monoClass, name);
|
||||||
if (field == nullptr)
|
if (field == nullptr)
|
||||||
@@ -216,6 +235,9 @@ MField* MClass::GetField(const char* name)
|
|||||||
auto mfield = New<MField>(field, name, this);
|
auto mfield = New<MField>(field, name, this);
|
||||||
_fields.Add(mfield);
|
_fields.Add(mfield);
|
||||||
return mfield;
|
return mfield;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MField*>& MClass::GetFields()
|
const Array<MField*>& MClass::GetFields()
|
||||||
@@ -223,6 +245,7 @@ const Array<MField*>& MClass::GetFields()
|
|||||||
if (_hasCachedFields)
|
if (_hasCachedFields)
|
||||||
return _fields;
|
return _fields;
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
void* iter = nullptr;
|
void* iter = nullptr;
|
||||||
MonoClassField* curClassField;
|
MonoClassField* curClassField;
|
||||||
while ((curClassField = mono_class_get_fields(_monoClass, &iter)))
|
while ((curClassField = mono_class_get_fields(_monoClass, &iter)))
|
||||||
@@ -230,6 +253,7 @@ const Array<MField*>& MClass::GetFields()
|
|||||||
const char* fieldName = mono_field_get_name(curClassField);
|
const char* fieldName = mono_field_get_name(curClassField);
|
||||||
GetField(fieldName);
|
GetField(fieldName);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_hasCachedFields = true;
|
_hasCachedFields = true;
|
||||||
return _fields;
|
return _fields;
|
||||||
@@ -246,34 +270,33 @@ MEvent* MClass::GetEvent(const char* name)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MEvent* MClass::AddEvent(const char* name, MonoEvent* event)
|
|
||||||
{
|
|
||||||
// Lookup for cached event
|
|
||||||
for (int32 i = 0; i < _events.Count(); i++)
|
|
||||||
{
|
|
||||||
if (_events[i]->GetName() == name)
|
|
||||||
return _events[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create field
|
|
||||||
auto result = New<MEvent>(event, name, this);
|
|
||||||
_events.Add(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Array<MEvent*>& MClass::GetEvents()
|
const Array<MEvent*>& MClass::GetEvents()
|
||||||
{
|
{
|
||||||
if (_hasCachedEvents)
|
if (_hasCachedEvents)
|
||||||
return _events;
|
return _events;
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
void* iter = nullptr;
|
void* iter = nullptr;
|
||||||
MonoEvent* curEvent;
|
MonoEvent* curEvent;
|
||||||
while ((curEvent = mono_class_get_events(_monoClass, &iter)))
|
while ((curEvent = mono_class_get_events(_monoClass, &iter)))
|
||||||
{
|
{
|
||||||
const char* fieldName = mono_event_get_name(curEvent);
|
const char* name = mono_event_get_name(curEvent);
|
||||||
AddEvent(fieldName, curEvent);
|
bool missing = true;
|
||||||
|
for (int32 i = 0; i < _events.Count(); i++)
|
||||||
|
{
|
||||||
|
if (_events[i]->GetName() == name)
|
||||||
|
{
|
||||||
|
missing = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (missing)
|
||||||
|
{
|
||||||
|
auto result = New<MEvent>(curEvent, name, this);
|
||||||
|
_events.Add(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_hasCachedEvents = true;
|
_hasCachedEvents = true;
|
||||||
return _events;
|
return _events;
|
||||||
@@ -288,6 +311,7 @@ MProperty* MClass::GetProperty(const char* name)
|
|||||||
return _properties[i];
|
return _properties[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
// Find mono property
|
// Find mono property
|
||||||
MonoProperty* monoProperty = mono_class_get_property_from_name(_monoClass, name);
|
MonoProperty* monoProperty = mono_class_get_property_from_name(_monoClass, name);
|
||||||
if (monoProperty == nullptr)
|
if (monoProperty == nullptr)
|
||||||
@@ -298,6 +322,9 @@ MProperty* MClass::GetProperty(const char* name)
|
|||||||
_properties.Add(mproperty);
|
_properties.Add(mproperty);
|
||||||
|
|
||||||
return mproperty;
|
return mproperty;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MProperty*>& MClass::GetProperties()
|
const Array<MProperty*>& MClass::GetProperties()
|
||||||
@@ -305,6 +332,7 @@ const Array<MProperty*>& MClass::GetProperties()
|
|||||||
if (_hasCachedProperties)
|
if (_hasCachedProperties)
|
||||||
return _properties;
|
return _properties;
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
void* iter = nullptr;
|
void* iter = nullptr;
|
||||||
MonoProperty* curClassProperty;
|
MonoProperty* curClassProperty;
|
||||||
while ((curClassProperty = mono_class_get_properties(_monoClass, &iter)))
|
while ((curClassProperty = mono_class_get_properties(_monoClass, &iter)))
|
||||||
@@ -312,52 +340,74 @@ const Array<MProperty*>& MClass::GetProperties()
|
|||||||
const char* propertyName = mono_property_get_name(curClassProperty);
|
const char* propertyName = mono_property_get_name(curClassProperty);
|
||||||
GetProperty(propertyName);
|
GetProperty(propertyName);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_hasCachedProperties = true;
|
_hasCachedProperties = true;
|
||||||
return _properties;
|
return _properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MClass::CreateInstance() const
|
MObject* MClass::CreateInstance() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoObject* obj = mono_object_new(mono_domain_get(), _monoClass);
|
MonoObject* obj = mono_object_new(mono_domain_get(), _monoClass);
|
||||||
if (!mono_class_is_valuetype(_monoClass))
|
if (!mono_class_is_valuetype(_monoClass))
|
||||||
mono_runtime_object_init(obj);
|
mono_runtime_object_init(obj);
|
||||||
return obj;
|
return obj;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MClass::CreateInstance(void** params, uint32 numParams)
|
MObject* MClass::CreateInstance(void** params, uint32 numParams)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoObject* obj = mono_object_new(mono_domain_get(), _monoClass);
|
MonoObject* obj = mono_object_new(mono_domain_get(), _monoClass);
|
||||||
const auto constructor = GetMethod(".ctor", numParams);
|
const auto constructor = GetMethod(".ctor", numParams);
|
||||||
ASSERT(constructor);
|
ASSERT(constructor);
|
||||||
constructor->Invoke(obj, params, nullptr);
|
constructor->Invoke(obj, params, nullptr);
|
||||||
return obj;
|
return obj;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MClass::HasAttribute(MClass* monoClass)
|
bool MClass::HasAttribute(MClass* monoClass)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
||||||
return attrInfo != nullptr && mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
return attrInfo != nullptr && mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MClass::HasAttribute()
|
bool MClass::HasAttribute()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
||||||
return attrInfo && attrInfo->num_attrs > 0;
|
return attrInfo && attrInfo->num_attrs > 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MClass::GetAttribute(MClass* monoClass)
|
MObject* MClass::GetAttribute(MClass* monoClass)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
||||||
return attrInfo ? mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()) : nullptr;
|
return attrInfo ? mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative()) : nullptr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MonoObject*>& MClass::GetAttributes()
|
const Array<MObject*>& MClass::GetAttributes()
|
||||||
{
|
{
|
||||||
if (_hasCachedAttributes)
|
if (_hasCachedAttributes)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
|
|
||||||
_hasCachedAttributes = true;
|
_hasCachedAttributes = true;
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
MonoCustomAttrInfo* attrInfo = GET_CUSTOM_ATTR();
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
@@ -366,9 +416,8 @@ const Array<MonoObject*>& MClass::GetAttributes()
|
|||||||
const auto length = (uint32)mono_array_length(monoAttributesArray);
|
const auto length = (uint32)mono_array_length(monoAttributesArray);
|
||||||
_attributes.Resize(length);
|
_attributes.Resize(length);
|
||||||
for (uint32 i = 0; i < length; i++)
|
for (uint32 i = 0; i < length; i++)
|
||||||
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject *, i);
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return _attributes;
|
return _attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -14,7 +14,7 @@ private:
|
|||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
MonoClass* _monoClass;
|
MonoClass* _monoClass;
|
||||||
void* _attrInfo;
|
void* _attrInfo = nullptr;
|
||||||
#endif
|
#endif
|
||||||
const MAssembly* _assembly;
|
const MAssembly* _assembly;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ private:
|
|||||||
Array<MMethod*> _methods;
|
Array<MMethod*> _methods;
|
||||||
Array<MField*> _fields;
|
Array<MField*> _fields;
|
||||||
Array<MProperty*> _properties;
|
Array<MProperty*> _properties;
|
||||||
Array<MonoObject*> _attributes;
|
Array<MObject*> _attributes;
|
||||||
Array<MEvent*> _events;
|
Array<MEvent*> _events;
|
||||||
|
|
||||||
MVisibility _visibility;
|
MVisibility _visibility;
|
||||||
@@ -40,6 +40,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MClass"/> class.
|
/// Initializes a new instance of the <see cref="MClass"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -47,6 +48,7 @@ public:
|
|||||||
/// <param name="monoClass">The Mono class.</param>
|
/// <param name="monoClass">The Mono class.</param>
|
||||||
/// <param name="fullname">The fullname.</param>
|
/// <param name="fullname">The fullname.</param>
|
||||||
MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MString& fullname);
|
MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const MString& fullname);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finalizes an instance of the <see cref="MClass"/> class.
|
/// Finalizes an instance of the <see cref="MClass"/> class.
|
||||||
@@ -72,12 +74,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Mono class handle.
|
/// Gets the Mono class handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoClass* GetNative() const;
|
FORCE_INLINE MonoClass* GetNative() const
|
||||||
|
{
|
||||||
|
return _monoClass;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -142,19 +145,21 @@ public:
|
|||||||
/// <returns>True if this class is a sub class of the specified class.</returns>
|
/// <returns>True if this class is a sub class of the specified class.</returns>
|
||||||
bool IsSubClassOf(const MClass* klass) const;
|
bool IsSubClassOf(const MClass* klass) const;
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if this class is a sub class of the specified class (including any derived types).
|
/// Checks if this class is a sub class of the specified class (including any derived types).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoClass">The Mono class.</param>
|
/// <param name="monoClass">The Mono class.</param>
|
||||||
/// <returns>True if this class is a sub class of the specified class.</returns>
|
/// <returns>True if this class is a sub class of the specified class.</returns>
|
||||||
bool IsSubClassOf(MonoClass* monoClass) const;
|
bool IsSubClassOf(MonoClass* monoClass) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks is the provided object instance of this class' type.
|
/// Checks is the provided object instance of this class' type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="object">The object to check.</param>
|
/// <param name="object">The object to check.</param>
|
||||||
/// <returns>True if object is an instance the this class.</returns>
|
/// <returns>True if object is an instance the this class.</returns>
|
||||||
bool IsInstanceOfType(MonoObject* object) const;
|
bool IsInstanceOfType(MObject* object) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the size of an instance of this class, in bytes.
|
/// Returns the size of an instance of this class, in bytes.
|
||||||
@@ -217,14 +222,6 @@ public:
|
|||||||
/// <returns>The event object.</returns>
|
/// <returns>The event object.</returns>
|
||||||
MEvent* GetEvent(const char* name);
|
MEvent* GetEvent(const char* name);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds event with the specified name to the cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">The event name.</param>
|
|
||||||
/// <param name="event">The event Mono object.</param>
|
|
||||||
/// <returns>The event.</returns>
|
|
||||||
MEvent* AddEvent(const char* name, MonoEvent* event);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all events belonging to this class.
|
/// Returns all events belonging to this class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -257,7 +254,7 @@ public:
|
|||||||
/// Creates a new instance of this class and constructs it.
|
/// Creates a new instance of this class and constructs it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The created managed object.</returns>
|
/// <returns>The created managed object.</returns>
|
||||||
MonoObject* CreateInstance() const;
|
MObject* CreateInstance() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of this class and then constructs it using the constructor with the specified number of parameters.
|
/// Creates a new instance of this class and then constructs it using the constructor with the specified number of parameters.
|
||||||
@@ -265,7 +262,7 @@ public:
|
|||||||
/// <param name="params">The array containing pointers to constructor parameters. Array length must be equal to number of parameters.</param>
|
/// <param name="params">The array containing pointers to constructor parameters. Array length must be equal to number of parameters.</param>
|
||||||
/// <param name="numParams">The number of parameters the constructor accepts.</param>
|
/// <param name="numParams">The number of parameters the constructor accepts.</param>
|
||||||
/// <returns>The created managed object.</returns>
|
/// <returns>The created managed object.</returns>
|
||||||
MonoObject* CreateInstance(void** params, uint32 numParams);
|
MObject* CreateInstance(void** params, uint32 numParams);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -287,11 +284,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoClass">The attribute class to take.</param>
|
/// <param name="monoClass">The attribute class to take.</param>
|
||||||
/// <returns>The attribute object.</returns>
|
/// <returns>The attribute object.</returns>
|
||||||
MonoObject* GetAttribute(MClass* monoClass);
|
MObject* GetAttribute(MClass* monoClass);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an instance of all attributes connected with given class. Returns null if the class doesn't have any attributes.
|
/// Returns an instance of all attributes connected with given class. Returns null if the class doesn't have any attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The array of attribute objects.</returns>
|
/// <returns>The array of attribute objects.</returns>
|
||||||
const Array<MonoObject*>& GetAttributes();
|
const Array<MObject*>& GetAttributes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MCore.h"
|
#include "MCore.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MDomain.h"
|
#include "MDomain.h"
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
@@ -16,6 +13,7 @@
|
|||||||
#include "Engine/Platform/Thread.h"
|
#include "Engine/Platform/Thread.h"
|
||||||
#include "Engine/Scripting/MException.h"
|
#include "Engine/Scripting/MException.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
#if USE_MONO
|
||||||
#ifdef USE_MONO_AOT_MODULE
|
#ifdef USE_MONO_AOT_MODULE
|
||||||
#include "Engine/Core/Types/TimeSpan.h"
|
#include "Engine/Core/Types/TimeSpan.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -33,15 +31,24 @@
|
|||||||
#if !USE_MONO_DYNAMIC_LIB
|
#if !USE_MONO_DYNAMIC_LIB
|
||||||
#include <ThirdParty/mono-2.0/mono/utils/mono-dl-fallback.h>
|
#include <ThirdParty/mono-2.0/mono/utils/mono-dl-fallback.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MONO_AOT_MODULE
|
#ifdef USE_MONO_AOT_MODULE
|
||||||
void* MonoAotModuleHandle = nullptr;
|
void* MonoAotModuleHandle = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MCore::MCore()
|
MDomain* MRootDomain = nullptr;
|
||||||
: _rootDomain(nullptr)
|
MDomain* MActiveDomain = nullptr;
|
||||||
, _activeDomain(nullptr)
|
Array<MDomain*, InlinedAllocation<4>> MDomains;
|
||||||
|
|
||||||
|
MDomain* MCore::GetRootDomain()
|
||||||
{
|
{
|
||||||
|
return MRootDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDomain* MCore::GetActiveDomain()
|
||||||
|
{
|
||||||
|
return MActiveDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
MDomain* MCore::CreateDomain(const MString& domainName)
|
MDomain* MCore::CreateDomain(const MString& domainName)
|
||||||
@@ -51,50 +58,56 @@ MDomain* MCore::CreateDomain(const MString& domainName)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int32 i = 0; i < _domains.Count(); i++)
|
for (int32 i = 0; i < MDomains.Count(); i++)
|
||||||
{
|
{
|
||||||
if (_domains[i]->GetName() == domainName)
|
if (MDomains[i]->GetName() == domainName)
|
||||||
return _domains[i];
|
return MDomains[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto domain = New<MDomain>(domainName);
|
||||||
|
#if USE_MONO
|
||||||
const auto monoDomain = mono_domain_create_appdomain((char*)domainName.Get(), nullptr);
|
const auto monoDomain = mono_domain_create_appdomain((char*)domainName.Get(), nullptr);
|
||||||
#if MONO_DEBUG_ENABLE
|
#if MONO_DEBUG_ENABLE
|
||||||
mono_debug_domain_create(monoDomain);
|
mono_debug_domain_create(monoDomain);
|
||||||
#endif
|
#endif
|
||||||
ASSERT(monoDomain);
|
ASSERT(monoDomain);
|
||||||
auto domain = New<MDomain>(domainName, monoDomain);
|
domain->_monoDomain = monoDomain;
|
||||||
_domains.Add(domain);
|
#endif
|
||||||
|
MDomains.Add(domain);
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCore::UnloadDomain(const MString& domainName)
|
void MCore::UnloadDomain(const MString& domainName)
|
||||||
{
|
{
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
for (; i < _domains.Count(); i++)
|
for (; i < MDomains.Count(); i++)
|
||||||
{
|
{
|
||||||
if (_domains[i]->GetName() == domainName)
|
if (MDomains[i]->GetName() == domainName)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == _domains.Count())
|
if (i == MDomains.Count())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto domain = _domains[i];
|
auto domain = MDomains[i];
|
||||||
|
#if USE_MONO
|
||||||
#if MONO_DEBUG_ENABLE
|
#if MONO_DEBUG_ENABLE
|
||||||
//mono_debug_domain_unload(domain->GetNative());
|
//mono_debug_domain_unload(domain->GetNative());
|
||||||
#endif
|
#endif
|
||||||
//mono_domain_finalize(_monoScriptsDomain, 2000);
|
//mono_domain_finalize(domain->GetNative(), 2000);
|
||||||
|
MObject* exception = nullptr;
|
||||||
MonoObject* exception = nullptr;
|
|
||||||
mono_domain_try_unload(domain->GetNative(), &exception);
|
mono_domain_try_unload(domain->GetNative(), &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
MException ex(exception);
|
MException ex(exception);
|
||||||
ex.Log(LogType::Fatal, TEXT("Scripting::Release"));
|
ex.Log(LogType::Fatal, TEXT("Scripting::Release"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Delete(domain);
|
Delete(domain);
|
||||||
_domains.RemoveAtKeepOrder(i);
|
MDomains.RemoveAtKeepOrder(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
void* MonoMalloc(size_t size)
|
void* MonoMalloc(size_t size)
|
||||||
@@ -254,7 +267,7 @@ void OnLogCallback(const char* logDomain, const char* logLevel, const char* mess
|
|||||||
|
|
||||||
if (currentDomain.IsEmpty())
|
if (currentDomain.IsEmpty())
|
||||||
{
|
{
|
||||||
auto domain = MCore::Instance()->GetActiveDomain();
|
auto domain = MCore::GetActiveDomain();
|
||||||
if (domain != nullptr)
|
if (domain != nullptr)
|
||||||
{
|
{
|
||||||
currentDomain = domain->GetName().Get();
|
currentDomain = domain->GetName().Get();
|
||||||
@@ -443,7 +456,7 @@ bool MCore::LoadEngine()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Connects to mono engine callback system
|
// Connects to mono engine callback system
|
||||||
mono_trace_set_log_handler(OnLogCallback, this);
|
mono_trace_set_log_handler(OnLogCallback, nullptr);
|
||||||
mono_trace_set_print_handler(OnPrintCallback);
|
mono_trace_set_print_handler(OnPrintCallback);
|
||||||
mono_trace_set_printerr_handler(OnPrintErrorCallback);
|
mono_trace_set_printerr_handler(OnPrintErrorCallback);
|
||||||
}
|
}
|
||||||
@@ -505,7 +518,7 @@ bool MCore::LoadEngine()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init Mono
|
// Init Mono
|
||||||
#if PLATFORM_ANDROID
|
#if PLATFORM_ANDROID
|
||||||
const char* monoVersion = "mobile";
|
const char* monoVersion = "mobile";
|
||||||
#else
|
#else
|
||||||
@@ -513,8 +526,9 @@ bool MCore::LoadEngine()
|
|||||||
#endif
|
#endif
|
||||||
auto monoRootDomain = mono_jit_init_version("Flax", monoVersion);
|
auto monoRootDomain = mono_jit_init_version("Flax", monoVersion);
|
||||||
ASSERT(monoRootDomain);
|
ASSERT(monoRootDomain);
|
||||||
_rootDomain = New<MDomain>("Root", monoRootDomain);
|
MRootDomain = New<MDomain>("Root");
|
||||||
_domains.Add(_rootDomain);
|
MRootDomain->_monoDomain = monoRootDomain;
|
||||||
|
MDomains.Add(MRootDomain);
|
||||||
|
|
||||||
auto exePath = Platform::GetExecutableFilePath();
|
auto exePath = Platform::GetExecutableFilePath();
|
||||||
auto configDir = StringUtils::GetDirectoryName(exePath).ToStringAnsi();
|
auto configDir = StringUtils::GetDirectoryName(exePath).ToStringAnsi();
|
||||||
@@ -553,29 +567,29 @@ void MCore::UnloadEngine()
|
|||||||
Thread::ThreadExiting.Unbind<OnThreadExiting>();
|
Thread::ThreadExiting.Unbind<OnThreadExiting>();
|
||||||
|
|
||||||
// Only root domain should be alive at this point
|
// Only root domain should be alive at this point
|
||||||
for (auto domain : _domains)
|
for (auto domain : MDomains)
|
||||||
{
|
{
|
||||||
if (domain != _rootDomain)
|
if (domain != MRootDomain)
|
||||||
Delete(domain);
|
Delete(domain);
|
||||||
}
|
}
|
||||||
_domains.Clear();
|
MDomains.Clear();
|
||||||
|
|
||||||
if (_rootDomain)
|
if (MRootDomain)
|
||||||
{
|
{
|
||||||
#if PLATFORM_WINDOWS && USE_EDITOR
|
#if PLATFORM_WINDOWS && USE_EDITOR
|
||||||
// TODO: reduce issues with hot-reloading C# DLLs because sometimes it crashes on exit
|
// TODO: reduce issues with hot-reloading C# DLLs because sometimes it crashes on exit
|
||||||
__try
|
__try
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
mono_jit_cleanup(_rootDomain->GetNative());
|
mono_jit_cleanup(MRootDomain->GetNative());
|
||||||
}
|
}
|
||||||
#if PLATFORM_WINDOWS && USE_EDITOR
|
#if PLATFORM_WINDOWS && USE_EDITOR
|
||||||
__except (MonoHackSehExceptionHandler(nullptr))
|
__except (MonoHackSehExceptionHandler(nullptr))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Delete(_rootDomain);
|
Delete(MRootDomain);
|
||||||
_rootDomain = nullptr;
|
MRootDomain = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_MONO_AOT_MODULE
|
#ifdef USE_MONO_AOT_MODULE
|
||||||
@@ -591,39 +605,65 @@ void MCore::UnloadEngine()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
bool MCore::LoadEngine()
|
||||||
|
{
|
||||||
|
MRootDomain = New<MDomain>("Root");
|
||||||
|
MDomains.Add(MRootDomain);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCore::UnloadEngine()
|
||||||
|
{
|
||||||
|
MDomains.ClearDelete();
|
||||||
|
MRootDomain = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void MCore::AttachThread()
|
void MCore::AttachThread()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (!IsInMainThread() && !mono_domain_get())
|
if (!IsInMainThread() && !mono_domain_get())
|
||||||
{
|
{
|
||||||
const auto domain = Instance()->GetActiveDomain();
|
const auto domain = GetActiveDomain();
|
||||||
ASSERT(domain);
|
ASSERT(domain);
|
||||||
mono_thread_attach(domain->GetNative());
|
mono_thread_attach(domain->GetNative());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCore::ExitThread()
|
void MCore::ExitThread()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (!IsInMainThread() && mono_domain_get())
|
if (!IsInMainThread() && mono_domain_get())
|
||||||
{
|
{
|
||||||
LOG(Info, "Thread 0x{0:x} exits the managed runtime", Platform::GetCurrentThreadID());
|
LOG(Info, "Thread 0x{0:x} exits the managed runtime", Platform::GetCurrentThreadID());
|
||||||
mono_thread_exit();
|
mono_thread_exit();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCore::GC::Collect()
|
void MCore::GC::Collect()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
mono_gc_collect(mono_gc_max_generation());
|
mono_gc_collect(mono_gc_max_generation());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCore::GC::Collect(int32 generation)
|
void MCore::GC::Collect(int32 generation)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
mono_gc_collect(generation);
|
mono_gc_collect(generation);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCore::GC::WaitForPendingFinalizers()
|
void MCore::GC::WaitForPendingFinalizers()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
PROFILE_CPU();
|
PROFILE_CPU();
|
||||||
if (mono_gc_pending_finalizers())
|
if (mono_gc_pending_finalizers())
|
||||||
{
|
{
|
||||||
@@ -633,9 +673,10 @@ void MCore::GC::WaitForPendingFinalizers()
|
|||||||
Platform::Sleep(1);
|
Platform::Sleep(1);
|
||||||
} while (mono_gc_pending_finalizers());
|
} while (mono_gc_pending_finalizers());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB
|
#if USE_MONO && PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB
|
||||||
|
|
||||||
// Export Mono functions
|
// Export Mono functions
|
||||||
#pragma comment(linker, "/export:mono_add_internal_call")
|
#pragma comment(linker, "/export:mono_add_internal_call")
|
||||||
@@ -2109,5 +2150,3 @@ void MCore::GC::WaitForPendingFinalizers()
|
|||||||
#pragma comment(linker, "/export:mono_jit_info_get_code_size")
|
#pragma comment(linker, "/export:mono_jit_info_get_code_size")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -2,63 +2,37 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Engine/Core/Types/String.h"
|
|
||||||
#include "Engine/Core/Collections/Array.h"
|
|
||||||
#include "Engine/Core/Singleton.h"
|
|
||||||
#include "MTypes.h"
|
#include "MTypes.h"
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main handler for CLR Engine.
|
/// Main handler for CLR Engine.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class FLAXENGINE_API MCore : public Singleton<MCore>
|
class FLAXENGINE_API MCore
|
||||||
{
|
{
|
||||||
friend MDomain;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
MDomain* _rootDomain;
|
|
||||||
MDomain* _activeDomain;
|
|
||||||
Array<MDomain*, InlinedAllocation<4>> _domains;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MCore"/> class.
|
/// Gets the root domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MCore();
|
static MDomain* GetRootDomain();
|
||||||
|
|
||||||
public:
|
/// <summary>
|
||||||
|
/// Gets the currently active domain.
|
||||||
|
/// </summary>
|
||||||
|
static MDomain* GetActiveDomain();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an new empty domain.
|
/// Creates an new empty domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="domainName">The domain name to create.</param>
|
/// <param name="domainName">The domain name to create.</param>
|
||||||
/// <returns>The domain object.</returns>
|
/// <returns>The domain object.</returns>
|
||||||
MDomain* CreateDomain(const MString& domainName);
|
static MDomain* CreateDomain(const MString& domainName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads the domain.
|
/// Unloads the domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="domainName">The domain name to remove.</param>
|
/// <param name="domainName">The domain name to remove.</param>
|
||||||
void UnloadDomain(const MString& domainName);
|
static void UnloadDomain(const MString& domainName);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the root domain.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The root domain.</returns>
|
|
||||||
FORCE_INLINE MDomain* GetRootDomain() const
|
|
||||||
{
|
|
||||||
return _rootDomain;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the currently active domain.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The current domain.</returns>
|
|
||||||
FORCE_INLINE MDomain* GetActiveDomain() const
|
|
||||||
{
|
|
||||||
return _activeDomain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -66,12 +40,12 @@ public:
|
|||||||
/// Initialize CLR Engine
|
/// Initialize CLR Engine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if failed, otherwise false.</returns>
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
bool LoadEngine();
|
static bool LoadEngine();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unload CLR Engine
|
/// Unload CLR Engine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void UnloadEngine();
|
static void UnloadEngine();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attaches CLR runtime to the current thread. Use it to allow invoking managed runtime from native threads.
|
/// Attaches CLR runtime to the current thread. Use it to allow invoking managed runtime from native threads.
|
||||||
|
|||||||
@@ -1,38 +1,31 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MDomain.h"
|
#include "MDomain.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MCore.h"
|
#include "MCore.h"
|
||||||
#include "MAssembly.h"
|
#include "MAssembly.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
#include "Engine/Debug/Exceptions/ArgumentException.h"
|
#include "Engine/Debug/Exceptions/ArgumentException.h"
|
||||||
#include "Engine/Debug/Exceptions/Exceptions.h"
|
#include "Engine/Debug/Exceptions/Exceptions.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/threads.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/threads.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
MDomain::MDomain(const MString& domainName, MonoDomain* monoDomain)
|
extern MDomain* MActiveDomain;
|
||||||
: _monoDomain(monoDomain)
|
|
||||||
, _domainName(domainName)
|
|
||||||
, _coreInstance(MCore::Instance())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoDomain* MDomain::GetNative() const
|
MDomain::MDomain(const MString& domainName)
|
||||||
|
: _domainName(domainName)
|
||||||
{
|
{
|
||||||
return _monoDomain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MDomain::SetCurrentDomain(bool force)
|
bool MDomain::SetCurrentDomain(bool force)
|
||||||
{
|
{
|
||||||
ASSERT(_monoDomain);
|
#if USE_MONO
|
||||||
const auto monoBool = mono_domain_set(_monoDomain, force) != 0;
|
if (mono_domain_set(_monoDomain, force) == 0)
|
||||||
if (monoBool)
|
return false;
|
||||||
{
|
#endif
|
||||||
_coreInstance->_activeDomain = this;
|
MActiveDomain = this;
|
||||||
}
|
return true;
|
||||||
return monoBool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MAssembly* MDomain::CreateEmptyAssembly(const MString& assemblyName, const MAssemblyOptions options)
|
MAssembly* MDomain::CreateEmptyAssembly(const MString& assemblyName, const MAssemblyOptions options)
|
||||||
@@ -72,10 +65,12 @@ MAssembly* MDomain::GetAssembly(const MString& assemblyName) const
|
|||||||
|
|
||||||
void MDomain::Dispatch() const
|
void MDomain::Dispatch() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
if (!IsInMainThread())
|
if (!IsInMainThread())
|
||||||
{
|
{
|
||||||
mono_thread_attach(_monoDomain);
|
mono_thread_attach(_monoDomain);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MClass* MDomain::FindClass(const StringAnsiView& fullname) const
|
MClass* MDomain::FindClass(const StringAnsiView& fullname) const
|
||||||
@@ -90,5 +85,3 @@ MClass* MDomain::FindClass(const StringAnsiView& fullname) const
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -17,7 +17,6 @@ class FLAXENGINE_API MDomain
|
|||||||
{
|
{
|
||||||
friend MCore;
|
friend MCore;
|
||||||
friend MAssembly;
|
friend MAssembly;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef Dictionary<MString, MAssembly*> AssembliesDictionary;
|
typedef Dictionary<MString, MAssembly*> AssembliesDictionary;
|
||||||
@@ -27,38 +26,43 @@ private:
|
|||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
MonoDomain* _monoDomain;
|
MonoDomain* _monoDomain;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MString _domainName;
|
MString _domainName;
|
||||||
AssembliesDictionary _assemblies;
|
AssembliesDictionary _assemblies;
|
||||||
MCore* _coreInstance;
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MDomain(const MString& domainName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
MDomain(const MString& domainName, MonoDomain* monoDomain);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets native domain class
|
/// Gets native domain class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The native domain.</returns>
|
FORCE_INLINE MonoDomain* GetNative() const
|
||||||
MonoDomain* GetNative() const;
|
{
|
||||||
|
return _monoDomain;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets current domain name
|
/// Gets current domain name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The name.</returns>
|
|
||||||
FORCE_INLINE const MString& GetName() const
|
FORCE_INLINE const MString& GetName() const
|
||||||
{
|
{
|
||||||
return _domainName;
|
return _domainName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current domain assemblies.
|
||||||
|
/// </summary>
|
||||||
|
FORCE_INLINE const AssembliesDictionary& GetAssemblies() const
|
||||||
|
{
|
||||||
|
return _assemblies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create assembly container from current domain
|
/// Create assembly container from current domain
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -73,15 +77,6 @@ public:
|
|||||||
/// <param name="assemblyName">Assembly name</param>
|
/// <param name="assemblyName">Assembly name</param>
|
||||||
void RemoveAssembly(const MString& assemblyName);
|
void RemoveAssembly(const MString& assemblyName);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current domain assemblies.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The assemblies.</returns>
|
|
||||||
FORCE_INLINE const AssembliesDictionary& GetAssemblies() const
|
|
||||||
{
|
|
||||||
return _assemblies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets current domain assembly.
|
/// Gets current domain assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MEvent.h"
|
#include "MEvent.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MType.h"
|
#include "MType.h"
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
|
|
||||||
MEvent::MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass)
|
MEvent::MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass)
|
||||||
@@ -24,13 +22,14 @@ MEvent::MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
MType MEvent::GetType()
|
MType MEvent::GetType()
|
||||||
{
|
{
|
||||||
if (GetAddMethod() != nullptr)
|
if (GetAddMethod() != nullptr)
|
||||||
return GetAddMethod()->GetReturnType();
|
return GetAddMethod()->GetReturnType();
|
||||||
if (GetRemoveMethod() != nullptr)
|
if (GetRemoveMethod() != nullptr)
|
||||||
return GetRemoveMethod()->GetReturnType();
|
return GetRemoveMethod()->GetReturnType();
|
||||||
CRASH;
|
|
||||||
return MType();
|
return MType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,12 +39,14 @@ MMethod* MEvent::GetAddMethod()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
if (_addMethod == nullptr)
|
if (_addMethod == nullptr)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto addMonoMethod = mono_event_get_add_method(_monoEvent);
|
auto addMonoMethod = mono_event_get_add_method(_monoEvent);
|
||||||
if (addMonoMethod != nullptr)
|
if (addMonoMethod != nullptr)
|
||||||
{
|
{
|
||||||
_hasAddMonoMethod = true;
|
_hasAddMonoMethod = true;
|
||||||
return _addMethod = New<MMethod>(addMonoMethod, _parentClass);
|
return _addMethod = New<MMethod>(addMonoMethod, _parentClass);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return _addMethod;
|
return _addMethod;
|
||||||
}
|
}
|
||||||
@@ -56,19 +57,21 @@ MMethod* MEvent::GetRemoveMethod()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
if (_removeMethod == nullptr)
|
if (_removeMethod == nullptr)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto removeMonoMethod = mono_event_get_remove_method(_monoEvent);
|
auto removeMonoMethod = mono_event_get_remove_method(_monoEvent);
|
||||||
if (removeMonoMethod)
|
if (removeMonoMethod)
|
||||||
{
|
{
|
||||||
_hasRemoveMonoMethod = true;
|
_hasRemoveMonoMethod = true;
|
||||||
return _removeMethod = New<MMethod>(removeMonoMethod, _parentClass);
|
return _removeMethod = New<MMethod>(removeMonoMethod, _parentClass);
|
||||||
}
|
}
|
||||||
return nullptr;
|
#endif
|
||||||
}
|
}
|
||||||
return _removeMethod;
|
return _removeMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MEvent::HasAttribute(MClass* monoClass) const
|
bool MEvent::HasAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -77,10 +80,14 @@ bool MEvent::HasAttribute(MClass* monoClass) const
|
|||||||
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return hasAttr;
|
return hasAttr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MEvent::HasAttribute() const
|
bool MEvent::HasAttribute() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -93,10 +100,14 @@ bool MEvent::HasAttribute() const
|
|||||||
}
|
}
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MEvent::GetAttribute(MClass* monoClass) const
|
MObject* MEvent::GetAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -105,14 +116,18 @@ MonoObject* MEvent::GetAttribute(MClass* monoClass) const
|
|||||||
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return foundAttr;
|
return foundAttr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MonoObject*>& MEvent::GetAttributes()
|
const Array<MObject*>& MEvent::GetAttributes()
|
||||||
{
|
{
|
||||||
if (_hasCachedAttributes)
|
if (_hasCachedAttributes)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
|
|
||||||
_hasCachedAttributes = true;
|
_hasCachedAttributes = true;
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
MonoClass* parentClass = mono_event_get_parent(_monoEvent);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_event(parentClass, _monoEvent);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -122,9 +137,8 @@ const Array<MonoObject*>& MEvent::GetAttributes()
|
|||||||
const auto length = (uint32)mono_array_length(monoAttributesArray);
|
const auto length = (uint32)mono_array_length(monoAttributesArray);
|
||||||
_attributes.Resize(length);
|
_attributes.Resize(length);
|
||||||
for (uint32 i = 0; i < length; i++)
|
for (uint32 i = 0; i < length; i++)
|
||||||
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject *, i);
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return _attributes;
|
return _attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -23,12 +23,12 @@ protected:
|
|||||||
|
|
||||||
MString _name;
|
MString _name;
|
||||||
|
|
||||||
Array<MonoObject*> _attributes;
|
|
||||||
|
|
||||||
int32 _hasCachedAttributes : 1;
|
int32 _hasCachedAttributes : 1;
|
||||||
int32 _hasAddMonoMethod : 1;
|
int32 _hasAddMonoMethod : 1;
|
||||||
int32 _hasRemoveMonoMethod : 1;
|
int32 _hasRemoveMonoMethod : 1;
|
||||||
|
|
||||||
|
Array<MObject*> _attributes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
@@ -40,7 +40,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the event name.
|
/// Gets the event name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The name.</returns>
|
|
||||||
FORCE_INLINE const MString& GetName() const
|
FORCE_INLINE const MString& GetName() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
@@ -49,7 +48,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the parent class that this method is contained with.
|
/// Returns the parent class that this method is contained with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The parent class.</returns>
|
|
||||||
FORCE_INLINE MClass* GetParentClass() const
|
FORCE_INLINE MClass* GetParentClass() const
|
||||||
{
|
{
|
||||||
return _parentClass;
|
return _parentClass;
|
||||||
@@ -58,25 +56,21 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the event type class.
|
/// Gets the event type class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The type class.</returns>
|
|
||||||
MType GetType();
|
MType GetType();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the event add method.
|
/// Gets the event add method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The method object.</returns>
|
|
||||||
MMethod* GetAddMethod();
|
MMethod* GetAddMethod();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the event remove method.
|
/// Gets the event remove method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The method object.</returns>
|
|
||||||
MMethod* GetRemoveMethod();
|
MMethod* GetRemoveMethod();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets event visibility in the class.
|
/// Gets event visibility in the class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The event visibility.</returns>
|
|
||||||
FORCE_INLINE MVisibility GetVisibility()
|
FORCE_INLINE MVisibility GetVisibility()
|
||||||
{
|
{
|
||||||
return GetAddMethod()->GetVisibility();
|
return GetAddMethod()->GetVisibility();
|
||||||
@@ -85,23 +79,19 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if event is static.
|
/// Returns true if event is static.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if is static, otherwise false.</returns>
|
|
||||||
FORCE_INLINE bool IsStatic()
|
FORCE_INLINE bool IsStatic()
|
||||||
{
|
{
|
||||||
return GetAddMethod()->IsStatic();
|
return GetAddMethod()->IsStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Mono event handle.
|
/// Gets the Mono event handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The Mono event.</returns>
|
|
||||||
FORCE_INLINE MonoEvent* GetNative() const
|
FORCE_INLINE MonoEvent* GetNative() const
|
||||||
{
|
{
|
||||||
return _monoEvent;
|
return _monoEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -124,11 +114,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoClass">The attribute class to take.</param>
|
/// <param name="monoClass">The attribute class to take.</param>
|
||||||
/// <returns>The attribute object.</returns>
|
/// <returns>The attribute object.</returns>
|
||||||
MonoObject* GetAttribute(MClass* monoClass) const;
|
MObject* GetAttribute(MClass* monoClass) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an instance of all attributes connected with given event. Returns null if the event doesn't have any attributes.
|
/// Returns an instance of all attributes connected with given event. Returns null if the event doesn't have any attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The array of attribute objects.</returns>
|
/// <returns>The array of attribute objects.</returns>
|
||||||
const Array<MonoObject*>& GetAttributes();
|
const Array<MObject*>& GetAttributes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MField.h"
|
#include "MField.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MType.h"
|
#include "MType.h"
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/attrdefs.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/attrdefs.h>
|
||||||
|
|
||||||
@@ -48,33 +46,52 @@ MField::MField(MonoClassField* monoField, const char* name, MClass* parentClass)
|
|||||||
_isStatic = (flags & MONO_FIELD_ATTR_STATIC) != 0;
|
_isStatic = (flags & MONO_FIELD_ATTR_STATIC) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
MType MField::GetType() const
|
MType MField::GetType() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return MType(_monoType);
|
return MType(_monoType);
|
||||||
|
#else
|
||||||
|
return MType();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MField::GetOffset() const
|
int32 MField::GetOffset() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return mono_field_get_offset(_monoField) - sizeof(MonoObject);
|
return mono_field_get_offset(_monoField) - sizeof(MonoObject);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MField::GetValue(MonoObject* instance, void* result) const
|
void MField::GetValue(MObject* instance, void* result) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
mono_field_get_value(instance, _monoField, result);
|
mono_field_get_value(instance, _monoField, result);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MField::GetValueBoxed(MonoObject* instance) const
|
MObject* MField::GetValueBoxed(MObject* instance) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return mono_field_get_value_object(mono_domain_get(), _monoField, instance);
|
return mono_field_get_value_object(mono_domain_get(), _monoField, instance);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MField::SetValue(MonoObject* instance, void* value) const
|
void MField::SetValue(MObject* instance, void* value) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
mono_field_set_value(instance, _monoField, value);
|
mono_field_set_value(instance, _monoField, value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MField::HasAttribute(MClass* monoClass) const
|
bool MField::HasAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -83,10 +100,14 @@ bool MField::HasAttribute(MClass* monoClass) const
|
|||||||
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return hasAttr;
|
return hasAttr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MField::HasAttribute() const
|
bool MField::HasAttribute() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -98,11 +119,13 @@ bool MField::HasAttribute() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MField::GetAttribute(MClass* monoClass) const
|
MObject* MField::GetAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -111,14 +134,18 @@ MonoObject* MField::GetAttribute(MClass* monoClass) const
|
|||||||
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return foundAttr;
|
return foundAttr;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MonoObject*>& MField::GetAttributes()
|
const Array<MObject*>& MField::GetAttributes()
|
||||||
{
|
{
|
||||||
if (_hasCachedAttributes)
|
if (_hasCachedAttributes)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
|
|
||||||
_hasCachedAttributes = true;
|
_hasCachedAttributes = true;
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
MonoClass* parentClass = mono_field_get_parent(_monoField);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, _monoField);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -130,7 +157,6 @@ const Array<MonoObject*>& MField::GetAttributes()
|
|||||||
for (uint32 i = 0; i < length; i++)
|
for (uint32 i = 0; i < length; i++)
|
||||||
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return _attributes;
|
return _attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -20,15 +20,15 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
MClass* _parentClass;
|
MClass* _parentClass;
|
||||||
|
|
||||||
MString _name;
|
MString _name;
|
||||||
MVisibility _visibility;
|
|
||||||
|
|
||||||
Array<MonoObject*> _attributes;
|
MVisibility _visibility;
|
||||||
|
|
||||||
int32 _hasCachedAttributes : 1;
|
int32 _hasCachedAttributes : 1;
|
||||||
int32 _isStatic : 1;
|
int32 _isStatic : 1;
|
||||||
|
|
||||||
|
Array<MObject*> _attributes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
@@ -40,7 +40,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets field name.
|
/// Gets field name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The field name.</returns>
|
|
||||||
FORCE_INLINE const MString& GetName() const
|
FORCE_INLINE const MString& GetName() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
@@ -49,7 +48,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the parent class that this method is contained with.
|
/// Returns the parent class that this method is contained with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The parent class.</returns>
|
|
||||||
FORCE_INLINE MClass* GetParentClass() const
|
FORCE_INLINE MClass* GetParentClass() const
|
||||||
{
|
{
|
||||||
return _parentClass;
|
return _parentClass;
|
||||||
@@ -58,19 +56,16 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets field type class.
|
/// Gets field type class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The field type.</returns>
|
|
||||||
MType GetType() const;
|
MType GetType() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the field offset (in bytes) from the start of the parent object.
|
/// Gets the field offset (in bytes) from the start of the parent object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The field offset in bytes.</returns>
|
|
||||||
int32 GetOffset() const;
|
int32 GetOffset() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets field visibility in the class.
|
/// Gets field visibility in the class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The field visibility.</returns>
|
|
||||||
FORCE_INLINE MVisibility GetVisibility() const
|
FORCE_INLINE MVisibility GetVisibility() const
|
||||||
{
|
{
|
||||||
return _visibility;
|
return _visibility;
|
||||||
@@ -79,23 +74,19 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if field is static.
|
/// Returns true if field is static.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if is static, otherwise false.</returns>
|
|
||||||
FORCE_INLINE bool IsStatic() const
|
FORCE_INLINE bool IsStatic() const
|
||||||
{
|
{
|
||||||
return _isStatic != 0;
|
return _isStatic != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets mono field handle.
|
/// Gets mono field handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The Mono field object.</returns>
|
|
||||||
FORCE_INLINE MonoClassField* GetNative() const
|
FORCE_INLINE MonoClassField* GetNative() const
|
||||||
{
|
{
|
||||||
return _monoField;
|
return _monoField;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -104,28 +95,28 @@ public:
|
|||||||
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null.
|
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Value will be a pointer to raw data type for value types (for example int, float), and a MonoObject* for reference types.
|
/// Value will be a pointer to raw data type for value types (for example int, float), and a MObject* for reference types.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="instance">The object of given type to get value from.</param>
|
/// <param name="instance">The object of given type to get value from.</param>
|
||||||
/// <param name="result">The return value of undefined type.</param>
|
/// <param name="result">The return value of undefined type.</param>
|
||||||
void GetValue(MonoObject* instance, void* result) const;
|
void GetValue(MObject* instance, void* result) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null. If returned value is a value type it will be boxed.
|
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null. If returned value is a value type it will be boxed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="instance">The object of given type to get value from.</param>
|
/// <param name="instance">The object of given type to get value from.</param>
|
||||||
/// <returns>The boxed value object.</returns>
|
/// <returns>The boxed value object.</returns>
|
||||||
MonoObject* GetValueBoxed(MonoObject* instance) const;
|
MObject* GetValueBoxed(MObject* instance) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets a value for the field on the specified object instance. If field is static object instance can be null.
|
/// Sets a value for the field on the specified object instance. If field is static object instance can be null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Value should be a pointer to raw data type for value types (for example int, float), and a MonoObject* for reference types.
|
/// Value should be a pointer to raw data type for value types (for example int, float), and a MObject* for reference types.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="instance">The object of given type to set value to.</param>
|
/// <param name="instance">The object of given type to set value to.</param>
|
||||||
/// <param name="value">Th value of undefined type.</param>
|
/// <param name="value">Th value of undefined type.</param>
|
||||||
void SetValue(MonoObject* instance, void* value) const;
|
void SetValue(MObject* instance, void* value) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -147,11 +138,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoClass">The attribute class to take.</param>
|
/// <param name="monoClass">The attribute class to take.</param>
|
||||||
/// <returns>The attribute object.</returns>
|
/// <returns>The attribute object.</returns>
|
||||||
MonoObject* GetAttribute(MClass* monoClass) const;
|
MObject* GetAttribute(MClass* monoClass) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an instance of all attributes connected with given field. Returns null if the field doesn't have any attributes.
|
/// Returns an instance of all attributes connected with given field. Returns null if the field doesn't have any attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The array of attribute objects.</returns>
|
/// <returns>The array of attribute objects.</returns>
|
||||||
const Array<MonoObject*>& GetAttributes();
|
const Array<MObject*>& GetAttributes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MMethod.h"
|
#include "MMethod.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "MType.h"
|
#include "MType.h"
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/attrdefs.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/attrdefs.h>
|
||||||
|
|
||||||
@@ -68,17 +66,27 @@ MMethod::MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MMethod::Invoke(void* instance, void** params, MonoObject** exception) const
|
#endif
|
||||||
|
|
||||||
|
MObject* MMethod::Invoke(void* instance, void** params, MObject** exception) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
PROFILE_CPU_SRC_LOC(ProfilerData);
|
PROFILE_CPU_SRC_LOC(ProfilerData);
|
||||||
return mono_runtime_invoke(_monoMethod, instance, params, exception);
|
return mono_runtime_invoke(_monoMethod, instance, params, exception);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MMethod::InvokeVirtual(MonoObject* instance, void** params, MonoObject** exception) const
|
MObject* MMethod::InvokeVirtual(MObject* instance, void** params, MObject** exception) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
PROFILE_CPU_SRC_LOC(ProfilerData);
|
PROFILE_CPU_SRC_LOC(ProfilerData);
|
||||||
MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, _monoMethod);
|
MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, _monoMethod);
|
||||||
return mono_runtime_invoke(virtualMethod, instance, params, exception);
|
return mono_runtime_invoke(virtualMethod, instance, params, exception);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !USE_MONO_AOT
|
#if !USE_MONO_AOT
|
||||||
@@ -87,7 +95,9 @@ void* MMethod::GetThunk()
|
|||||||
{
|
{
|
||||||
if (!_cachedThunk)
|
if (!_cachedThunk)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
_cachedThunk = mono_method_get_unmanaged_thunk(_monoMethod);
|
_cachedThunk = mono_method_get_unmanaged_thunk(_monoMethod);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return _cachedThunk;
|
return _cachedThunk;
|
||||||
}
|
}
|
||||||
@@ -96,35 +106,52 @@ void* MMethod::GetThunk()
|
|||||||
|
|
||||||
MType MMethod::GetReturnType() const
|
MType MMethod::GetReturnType() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
||||||
MonoType* returnType = mono_signature_get_return_type(sig);
|
MonoType* returnType = mono_signature_get_return_type(sig);
|
||||||
return MType(returnType);
|
return MType(returnType);
|
||||||
|
#else
|
||||||
|
return MType();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MMethod::GetParametersCount() const
|
int32 MMethod::GetParametersCount() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
||||||
return mono_signature_get_param_count(sig);
|
return mono_signature_get_param_count(sig);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MType MMethod::GetParameterType(int32 paramIdx) const
|
MType MMethod::GetParameterType(int32 paramIdx) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
||||||
ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig));
|
ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig));
|
||||||
void* it = nullptr;
|
void* it = nullptr;
|
||||||
mono_signature_get_params(sig, &it);
|
mono_signature_get_params(sig, &it);
|
||||||
return MType(((MonoType**)it)[paramIdx]);
|
return MType(((MonoType**)it)[paramIdx]);
|
||||||
|
#else
|
||||||
|
return MType();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMethod::GetParameterIsOut(int32 paramIdx) const
|
bool MMethod::GetParameterIsOut(int32 paramIdx) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
MonoMethodSignature* sig = mono_method_signature(_monoMethod);
|
||||||
ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig));
|
ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < (int32)mono_signature_get_param_count(sig));
|
||||||
return mono_signature_param_is_out(sig, paramIdx) != 0;
|
return mono_signature_param_is_out(sig, paramIdx) != 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMethod::HasAttribute(MClass* monoClass) const
|
bool MMethod::HasAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
return false;
|
return false;
|
||||||
@@ -132,10 +159,14 @@ bool MMethod::HasAttribute(MClass* monoClass) const
|
|||||||
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return hasAttr;
|
return hasAttr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMethod::HasAttribute() const
|
bool MMethod::HasAttribute() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
return false;
|
return false;
|
||||||
@@ -146,11 +177,13 @@ bool MMethod::HasAttribute() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MMethod::GetAttribute(MClass* monoClass) const
|
MObject* MMethod::GetAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -158,14 +191,18 @@ MonoObject* MMethod::GetAttribute(MClass* monoClass) const
|
|||||||
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return foundAttr;
|
return foundAttr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MonoObject*>& MMethod::GetAttributes()
|
const Array<MObject*>& MMethod::GetAttributes()
|
||||||
{
|
{
|
||||||
if (_hasCachedAttributes)
|
if (_hasCachedAttributes)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
|
|
||||||
_hasCachedAttributes = true;
|
_hasCachedAttributes = true;
|
||||||
|
#if USE_MONO
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(_monoMethod);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
@@ -176,7 +213,6 @@ const Array<MonoObject*>& MMethod::GetAttributes()
|
|||||||
for (uint32 i = 0; i < length; i++)
|
for (uint32 i = 0; i < length; i++)
|
||||||
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return _attributes;
|
return _attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -29,11 +29,11 @@ protected:
|
|||||||
void* _cachedThunk = nullptr;
|
void* _cachedThunk = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Array<MonoObject*> _attributes;
|
|
||||||
|
|
||||||
int32 _hasCachedAttributes : 1;
|
int32 _hasCachedAttributes : 1;
|
||||||
int32 _isStatic : 1;
|
int32 _isStatic : 1;
|
||||||
|
|
||||||
|
Array<MObject*> _attributes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
@@ -48,8 +48,6 @@ public:
|
|||||||
SourceLocationData ProfilerData;
|
SourceLocationData ProfilerData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invokes the method on the provided object instance. This does not respect polymorphism and will invoke the exact method of the class this object was retrieved from.Use invokeVirtual() if you need polymorphism.
|
/// Invokes the method on the provided object instance. This does not respect polymorphism and will invoke the exact method of the class this object was retrieved from.Use invokeVirtual() if you need polymorphism.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -59,10 +57,10 @@ public:
|
|||||||
/// <param name="instance">Instance of the object to invoke the method on. Can be null for static methods.</param>
|
/// <param name="instance">Instance of the object to invoke the method on. Can be null for static methods.</param>
|
||||||
/// <param name="params">Array of parameters to pass to the method. Caller must ensure they match method
|
/// <param name="params">Array of parameters to pass to the method. Caller must ensure they match method
|
||||||
/// parameter count and type.For value types parameters should be pointers to the
|
/// parameter count and type.For value types parameters should be pointers to the
|
||||||
/// values and for reference types they should be pointers to MonoObject.</param>
|
/// values and for reference types they should be pointers to MObject.</param>
|
||||||
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
||||||
/// <returns>A boxed return value, or null if method has no return value.</returns>
|
/// <returns>A boxed return value, or null if method has no return value.</returns>
|
||||||
MonoObject* Invoke(void* instance, void** params, MonoObject** exception) const;
|
MObject* Invoke(void* instance, void** params, MObject** exception) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invokes the method on the provided object instance. If the instance has an override of this method it will be called.
|
/// Invokes the method on the provided object instance. If the instance has an override of this method it will be called.
|
||||||
@@ -74,16 +72,13 @@ public:
|
|||||||
/// <param name="params">
|
/// <param name="params">
|
||||||
/// Array of parameters to pass to the method. Caller must ensure they match method
|
/// Array of parameters to pass to the method. Caller must ensure they match method
|
||||||
/// parameter count and type. For value types parameters should be pointers to the
|
/// parameter count and type. For value types parameters should be pointers to the
|
||||||
/// values and for reference types they should be pointers to MonoObject.
|
/// values and for reference types they should be pointers to MObject.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
||||||
/// <returns>A boxed return value, or null if method has no return value.</returns>
|
/// <returns>A boxed return value, or null if method has no return value.</returns>
|
||||||
MonoObject* InvokeVirtual(MonoObject* instance, void** params, MonoObject** exception) const;
|
MObject* InvokeVirtual(MObject* instance, void** params, MObject** exception) const;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !USE_MONO_AOT
|
#if !USE_MONO_AOT
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a thunk for this method. A thunk is a C++ like function pointer that you can use for calling the method.
|
/// Gets a thunk for this method. A thunk is a C++ like function pointer that you can use for calling the method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -93,7 +88,6 @@ public:
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>The method thunk pointer.</returns>
|
/// <returns>The method thunk pointer.</returns>
|
||||||
void* GetThunk();
|
void* GetThunk();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -153,7 +147,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Mono method handle.
|
/// Gets the Mono method handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -161,7 +154,6 @@ public:
|
|||||||
{
|
{
|
||||||
return _monoMethod;
|
return _monoMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -184,11 +176,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoClass">The attribute Class to take.</param>
|
/// <param name="monoClass">The attribute Class to take.</param>
|
||||||
/// <returns>The attribute object.</returns>
|
/// <returns>The attribute object.</returns>
|
||||||
MonoObject* GetAttribute(MClass* monoClass) const;
|
MObject* GetAttribute(MClass* monoClass) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an instance of all attributes connected with given method. Returns null if the method doesn't have any attributes.
|
/// Returns an instance of all attributes connected with given method. Returns null if the method doesn't have any attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The array of attribute objects.</returns>
|
/// <returns>The array of attribute objects.</returns>
|
||||||
const Array<MonoObject*>& GetAttributes();
|
const Array<MObject*>& GetAttributes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "MProperty.h"
|
#include "MProperty.h"
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
#include "Engine/Core/Math/Math.h"
|
#include "Engine/Core/Math/Math.h"
|
||||||
#include "MMethod.h"
|
#include "MMethod.h"
|
||||||
#include "MClass.h"
|
#include "MClass.h"
|
||||||
#include "MType.h"
|
#include "MType.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
|
|
||||||
MProperty::MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass)
|
MProperty::MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass)
|
||||||
@@ -29,6 +27,8 @@ MProperty::MProperty(MonoProperty* monoProperty, const char* name, MClass* paren
|
|||||||
GetSetMethod();
|
GetSetMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
MProperty::~MProperty()
|
MProperty::~MProperty()
|
||||||
{
|
{
|
||||||
if (_getMethod)
|
if (_getMethod)
|
||||||
@@ -48,18 +48,17 @@ MMethod* MProperty::GetGetMethod()
|
|||||||
{
|
{
|
||||||
if (!_hasGetMethod)
|
if (!_hasGetMethod)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (_getMethod == nullptr)
|
if (_getMethod == nullptr)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto method = mono_property_get_get_method(_monoProperty);
|
auto method = mono_property_get_get_method(_monoProperty);
|
||||||
if (method != nullptr)
|
if (method != nullptr)
|
||||||
{
|
{
|
||||||
_hasGetMethod = true;
|
_hasGetMethod = true;
|
||||||
return _getMethod = New<MMethod>(method, _parentClass);
|
return _getMethod = New<MMethod>(method, _parentClass);
|
||||||
}
|
}
|
||||||
return nullptr;
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return _getMethod;
|
return _getMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,18 +66,17 @@ MMethod* MProperty::GetSetMethod()
|
|||||||
{
|
{
|
||||||
if (!_hasSetMethod)
|
if (!_hasSetMethod)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (_setMethod == nullptr)
|
if (_setMethod == nullptr)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto method = mono_property_get_set_method(_monoProperty);
|
auto method = mono_property_get_set_method(_monoProperty);
|
||||||
if (method != nullptr)
|
if (method != nullptr)
|
||||||
{
|
{
|
||||||
_hasSetMethod = true;
|
_hasSetMethod = true;
|
||||||
return _setMethod = New<MMethod>(method, _parentClass);
|
return _setMethod = New<MMethod>(method, _parentClass);
|
||||||
}
|
}
|
||||||
return nullptr;
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return _setMethod;
|
return _setMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,20 +110,27 @@ bool MProperty::IsStatic()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MProperty::GetValue(MonoObject* instance, MonoObject** exception)
|
MObject* MProperty::GetValue(MObject* instance, MObject** exception)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return mono_property_get_value(_monoProperty, instance, nullptr, exception);
|
return mono_property_get_value(_monoProperty, instance, nullptr, exception);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MProperty::SetValue(MonoObject* instance, void* value, MonoObject** exception)
|
void MProperty::SetValue(MObject* instance, void* value, MObject** exception)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = value;
|
params[0] = value;
|
||||||
mono_property_set_value(_monoProperty, instance, params, exception);
|
mono_property_set_value(_monoProperty, instance, params, exception);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MProperty::HasAttribute(MClass* monoClass) const
|
bool MProperty::HasAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -134,10 +139,14 @@ bool MProperty::HasAttribute(MClass* monoClass) const
|
|||||||
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return hasAttr;
|
return hasAttr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MProperty::HasAttribute() const
|
bool MProperty::HasAttribute() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -150,10 +159,14 @@ bool MProperty::HasAttribute() const
|
|||||||
}
|
}
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* MProperty::GetAttribute(MClass* monoClass) const
|
MObject* MProperty::GetAttribute(MClass* monoClass) const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -162,14 +175,18 @@ MonoObject* MProperty::GetAttribute(MClass* monoClass) const
|
|||||||
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
return foundAttr;
|
return foundAttr;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<MonoObject*>& MProperty::GetAttributes()
|
const Array<MObject*>& MProperty::GetAttributes()
|
||||||
{
|
{
|
||||||
if (_hasCachedAttributes)
|
if (_hasCachedAttributes)
|
||||||
return _attributes;
|
return _attributes;
|
||||||
|
|
||||||
_hasCachedAttributes = true;
|
_hasCachedAttributes = true;
|
||||||
|
#if USE_MONO
|
||||||
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
|
||||||
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
|
||||||
if (attrInfo == nullptr)
|
if (attrInfo == nullptr)
|
||||||
@@ -179,9 +196,8 @@ const Array<MonoObject*>& MProperty::GetAttributes()
|
|||||||
const auto length = (uint32)mono_array_length(monoAttributesArray);
|
const auto length = (uint32)mono_array_length(monoAttributesArray);
|
||||||
_attributes.Resize(length);
|
_attributes.Resize(length);
|
||||||
for (uint32 i = 0; i < length; i++)
|
for (uint32 i = 0; i < length; i++)
|
||||||
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
|
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject *, i);
|
||||||
mono_custom_attrs_free(attrInfo);
|
mono_custom_attrs_free(attrInfo);
|
||||||
|
#endif
|
||||||
return _attributes;
|
return _attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -25,12 +25,12 @@ protected:
|
|||||||
|
|
||||||
MString _name;
|
MString _name;
|
||||||
|
|
||||||
Array<MonoObject*> _attributes;
|
|
||||||
|
|
||||||
int32 _hasCachedAttributes : 1;
|
int32 _hasCachedAttributes : 1;
|
||||||
int32 _hasSetMethod : 1;
|
int32 _hasSetMethod : 1;
|
||||||
int32 _hasGetMethod : 1;
|
int32 _hasGetMethod : 1;
|
||||||
|
|
||||||
|
Array<MObject*> _attributes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
@@ -47,7 +47,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property name.
|
/// Gets the property name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The property name.</returns>
|
|
||||||
FORCE_INLINE const MString& GetName() const
|
FORCE_INLINE const MString& GetName() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
@@ -56,7 +55,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the parent class that this method is contained with.
|
/// Returns the parent class that this method is contained with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The parent class.</returns>
|
|
||||||
FORCE_INLINE MClass* GetParentClass() const
|
FORCE_INLINE MClass* GetParentClass() const
|
||||||
{
|
{
|
||||||
return _parentClass;
|
return _parentClass;
|
||||||
@@ -65,31 +63,26 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets property type class.
|
/// Gets property type class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The property type.</returns>
|
|
||||||
MType GetType();
|
MType GetType();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets property get method.
|
/// Gets property get method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The getter method.</returns>
|
|
||||||
MMethod* GetGetMethod();
|
MMethod* GetGetMethod();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets property set method.
|
/// Gets property set method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The setter method.</returns>
|
|
||||||
MMethod* GetSetMethod();
|
MMethod* GetSetMethod();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets property visibility in the class.
|
/// Gets property visibility in the class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The property visibility.</returns>
|
|
||||||
MVisibility GetVisibility();
|
MVisibility GetVisibility();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if property is static.
|
/// Returns true if property is static.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if is static, otherwise false.</returns>
|
|
||||||
bool IsStatic();
|
bool IsStatic();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -98,23 +91,24 @@ public:
|
|||||||
/// Retrieves value currently set in the property on the specified object instance. If property is static object instance can be null.
|
/// Retrieves value currently set in the property on the specified object instance. If property is static object instance can be null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Value will be a pointer to raw data type for value types (for example int, float), and a MonoObject* for reference types.
|
/// Value will be a pointer to raw data type for value types (for example int, float), and a MObject* for reference types.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="instance">The object of given type to get value from.</param>
|
/// <param name="instance">The object of given type to get value from.</param>
|
||||||
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
||||||
/// <returns>The returned boxed value object.</returns>
|
/// <returns>The returned boxed value object.</returns>
|
||||||
MonoObject* GetValue(MonoObject* instance, MonoObject** exception);
|
MObject* GetValue(MObject* instance, MObject** exception);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets a value for the property on the specified object instance. If property is static object instance can be null.
|
/// Sets a value for the property on the specified object instance. If property is static object instance can be null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Value should be a pointer to raw data type for value types (for example int, float), and a MonoObject* for reference types.
|
/// Value should be a pointer to raw data type for value types (for example int, float), and a MObject* for reference types.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="instance">Object of given type to set value to.</param>
|
/// <param name="instance">Object of given type to set value to.</param>
|
||||||
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
/// <param name="exception">An optional pointer to the exception value to store exception object reference.</param>
|
||||||
/// <param name="value">The value to set of undefined type.</param>
|
/// <param name="value">The value to set of undefined type.</param>
|
||||||
void SetValue(MonoObject* instance, void* value, MonoObject** exception);
|
void SetValue(MObject* instance, void* value, MObject** exception);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -136,11 +130,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="monoClass">The attribute class to take.</param>
|
/// <param name="monoClass">The attribute class to take.</param>
|
||||||
/// <returns>The attribute object.</returns>
|
/// <returns>The attribute object.</returns>
|
||||||
MonoObject* GetAttribute(MClass* monoClass) const;
|
MObject* GetAttribute(MClass* monoClass) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an instance of all attributes connected with given property. Returns null if the property doesn't have any attributes.
|
/// Returns an instance of all attributes connected with given property. Returns null if the property doesn't have any attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The array of attribute objects.</returns>
|
/// <returns>The array of attribute objects.</returns>
|
||||||
const Array<MonoObject*>& GetAttributes();
|
const Array<MObject*>& GetAttributes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Engine/Core/Types/String.h"
|
#include "Engine/Core/Types/String.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class for converting mono classes and methods into usable form without instancing a class.
|
/// Class for converting mono classes and methods into usable form without instancing a class.
|
||||||
@@ -13,6 +15,7 @@ class MStaticConverter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
static MonoClass* GetMonoClassFromObject(MonoObject* monoObject)
|
static MonoClass* GetMonoClassFromObject(MonoObject* monoObject)
|
||||||
{
|
{
|
||||||
ASSERT(monoObject);
|
ASSERT(monoObject);
|
||||||
@@ -63,4 +66,5 @@ public:
|
|||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
#include "MType.h"
|
#include "MType.h"
|
||||||
#include "MUtils.h"
|
#include "MUtils.h"
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
|
|
||||||
String MType::ToString() const
|
String MType::ToString() const
|
||||||
@@ -42,4 +40,11 @@ bool MType::IsByRef() const
|
|||||||
return mono_type_is_byref(_monoType) != 0;
|
return mono_type_is_byref(_monoType) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
String MType::ToString() const
|
||||||
|
{
|
||||||
|
return String::Empty;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,14 +5,13 @@
|
|||||||
#include "MTypes.h"
|
#include "MTypes.h"
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information about managed type
|
/// Contains information about managed type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class MType
|
class MType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
MonoType* _monoType;
|
MonoType* _monoType;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -31,7 +30,6 @@ public:
|
|||||||
: _monoType(nullptr)
|
: _monoType(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,11 +44,9 @@ public:
|
|||||||
String ToString() const;
|
String ToString() const;
|
||||||
|
|
||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets mono type handle
|
/// Gets mono type handle
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Mono type</returns>
|
|
||||||
MonoType* GetNative() const
|
MonoType* GetNative() const
|
||||||
{
|
{
|
||||||
return _monoType;
|
return _monoType;
|
||||||
@@ -78,6 +74,5 @@ public:
|
|||||||
{
|
{
|
||||||
return _monoType != nullptr;
|
return _monoType != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,63 +2,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Types.h"
|
||||||
#include "Engine/Core/Types/String.h"
|
#include "Engine/Core/Types/String.h"
|
||||||
#include "Engine/Core/Types/StringView.h"
|
#include "Engine/Core/Types/StringView.h"
|
||||||
|
|
||||||
// Enable/disable mono debugging
|
|
||||||
#define MONO_DEBUG_ENABLE (!BUILD_RELEASE)
|
|
||||||
#define USE_MONO (1)
|
|
||||||
#define USE_NETCORE (0)
|
|
||||||
|
|
||||||
#ifndef USE_MONO_AOT
|
|
||||||
#define USE_MONO_AOT 0
|
|
||||||
#define USE_MONO_AOT_MODE MONO_AOT_MODE_NONE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Enables/disables profiling managed world via Mono
|
|
||||||
#define USE_MONO_PROFILER (COMPILE_WITH_PROFILER)
|
|
||||||
|
|
||||||
// Enables using single (root) app domain for the user scripts
|
|
||||||
#define USE_SINGLE_DOMAIN 1
|
|
||||||
|
|
||||||
#if USE_MONO
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// String container for names and typenames used by the managed runtime backend.
|
/// String container for names and typenames used by the managed runtime backend (8-bit chars).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
typedef StringAnsi MString;
|
typedef StringAnsi MString;
|
||||||
|
|
||||||
// Mono types declarations
|
|
||||||
typedef struct _MonoClass MonoClass;
|
|
||||||
typedef struct _MonoDomain MonoDomain;
|
|
||||||
typedef struct _MonoImage MonoImage;
|
|
||||||
typedef struct _MonoAssembly MonoAssembly;
|
|
||||||
typedef struct _MonoMethod MonoMethod;
|
|
||||||
typedef struct _MonoProperty MonoProperty;
|
|
||||||
typedef struct _MonoObject MonoObject;
|
|
||||||
typedef struct _MonoEvent MonoEvent;
|
|
||||||
typedef struct _MonoType MonoType;
|
|
||||||
typedef struct _MonoString MonoString;
|
|
||||||
typedef struct _MonoArray MonoArray;
|
|
||||||
typedef struct _MonoReflectionType MonoReflectionType;
|
|
||||||
typedef struct _MonoReflectionAssembly MonoReflectionAssembly;
|
|
||||||
typedef struct _MonoException MonoException;
|
|
||||||
typedef struct _MonoClassField MonoClassField;
|
|
||||||
typedef MonoObject MObject;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
class MCore;
|
|
||||||
class MAssembly;
|
|
||||||
class MClass;
|
|
||||||
class MField;
|
|
||||||
class MMethod;
|
|
||||||
class MProperty;
|
|
||||||
class MEvent;
|
|
||||||
class MDomain;
|
|
||||||
class MType;
|
|
||||||
|
|
||||||
enum class MVisibility
|
enum class MVisibility
|
||||||
{
|
{
|
||||||
Private,
|
Private,
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include "Engine/Utilities/StringConverter.h"
|
#include "Engine/Utilities/StringConverter.h"
|
||||||
#include "Engine/Content/Asset.h"
|
#include "Engine/Content/Asset.h"
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
struct _MonoType
|
struct _MonoType
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
@@ -846,3 +848,5 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, const MType& type, bool& fa
|
|||||||
failed = true;
|
failed = true;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
#include "Engine/Core/Types/Variant.h"
|
#include "Engine/Core/Types/Variant.h"
|
||||||
#include "Engine/Core/Collections/Array.h"
|
#include "Engine/Core/Collections/Array.h"
|
||||||
#include "Engine/Scripting/ScriptingObject.h"
|
#include "Engine/Scripting/ScriptingObject.h"
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
|
||||||
@@ -498,3 +501,5 @@ namespace MUtils
|
|||||||
|
|
||||||
extern void* VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed);
|
extern void* VariantToManagedArgPtr(Variant& value, const MType& type, bool& failed);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "ManagedSerialization.h"
|
#include "ManagedSerialization.h"
|
||||||
|
#if USE_MONO
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
#include "Engine/Serialization/Json.h"
|
#include "Engine/Serialization/Json.h"
|
||||||
#include "Engine/Serialization/JsonWriter.h"
|
#include "Engine/Serialization/JsonWriter.h"
|
||||||
@@ -26,7 +27,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, Mon
|
|||||||
params[1] = &isManagedOnly;
|
params[1] = &isManagedOnly;
|
||||||
|
|
||||||
// Call serialization tool
|
// Call serialization tool
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
// TODO: use method thunk
|
// TODO: use method thunk
|
||||||
auto invokeResultStr = (MonoString*)StdTypesContainer::Instance()->Json_Serialize->Invoke(nullptr, params, &exception);
|
auto invokeResultStr = (MonoString*)StdTypesContainer::Instance()->Json_Serialize->Invoke(nullptr, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
@@ -64,7 +65,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream,
|
|||||||
params[2] = &isManagedOnly;
|
params[2] = &isManagedOnly;
|
||||||
|
|
||||||
// Call serialization tool
|
// Call serialization tool
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
// TODO: use method thunk
|
// TODO: use method thunk
|
||||||
auto invokeResultStr = (MonoString*)StdTypesContainer::Instance()->Json_SerializeDiff->Invoke(nullptr, params, &exception);
|
auto invokeResultStr = (MonoString*)StdTypesContainer::Instance()->Json_SerializeDiff->Invoke(nullptr, params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
@@ -115,7 +116,7 @@ void ManagedSerialization::Deserialize(const StringAnsiView& data, MonoObject* o
|
|||||||
args[2] = (void*)&len;
|
args[2] = (void*)&len;
|
||||||
|
|
||||||
// Call serialization tool
|
// Call serialization tool
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
// TODO: use method thunk
|
// TODO: use method thunk
|
||||||
StdTypesContainer::Instance()->Json_Deserialize->Invoke(nullptr, args, &exception);
|
StdTypesContainer::Instance()->Json_Deserialize->Invoke(nullptr, args, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
@@ -124,3 +125,5 @@ void ManagedSerialization::Deserialize(const StringAnsiView& data, MonoObject* o
|
|||||||
ex.Log(LogType::Error, TEXT("ManagedSerialization::Deserialize"));
|
ex.Log(LogType::Error, TEXT("ManagedSerialization::Deserialize"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class FLAXENGINE_API ManagedSerialization
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serializes managed object to JSON.
|
/// Serializes managed object to JSON.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -40,4 +41,5 @@ public:
|
|||||||
/// <param name="data">The input data.</param>
|
/// <param name="data">The input data.</param>
|
||||||
/// <param name="object">The object to deserialize.</param>
|
/// <param name="object">The object to deserialize.</param>
|
||||||
static void Deserialize(const StringAnsiView& data, MonoObject* object);
|
static void Deserialize(const StringAnsiView& data, MonoObject* object);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,13 +44,14 @@ PluginManagerService PluginManagerServiceInstance;
|
|||||||
|
|
||||||
void PluginManagerImpl::LoadPlugin(MClass* klass, bool isEditor)
|
void PluginManagerImpl::LoadPlugin(MClass* klass, bool isEditor)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
if (Internal_LoadPlugin == nullptr)
|
if (Internal_LoadPlugin == nullptr)
|
||||||
{
|
{
|
||||||
Internal_LoadPlugin = PluginManager::GetStaticClass()->GetMethod("Internal_LoadPlugin", 2);
|
Internal_LoadPlugin = PluginManager::GetStaticClass()->GetMethod("Internal_LoadPlugin", 2);
|
||||||
ASSERT(Internal_LoadPlugin);
|
ASSERT(Internal_LoadPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
void* params[2];
|
void* params[2];
|
||||||
params[0] = MUtils::GetType(klass->GetNative());
|
params[0] = MUtils::GetType(klass->GetNative());
|
||||||
params[1] = &isEditor;
|
params[1] = &isEditor;
|
||||||
@@ -59,6 +60,7 @@ void PluginManagerImpl::LoadPlugin(MClass* klass, bool isEditor)
|
|||||||
{
|
{
|
||||||
DebugLog::LogException(exception);
|
DebugLog::LogException(exception);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
|
void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
|
||||||
@@ -113,10 +115,11 @@ void PluginManagerImpl::OnAssemblyLoaded(MAssembly* assembly)
|
|||||||
|
|
||||||
void PluginManagerImpl::OnAssemblyUnloading(MAssembly* assembly)
|
void PluginManagerImpl::OnAssemblyUnloading(MAssembly* assembly)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Cleanup plugins from this assembly
|
// Cleanup plugins from this assembly
|
||||||
const auto disposeMethod = PluginManager::GetStaticClass()->GetMethod("Internal_Dispose", 1);
|
const auto disposeMethod = PluginManager::GetStaticClass()->GetMethod("Internal_Dispose", 1);
|
||||||
ASSERT(disposeMethod);
|
ASSERT(disposeMethod);
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = assembly->GetNative();
|
params[0] = assembly->GetNative();
|
||||||
disposeMethod->Invoke(nullptr, params, &exception);
|
disposeMethod->Invoke(nullptr, params, &exception);
|
||||||
@@ -124,6 +127,7 @@ void PluginManagerImpl::OnAssemblyUnloading(MAssembly* assembly)
|
|||||||
{
|
{
|
||||||
DebugLog::LogException(exception);
|
DebugLog::LogException(exception);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginManagerImpl::OnBinaryModuleLoaded(BinaryModule* module)
|
void PluginManagerImpl::OnBinaryModuleLoaded(BinaryModule* module)
|
||||||
@@ -169,13 +173,15 @@ void PluginManagerService::Dispose()
|
|||||||
|
|
||||||
PROFILE_CPU_NAMED("Dispose Plugins");
|
PROFILE_CPU_NAMED("Dispose Plugins");
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Cleanup all plugins
|
// Cleanup all plugins
|
||||||
const auto disposeMethod = PluginManager::GetStaticClass()->GetMethod("Internal_Dispose");
|
const auto disposeMethod = PluginManager::GetStaticClass()->GetMethod("Internal_Dispose");
|
||||||
ASSERT(disposeMethod);
|
ASSERT(disposeMethod);
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
disposeMethod->Invoke(nullptr, nullptr, &exception);
|
disposeMethod->Invoke(nullptr, nullptr, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
DebugLog::LogException(exception);
|
DebugLog::LogException(exception);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ public class Scripting : EngineModule
|
|||||||
{
|
{
|
||||||
base.Setup(options);
|
base.Setup(options);
|
||||||
|
|
||||||
options.PublicDependencies.Add("mono");
|
if (EngineConfiguration.WithCSharp(options))
|
||||||
|
{
|
||||||
|
options.PublicDependencies.Add("mono");
|
||||||
|
}
|
||||||
|
|
||||||
options.PrivateDependencies.Add("Utilities");
|
options.PrivateDependencies.Add("Utilities");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "Engine/Core/Types/Pair.h"
|
#include "Engine/Core/Types/Pair.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
namespace ProfilerInternal
|
namespace ProfilerInternal
|
||||||
{
|
{
|
||||||
@@ -99,9 +103,12 @@ namespace ProfilerInternal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class ScriptingInternal
|
class ScriptingInternal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if USE_MONO
|
||||||
static bool HasGameModulesLoaded()
|
static bool HasGameModulesLoaded()
|
||||||
{
|
{
|
||||||
return Scripting::HasGameModulesLoaded();
|
return Scripting::HasGameModulesLoaded();
|
||||||
@@ -117,9 +124,11 @@ public:
|
|||||||
ASSERT(IsInMainThread());
|
ASSERT(IsInMainThread());
|
||||||
ObjectsRemovalService::Flush();
|
ObjectsRemovalService::Flush();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void InitRuntime()
|
static void InitRuntime()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Scripting API
|
// Scripting API
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Scripting::HasGameModulesLoaded", &HasGameModulesLoaded);
|
ADD_INTERNAL_CALL("FlaxEngine.Scripting::HasGameModulesLoaded", &HasGameModulesLoaded);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Scripting::IsTypeFromGameScripts", &IsTypeFromGameScripts);
|
ADD_INTERNAL_CALL("FlaxEngine.Scripting::IsTypeFromGameScripts", &IsTypeFromGameScripts);
|
||||||
@@ -130,6 +139,7 @@ public:
|
|||||||
ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEvent", &ProfilerInternal::EndEvent);
|
ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEvent", &ProfilerInternal::EndEvent);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Profiler::BeginEventGPU", &ProfilerInternal::BeginEventGPU);
|
ADD_INTERNAL_CALL("FlaxEngine.Profiler::BeginEventGPU", &ProfilerInternal::BeginEventGPU);
|
||||||
ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEventGPU", &ProfilerInternal::EndEventGPU);
|
ADD_INTERNAL_CALL("FlaxEngine.Profiler::EndEventGPU", &ProfilerInternal::EndEventGPU);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,10 @@
|
|||||||
#include "Engine/Engine/Globals.h"
|
#include "Engine/Engine/Globals.h"
|
||||||
#include "Engine/Graphics/RenderTask.h"
|
#include "Engine/Graphics/RenderTask.h"
|
||||||
#include "Engine/Serialization/JsonTools.h"
|
#include "Engine/Serialization/JsonTools.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void registerFlaxEngineInternalCalls();
|
extern void registerFlaxEngineInternalCalls();
|
||||||
|
|
||||||
@@ -55,8 +57,8 @@ public:
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
MDomain* _monoRootDomain = nullptr;
|
MDomain* _rootDomain = nullptr;
|
||||||
MDomain* _monoScriptsDomain = nullptr;
|
MDomain* _scriptsDomain = nullptr;
|
||||||
CriticalSection _objectsLocker;
|
CriticalSection _objectsLocker;
|
||||||
#define USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING 0
|
#define USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING 0
|
||||||
#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING
|
#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING
|
||||||
@@ -134,24 +136,24 @@ bool ScriptingService::Init()
|
|||||||
engineAssembly->Unloading.Bind(onEngineUnloading);
|
engineAssembly->Unloading.Bind(onEngineUnloading);
|
||||||
|
|
||||||
// Initialize managed runtime
|
// Initialize managed runtime
|
||||||
if (MCore::Instance()->LoadEngine())
|
if (MCore::LoadEngine())
|
||||||
{
|
{
|
||||||
LOG(Fatal, "Mono initialization failed.");
|
LOG(Fatal, "Mono initialization failed.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache root domain
|
// Cache root domain
|
||||||
_monoRootDomain = MCore::Instance()->GetRootDomain();
|
_rootDomain = MCore::GetRootDomain();
|
||||||
|
|
||||||
#if USE_SINGLE_DOMAIN
|
#if USE_SCRIPTING_SINGLE_DOMAIN
|
||||||
// Use single root domain
|
// Use single root domain
|
||||||
auto domain = _monoRootDomain;
|
auto domain = _rootDomain;
|
||||||
#else
|
#else
|
||||||
// Create Mono domain for scripts
|
// Create Mono domain for scripts
|
||||||
auto domain = MCore::Instance()->CreateDomain(TEXT("Scripts Domain"));
|
auto domain = MCore::CreateDomain("Scripts Domain");
|
||||||
#endif
|
#endif
|
||||||
domain->SetCurrentDomain(true);
|
domain->SetCurrentDomain(true);
|
||||||
_monoScriptsDomain = domain;
|
_scriptsDomain = domain;
|
||||||
|
|
||||||
// Add internal calls
|
// Add internal calls
|
||||||
registerFlaxEngineInternalCalls();
|
registerFlaxEngineInternalCalls();
|
||||||
@@ -169,6 +171,9 @@ bool ScriptingService::Init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if COMPILE_WITHOUT_CSHARP
|
||||||
|
#define INVOKE_EVENT(name)
|
||||||
|
#else
|
||||||
#define INVOKE_EVENT(name) \
|
#define INVOKE_EVENT(name) \
|
||||||
if (!_isEngineAssemblyLoaded) return; \
|
if (!_isEngineAssemblyLoaded) return; \
|
||||||
if (_method_##name == nullptr) \
|
if (_method_##name == nullptr) \
|
||||||
@@ -186,9 +191,10 @@ bool ScriptingService::Init()
|
|||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
MonoObject* exception = nullptr; \
|
MObject* exception = nullptr; \
|
||||||
_method_##name->Invoke(nullptr, nullptr, &exception); \
|
_method_##name->Invoke(nullptr, nullptr, &exception); \
|
||||||
DebugLog::LogException(exception)
|
DebugLog::LogException(exception)
|
||||||
|
#endif
|
||||||
|
|
||||||
void ScriptingService::Update()
|
void ScriptingService::Update()
|
||||||
{
|
{
|
||||||
@@ -227,12 +233,12 @@ void ScriptingService::BeforeExit()
|
|||||||
|
|
||||||
MDomain* Scripting::GetRootDomain()
|
MDomain* Scripting::GetRootDomain()
|
||||||
{
|
{
|
||||||
return _monoRootDomain;
|
return _rootDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
MDomain* Scripting::GetScriptsDomain()
|
MDomain* Scripting::GetScriptsDomain()
|
||||||
{
|
{
|
||||||
return _monoScriptsDomain;
|
return _scriptsDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scripting::ProcessBuildInfoPath(String& path, const String& projectFolderPath)
|
void Scripting::ProcessBuildInfoPath(String& path, const String& projectFolderPath)
|
||||||
@@ -276,10 +282,9 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde
|
|||||||
|
|
||||||
// Load all references
|
// Load all references
|
||||||
auto referencesMember = document.FindMember("References");
|
auto referencesMember = document.FindMember("References");
|
||||||
if (referencesMember != document.MemberEnd())
|
if (referencesMember != document.MemberEnd() && referencesMember->value.IsArray())
|
||||||
{
|
{
|
||||||
auto& referencesArray = referencesMember->value;
|
auto& referencesArray = referencesMember->value;
|
||||||
ASSERT(referencesArray.IsArray());
|
|
||||||
for (rapidjson::SizeType i = 0; i < referencesArray.Size(); i++)
|
for (rapidjson::SizeType i = 0; i < referencesArray.Size(); i++)
|
||||||
{
|
{
|
||||||
auto& reference = referencesArray[i];
|
auto& reference = referencesArray[i];
|
||||||
@@ -308,10 +313,9 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde
|
|||||||
|
|
||||||
// Load all binary modules
|
// Load all binary modules
|
||||||
auto binaryModulesMember = document.FindMember("BinaryModules");
|
auto binaryModulesMember = document.FindMember("BinaryModules");
|
||||||
if (binaryModulesMember != document.MemberEnd())
|
if (binaryModulesMember != document.MemberEnd() && binaryModulesMember->value.IsArray())
|
||||||
{
|
{
|
||||||
auto& binaryModulesArray = binaryModulesMember->value;
|
auto& binaryModulesArray = binaryModulesMember->value;
|
||||||
ASSERT(binaryModulesArray.IsArray());
|
|
||||||
for (rapidjson::SizeType i = 0; i < binaryModulesArray.Size(); i++)
|
for (rapidjson::SizeType i = 0; i < binaryModulesArray.Size(); i++)
|
||||||
{
|
{
|
||||||
auto& binaryModule = binaryModulesArray[i];
|
auto& binaryModule = binaryModulesArray[i];
|
||||||
@@ -396,6 +400,7 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// C#
|
// C#
|
||||||
if (managedPath.HasChars() && !((ManagedBinaryModule*)module)->Assembly->IsLoaded())
|
if (managedPath.HasChars() && !((ManagedBinaryModule*)module)->Assembly->IsLoaded())
|
||||||
{
|
{
|
||||||
@@ -405,6 +410,7 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BinaryModuleLoaded(module);
|
BinaryModuleLoaded(module);
|
||||||
}
|
}
|
||||||
@@ -419,12 +425,14 @@ bool Scripting::Load()
|
|||||||
// Note: this action can be called from main thread (due to Mono problems with assemblies actions from other threads)
|
// Note: this action can be called from main thread (due to Mono problems with assemblies actions from other threads)
|
||||||
ASSERT(IsInMainThread());
|
ASSERT(IsInMainThread());
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Load C# core assembly
|
// Load C# core assembly
|
||||||
if (GetBinaryModuleCorlib()->Assembly->Load(mono_get_corlib()))
|
if (GetBinaryModuleCorlib()->Assembly->Load(mono_get_corlib()))
|
||||||
{
|
{
|
||||||
LOG(Error, "Failed to load corlib C# assembly.");
|
LOG(Error, "Failed to load corlib C# assembly.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Load FlaxEngine
|
// Load FlaxEngine
|
||||||
const String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
|
const String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
|
||||||
@@ -539,7 +547,7 @@ void Scripting::Release()
|
|||||||
ObjectsRemovalService::Flush();
|
ObjectsRemovalService::Flush();
|
||||||
|
|
||||||
// Switch domain
|
// Switch domain
|
||||||
auto rootDomain = MCore::Instance()->GetRootDomain();
|
auto rootDomain = MCore::GetRootDomain();
|
||||||
if (rootDomain)
|
if (rootDomain)
|
||||||
{
|
{
|
||||||
if (!rootDomain->SetCurrentDomain(false))
|
if (!rootDomain->SetCurrentDomain(false))
|
||||||
@@ -548,8 +556,8 @@ void Scripting::Release()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !USE_SINGLE_DOMAIN
|
#if !USE_SCRIPTING_SINGLE_DOMAIN
|
||||||
MCore::Instance()->UnloadDomain("Scripts Domain");
|
MCore::UnloadDomain("Scripts Domain");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,25 +655,6 @@ void Scripting::Reload(bool canTriggerSceneReload)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MClass* Scripting::FindClass(MonoClass* monoClass)
|
|
||||||
{
|
|
||||||
if (monoClass == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
PROFILE_CPU();
|
|
||||||
auto& modules = BinaryModule::GetModules();
|
|
||||||
for (auto module : modules)
|
|
||||||
{
|
|
||||||
auto managedModule = dynamic_cast<ManagedBinaryModule*>(module);
|
|
||||||
if (managedModule && managedModule->Assembly->IsLoaded())
|
|
||||||
{
|
|
||||||
MClass* result = managedModule->Assembly->GetClass(monoClass);
|
|
||||||
if (result != nullptr)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
MClass* Scripting::FindClass(const StringAnsiView& fullname)
|
MClass* Scripting::FindClass(const StringAnsiView& fullname)
|
||||||
{
|
{
|
||||||
if (fullname.IsEmpty())
|
if (fullname.IsEmpty())
|
||||||
@@ -685,6 +674,27 @@ MClass* Scripting::FindClass(const StringAnsiView& fullname)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
|
MClass* Scripting::FindClass(MonoClass* monoClass)
|
||||||
|
{
|
||||||
|
if (monoClass == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
PROFILE_CPU();
|
||||||
|
auto& modules = BinaryModule::GetModules();
|
||||||
|
for (auto module : modules)
|
||||||
|
{
|
||||||
|
auto managedModule = dynamic_cast<ManagedBinaryModule*>(module);
|
||||||
|
if (managedModule && managedModule->Assembly->IsLoaded())
|
||||||
|
{
|
||||||
|
MClass* result = managedModule->Assembly->GetClass(monoClass);
|
||||||
|
if (result != nullptr)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
MonoClass* Scripting::FindClassNative(const StringAnsiView& fullname)
|
MonoClass* Scripting::FindClassNative(const StringAnsiView& fullname)
|
||||||
{
|
{
|
||||||
if (fullname.IsEmpty())
|
if (fullname.IsEmpty())
|
||||||
@@ -704,6 +714,8 @@ MonoClass* Scripting::FindClassNative(const StringAnsiView& fullname)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
ScriptingTypeHandle Scripting::FindScriptingType(const StringAnsiView& fullname)
|
ScriptingTypeHandle Scripting::FindScriptingType(const StringAnsiView& fullname)
|
||||||
{
|
{
|
||||||
if (fullname.IsEmpty())
|
if (fullname.IsEmpty())
|
||||||
@@ -816,7 +828,7 @@ ScriptingObject* Scripting::TryFindObject(Guid id, MClass* type)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptingObject* Scripting::FindObject(const MonoObject* managedInstance)
|
ScriptingObject* Scripting::FindObject(const MObject* managedInstance)
|
||||||
{
|
{
|
||||||
if (managedInstance == nullptr)
|
if (managedInstance == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -938,13 +950,14 @@ bool initFlaxEngine()
|
|||||||
if (StdTypesContainer::Instance()->Gather())
|
if (StdTypesContainer::Instance()->Gather())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Init C# class library
|
// Init C# class library
|
||||||
{
|
{
|
||||||
auto scriptingClass = Scripting::GetStaticClass();
|
auto scriptingClass = Scripting::GetStaticClass();
|
||||||
ASSERT(scriptingClass);
|
ASSERT(scriptingClass);
|
||||||
const auto initMethod = scriptingClass->GetMethod("Init");
|
const auto initMethod = scriptingClass->GetMethod("Init");
|
||||||
ASSERT(initMethod);
|
ASSERT(initMethod);
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
initMethod->Invoke(nullptr, nullptr, &exception);
|
initMethod->Invoke(nullptr, nullptr, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -952,10 +965,11 @@ bool initFlaxEngine()
|
|||||||
ex.Log(LogType::Fatal, TEXT("FlaxEngine.Scripting.Init"));
|
ex.Log(LogType::Fatal, TEXT("FlaxEngine.Scripting.Init"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move it somewhere to game instance class or similar
|
|
||||||
MainRenderTask::Instance = New<MainRenderTask>();
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: move it somewhere to game instance class or similar
|
||||||
|
MainRenderTask::Instance = New<MainRenderTask>();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -989,5 +1003,5 @@ void ScriptingService::Dispose()
|
|||||||
{
|
{
|
||||||
Scripting::Release();
|
Scripting::Release();
|
||||||
|
|
||||||
MCore::Instance()->UnloadEngine();
|
MCore::UnloadEngine();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ public:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets mono root domain
|
/// Gets the root domain.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static MDomain* GetRootDomain();
|
static MDomain* GetRootDomain();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets scripts domain
|
/// Gets the scripts domain (it can be the root domain if not using separate domain for scripting).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static MDomain* GetScriptsDomain();
|
static MDomain* GetScriptsDomain();
|
||||||
|
|
||||||
@@ -70,17 +70,23 @@ public:
|
|||||||
static void Release();
|
static void Release();
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reloads scripts.
|
/// Reloads scripts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="canTriggerSceneReload">True if allow to scene scripts reload callback, otherwise it won't be possible.</param>
|
/// <param name="canTriggerSceneReload">True if allow to scene scripts reload callback, otherwise it won't be possible.</param>
|
||||||
static void Reload(bool canTriggerSceneReload = true);
|
static void Reload(bool canTriggerSceneReload = true);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the class with given fully qualified name within whole assembly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fullname">The full name of the type eg: System.Int64.</param>
|
||||||
|
/// <returns>The MClass object or null if missing.</returns>
|
||||||
|
static MClass* FindClass(const StringAnsiView& fullname);
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the class from the given Mono class object within whole assembly.
|
/// Finds the class from the given Mono class object within whole assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -88,19 +94,13 @@ public:
|
|||||||
/// <returns>The MClass object or null if missing.</returns>
|
/// <returns>The MClass object or null if missing.</returns>
|
||||||
static MClass* FindClass(MonoClass* monoClass);
|
static MClass* FindClass(MonoClass* monoClass);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds the class with given fully qualified name within whole assembly.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fullname">The full name of the type eg: System.Int64.</param>
|
|
||||||
/// <returns>The MClass object or null if missing.</returns>
|
|
||||||
static MClass* FindClass(const StringAnsiView& fullname);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the native class with given fully qualified name within whole assembly.
|
/// Finds the native class with given fully qualified name within whole assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fullname">The full name of the type eg: System.Int64.</param>
|
/// <param name="fullname">The full name of the type eg: System.Int64.</param>
|
||||||
/// <returns>The MClass object or null if missing.</returns>
|
/// <returns>The MClass object or null if missing.</returns>
|
||||||
static MonoClass* FindClassNative(const StringAnsiView& fullname);
|
static MonoClass* FindClassNative(const StringAnsiView& fullname);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the scripting type of the given fullname by searching loaded scripting assemblies.
|
/// Finds the scripting type of the given fullname by searching loaded scripting assemblies.
|
||||||
@@ -161,7 +161,7 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="managedInstance">The managed instance pointer.</param>
|
/// <param name="managedInstance">The managed instance pointer.</param>
|
||||||
/// <returns>The found object or null if missing.</returns>
|
/// <returns>The found object or null if missing.</returns>
|
||||||
static ScriptingObject* FindObject(const MonoObject* managedInstance);
|
static ScriptingObject* FindObject(const MObject* managedInstance);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event called by the internal call on a finalizer thread when the managed objects gets deleted by the GC.
|
/// Event called by the internal call on a finalizer thread when the managed objects gets deleted by the GC.
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
#include "Engine/Scripting/ManagedCLR/MTypes.h"
|
#include "Engine/Scripting/ManagedCLR/MTypes.h"
|
||||||
|
|
||||||
typedef void (*Thunk_Void_0)(MonoObject** exception);
|
typedef void (*Thunk_Void_0)(MObject** exception);
|
||||||
typedef void (*Thunk_Void_1)(void* param_1, MonoObject** exception);
|
typedef void (*Thunk_Void_1)(void* param_1, MObject** exception);
|
||||||
typedef void (*Thunk_Void_2)(void* param_1, void* param_2, MonoObject** exception);
|
typedef void (*Thunk_Void_2)(void* param_1, void* param_2, MObject** exception);
|
||||||
typedef void (*Thunk_Void_3)(void* param_1, void* param_2, void* param_3, MonoObject** exception);
|
typedef void (*Thunk_Void_3)(void* param_1, void* param_2, void* param_3, MObject** exception);
|
||||||
typedef void (*Thunk_Void_4)(void* param_1, void* param_2, void* param_3, void* param_4, MonoObject** exception);
|
typedef void (*Thunk_Void_4)(void* param_1, void* param_2, void* param_3, void* param_4, MObject** exception);
|
||||||
|
|
||||||
typedef MonoObject* (*Thunk_Object_0)(MonoObject** exception);
|
typedef MObject* (*Thunk_Object_0)(MObject** exception);
|
||||||
typedef MonoObject* (*Thunk_Object_1)(void* param_1, MonoObject** exception);
|
typedef MObject* (*Thunk_Object_1)(void* param_1, MObject** exception);
|
||||||
typedef MonoObject* (*Thunk_Object_2)(void* param_1, void* param_2, MonoObject** exception);
|
typedef MObject* (*Thunk_Object_2)(void* param_1, void* param_2, MObject** exception);
|
||||||
typedef MonoObject* (*Thunk_Object_3)(void* param_1, void* param_2, void* param_3, MonoObject** exception);
|
typedef MObject* (*Thunk_Object_3)(void* param_1, void* param_2, void* param_3, MObject** exception);
|
||||||
typedef MonoObject* (*Thunk_Object_4)(void* param_1, void* param_2, void* param_3, void* param_4, MonoObject** exception);
|
typedef MObject* (*Thunk_Object_4)(void* param_1, void* param_2, void* param_3, void* param_4, MObject** exception);
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
#include "ManagedCLR/MCore.h"
|
#include "ManagedCLR/MCore.h"
|
||||||
#endif
|
#endif
|
||||||
#include "FlaxEngine.Gen.h"
|
#include "FlaxEngine.Gen.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ScriptingObject_unmanagedPtr "__unmanagedPtr"
|
#define ScriptingObject_unmanagedPtr "__unmanagedPtr"
|
||||||
#define ScriptingObject_id "__internalId"
|
#define ScriptingObject_id "__internalId"
|
||||||
@@ -54,14 +56,18 @@ ScriptingObject::~ScriptingObject()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* ScriptingObject::GetManagedInstance() const
|
MObject* ScriptingObject::GetManagedInstance() const
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
return _gcHandle ? mono_gchandle_get_target(_gcHandle) : nullptr;
|
return _gcHandle ? mono_gchandle_get_target(_gcHandle) : nullptr;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject* ScriptingObject::GetOrCreateManagedInstance() const
|
MObject* ScriptingObject::GetOrCreateManagedInstance() const
|
||||||
{
|
{
|
||||||
MonoObject* managedInstance = GetManagedInstance();
|
MObject* managedInstance = GetManagedInstance();
|
||||||
if (!managedInstance)
|
if (!managedInstance)
|
||||||
{
|
{
|
||||||
const_cast<ScriptingObject*>(this)->CreateManaged();
|
const_cast<ScriptingObject*>(this)->CreateManaged();
|
||||||
@@ -144,9 +150,10 @@ void* ScriptingObject::ToInterface(ScriptingObject* obj, const ScriptingTypeHand
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptingObject* ScriptingObject::ToNative(MonoObject* obj)
|
ScriptingObject* ScriptingObject::ToNative(MObject* obj)
|
||||||
{
|
{
|
||||||
ScriptingObject* ptr = nullptr;
|
ScriptingObject* ptr = nullptr;
|
||||||
|
#if USE_MONO
|
||||||
if (obj)
|
if (obj)
|
||||||
{
|
{
|
||||||
// TODO: cache the field offset from object and read directly from object pointer
|
// TODO: cache the field offset from object and read directly from object pointer
|
||||||
@@ -154,6 +161,7 @@ ScriptingObject* ScriptingObject::ToNative(MonoObject* obj)
|
|||||||
CHECK_RETURN(ptrField, nullptr);
|
CHECK_RETURN(ptrField, nullptr);
|
||||||
mono_field_get_value(obj, ptrField, &ptr);
|
mono_field_get_value(obj, ptrField, &ptr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +199,9 @@ void ScriptingObject::OnManagedInstanceDeleted()
|
|||||||
// Release the handle
|
// Release the handle
|
||||||
if (_gcHandle)
|
if (_gcHandle)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
mono_gchandle_free(_gcHandle);
|
mono_gchandle_free(_gcHandle);
|
||||||
|
#endif
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +222,8 @@ void ScriptingObject::OnScriptingDispose()
|
|||||||
DeleteObject();
|
DeleteObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
MonoObject* ScriptingObject::CreateManagedInternal()
|
MonoObject* ScriptingObject::CreateManagedInternal()
|
||||||
{
|
{
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
@@ -254,8 +266,11 @@ MonoObject* ScriptingObject::CreateManagedInternal()
|
|||||||
return managedInstance;
|
return managedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void ScriptingObject::DestroyManaged()
|
void ScriptingObject::DestroyManaged()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
// Get managed instance
|
// Get managed instance
|
||||||
const auto managedInstance = GetManagedInstance();
|
const auto managedInstance = GetManagedInstance();
|
||||||
|
|
||||||
@@ -279,6 +294,9 @@ void ScriptingObject::DestroyManaged()
|
|||||||
mono_gchandle_free(_gcHandle);
|
mono_gchandle_free(_gcHandle);
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
_gcHandle = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptingObject::RegisterObject()
|
void ScriptingObject::RegisterObject()
|
||||||
@@ -319,6 +337,8 @@ bool ScriptingObject::CanCast(MClass* from, MClass* to)
|
|||||||
return from->IsSubClassOf(to);
|
return from->IsSubClassOf(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
bool ScriptingObject::CanCast(MClass* from, MonoClass* to)
|
bool ScriptingObject::CanCast(MClass* from, MonoClass* to)
|
||||||
{
|
{
|
||||||
if (!from && !to)
|
if (!from && !to)
|
||||||
@@ -333,6 +353,8 @@ bool ScriptingObject::CanCast(MClass* from, MonoClass* to)
|
|||||||
return from->IsSubClassOf(to);
|
return from->IsSubClassOf(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void ScriptingObject::OnDeleteObject()
|
void ScriptingObject::OnDeleteObject()
|
||||||
{
|
{
|
||||||
// Cleanup managed object
|
// Cleanup managed object
|
||||||
@@ -358,6 +380,7 @@ ManagedScriptingObject::ManagedScriptingObject(const SpawnParams& params)
|
|||||||
|
|
||||||
void ManagedScriptingObject::CreateManaged()
|
void ManagedScriptingObject::CreateManaged()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoObject* managedInstance = CreateManagedInternal();
|
MonoObject* managedInstance = CreateManagedInternal();
|
||||||
if (managedInstance)
|
if (managedInstance)
|
||||||
{
|
{
|
||||||
@@ -368,6 +391,11 @@ void ManagedScriptingObject::CreateManaged()
|
|||||||
if (!IsRegistered())
|
if (!IsRegistered())
|
||||||
RegisterObject();
|
RegisterObject();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Ensure to be registered
|
||||||
|
if (!IsRegistered())
|
||||||
|
RegisterObject();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentScriptingObject::PersistentScriptingObject(const SpawnParams& params)
|
PersistentScriptingObject::PersistentScriptingObject(const SpawnParams& params)
|
||||||
@@ -385,7 +413,9 @@ void PersistentScriptingObject::OnManagedInstanceDeleted()
|
|||||||
// Cleanup
|
// Cleanup
|
||||||
if (_gcHandle)
|
if (_gcHandle)
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
mono_gchandle_free(_gcHandle);
|
mono_gchandle_free(_gcHandle);
|
||||||
|
#endif
|
||||||
_gcHandle = 0;
|
_gcHandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +434,7 @@ void PersistentScriptingObject::OnScriptingDispose()
|
|||||||
|
|
||||||
void PersistentScriptingObject::CreateManaged()
|
void PersistentScriptingObject::CreateManaged()
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoObject* managedInstance = CreateManagedInternal();
|
MonoObject* managedInstance = CreateManagedInternal();
|
||||||
if (managedInstance)
|
if (managedInstance)
|
||||||
{
|
{
|
||||||
@@ -414,11 +445,18 @@ void PersistentScriptingObject::CreateManaged()
|
|||||||
if (!IsRegistered())
|
if (!IsRegistered())
|
||||||
RegisterObject();
|
RegisterObject();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Ensure to be registered
|
||||||
|
if (!IsRegistered())
|
||||||
|
RegisterObject();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScriptingObjectInternal
|
class ScriptingObjectInternal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
static MonoObject* Create1(MonoReflectionType* type)
|
static MonoObject* Create1(MonoReflectionType* type)
|
||||||
{
|
{
|
||||||
@@ -676,6 +714,14 @@ public:
|
|||||||
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &GetUnmanagedInterface);
|
ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetUnmanagedInterface", &GetUnmanagedInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void InitRuntime()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static ScriptingObject* Spawn(const ScriptingObjectSpawnParams& params)
|
static ScriptingObject* Spawn(const ScriptingObjectSpawnParams& params)
|
||||||
{
|
{
|
||||||
return New<PersistentScriptingObject>(params);
|
return New<PersistentScriptingObject>(params);
|
||||||
|
|||||||
@@ -62,12 +62,12 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the managed instance object.
|
/// Gets the managed instance object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoObject* GetManagedInstance() const;
|
MObject* GetManagedInstance() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the managed instance object or creates it if missing.
|
/// Gets the managed instance object or creates it if missing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoObject* GetOrCreateManagedInstance() const;
|
MObject* GetOrCreateManagedInstance() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether managed instance is alive.
|
/// Determines whether managed instance is alive.
|
||||||
@@ -117,9 +117,9 @@ public:
|
|||||||
return (T*)ToInterface(obj, T::TypeInitializer);
|
return (T*)ToInterface(obj, T::TypeInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScriptingObject* ToNative(MonoObject* obj);
|
static ScriptingObject* ToNative(MObject* obj);
|
||||||
|
|
||||||
static MonoObject* ToManaged(ScriptingObject* obj)
|
static MObject* ToManaged(ScriptingObject* obj)
|
||||||
{
|
{
|
||||||
return obj ? obj->GetOrCreateManagedInstance() : nullptr;
|
return obj ? obj->GetOrCreateManagedInstance() : nullptr;
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,9 @@ public:
|
|||||||
/// <param name="to">The destination class to the cast.</param>
|
/// <param name="to">The destination class to the cast.</param>
|
||||||
/// <returns>True if can, otherwise false.</returns>
|
/// <returns>True if can, otherwise false.</returns>
|
||||||
static bool CanCast(MClass* from, MClass* to);
|
static bool CanCast(MClass* from, MClass* to);
|
||||||
|
#if USE_MONO
|
||||||
static bool CanCast(MClass* from, MonoClass* to);
|
static bool CanCast(MClass* from, MonoClass* to);
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static T* Cast(ScriptingObject* obj)
|
static T* Cast(ScriptingObject* obj)
|
||||||
@@ -154,10 +156,12 @@ public:
|
|||||||
return CanCast(GetClass(), type);
|
return CanCast(GetClass(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
bool Is(MonoClass* klass) const
|
bool Is(MonoClass* klass) const
|
||||||
{
|
{
|
||||||
return CanCast(GetClass(), klass);
|
return CanCast(GetClass(), klass);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool Is() const
|
bool Is() const
|
||||||
@@ -186,7 +190,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether this object is registered or not (can be found by the queries and used in a game).
|
/// Determines whether this object is registered or not (can be found by the queries and used in a game).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns><c>true</c> if this instance is registered; otherwise, <c>false</c>.</returns>
|
|
||||||
FORCE_INLINE bool IsRegistered() const
|
FORCE_INLINE bool IsRegistered() const
|
||||||
{
|
{
|
||||||
return (Flags & ObjectFlags::IsRegistered) != 0;
|
return (Flags & ObjectFlags::IsRegistered) != 0;
|
||||||
@@ -204,10 +207,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new managed object.
|
/// Create a new managed object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoObject* CreateManagedInternal();
|
MonoObject* CreateManagedInternal();
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets managed instance object (or null if no object linked).
|
/// Gets managed instance object (or null if no object linked).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
FORCE_INLINE MonoObject* GetManagedInstance() const
|
FORCE_INLINE MObject* GetManagedInstance() const
|
||||||
{
|
{
|
||||||
return _object ? _object->GetOrCreateManagedInstance() : nullptr;
|
return _object ? _object->GetOrCreateManagedInstance() : nullptr;
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the managed instance object or creates it if missing or null if not assigned.
|
/// Gets the managed instance object or creates it if missing or null if not assigned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
FORCE_INLINE MonoObject* GetOrCreateManagedInstance() const
|
FORCE_INLINE MObject* GetOrCreateManagedInstance() const
|
||||||
{
|
{
|
||||||
return _object ? _object->GetOrCreateManagedInstance() : nullptr;
|
return _object ? _object->GetOrCreateManagedInstance() : nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ class NativeBinaryModule;
|
|||||||
struct ScriptingTypeHandle;
|
struct ScriptingTypeHandle;
|
||||||
struct ScriptingTypeInitializer;
|
struct ScriptingTypeInitializer;
|
||||||
struct ScriptingObjectSpawnParams;
|
struct ScriptingObjectSpawnParams;
|
||||||
typedef struct _MonoClass MonoClass;
|
|
||||||
typedef struct _MonoObject MonoObject;
|
|
||||||
typedef struct _MonoType MonoType;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The safe handle to the scripting type contained in the scripting assembly.
|
/// The safe handle to the scripting type contained in the scripting assembly.
|
||||||
@@ -113,8 +110,8 @@ struct FLAXENGINE_API ScriptingType
|
|||||||
typedef void (*Ctor)(void* ptr);
|
typedef void (*Ctor)(void* ptr);
|
||||||
typedef void (*Dtor)(void* ptr);
|
typedef void (*Dtor)(void* ptr);
|
||||||
typedef void (*Copy)(void* dst, void* src);
|
typedef void (*Copy)(void* dst, void* src);
|
||||||
typedef MonoObject* (*Box)(void* ptr);
|
typedef MObject* (*Box)(void* ptr);
|
||||||
typedef void (*Unbox)(void* ptr, MonoObject* managed);
|
typedef void (*Unbox)(void* ptr, MObject* managed);
|
||||||
typedef void (*GetField)(void* ptr, const String& name, Variant& value);
|
typedef void (*GetField)(void* ptr, const String& name, Variant& value);
|
||||||
typedef void (*SetField)(void* ptr, const String& name, const Variant& value);
|
typedef void (*SetField)(void* ptr, const String& name, const Variant& value);
|
||||||
typedef void* (*GetInterfaceWrapper)(ScriptingObject* obj);
|
typedef void* (*GetInterfaceWrapper)(ScriptingObject* obj);
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ public:
|
|||||||
/// Gets managed instance object (or null if no object linked).
|
/// Gets managed instance object (or null if no object linked).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The managed object instance.</returns>
|
/// <returns>The managed object instance.</returns>
|
||||||
MonoObject* GetManagedInstance() const
|
MObject* GetManagedInstance() const
|
||||||
{
|
{
|
||||||
auto object = Get();
|
auto object = Get();
|
||||||
return object ? object->GetOrCreateManagedInstance() : nullptr;
|
return object ? object->GetOrCreateManagedInstance() : nullptr;
|
||||||
@@ -301,7 +301,7 @@ public:
|
|||||||
/// Gets the managed instance object or creates it if missing or null if not assigned.
|
/// Gets the managed instance object or creates it if missing or null if not assigned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The Mono managed object.</returns>
|
/// <returns>The Mono managed object.</returns>
|
||||||
MonoObject* GetOrCreateManagedInstance() const
|
MObject* GetOrCreateManagedInstance() const
|
||||||
{
|
{
|
||||||
auto object = Get();
|
auto object = Get();
|
||||||
return object ? object->GetOrCreateManagedInstance() : nullptr;
|
return object ? object->GetOrCreateManagedInstance() : nullptr;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ void StdTypesContainer::Clear()
|
|||||||
|
|
||||||
bool StdTypesContainer::Gather()
|
bool StdTypesContainer::Gather()
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
#define GET_CLASS(assembly, type, typeName) \
|
#define GET_CLASS(assembly, type, typeName) \
|
||||||
type = ((ManagedBinaryModule*)CONCAT_MACROS(GetBinaryModule, assembly)())->Assembly->GetClass(typeName); \
|
type = ((ManagedBinaryModule*)CONCAT_MACROS(GetBinaryModule, assembly)())->Assembly->GetClass(typeName); \
|
||||||
if (type == nullptr) \
|
if (type == nullptr) \
|
||||||
@@ -93,5 +94,6 @@ bool StdTypesContainer::Gather()
|
|||||||
|
|
||||||
#undef GET_CLASS
|
#undef GET_CLASS
|
||||||
#undef GET_METHOD
|
#undef GET_METHOD
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,69 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
class Scripting;
|
class Scripting;
|
||||||
struct ScriptingType;
|
struct ScriptingType;
|
||||||
class BinaryModule;
|
class BinaryModule;
|
||||||
class ScriptingObject;
|
class ScriptingObject;
|
||||||
|
class MCore;
|
||||||
class MDomain;
|
class MDomain;
|
||||||
class MException;
|
class MException;
|
||||||
class MAssembly;
|
class MAssembly;
|
||||||
class MClass;
|
class MClass;
|
||||||
class MField;
|
class MField;
|
||||||
|
class MMethod;
|
||||||
class MProperty;
|
class MProperty;
|
||||||
class MEvent;
|
class MEvent;
|
||||||
|
class MDomain;
|
||||||
|
class MType;
|
||||||
|
|
||||||
|
#if COMPILE_WITHOUT_CSHARP
|
||||||
|
|
||||||
|
// No Scripting
|
||||||
|
#define USE_MONO 0
|
||||||
|
#define USE_NETCORE 0
|
||||||
|
typedef void MObject;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define USE_MONO 1
|
||||||
|
#define USE_NETCORE 0
|
||||||
|
|
||||||
|
// Enables using single (root) app domain for the user scripts
|
||||||
|
#define USE_SCRIPTING_SINGLE_DOMAIN 1
|
||||||
|
|
||||||
|
#if USE_MONO
|
||||||
|
|
||||||
|
// Enables/disables profiling managed world via Mono
|
||||||
|
#define USE_MONO_PROFILER (COMPILE_WITH_PROFILER)
|
||||||
|
|
||||||
|
// Enable/disable mono debugging
|
||||||
|
#define MONO_DEBUG_ENABLE (!BUILD_RELEASE)
|
||||||
|
|
||||||
|
#ifndef USE_MONO_AOT
|
||||||
|
#define USE_MONO_AOT 0
|
||||||
|
#define USE_MONO_AOT_MODE MONO_AOT_MODE_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mono types declarations
|
||||||
|
typedef struct _MonoClass MonoClass;
|
||||||
|
typedef struct _MonoDomain MonoDomain;
|
||||||
|
typedef struct _MonoImage MonoImage;
|
||||||
|
typedef struct _MonoAssembly MonoAssembly;
|
||||||
|
typedef struct _MonoMethod MonoMethod;
|
||||||
|
typedef struct _MonoProperty MonoProperty;
|
||||||
|
typedef struct _MonoObject MonoObject;
|
||||||
|
typedef struct _MonoEvent MonoEvent;
|
||||||
|
typedef struct _MonoType MonoType;
|
||||||
|
typedef struct _MonoString MonoString;
|
||||||
|
typedef struct _MonoArray MonoArray;
|
||||||
|
typedef struct _MonoReflectionType MonoReflectionType;
|
||||||
|
typedef struct _MonoReflectionAssembly MonoReflectionAssembly;
|
||||||
|
typedef struct _MonoException MonoException;
|
||||||
|
typedef struct _MonoClassField MonoClassField;
|
||||||
|
typedef MonoObject MObject;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -208,12 +208,14 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
|
|||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
case VariantType::Structure:
|
case VariantType::Structure:
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoObject* obj;
|
MonoObject* obj;
|
||||||
if (v.Type.Type == VariantType::Structure)
|
if (v.Type.Type == VariantType::Structure)
|
||||||
obj = MUtils::BoxVariant(v);
|
obj = MUtils::BoxVariant(v);
|
||||||
else
|
else
|
||||||
obj = (MonoObject*)v;
|
obj = (MonoObject*)v;
|
||||||
ManagedSerialization::Serialize(stream, obj);
|
ManagedSerialization::Serialize(stream, obj);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -346,6 +348,7 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
|||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
case VariantType::Structure:
|
case VariantType::Structure:
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
auto obj = (MonoObject*)v;
|
auto obj = (MonoObject*)v;
|
||||||
if (!obj && v.Type.TypeName)
|
if (!obj && v.Type.TypeName)
|
||||||
{
|
{
|
||||||
@@ -369,6 +372,7 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
|||||||
ManagedSerialization::Deserialize(value, obj);
|
ManagedSerialization::Deserialize(value, obj);
|
||||||
if (v.Type.Type == VariantType::Structure)
|
if (v.Type.Type == VariantType::Structure)
|
||||||
v = MUtils::UnboxVariant(obj);
|
v = MUtils::UnboxVariant(obj);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -356,6 +356,7 @@ void ReadStream::ReadVariant(Variant* data)
|
|||||||
// Json
|
// Json
|
||||||
StringAnsi json;
|
StringAnsi json;
|
||||||
ReadStringAnsi(&json, -71);
|
ReadStringAnsi(&json, -71);
|
||||||
|
#if USE_MONO
|
||||||
MCore::AttachThread();
|
MCore::AttachThread();
|
||||||
MonoClass* klass = MUtils::GetClass(data->Type);
|
MonoClass* klass = MUtils::GetClass(data->Type);
|
||||||
if (!klass)
|
if (!klass)
|
||||||
@@ -376,6 +377,7 @@ void ReadStream::ReadVariant(Variant* data)
|
|||||||
data->SetManagedObject(obj);
|
data->SetManagedObject(obj);
|
||||||
else
|
else
|
||||||
*data = MUtils::UnboxVariant(obj);
|
*data = MUtils::UnboxVariant(obj);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -706,6 +708,7 @@ void WriteStream::WriteVariant(const Variant& data)
|
|||||||
case VariantType::ManagedObject:
|
case VariantType::ManagedObject:
|
||||||
case VariantType::Structure:
|
case VariantType::Structure:
|
||||||
{
|
{
|
||||||
|
#if USE_MONO
|
||||||
MonoObject* obj;
|
MonoObject* obj;
|
||||||
if (data.Type.Type == VariantType::Structure)
|
if (data.Type.Type == VariantType::Structure)
|
||||||
obj = MUtils::BoxVariant(data);
|
obj = MUtils::BoxVariant(data);
|
||||||
@@ -721,6 +724,7 @@ void WriteStream::WriteVariant(const Variant& data)
|
|||||||
WriteStringAnsi(StringAnsiView(json.GetString(), (int32)json.GetSize()), -71);
|
WriteStringAnsi(StringAnsiView(json.GetString(), (int32)json.GetSize()), -71);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ int32 JobSystemThread::Run()
|
|||||||
// Ensure to have C# thread attached to this thead (late init due to MCore being initialized after Job System)
|
// Ensure to have C# thread attached to this thead (late init due to MCore being initialized after Job System)
|
||||||
if (attachMonoThread && !mono_domain_get())
|
if (attachMonoThread && !mono_domain_get())
|
||||||
{
|
{
|
||||||
const auto domain = MCore::Instance()->GetActiveDomain();
|
const auto domain = MCore::GetActiveDomain();
|
||||||
mono_thread_attach(domain->GetNative());
|
mono_thread_attach(domain->GetNative());
|
||||||
attachMonoThread = false;
|
attachMonoThread = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,13 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
#include "Engine/Serialization/Serialization.h"
|
#include "Engine/Serialization/Serialization.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if COMPILE_WITHOUT_CSHARP
|
||||||
|
#define UICANVAS_INVOKE(event)
|
||||||
|
#else
|
||||||
// Cached methods (FlaxEngine.CSharp.dll is loaded only once)
|
// Cached methods (FlaxEngine.CSharp.dll is loaded only once)
|
||||||
MMethod* UICanvas_Serialize = nullptr;
|
MMethod* UICanvas_Serialize = nullptr;
|
||||||
MMethod* UICanvas_SerializeDiff = nullptr;
|
MMethod* UICanvas_SerializeDiff = nullptr;
|
||||||
@@ -24,7 +29,7 @@ MMethod* UICanvas_ParentChanged = nullptr;
|
|||||||
auto instance = GetManagedInstance(); \
|
auto instance = GetManagedInstance(); \
|
||||||
if (instance) \
|
if (instance) \
|
||||||
{ \
|
{ \
|
||||||
MonoObject* exception = nullptr; \
|
MObject* exception = nullptr; \
|
||||||
UICanvas_##event->Invoke(instance, nullptr, &exception); \
|
UICanvas_##event->Invoke(instance, nullptr, &exception); \
|
||||||
if (exception) \
|
if (exception) \
|
||||||
{ \
|
{ \
|
||||||
@@ -32,10 +37,12 @@ MMethod* UICanvas_ParentChanged = nullptr;
|
|||||||
ex.Log(LogType::Error, TEXT("UICanvas::" #event)); \
|
ex.Log(LogType::Error, TEXT("UICanvas::" #event)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UICanvas::UICanvas(const SpawnParams& params)
|
UICanvas::UICanvas(const SpawnParams& params)
|
||||||
: Actor(params)
|
: Actor(params)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
Platform::MemoryBarrier();
|
Platform::MemoryBarrier();
|
||||||
if (UICanvas_Serialize == nullptr)
|
if (UICanvas_Serialize == nullptr)
|
||||||
{
|
{
|
||||||
@@ -52,6 +59,7 @@ UICanvas::UICanvas(const SpawnParams& params)
|
|||||||
UICanvas_EndPlay = mclass->GetMethod("EndPlay");
|
UICanvas_EndPlay = mclass->GetMethod("EndPlay");
|
||||||
UICanvas_ParentChanged = mclass->GetMethod("ParentChanged");
|
UICanvas_ParentChanged = mclass->GetMethod("ParentChanged");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
@@ -71,10 +79,11 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
|
|
||||||
SERIALIZE_GET_OTHER_OBJ(UICanvas);
|
SERIALIZE_GET_OTHER_OBJ(UICanvas);
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
stream.JKEY("V");
|
stream.JKEY("V");
|
||||||
void* params[1];
|
void* params[1];
|
||||||
params[0] = other ? other->GetOrCreateManagedInstance() : nullptr;
|
params[0] = other ? other->GetOrCreateManagedInstance() : nullptr;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
auto method = other ? UICanvas_SerializeDiff : UICanvas_Serialize;
|
auto method = other ? UICanvas_SerializeDiff : UICanvas_Serialize;
|
||||||
auto invokeResultStr = (MonoString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
auto invokeResultStr = (MonoString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
@@ -93,6 +102,7 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
stream.RawValue(invokeResultChars);
|
stream.RawValue(invokeResultChars);
|
||||||
mono_free(invokeResultChars);
|
mono_free(invokeResultChars);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||||
@@ -100,6 +110,7 @@ void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifi
|
|||||||
// Base
|
// Base
|
||||||
Actor::Deserialize(stream, modifier);
|
Actor::Deserialize(stream, modifier);
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
// Handle C# object data serialization
|
// Handle C# object data serialization
|
||||||
const auto dataMember = stream.FindMember("V");
|
const auto dataMember = stream.FindMember("V");
|
||||||
if (dataMember != stream.MemberEnd())
|
if (dataMember != stream.MemberEnd())
|
||||||
@@ -110,7 +121,7 @@ void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifi
|
|||||||
const auto str = buffer.GetString();
|
const auto str = buffer.GetString();
|
||||||
void* args[1];
|
void* args[1];
|
||||||
args[0] = mono_string_new(mono_domain_get(), str);
|
args[0] = mono_string_new(mono_domain_get(), str);
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
UICanvas_Deserialize->Invoke(GetOrCreateManagedInstance(), args, &exception);
|
UICanvas_Deserialize->Invoke(GetOrCreateManagedInstance(), args, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -118,6 +129,7 @@ void UICanvas::Deserialize(DeserializeStream& stream, ISerializeModifier* modifi
|
|||||||
ex.Log(LogType::Error, TEXT("UICanvas::Deserialize"));
|
ex.Log(LogType::Error, TEXT("UICanvas::Deserialize"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (IsDuringPlay())
|
if (IsDuringPlay())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,8 +6,13 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
#include "Engine/Scripting/Scripting.h"
|
#include "Engine/Scripting/Scripting.h"
|
||||||
#include "Engine/Serialization/Serialization.h"
|
#include "Engine/Serialization/Serialization.h"
|
||||||
|
#if USE_MONO
|
||||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if COMPILE_WITHOUT_CSHARP
|
||||||
|
#define UICONTROL_INVOKE(event)
|
||||||
|
#else
|
||||||
// Cached methods (FlaxEngine.CSharp.dll is loaded only once)
|
// Cached methods (FlaxEngine.CSharp.dll is loaded only once)
|
||||||
MMethod* UIControl_Serialize = nullptr;
|
MMethod* UIControl_Serialize = nullptr;
|
||||||
MMethod* UIControl_SerializeDiff = nullptr;
|
MMethod* UIControl_SerializeDiff = nullptr;
|
||||||
@@ -22,7 +27,7 @@ MMethod* UIControl_EndPlay = nullptr;
|
|||||||
#define UICONTROL_INVOKE(event) \
|
#define UICONTROL_INVOKE(event) \
|
||||||
if (HasManagedInstance()) \
|
if (HasManagedInstance()) \
|
||||||
{ \
|
{ \
|
||||||
MonoObject* exception = nullptr; \
|
MObject* exception = nullptr; \
|
||||||
UIControl_##event->Invoke(GetManagedInstance(), nullptr, &exception); \
|
UIControl_##event->Invoke(GetManagedInstance(), nullptr, &exception); \
|
||||||
if (exception) \
|
if (exception) \
|
||||||
{ \
|
{ \
|
||||||
@@ -30,10 +35,12 @@ MMethod* UIControl_EndPlay = nullptr;
|
|||||||
ex.Log(LogType::Error, TEXT("UICanvas::" #event)); \
|
ex.Log(LogType::Error, TEXT("UICanvas::" #event)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UIControl::UIControl(const SpawnParams& params)
|
UIControl::UIControl(const SpawnParams& params)
|
||||||
: Actor(params)
|
: Actor(params)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
if (UIControl_Serialize == nullptr)
|
if (UIControl_Serialize == nullptr)
|
||||||
{
|
{
|
||||||
MClass* mclass = GetClass();
|
MClass* mclass = GetClass();
|
||||||
@@ -47,6 +54,7 @@ UIControl::UIControl(const SpawnParams& params)
|
|||||||
UIControl_BeginPlay = mclass->GetMethod("BeginPlay");
|
UIControl_BeginPlay = mclass->GetMethod("BeginPlay");
|
||||||
UIControl_EndPlay = mclass->GetMethod("EndPlay");
|
UIControl_EndPlay = mclass->GetMethod("EndPlay");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
@@ -66,11 +74,12 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
|
|
||||||
SERIALIZE_GET_OTHER_OBJ(UIControl);
|
SERIALIZE_GET_OTHER_OBJ(UIControl);
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
void* params[2];
|
void* params[2];
|
||||||
MonoString* controlType = nullptr;
|
MonoString* controlType = nullptr;
|
||||||
params[0] = &controlType;
|
params[0] = &controlType;
|
||||||
params[1] = other ? other->GetOrCreateManagedInstance() : nullptr;
|
params[1] = other ? other->GetOrCreateManagedInstance() : nullptr;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
const auto method = other ? UIControl_SerializeDiff : UIControl_Serialize;
|
const auto method = other ? UIControl_SerializeDiff : UIControl_Serialize;
|
||||||
const auto invokeResultStr = (MonoString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
const auto invokeResultStr = (MonoString*)method->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
@@ -107,6 +116,7 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
const auto invokeResultChars = mono_string_to_utf8(invokeResultStr);
|
const auto invokeResultChars = mono_string_to_utf8(invokeResultStr);
|
||||||
stream.RawValue(invokeResultChars);
|
stream.RawValue(invokeResultChars);
|
||||||
mono_free(invokeResultChars);
|
mono_free(invokeResultChars);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||||
@@ -114,6 +124,7 @@ void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modif
|
|||||||
// Base
|
// Base
|
||||||
Actor::Deserialize(stream, modifier);
|
Actor::Deserialize(stream, modifier);
|
||||||
|
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
MonoReflectionType* typeObj = nullptr;
|
MonoReflectionType* typeObj = nullptr;
|
||||||
const auto controlMember = stream.FindMember("Control");
|
const auto controlMember = stream.FindMember("Control");
|
||||||
if (controlMember != stream.MemberEnd())
|
if (controlMember != stream.MemberEnd())
|
||||||
@@ -140,7 +151,7 @@ void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modif
|
|||||||
void* args[2];
|
void* args[2];
|
||||||
args[0] = mono_string_new(mono_domain_get(), str);
|
args[0] = mono_string_new(mono_domain_get(), str);
|
||||||
args[1] = typeObj;
|
args[1] = typeObj;
|
||||||
MonoObject* exception = nullptr;
|
MObject* exception = nullptr;
|
||||||
UIControl_Deserialize->Invoke(GetOrCreateManagedInstance(), args, &exception);
|
UIControl_Deserialize->Invoke(GetOrCreateManagedInstance(), args, &exception);
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
@@ -148,6 +159,7 @@ void UIControl::Deserialize(DeserializeStream& stream, ISerializeModifier* modif
|
|||||||
ex.Log(LogType::Error, TEXT("UIControl::Deserialize"));
|
ex.Log(LogType::Error, TEXT("UIControl::Deserialize"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIControl::OnParentChanged()
|
void UIControl::OnParentChanged()
|
||||||
|
|||||||
@@ -523,6 +523,7 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value)
|
|||||||
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeNameAnsiView);
|
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeNameAnsiView);
|
||||||
if (!typeHandle)
|
if (!typeHandle)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
const auto mclass = Scripting::FindClass(typeNameAnsiView);
|
const auto mclass = Scripting::FindClass(typeNameAnsiView);
|
||||||
if (mclass)
|
if (mclass)
|
||||||
{
|
{
|
||||||
@@ -559,6 +560,7 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typeName.HasChars())
|
else if (typeName.HasChars())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
OnError(node, box, String::Format(TEXT("Missing type '{0}'"), typeName));
|
OnError(node, box, String::Format(TEXT("Missing type '{0}'"), typeName));
|
||||||
}
|
}
|
||||||
@@ -609,6 +611,7 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value)
|
|||||||
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeNameAnsiView);
|
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeNameAnsiView);
|
||||||
if (!typeHandle)
|
if (!typeHandle)
|
||||||
{
|
{
|
||||||
|
#if !COMPILE_WITHOUT_CSHARP
|
||||||
const auto mclass = Scripting::FindClass(typeNameAnsiView);
|
const auto mclass = Scripting::FindClass(typeNameAnsiView);
|
||||||
if (mclass)
|
if (mclass)
|
||||||
{
|
{
|
||||||
@@ -646,6 +649,7 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typeName.HasChars())
|
else if (typeName.HasChars())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
OnError(node, box, String::Format(TEXT("Missing type '{0}'"), typeName));
|
OnError(node, box, String::Format(TEXT("Missing type '{0}'"), typeName));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,19 @@ namespace Flax.Build.Bindings
|
|||||||
private static readonly HashSet<TypeInfo> CppVariantFromTypes = new HashSet<TypeInfo>();
|
private static readonly HashSet<TypeInfo> CppVariantFromTypes = new HashSet<TypeInfo>();
|
||||||
private static bool CppNonPodTypesConvertingGeneration = false;
|
private static bool CppNonPodTypesConvertingGeneration = false;
|
||||||
|
|
||||||
public static readonly List<string> CppScriptObjectVirtualWrapperMethodsPostfixes = new List<string>
|
public class ScriptingLangInfo
|
||||||
{
|
{
|
||||||
"_ManagedWrapper", // C#
|
public bool Enabled;
|
||||||
|
public string VirtualWrapperMethodsPostfix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly List<ScriptingLangInfo> ScriptingLangInfos = new List<ScriptingLangInfo>
|
||||||
|
{
|
||||||
|
new ScriptingLangInfo
|
||||||
|
{
|
||||||
|
Enabled = true,
|
||||||
|
VirtualWrapperMethodsPostfix = "_ManagedWrapper", // C#
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
public static event Action<BuildData, IGrouping<string, Module>, StringBuilder> GenerateCppBinaryModuleHeader;
|
public static event Action<BuildData, IGrouping<string, Module>, StringBuilder> GenerateCppBinaryModuleHeader;
|
||||||
@@ -1003,6 +1013,8 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
private static void GenerateCppManagedWrapperFunction(BuildData buildData, StringBuilder contents, VirtualClassInfo classInfo, FunctionInfo functionInfo, int scriptVTableSize, int scriptVTableIndex)
|
private static void GenerateCppManagedWrapperFunction(BuildData buildData, StringBuilder contents, VirtualClassInfo classInfo, FunctionInfo functionInfo, int scriptVTableSize, int scriptVTableIndex)
|
||||||
{
|
{
|
||||||
|
if (!EngineConfiguration.WithCSharp(buildData.TargetOptions))
|
||||||
|
return;
|
||||||
contents.AppendFormat(" {0} {1}_ManagedWrapper(", functionInfo.ReturnType, functionInfo.UniqueName);
|
contents.AppendFormat(" {0} {1}_ManagedWrapper(", functionInfo.ReturnType, functionInfo.UniqueName);
|
||||||
var separator = false;
|
var separator = false;
|
||||||
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||||
@@ -1240,13 +1252,17 @@ namespace Flax.Build.Bindings
|
|||||||
contents.AppendLine(" if (vtableIndex > 0 && vtableIndex < entriesCount)");
|
contents.AppendLine(" if (vtableIndex > 0 && vtableIndex < entriesCount)");
|
||||||
contents.AppendLine(" {");
|
contents.AppendLine(" {");
|
||||||
contents.AppendLine($" scriptVTableBase[{scriptVTableIndex} + 2] = vtable[vtableIndex];");
|
contents.AppendLine($" scriptVTableBase[{scriptVTableIndex} + 2] = vtable[vtableIndex];");
|
||||||
for (var i = 0; i < CppScriptObjectVirtualWrapperMethodsPostfixes.Count; i++)
|
for (int i = 0, count = 0; i < ScriptingLangInfos.Count; i++)
|
||||||
{
|
{
|
||||||
contents.AppendLine(i == 0 ? " if (wrapperIndex == 0)" : $" else if (wrapperIndex == {i})");
|
var langInfo = ScriptingLangInfos[i];
|
||||||
|
if (!langInfo.Enabled)
|
||||||
|
continue;
|
||||||
|
contents.AppendLine(count == 0 ? " if (wrapperIndex == 0)" : $" else if (wrapperIndex == {count})");
|
||||||
contents.AppendLine(" {");
|
contents.AppendLine(" {");
|
||||||
contents.AppendLine($" auto thunkPtr = &{classInfo.NativeName}Internal::{functionInfo.UniqueName}{CppScriptObjectVirtualWrapperMethodsPostfixes[i]};");
|
contents.AppendLine($" auto thunkPtr = &{classInfo.NativeName}Internal::{functionInfo.UniqueName}{langInfo.VirtualWrapperMethodsPostfix};");
|
||||||
contents.AppendLine(" vtable[vtableIndex] = *(void**)&thunkPtr;");
|
contents.AppendLine(" vtable[vtableIndex] = *(void**)&thunkPtr;");
|
||||||
contents.AppendLine(" }");
|
contents.AppendLine(" }");
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
contents.AppendLine(" }");
|
contents.AppendLine(" }");
|
||||||
contents.AppendLine(" else");
|
contents.AppendLine(" else");
|
||||||
@@ -1412,6 +1428,7 @@ namespace Flax.Build.Bindings
|
|||||||
if (classInfo.Parent != null && !(classInfo.Parent is FileInfo))
|
if (classInfo.Parent != null && !(classInfo.Parent is FileInfo))
|
||||||
classTypeNameInternal = classInfo.Parent.FullNameNative + '_' + classTypeNameInternal;
|
classTypeNameInternal = classInfo.Parent.FullNameNative + '_' + classTypeNameInternal;
|
||||||
var useScripting = classInfo.IsStatic || classInfo.IsScriptingObject;
|
var useScripting = classInfo.IsStatic || classInfo.IsScriptingObject;
|
||||||
|
var useCSharp = EngineConfiguration.WithCSharp(buildData.TargetOptions);
|
||||||
var hasInterface = classInfo.Interfaces != null && classInfo.Interfaces.Any(x => x.Access == AccessLevel.Public);
|
var hasInterface = classInfo.Interfaces != null && classInfo.Interfaces.Any(x => x.Access == AccessLevel.Public);
|
||||||
|
|
||||||
if (classInfo.IsAutoSerialization)
|
if (classInfo.IsAutoSerialization)
|
||||||
@@ -1428,74 +1445,77 @@ namespace Flax.Build.Bindings
|
|||||||
if (!useScripting)
|
if (!useScripting)
|
||||||
continue;
|
continue;
|
||||||
var paramsCount = eventInfo.Type.GenericArgs?.Count ?? 0;
|
var paramsCount = eventInfo.Type.GenericArgs?.Count ?? 0;
|
||||||
|
|
||||||
// C# event invoking wrapper (calls C# event from C++ delegate)
|
|
||||||
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
|
||||||
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MEvent.h");
|
|
||||||
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
|
||||||
CppIncludeFiles.Add("Engine/Profiler/ProfilerCPU.h");
|
CppIncludeFiles.Add("Engine/Profiler/ProfilerCPU.h");
|
||||||
contents.Append(" ");
|
|
||||||
if (eventInfo.IsStatic)
|
|
||||||
contents.Append("static ");
|
|
||||||
contents.AppendFormat("void {0}_ManagedWrapper(", eventInfo.Name);
|
|
||||||
for (var i = 0; i < paramsCount; i++)
|
|
||||||
{
|
|
||||||
if (i != 0)
|
|
||||||
contents.Append(", ");
|
|
||||||
contents.Append(eventInfo.Type.GenericArgs[i]).Append(" arg" + i);
|
|
||||||
}
|
|
||||||
contents.Append(')').AppendLine();
|
|
||||||
contents.Append(" {").AppendLine();
|
|
||||||
contents.Append(" static MMethod* mmethod = nullptr;").AppendLine();
|
|
||||||
contents.Append(" if (!mmethod)").AppendLine();
|
|
||||||
contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetType().ManagedClass->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine();
|
|
||||||
contents.Append(" CHECK(mmethod);").AppendLine();
|
|
||||||
contents.Append($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::On{eventInfo.Name}\");").AppendLine();
|
|
||||||
contents.Append(" MonoObject* exception = nullptr;").AppendLine();
|
|
||||||
if (paramsCount == 0)
|
|
||||||
contents.AppendLine(" void** params = nullptr;");
|
|
||||||
else
|
|
||||||
contents.AppendLine($" void* params[{paramsCount}];");
|
|
||||||
for (var i = 0; i < paramsCount; i++)
|
|
||||||
{
|
|
||||||
var paramType = eventInfo.Type.GenericArgs[i];
|
|
||||||
var paramName = "arg" + i;
|
|
||||||
var paramValue = GenerateCppWrapperNativeToManagedParam(buildData, contents, paramType, paramName, classInfo, false);
|
|
||||||
contents.Append($" params[{i}] = {paramValue};").AppendLine();
|
|
||||||
}
|
|
||||||
if (eventInfo.IsStatic)
|
|
||||||
contents.AppendLine(" MonoObject* instance = nullptr;");
|
|
||||||
else
|
|
||||||
contents.AppendLine($" MonoObject* instance = (({classTypeNameNative}*)this)->GetManagedInstance();");
|
|
||||||
contents.Append(" mono_runtime_invoke(mmethod->GetNative(), instance, params, &exception);").AppendLine();
|
|
||||||
contents.Append(" if (exception)").AppendLine();
|
|
||||||
contents.Append(" DebugLog::LogException(exception);").AppendLine();
|
|
||||||
contents.Append(" }").AppendLine().AppendLine();
|
|
||||||
|
|
||||||
// C# event wrapper binding method (binds/unbinds C# wrapper to C++ delegate)
|
|
||||||
contents.AppendFormat(" static void {0}_ManagedBind(", eventInfo.Name);
|
|
||||||
if (!eventInfo.IsStatic)
|
|
||||||
contents.AppendFormat("{0}* obj, ", classTypeNameNative);
|
|
||||||
contents.Append("bool bind)").AppendLine();
|
|
||||||
contents.Append(" {").AppendLine();
|
|
||||||
contents.Append(" Function<void(");
|
|
||||||
for (var i = 0; i < paramsCount; i++)
|
|
||||||
{
|
|
||||||
if (i != 0)
|
|
||||||
contents.Append(", ");
|
|
||||||
contents.Append(eventInfo.Type.GenericArgs[i]);
|
|
||||||
}
|
|
||||||
contents.Append(")> f;").AppendLine();
|
|
||||||
if (eventInfo.IsStatic)
|
|
||||||
contents.AppendFormat(" f.Bind<{0}_ManagedWrapper>();", eventInfo.Name).AppendLine();
|
|
||||||
else
|
|
||||||
contents.AppendFormat(" f.Bind<{1}Internal, &{1}Internal::{0}_ManagedWrapper>(({1}Internal*)obj);", eventInfo.Name, classTypeNameInternal).AppendLine();
|
|
||||||
contents.Append(" if (bind)").AppendLine();
|
|
||||||
var bindPrefix = eventInfo.IsStatic ? classTypeNameNative + "::" : "obj->";
|
var bindPrefix = eventInfo.IsStatic ? classTypeNameNative + "::" : "obj->";
|
||||||
contents.AppendFormat(" {0}{1}.Bind(f);", bindPrefix, eventInfo.Name).AppendLine();
|
|
||||||
contents.Append(" else").AppendLine();
|
if (useCSharp)
|
||||||
contents.AppendFormat(" {0}{1}.Unbind(f);", bindPrefix, eventInfo.Name).AppendLine();
|
{
|
||||||
contents.Append(" }").AppendLine().AppendLine();
|
// C# event invoking wrapper (calls C# event from C++ delegate)
|
||||||
|
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
||||||
|
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MEvent.h");
|
||||||
|
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
||||||
|
contents.Append(" ");
|
||||||
|
if (eventInfo.IsStatic)
|
||||||
|
contents.Append("static ");
|
||||||
|
contents.AppendFormat("void {0}_ManagedWrapper(", eventInfo.Name);
|
||||||
|
for (var i = 0; i < paramsCount; i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
contents.Append(", ");
|
||||||
|
contents.Append(eventInfo.Type.GenericArgs[i]).Append(" arg" + i);
|
||||||
|
}
|
||||||
|
contents.Append(')').AppendLine();
|
||||||
|
contents.Append(" {").AppendLine();
|
||||||
|
contents.Append(" static MMethod* mmethod = nullptr;").AppendLine();
|
||||||
|
contents.Append(" if (!mmethod)").AppendLine();
|
||||||
|
contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetType().ManagedClass->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine();
|
||||||
|
contents.Append(" CHECK(mmethod);").AppendLine();
|
||||||
|
contents.Append($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::On{eventInfo.Name}\");").AppendLine();
|
||||||
|
contents.Append(" MonoObject* exception = nullptr;").AppendLine();
|
||||||
|
if (paramsCount == 0)
|
||||||
|
contents.AppendLine(" void** params = nullptr;");
|
||||||
|
else
|
||||||
|
contents.AppendLine($" void* params[{paramsCount}];");
|
||||||
|
for (var i = 0; i < paramsCount; i++)
|
||||||
|
{
|
||||||
|
var paramType = eventInfo.Type.GenericArgs[i];
|
||||||
|
var paramName = "arg" + i;
|
||||||
|
var paramValue = GenerateCppWrapperNativeToManagedParam(buildData, contents, paramType, paramName, classInfo, false);
|
||||||
|
contents.Append($" params[{i}] = {paramValue};").AppendLine();
|
||||||
|
}
|
||||||
|
if (eventInfo.IsStatic)
|
||||||
|
contents.AppendLine(" MonoObject* instance = nullptr;");
|
||||||
|
else
|
||||||
|
contents.AppendLine($" MonoObject* instance = (({classTypeNameNative}*)this)->GetManagedInstance();");
|
||||||
|
contents.Append(" mono_runtime_invoke(mmethod->GetNative(), instance, params, &exception);").AppendLine();
|
||||||
|
contents.Append(" if (exception)").AppendLine();
|
||||||
|
contents.Append(" DebugLog::LogException(exception);").AppendLine();
|
||||||
|
contents.Append(" }").AppendLine().AppendLine();
|
||||||
|
|
||||||
|
// C# event wrapper binding method (binds/unbinds C# wrapper to C++ delegate)
|
||||||
|
contents.AppendFormat(" static void {0}_ManagedBind(", eventInfo.Name);
|
||||||
|
if (!eventInfo.IsStatic)
|
||||||
|
contents.AppendFormat("{0}* obj, ", classTypeNameNative);
|
||||||
|
contents.Append("bool bind)").AppendLine();
|
||||||
|
contents.Append(" {").AppendLine();
|
||||||
|
contents.Append(" Function<void(");
|
||||||
|
for (var i = 0; i < paramsCount; i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
contents.Append(", ");
|
||||||
|
contents.Append(eventInfo.Type.GenericArgs[i]);
|
||||||
|
}
|
||||||
|
contents.Append(")> f;").AppendLine();
|
||||||
|
if (eventInfo.IsStatic)
|
||||||
|
contents.AppendFormat(" f.Bind<{0}_ManagedWrapper>();", eventInfo.Name).AppendLine();
|
||||||
|
else
|
||||||
|
contents.AppendFormat(" f.Bind<{1}Internal, &{1}Internal::{0}_ManagedWrapper>(({1}Internal*)obj);", eventInfo.Name, classTypeNameInternal).AppendLine();
|
||||||
|
contents.Append(" if (bind)").AppendLine();
|
||||||
|
contents.AppendFormat(" {0}{1}.Bind(f);", bindPrefix, eventInfo.Name).AppendLine();
|
||||||
|
contents.Append(" else").AppendLine();
|
||||||
|
contents.AppendFormat(" {0}{1}.Unbind(f);", bindPrefix, eventInfo.Name).AppendLine();
|
||||||
|
contents.Append(" }").AppendLine().AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
// Generic scripting event invoking wrapper (calls scripting code from C++ delegate)
|
// Generic scripting event invoking wrapper (calls scripting code from C++ delegate)
|
||||||
CppIncludeFiles.Add("Engine/Scripting/Events.h");
|
CppIncludeFiles.Add("Engine/Scripting/Events.h");
|
||||||
@@ -1551,7 +1571,7 @@ namespace Flax.Build.Bindings
|
|||||||
// Fields
|
// Fields
|
||||||
foreach (var fieldInfo in classInfo.Fields)
|
foreach (var fieldInfo in classInfo.Fields)
|
||||||
{
|
{
|
||||||
if (!useScripting)
|
if (!useScripting || !useCSharp)
|
||||||
continue;
|
continue;
|
||||||
if (fieldInfo.Getter != null)
|
if (fieldInfo.Getter != null)
|
||||||
GenerateCppWrapperFunction(buildData, contents, classInfo, fieldInfo.Getter, "{0}");
|
GenerateCppWrapperFunction(buildData, contents, classInfo, fieldInfo.Getter, "{0}");
|
||||||
@@ -1568,7 +1588,7 @@ namespace Flax.Build.Bindings
|
|||||||
// Properties
|
// Properties
|
||||||
foreach (var propertyInfo in classInfo.Properties)
|
foreach (var propertyInfo in classInfo.Properties)
|
||||||
{
|
{
|
||||||
if (!useScripting)
|
if (!useScripting || !useCSharp)
|
||||||
continue;
|
continue;
|
||||||
if (propertyInfo.Getter != null)
|
if (propertyInfo.Getter != null)
|
||||||
GenerateCppWrapperFunction(buildData, contents, classInfo, propertyInfo.Getter);
|
GenerateCppWrapperFunction(buildData, contents, classInfo, propertyInfo.Getter);
|
||||||
@@ -1579,13 +1599,15 @@ namespace Flax.Build.Bindings
|
|||||||
// Functions
|
// Functions
|
||||||
foreach (var functionInfo in classInfo.Functions)
|
foreach (var functionInfo in classInfo.Functions)
|
||||||
{
|
{
|
||||||
|
if (!useCSharp)
|
||||||
|
continue;
|
||||||
if (!useScripting)
|
if (!useScripting)
|
||||||
throw new Exception($"Not supported function {functionInfo.Name} inside non-static and non-scripting class type {classInfo.Name}.");
|
throw new Exception($"Not supported function {functionInfo.Name} inside non-static and non-scripting class type {classInfo.Name}.");
|
||||||
GenerateCppWrapperFunction(buildData, contents, classInfo, functionInfo);
|
GenerateCppWrapperFunction(buildData, contents, classInfo, functionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface implementation
|
// Interface implementation
|
||||||
if (hasInterface)
|
if (hasInterface && useCSharp)
|
||||||
{
|
{
|
||||||
foreach (var interfaceInfo in classInfo.Interfaces)
|
foreach (var interfaceInfo in classInfo.Interfaces)
|
||||||
{
|
{
|
||||||
@@ -1612,11 +1634,16 @@ namespace Flax.Build.Bindings
|
|||||||
{
|
{
|
||||||
foreach (var eventInfo in classInfo.Events)
|
foreach (var eventInfo in classInfo.Events)
|
||||||
{
|
{
|
||||||
contents.AppendLine($" ADD_INTERNAL_CALL(\"{classTypeNameManagedInternalCall}::Internal_{eventInfo.Name}_Bind\", &{eventInfo.Name}_ManagedBind);");
|
|
||||||
|
|
||||||
// Register scripting event binder
|
// Register scripting event binder
|
||||||
contents.AppendLine($" ScriptingEvents::EventsTable[Pair<ScriptingTypeHandle, StringView>({classTypeNameNative}::TypeInitializer, StringView(TEXT(\"{eventInfo.Name}\"), {eventInfo.Name.Length}))] = (void(*)(ScriptingObject*, void*, bool)){classTypeNameInternal}Internal::{eventInfo.Name}_Bind;");
|
contents.AppendLine($" ScriptingEvents::EventsTable[Pair<ScriptingTypeHandle, StringView>({classTypeNameNative}::TypeInitializer, StringView(TEXT(\"{eventInfo.Name}\"), {eventInfo.Name.Length}))] = (void(*)(ScriptingObject*, void*, bool)){classTypeNameInternal}Internal::{eventInfo.Name}_Bind;");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (useScripting && useCSharp)
|
||||||
|
{
|
||||||
|
foreach (var eventInfo in classInfo.Events)
|
||||||
|
{
|
||||||
|
contents.AppendLine($" ADD_INTERNAL_CALL(\"{classTypeNameManagedInternalCall}::Internal_{eventInfo.Name}_Bind\", &{eventInfo.Name}_ManagedBind);");
|
||||||
|
}
|
||||||
foreach (var fieldInfo in classInfo.Fields)
|
foreach (var fieldInfo in classInfo.Fields)
|
||||||
{
|
{
|
||||||
if (fieldInfo.Getter != null)
|
if (fieldInfo.Getter != null)
|
||||||
@@ -1720,6 +1747,7 @@ namespace Flax.Build.Bindings
|
|||||||
var structureTypeNameInternal = structureInfo.NativeName;
|
var structureTypeNameInternal = structureInfo.NativeName;
|
||||||
if (structureInfo.Parent != null && !(structureInfo.Parent is FileInfo))
|
if (structureInfo.Parent != null && !(structureInfo.Parent is FileInfo))
|
||||||
structureTypeNameInternal = structureInfo.Parent.FullNameNative + '_' + structureTypeNameInternal;
|
structureTypeNameInternal = structureInfo.Parent.FullNameNative + '_' + structureTypeNameInternal;
|
||||||
|
var useCSharp = EngineConfiguration.WithCSharp(buildData.TargetOptions);
|
||||||
|
|
||||||
if (structureInfo.IsAutoSerialization)
|
if (structureInfo.IsAutoSerialization)
|
||||||
GenerateCppAutoSerialization(buildData, contents, moduleInfo, structureInfo, structureTypeNameNative);
|
GenerateCppAutoSerialization(buildData, contents, moduleInfo, structureInfo, structureTypeNameNative);
|
||||||
@@ -1786,12 +1814,15 @@ namespace Flax.Build.Bindings
|
|||||||
contents.AppendLine(" static void InitRuntime()");
|
contents.AppendLine(" static void InitRuntime()");
|
||||||
contents.AppendLine(" {");
|
contents.AppendLine(" {");
|
||||||
|
|
||||||
foreach (var fieldInfo in structureInfo.Fields)
|
if (useCSharp)
|
||||||
{
|
{
|
||||||
if (fieldInfo.Getter != null)
|
foreach (var fieldInfo in structureInfo.Fields)
|
||||||
contents.AppendLine($" ADD_INTERNAL_CALL(\"{structureTypeNameManagedInternalCall}::Internal_{fieldInfo.Getter.UniqueName}\", &{fieldInfo.Getter.UniqueName});");
|
{
|
||||||
if (fieldInfo.Setter != null)
|
if (fieldInfo.Getter != null)
|
||||||
contents.AppendLine($" ADD_INTERNAL_CALL(\"{structureTypeNameManagedInternalCall}::Internal_{fieldInfo.Setter.UniqueName}\", &{fieldInfo.Setter.UniqueName});");
|
contents.AppendLine($" ADD_INTERNAL_CALL(\"{structureTypeNameManagedInternalCall}::Internal_{fieldInfo.Getter.UniqueName}\", &{fieldInfo.Getter.UniqueName});");
|
||||||
|
if (fieldInfo.Setter != null)
|
||||||
|
contents.AppendLine($" ADD_INTERNAL_CALL(\"{structureTypeNameManagedInternalCall}::Internal_{fieldInfo.Setter.UniqueName}\", &{fieldInfo.Setter.UniqueName});");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.AppendLine(" }").AppendLine();
|
contents.AppendLine(" }").AppendLine();
|
||||||
@@ -1814,28 +1845,41 @@ namespace Flax.Build.Bindings
|
|||||||
contents.AppendLine($" *({structureTypeNameNative}*)dst = *({structureTypeNameNative}*)src;");
|
contents.AppendLine($" *({structureTypeNameNative}*)dst = *({structureTypeNameNative}*)src;");
|
||||||
contents.AppendLine(" }").AppendLine();
|
contents.AppendLine(" }").AppendLine();
|
||||||
|
|
||||||
// Boxing structures from native data to managed object
|
if (useCSharp)
|
||||||
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
{
|
||||||
if (!structureInfo.IsPod && !CppUsedNonPodTypes.Contains(structureInfo))
|
// Boxing structures from native data to managed object
|
||||||
CppUsedNonPodTypes.Add(structureInfo);
|
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h");
|
||||||
contents.AppendLine(" static MonoObject* Box(void* ptr)");
|
if (!structureInfo.IsPod && !CppUsedNonPodTypes.Contains(structureInfo))
|
||||||
contents.AppendLine(" {");
|
CppUsedNonPodTypes.Add(structureInfo);
|
||||||
contents.AppendLine($" MonoObject* managed = mono_object_new(mono_domain_get(), {structureTypeNameNative}::TypeInitializer.GetType().ManagedClass->GetNative());");
|
contents.AppendLine(" static MObject* Box(void* ptr)");
|
||||||
if (structureInfo.IsPod)
|
contents.AppendLine(" {");
|
||||||
contents.AppendLine($" Platform::MemoryCopy(mono_object_unbox(managed), ptr, sizeof({structureTypeNameNative}));");
|
contents.AppendLine($" MonoObject* managed = mono_object_new(mono_domain_get(), {structureTypeNameNative}::TypeInitializer.GetType().ManagedClass->GetNative());");
|
||||||
else
|
if (structureInfo.IsPod)
|
||||||
contents.AppendLine($" *({structureInfo.NativeName}Managed*)mono_object_unbox(managed) = ToManaged(*({structureTypeNameNative}*)ptr);");
|
contents.AppendLine($" Platform::MemoryCopy(mono_object_unbox(managed), ptr, sizeof({structureTypeNameNative}));");
|
||||||
contents.AppendLine(" return managed;");
|
else
|
||||||
contents.AppendLine(" }").AppendLine();
|
contents.AppendLine($" *({structureInfo.NativeName}Managed*)mono_object_unbox(managed) = ToManaged(*({structureTypeNameNative}*)ptr);");
|
||||||
|
contents.AppendLine(" return managed;");
|
||||||
|
contents.AppendLine(" }").AppendLine();
|
||||||
|
|
||||||
// Unboxing structures from managed object to native data
|
// Unboxing structures from managed object to native data
|
||||||
contents.AppendLine(" static void Unbox(void* ptr, MonoObject* managed)");
|
contents.AppendLine(" static void Unbox(void* ptr, MObject* managed)");
|
||||||
contents.AppendLine(" {");
|
contents.AppendLine(" {");
|
||||||
if (structureInfo.IsPod)
|
if (structureInfo.IsPod)
|
||||||
contents.AppendLine($" Platform::MemoryCopy(ptr, mono_object_unbox(managed), sizeof({structureTypeNameNative}));");
|
contents.AppendLine($" Platform::MemoryCopy(ptr, mono_object_unbox(managed), sizeof({structureTypeNameNative}));");
|
||||||
|
else
|
||||||
|
contents.AppendLine($" *({structureTypeNameNative}*)ptr = ToNative(*({structureInfo.NativeName}Managed*)mono_object_unbox(managed));");
|
||||||
|
contents.AppendLine(" }").AppendLine();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
contents.AppendLine($" *({structureTypeNameNative}*)ptr = ToNative(*({structureInfo.NativeName}Managed*)mono_object_unbox(managed));");
|
{
|
||||||
contents.AppendLine(" }").AppendLine();
|
contents.AppendLine(" static MObject* Box(void* ptr)");
|
||||||
|
contents.AppendLine(" {");
|
||||||
|
contents.AppendLine(" return nullptr;");
|
||||||
|
contents.AppendLine(" }").AppendLine();
|
||||||
|
contents.AppendLine(" static void Unbox(void* ptr, MObject* managed)");
|
||||||
|
contents.AppendLine(" {");
|
||||||
|
contents.AppendLine(" }").AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
// Getter for structure field
|
// Getter for structure field
|
||||||
contents.AppendLine(" static void GetField(void* ptr, const String& name, Variant& value)");
|
contents.AppendLine(" static void GetField(void* ptr, const String& name, Variant& value)");
|
||||||
@@ -2060,6 +2104,9 @@ namespace Flax.Build.Bindings
|
|||||||
CppVariantToTypes.Clear();
|
CppVariantToTypes.Clear();
|
||||||
CppVariantFromTypes.Clear();
|
CppVariantFromTypes.Clear();
|
||||||
|
|
||||||
|
// Disable C# scripting based on configuration
|
||||||
|
ScriptingLangInfos[0].Enabled = EngineConfiguration.WithCSharp(buildData.TargetOptions);
|
||||||
|
|
||||||
contents.AppendLine("// This code was auto-generated. Do not modify it.");
|
contents.AppendLine("// This code was auto-generated. Do not modify it.");
|
||||||
contents.AppendLine();
|
contents.AppendLine();
|
||||||
contents.AppendLine("#include \"Engine/Core/Compiler.h\"");
|
contents.AppendLine("#include \"Engine/Core/Compiler.h\"");
|
||||||
@@ -2174,8 +2221,11 @@ namespace Flax.Build.Bindings
|
|||||||
|
|
||||||
// Non-POD types
|
// Non-POD types
|
||||||
CppUsedNonPodTypesList.Clear();
|
CppUsedNonPodTypesList.Clear();
|
||||||
for (int k = 0; k < CppUsedNonPodTypes.Count; k++)
|
if (EngineConfiguration.WithCSharp(buildData.TargetOptions))
|
||||||
GenerateCppCppUsedNonPodTypes(buildData, CppUsedNonPodTypes[k]);
|
{
|
||||||
|
for (int k = 0; k < CppUsedNonPodTypes.Count; k++)
|
||||||
|
GenerateCppCppUsedNonPodTypes(buildData, CppUsedNonPodTypes[k]);
|
||||||
|
}
|
||||||
foreach (var apiType in CppUsedNonPodTypesList)
|
foreach (var apiType in CppUsedNonPodTypesList)
|
||||||
{
|
{
|
||||||
header.AppendLine();
|
header.AppendLine();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Flax.Build.NativeCpp;
|
using Flax.Build.NativeCpp;
|
||||||
@@ -34,8 +35,20 @@ namespace Flax.Build.Bindings
|
|||||||
/// The generated C# file path that contains a API bindings wrapper code to setup the glue code.
|
/// The generated C# file path that contains a API bindings wrapper code to setup the glue code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string GeneratedCSharpFilePath;
|
public string GeneratedCSharpFilePath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The custom data per-scripting language.
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, string> CustomScriptingData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate void GenerateModuleBindingsDelegate(BuildData buildData, IGrouping<string, Module> binaryModule);
|
||||||
|
|
||||||
|
public delegate void GenerateBinaryModuleBindingsDelegate(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings);
|
||||||
|
|
||||||
|
public static event GenerateModuleBindingsDelegate GenerateModuleBindings;
|
||||||
|
public static event GenerateBinaryModuleBindingsDelegate GenerateBinaryModuleBindings;
|
||||||
|
|
||||||
public static ModuleInfo ParseModule(BuildData buildData, Module module, BuildOptions moduleOptions = null)
|
public static ModuleInfo ParseModule(BuildData buildData, Module module, BuildOptions moduleOptions = null)
|
||||||
{
|
{
|
||||||
if (buildData.ModulesInfo.TryGetValue(module, out var moduleInfo))
|
if (buildData.ModulesInfo.TryGetValue(module, out var moduleInfo))
|
||||||
@@ -513,7 +526,7 @@ namespace Flax.Build.Bindings
|
|||||||
buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo);
|
buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo);
|
||||||
|
|
||||||
// Ensure that generated files are included into build
|
// Ensure that generated files are included into build
|
||||||
if (!moduleBuildInfo.SourceFiles.Contains(bindings.GeneratedCSharpFilePath))
|
if (EngineConfiguration.WithCSharp(buildData.TargetOptions) && !moduleBuildInfo.SourceFiles.Contains(bindings.GeneratedCSharpFilePath))
|
||||||
moduleBuildInfo.SourceFiles.Add(bindings.GeneratedCSharpFilePath);
|
moduleBuildInfo.SourceFiles.Add(bindings.GeneratedCSharpFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,10 +546,12 @@ namespace Flax.Build.Bindings
|
|||||||
Log.Verbose($"Generating API bindings for {module.Name} ({moduleInfo.Name})");
|
Log.Verbose($"Generating API bindings for {module.Name} ({moduleInfo.Name})");
|
||||||
using (new ProfileEventScope("Cpp"))
|
using (new ProfileEventScope("Cpp"))
|
||||||
GenerateCpp(buildData, moduleInfo, ref bindings);
|
GenerateCpp(buildData, moduleInfo, ref bindings);
|
||||||
using (new ProfileEventScope("CSharp"))
|
if (EngineConfiguration.WithCSharp(buildData.TargetOptions))
|
||||||
GenerateCSharp(buildData, moduleInfo, ref bindings);
|
{
|
||||||
|
using (new ProfileEventScope("CSharp"))
|
||||||
// TODO: add support for extending this code and support generating bindings for other scripting languages
|
GenerateCSharp(buildData, moduleInfo, ref bindings);
|
||||||
|
}
|
||||||
|
GenerateBinaryModuleBindings?.Invoke(buildData, moduleInfo, ref bindings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,9 +567,11 @@ namespace Flax.Build.Bindings
|
|||||||
// Generate bindings for binary module
|
// Generate bindings for binary module
|
||||||
Log.Verbose($"Generating binary module bindings for {binaryModule.Key}");
|
Log.Verbose($"Generating binary module bindings for {binaryModule.Key}");
|
||||||
GenerateCpp(buildData, binaryModule);
|
GenerateCpp(buildData, binaryModule);
|
||||||
GenerateCSharp(buildData, binaryModule);
|
if (EngineConfiguration.WithCSharp(buildData.TargetOptions))
|
||||||
|
{
|
||||||
// TODO: add support for extending this code and support generating bindings for other scripting languages
|
GenerateCSharp(buildData, binaryModule);
|
||||||
|
}
|
||||||
|
GenerateModuleBindings?.Invoke(buildData, binaryModule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Flax.Build
|
|||||||
throw new NotImplementedException("TODO: building C# targets");
|
throw new NotImplementedException("TODO: building C# targets");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void BuildTargetBindings(RulesAssembly rules, TaskGraph graph, BuildData buildData)
|
private static void BuildTargetBindings(TaskGraph graph, BuildData buildData)
|
||||||
{
|
{
|
||||||
var workspaceRoot = buildData.TargetOptions.WorkingDirectory;
|
var workspaceRoot = buildData.TargetOptions.WorkingDirectory;
|
||||||
var args = new List<string>();
|
var args = new List<string>();
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ namespace Flax.Build
|
|||||||
|
|
||||||
public static event Action<TaskGraph, BuildOptions> PreBuild;
|
public static event Action<TaskGraph, BuildOptions> PreBuild;
|
||||||
public static event Action<TaskGraph, BuildOptions> PostBuild;
|
public static event Action<TaskGraph, BuildOptions> PostBuild;
|
||||||
|
public static event Action<TaskGraph, BuildData> BuildBindings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Collects the modules required by the given target to build (includes dependencies).
|
/// Collects the modules required by the given target to build (includes dependencies).
|
||||||
@@ -226,6 +227,20 @@ namespace Flax.Build
|
|||||||
return buildData.Modules;
|
return buildData.Modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void OnBuildBindings(BuildData buildData, TaskGraph graph)
|
||||||
|
{
|
||||||
|
if (buildData.Target.IsPreBuilt)
|
||||||
|
return;
|
||||||
|
using (new ProfileEventScope("BuildBindings"))
|
||||||
|
{
|
||||||
|
if (EngineConfiguration.WithCSharp(buildData.TargetOptions))
|
||||||
|
{
|
||||||
|
BuildTargetBindings(graph, buildData);
|
||||||
|
}
|
||||||
|
BuildBindings?.Invoke(graph, buildData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void LinkNativeBinary(BuildData buildData, BuildOptions buildOptions, string outputPath)
|
private static void LinkNativeBinary(BuildData buildData, BuildOptions buildOptions, string outputPath)
|
||||||
{
|
{
|
||||||
using (new ProfileEventScope("LinkNativeBinary"))
|
using (new ProfileEventScope("LinkNativeBinary"))
|
||||||
@@ -794,13 +809,7 @@ namespace Flax.Build
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build scripting API bindings
|
// Build scripting API bindings
|
||||||
using (new ProfileEventScope("BuildBindings"))
|
OnBuildBindings(buildData, graph);
|
||||||
{
|
|
||||||
if (!buildData.Target.IsPreBuilt)
|
|
||||||
{
|
|
||||||
BuildTargetBindings(rules, graph, buildData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link modules into a target
|
// Link modules into a target
|
||||||
var outputTargetFilePath = target.GetOutputFilePath(targetBuildOptions);
|
var outputTargetFilePath = target.GetOutputFilePath(targetBuildOptions);
|
||||||
@@ -835,7 +844,7 @@ namespace Flax.Build
|
|||||||
var binaryModuleInfo = new BuildTargetBinaryModuleInfo
|
var binaryModuleInfo = new BuildTargetBinaryModuleInfo
|
||||||
{
|
{
|
||||||
Name = binaryModule.Key,
|
Name = binaryModule.Key,
|
||||||
ManagedPath = Path.Combine(outputPath, binaryModule.Key + ".CSharp.dll"),
|
ManagedPath = EngineConfiguration.WithCSharp(targetBuildOptions) ? Path.Combine(outputPath, binaryModule.Key + ".CSharp.dll") : string.Empty,
|
||||||
};
|
};
|
||||||
switch (target.LinkType)
|
switch (target.LinkType)
|
||||||
{
|
{
|
||||||
@@ -1069,11 +1078,7 @@ namespace Flax.Build
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build scripting API bindings
|
// Build scripting API bindings
|
||||||
using (new ProfileEventScope("BuildBindings"))
|
OnBuildBindings(buildData, graph);
|
||||||
{
|
|
||||||
if (!buildData.Target.IsPreBuilt)
|
|
||||||
BuildTargetBindings(rules, graph, buildData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link modules into a target
|
// Link modules into a target
|
||||||
var outputTargetFilePath = target.GetOutputFilePath(targetBuildOptions);
|
var outputTargetFilePath = target.GetOutputFilePath(targetBuildOptions);
|
||||||
@@ -1099,7 +1104,7 @@ namespace Flax.Build
|
|||||||
var binaryModuleInfo = new BuildTargetBinaryModuleInfo
|
var binaryModuleInfo = new BuildTargetBinaryModuleInfo
|
||||||
{
|
{
|
||||||
Name = binaryModule.Key,
|
Name = binaryModule.Key,
|
||||||
ManagedPath = Path.Combine(outputPath, binaryModule.Key + ".CSharp.dll"),
|
ManagedPath = EngineConfiguration.WithCSharp(targetBuildOptions) ? Path.Combine(outputPath, binaryModule.Key + ".CSharp.dll") : string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
binaryModuleInfo.NativePathProcessed = string.Empty;
|
binaryModuleInfo.NativePathProcessed = string.Empty;
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ namespace Flax.Build.Plugins
|
|||||||
base.Init();
|
base.Init();
|
||||||
|
|
||||||
BindingsGenerator.GenerateCppScriptWrapperFunction += OnGenerateCppScriptWrapperFunction;
|
BindingsGenerator.GenerateCppScriptWrapperFunction += OnGenerateCppScriptWrapperFunction;
|
||||||
BindingsGenerator.CppScriptObjectVirtualWrapperMethodsPostfixes.Add("_VisualScriptWrapper");
|
BindingsGenerator.ScriptingLangInfos.Add(new BindingsGenerator.ScriptingLangInfo
|
||||||
|
{
|
||||||
|
Enabled = true,
|
||||||
|
VirtualWrapperMethodsPostfix = "_VisualScriptWrapper",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGenerateCppScriptWrapperFunction(Builder.BuildData buildData, VirtualClassInfo classInfo, FunctionInfo functionInfo, int scriptVTableSize, int scriptVTableIndex, StringBuilder contents)
|
private void OnGenerateCppScriptWrapperFunction(Builder.BuildData buildData, VirtualClassInfo classInfo, FunctionInfo functionInfo, int scriptVTableSize, int scriptVTableIndex, StringBuilder contents)
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ namespace Flax.Build
|
|||||||
options.CompileEnv.IncludePaths.Add(Path.Combine(Project.ProjectFolderPath, "Source"));
|
options.CompileEnv.IncludePaths.Add(Path.Combine(Project.ProjectFolderPath, "Source"));
|
||||||
options.LinkEnv.LibraryPaths.Add(depsRoot);
|
options.LinkEnv.LibraryPaths.Add(depsRoot);
|
||||||
|
|
||||||
|
// Ensure to propagate no-C# scripting define to the whole codebase
|
||||||
|
if (!EngineConfiguration.WithCSharp(options))
|
||||||
|
{
|
||||||
|
options.CompileEnv.PreprocessorDefinitions.Add("COMPILE_WITHOUT_CSHARP");
|
||||||
|
}
|
||||||
|
|
||||||
// Add include paths for referenced projects sources
|
// Add include paths for referenced projects sources
|
||||||
foreach (var reference in Project.References)
|
foreach (var reference in Project.References)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -212,4 +212,21 @@ namespace Flax.Build
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<string> CustomDefines = new List<string>();
|
public static List<string> CustomDefines = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The engine configuration options.
|
||||||
|
/// </summary>
|
||||||
|
public static partial class EngineConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// True if managed C# scripting should be enabled, otherwise false. Engine without C# is partially supported and can be used when porting to a new platform before implementing C# runtime on it.
|
||||||
|
/// </summary>
|
||||||
|
[CommandLine("useCSharp", "0 to disable C# support in build")]
|
||||||
|
public static bool UseCSharp = true;
|
||||||
|
|
||||||
|
public static bool WithCSharp(NativeCpp.BuildOptions options)
|
||||||
|
{
|
||||||
|
return UseCSharp || options.Target.IsEditor;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace Flax.Build
|
|||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
CommandLine.Configure(typeof(Configuration));
|
CommandLine.Configure(typeof(Configuration));
|
||||||
|
CommandLine.Configure(typeof(EngineConfiguration));
|
||||||
foreach (var option in CommandLine.GetOptions())
|
foreach (var option in CommandLine.GetOptions())
|
||||||
{
|
{
|
||||||
if (option.Name.Length > 1 && option.Name[0] == 'D')
|
if (option.Name.Length > 1 && option.Name[0] == 'D')
|
||||||
|
|||||||
Reference in New Issue
Block a user