Merge remote-tracking branch 'origin/master' into 1.12
# Conflicts: # Content/Editor/MaterialTemplates/Deformable.shader # Flax.flaxproj # Source/Engine/Content/Content.h # Source/Engine/Serialization/JsonTools.cpp
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
#include "FlaxEngine.Gen.h"
|
||||
#include "Scripting.h"
|
||||
#include "Events.h"
|
||||
#include "Internal/StdTypesContainer.h"
|
||||
|
||||
Dictionary<Pair<ScriptingTypeHandle, StringView>, void(*)(ScriptingObject*, void*, bool)> ScriptingEvents::EventsTable;
|
||||
Delegate<ScriptingObject*, Span<Variant>, ScriptingTypeHandle, StringView> ScriptingEvents::Event;
|
||||
@@ -32,6 +31,18 @@ ManagedBinaryModule* GetBinaryModuleCorlib()
|
||||
#endif
|
||||
}
|
||||
|
||||
MMethod* MClass::FindMethod(const char* name, int32 numParams, bool checkBaseClasses) const
|
||||
{
|
||||
MMethod* method = GetMethod(name, numParams);
|
||||
if (!method && checkBaseClasses)
|
||||
{
|
||||
MClass* base = GetBaseClass();
|
||||
if (base)
|
||||
method = base->FindMethod(name, numParams, true);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
ScriptingTypeHandle::ScriptingTypeHandle(const ScriptingTypeInitializer& initializer)
|
||||
: Module(initializer.Module)
|
||||
, TypeIndex(initializer.TypeIndex)
|
||||
@@ -835,61 +846,17 @@ namespace
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool VariantTypeEquals(const VariantType& type, MType* mType, bool isOut = false)
|
||||
{
|
||||
MClass* mClass = MCore::Type::GetClass(mType);
|
||||
MClass* variantClass = MUtils::GetClass(type);
|
||||
if (variantClass != mClass)
|
||||
{
|
||||
// Hack for Vector2/3/4 which alias with Float2/3/4 or Double2/3/4 (depending on USE_LARGE_WORLDS)
|
||||
const auto& stdTypes = *StdTypesContainer::Instance();
|
||||
if (mClass == stdTypes.Vector2Class && (type.Type == VariantType::Float2 || type.Type == VariantType::Double2))
|
||||
return true;
|
||||
if (mClass == stdTypes.Vector3Class && (type.Type == VariantType::Float3 || type.Type == VariantType::Double3))
|
||||
return true;
|
||||
if (mClass == stdTypes.Vector4Class && (type.Type == VariantType::Float4 || type.Type == VariantType::Double4))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MMethod* ManagedBinaryModule::FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature)
|
||||
MMethod* ManagedBinaryModule::FindMethod(const MClass* mclass, const ScriptingTypeMethodSignature& signature)
|
||||
{
|
||||
#if USE_CSHARP
|
||||
if (!mclass)
|
||||
return nullptr;
|
||||
const auto& methods = mclass->GetMethods();
|
||||
for (MMethod* method : methods)
|
||||
{
|
||||
if (method->IsStatic() != signature.IsStatic)
|
||||
continue;
|
||||
if (method->GetName() != signature.Name)
|
||||
continue;
|
||||
if (method->GetParametersCount() != signature.Params.Count())
|
||||
continue;
|
||||
bool isValid = true;
|
||||
for (int32 paramIdx = 0; paramIdx < signature.Params.Count(); paramIdx++)
|
||||
{
|
||||
auto& param = signature.Params[paramIdx];
|
||||
MType* type = method->GetParameterType(paramIdx);
|
||||
if (param.IsOut != method->GetParameterIsOut(paramIdx) ||
|
||||
!VariantTypeEquals(param.Type, type, param.IsOut))
|
||||
{
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isValid && VariantTypeEquals(signature.ReturnType, method->GetReturnType()))
|
||||
return method;
|
||||
}
|
||||
#endif
|
||||
return mclass ? mclass->GetMethod(signature) : nullptr;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_CSHARP
|
||||
|
||||
@@ -23,7 +23,7 @@ struct ScriptingTypeMethodSignature
|
||||
|
||||
StringAnsiView Name;
|
||||
VariantType ReturnType;
|
||||
bool IsStatic;
|
||||
bool IsStatic = false;
|
||||
Array<Param, InlinedAllocation<16>> Params;
|
||||
};
|
||||
|
||||
@@ -322,7 +322,7 @@ public:
|
||||
#endif
|
||||
|
||||
static ScriptingObject* ManagedObjectSpawn(const ScriptingObjectSpawnParams& params);
|
||||
static MMethod* FindMethod(MClass* mclass, const ScriptingTypeMethodSignature& signature);
|
||||
static MMethod* FindMethod(const MClass* mclass, const ScriptingTypeMethodSignature& signature);
|
||||
#if USE_CSHARP
|
||||
static ManagedBinaryModule* FindModule(const MClass* klass);
|
||||
static ScriptingTypeHandle FindType(const MClass* klass);
|
||||
|
||||
@@ -188,11 +188,11 @@ public:
|
||||
MClass* GetBaseClass() const;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this class is a sub class of the specified class (including any derived types).
|
||||
/// Checks if this class is a subclass of the specified class (including any derived types).
|
||||
/// </summary>
|
||||
/// <param name="klass">The class.</param>
|
||||
/// <param name="checkInterfaces">True if check interfaces, otherwise just base class.</param>
|
||||
/// <returns>True if this class is a sub class of the specified class.</returns>
|
||||
/// <returns>True if this class is a subclass of the specified class.</returns>
|
||||
bool IsSubClassOf(const MClass* klass, bool checkInterfaces = false) const;
|
||||
|
||||
/// <summary>
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
/// Checks is the provided object instance of this class' type.
|
||||
/// </summary>
|
||||
/// <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 this class.</returns>
|
||||
bool IsInstanceOfType(MObject* object) const;
|
||||
|
||||
/// <summary>
|
||||
@@ -227,17 +227,7 @@ public:
|
||||
/// <param name="numParams">The method parameters count.</param>
|
||||
/// <param name="checkBaseClasses">True if check base classes when searching for the given method.</param>
|
||||
/// <returns>The method or null if failed to find it.</returns>
|
||||
MMethod* FindMethod(const char* name, int32 numParams, bool checkBaseClasses = true) const
|
||||
{
|
||||
MMethod* method = GetMethod(name, numParams);
|
||||
if (!method && checkBaseClasses)
|
||||
{
|
||||
MClass* base = GetBaseClass();
|
||||
if (base)
|
||||
method = base->FindMethod(name, numParams, true);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
MMethod* FindMethod(const char* name, int32 numParams, bool checkBaseClasses = true) const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an object referencing a method with the specified name and number of parameters.
|
||||
@@ -248,6 +238,13 @@ public:
|
||||
/// <returns>The method or null if failed to get it.</returns>
|
||||
MMethod* GetMethod(const char* name, int32 numParams = 0) const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an object referencing a method with the specified signature.
|
||||
/// </summary>
|
||||
/// <param name="signature">The method signature.</param>
|
||||
/// <returns>The method or null if failed to get it.</returns>
|
||||
MMethod* GetMethod(const struct ScriptingTypeMethodSignature& signature) const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns all methods belonging to this class.
|
||||
/// </summary>
|
||||
@@ -271,7 +268,7 @@ public:
|
||||
const Array<MField*, ArenaAllocation>& GetFields() const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an object referencing a event with the specified name.
|
||||
/// Returns an object referencing an event with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The event name.</param>
|
||||
/// <returns>The event object.</returns>
|
||||
|
||||
@@ -29,6 +29,7 @@ protected:
|
||||
int32 _paramsCount;
|
||||
mutable void* _returnType;
|
||||
mutable Array<void*, InlinedAllocation<8>> _parameterTypes;
|
||||
mutable uint64 _parameterOuts = 0;
|
||||
void CacheSignature() const;
|
||||
#else
|
||||
StringAnsiView _name;
|
||||
|
||||
@@ -845,7 +845,6 @@ MClass* MUtils::GetClass(const VariantType& value)
|
||||
auto mclass = Scripting::FindClass(StringAnsiView(value.TypeName));
|
||||
if (mclass)
|
||||
return mclass;
|
||||
const auto& stdTypes = *StdTypesContainer::Instance();
|
||||
switch (value.Type)
|
||||
{
|
||||
case VariantType::Void:
|
||||
@@ -891,25 +890,25 @@ MClass* MUtils::GetClass(const VariantType& value)
|
||||
case VariantType::Double4:
|
||||
return Double4::TypeInitializer.GetClass();
|
||||
case VariantType::Color:
|
||||
return stdTypes.ColorClass;
|
||||
return Color::TypeInitializer.GetClass();
|
||||
case VariantType::Guid:
|
||||
return stdTypes.GuidClass;
|
||||
return GetBinaryModuleCorlib()->Assembly->GetClass("System.Guid");
|
||||
case VariantType::Typename:
|
||||
return stdTypes.TypeClass;
|
||||
return GetBinaryModuleCorlib()->Assembly->GetClass("System.Type");
|
||||
case VariantType::BoundingBox:
|
||||
return stdTypes.BoundingBoxClass;
|
||||
return BoundingBox::TypeInitializer.GetClass();
|
||||
case VariantType::BoundingSphere:
|
||||
return stdTypes.BoundingSphereClass;
|
||||
return BoundingSphere::TypeInitializer.GetClass();
|
||||
case VariantType::Quaternion:
|
||||
return stdTypes.QuaternionClass;
|
||||
return Quaternion::TypeInitializer.GetClass();
|
||||
case VariantType::Transform:
|
||||
return stdTypes.TransformClass;
|
||||
return Transform::TypeInitializer.GetClass();
|
||||
case VariantType::Rectangle:
|
||||
return stdTypes.RectangleClass;
|
||||
return Rectangle::TypeInitializer.GetClass();
|
||||
case VariantType::Ray:
|
||||
return stdTypes.RayClass;
|
||||
return Ray::TypeInitializer.GetClass();
|
||||
case VariantType::Matrix:
|
||||
return stdTypes.MatrixClass;
|
||||
return Matrix::TypeInitializer.GetClass();
|
||||
case VariantType::Array:
|
||||
if (value.TypeName)
|
||||
{
|
||||
@@ -1202,8 +1201,7 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, MType* type, bool& failed)
|
||||
if (value.Type.Type != VariantType::Array)
|
||||
return nullptr;
|
||||
MObject* object = BoxVariant(value);
|
||||
auto typeStr = MCore::Type::ToString(type);
|
||||
if (object && !MCore::Object::GetClass(object)->IsSubClassOf(MCore::Type::GetClass(type)))
|
||||
if (object && MCore::Type::GetClass(type) != MCore::Array::GetArrayClass((MArray*)object))
|
||||
object = nullptr;
|
||||
return object;
|
||||
}
|
||||
@@ -1238,6 +1236,29 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, MType* type, bool& failed)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MUtils::VariantTypeEquals(const VariantType& type, MType* mType, bool isOut)
|
||||
{
|
||||
MClass* mClass = MCore::Type::GetClass(mType);
|
||||
MClass* variantClass = MUtils::GetClass(type);
|
||||
if (variantClass != mClass)
|
||||
{
|
||||
// Hack for Vector2/3/4 which alias with Float2/3/4 or Double2/3/4 (depending on USE_LARGE_WORLDS)
|
||||
if (mClass->GetFullName() == StringAnsiView("FlaxEngine.Vector2", 18) && (type.Type == VariantType::Float2 || type.Type == VariantType::Double2))
|
||||
return true;
|
||||
if (mClass->GetFullName() == StringAnsiView("FlaxEngine.Vector3", 18) && (type.Type == VariantType::Float3 || type.Type == VariantType::Double3))
|
||||
return true;
|
||||
if (mClass->GetFullName() == StringAnsiView("FlaxEngine.Vector4", 18) && (type.Type == VariantType::Float4 || type.Type == VariantType::Double4))
|
||||
return true;
|
||||
|
||||
// Arrays
|
||||
if (type == VariantType::Array && type.GetElementType() == VariantType::Object)
|
||||
return MCore::Type::GetType(mType) == MTypes::Array;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MObject* MUtils::ToManaged(const Version& value)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
|
||||
@@ -621,6 +621,7 @@ namespace MUtils
|
||||
#endif
|
||||
|
||||
extern void* VariantToManagedArgPtr(Variant& value, MType* type, bool& failed);
|
||||
extern bool VariantTypeEquals(const VariantType& type, MType* mType, bool isOut = false);
|
||||
|
||||
extern MObject* ToManaged(const Version& value);
|
||||
extern Version ToNative(MObject* value);
|
||||
|
||||
@@ -1062,10 +1062,39 @@ MClass* MClass::GetElementClass() const
|
||||
MMethod* MClass::GetMethod(const char* name, int32 numParams) const
|
||||
{
|
||||
GetMethods();
|
||||
for (int32 i = 0; i < _methods.Count(); i++)
|
||||
for (MMethod* method : _methods)
|
||||
{
|
||||
if (_methods[i]->GetParametersCount() == numParams && _methods[i]->GetName() == name)
|
||||
return _methods[i];
|
||||
if (method->GetParametersCount() == numParams && method->GetName() == name)
|
||||
return method;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MMethod* MClass::GetMethod(const ScriptingTypeMethodSignature& signature) const
|
||||
{
|
||||
GetMethods();
|
||||
for (MMethod* method : _methods)
|
||||
{
|
||||
if (method->IsStatic() != signature.IsStatic)
|
||||
continue;
|
||||
if (method->GetName() != signature.Name)
|
||||
continue;
|
||||
if (method->GetParametersCount() != signature.Params.Count())
|
||||
continue;
|
||||
bool isValid = true;
|
||||
for (int32 paramIdx = 0; paramIdx < signature.Params.Count(); paramIdx++)
|
||||
{
|
||||
auto& param = signature.Params[paramIdx];
|
||||
MType* type = method->GetParameterType(paramIdx);
|
||||
if (param.IsOut != method->GetParameterIsOut(paramIdx) ||
|
||||
!MUtils::VariantTypeEquals(param.Type, type, param.IsOut))
|
||||
{
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isValid && (signature.ReturnType.Type == VariantType::Null || MUtils::VariantTypeEquals(signature.ReturnType, method->GetReturnType())))
|
||||
return method;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1485,13 +1514,16 @@ void MMethod::CacheSignature() const
|
||||
|
||||
static void* GetMethodReturnTypePtr = GetStaticMethodPointer(TEXT("GetMethodReturnType"));
|
||||
static void* GetMethodParameterTypesPtr = GetStaticMethodPointer(TEXT("GetMethodParameterTypes"));
|
||||
static void* GetMethodParameterIsOutPtr = GetStaticMethodPointer(TEXT("GetMethodParameterIsOut"));
|
||||
_returnType = CallStaticMethod<void*, void*>(GetMethodReturnTypePtr, _handle);
|
||||
_parameterOuts = 0;
|
||||
if (_paramsCount != 0)
|
||||
{
|
||||
void** parameterTypeHandles;
|
||||
CallStaticMethod<void, void*, void***>(GetMethodParameterTypesPtr, _handle, ¶meterTypeHandles);
|
||||
_parameterTypes.Set(parameterTypeHandles, _paramsCount);
|
||||
MCore::GC::FreeMemory(parameterTypeHandles);
|
||||
_parameterOuts = CallStaticMethod<uint64, void*>(GetMethodParameterIsOutPtr, _handle);
|
||||
}
|
||||
|
||||
_hasCachedSignature = true;
|
||||
@@ -1558,9 +1590,7 @@ bool MMethod::GetParameterIsOut(int32 paramIdx) const
|
||||
if (!_hasCachedSignature)
|
||||
CacheSignature();
|
||||
ASSERT_LOW_LAYER(paramIdx >= 0 && paramIdx < _paramsCount);
|
||||
// TODO: cache GetParameterIsOut maybe?
|
||||
static void* GetMethodParameterIsOutPtr = GetStaticMethodPointer(TEXT("GetMethodParameterIsOut"));
|
||||
return CallStaticMethod<bool, void*, int>(GetMethodParameterIsOutPtr, _handle, paramIdx);
|
||||
return _parameterOuts & (1ull << paramIdx);
|
||||
}
|
||||
|
||||
bool MMethod::HasAttribute(const MClass* klass) const
|
||||
|
||||
@@ -1357,6 +1357,11 @@ MMethod* MClass::GetMethod(const char* name, int32 numParams) const
|
||||
return method;
|
||||
}
|
||||
|
||||
MMethod* MClass::GetMethod(const ScriptingTypeMethodSignature& signature) const
|
||||
{
|
||||
return GetMethod(signature.Name.Get(), signature.Params.Count());
|
||||
}
|
||||
|
||||
const Array<MMethod*>& MClass::GetMethods() const
|
||||
{
|
||||
if (_hasCachedMethods)
|
||||
|
||||
@@ -363,6 +363,11 @@ MMethod* MClass::GetMethod(const char* name, int32 numParams) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MMethod* MClass::GetMethod(const ScriptingTypeMethodSignature& signature) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Array<MMethod*, ArenaAllocation>& MClass::GetMethods() const
|
||||
{
|
||||
_hasCachedMethods = true;
|
||||
|
||||
Reference in New Issue
Block a user