Files
MingSimulator/Plugins/Puerts/Source/JsEnv/Public/UEDataBinding.hpp
T
starmen1265 ed21658256 从master分支拉取puerts,并拉取v8制品,修改puerts插件部分UE5_5以下兼容的宏代码。保证puerts编译通过。包括
CSharpParamDefaultValueMetas.cs和ubtplugin.csproj和declarationGenerator.cpp和PropertyTranslator.cpp对UserDefinedStruct.h的引用
2024-12-02 01:03:52 +08:00

551 lines
20 KiB
C++

/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may
* be subject to their corresponding license terms. This file is subject to the terms and conditions defined in file 'LICENSE',
* which is part of this source code package.
*/
#pragma once
#include "ScriptBackend.hpp"
#include "DataTransfer.h"
#include "ArrayBuffer.h"
#include "UECompatible.h"
#include "PuertsNamespaceDef.h"
#define UsingUClass(CLS) \
namespace PUERTS_NAMESPACE \
{ \
template <> \
struct ScriptTypeName<CLS> \
{ \
static constexpr auto value() \
{ \
return internal::Literal(#CLS).Sub<1>(); \
} \
}; \
} \
namespace PUERTS_NAMESPACE \
{ \
template <> \
struct is_uetype<CLS> : public std::true_type \
{ \
}; \
}
#define UsingTArrayWithName(CLS, CLSNAME) \
namespace PUERTS_NAMESPACE \
{ \
template <> \
struct ScriptTypeName<TArray<CLS>> \
{ \
static constexpr auto value() \
{ \
return internal::Literal(CLSNAME); \
} \
}; \
} \
__DefObjectType(TArray<CLS>) __DefCDataPointerConverter(TArray<CLS>)
#define UsingCrossModuleCppType(CLS) \
namespace PUERTS_NAMESPACE \
{ \
template <> \
struct StaticTypeId<CLS> \
{ \
static const void* get() \
{ \
static const void* cache_type_id = nullptr; \
if (!cache_type_id) \
{ \
auto info = PUERTS_NAMESPACE::FindCppTypeClassByName(#CLS); \
cache_type_id = info ? info->TypeId : &cache_type_id; \
} \
return cache_type_id; \
} \
}; \
} \
UsingNamedCppType(CLS, CLS)
#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4
#define RegisterTArray(CLS) \
PUERTS_NAMESPACE::DefineClass<TArray<CLS>>() \
.Method("Add", SelectFunction(int (TArray<CLS>::*)(CLS const&), &TArray<CLS>::Add)) \
.Method("Get", SelectFunction(CLS& (TArray<CLS>::*) (int), &TArray<CLS>::operator[])) \
.Method("GetRef", SelectFunction(CLS& (TArray<CLS>::*) (int), &TArray<CLS>::operator[])) \
.Method("Num", MakeFunction(&TArray<CLS>::Num)) \
.Method("Contains", MakeFunction(&TArray<CLS>::Contains<CLS>)) \
.Method("FindIndex", SelectFunction(int (TArray<CLS>::*)(CLS const&) const, &TArray<CLS>::Find)) \
.Method( \
"RemoveAt", SelectFunction(void (TArray<CLS>::*)(int, /* New param in 5.4*/ EAllowShrinking), &TArray<CLS>::RemoveAt)) \
.Method("IsValidIndex", MakeFunction(&TArray<CLS>::IsValidIndex)) \
.Method("Empty", MakeFunction(&TArray<CLS>::Empty)) \
.Register()
#else
#define RegisterTArray(CLS) \
PUERTS_NAMESPACE::DefineClass<TArray<CLS>>() \
.Method("Add", SelectFunction(int (TArray<CLS>::*)(CLS const&), &TArray<CLS>::Add)) \
.Method("Get", SelectFunction(CLS& (TArray<CLS>::*) (int), &TArray<CLS>::operator[])) \
.Method("GetRef", SelectFunction(CLS& (TArray<CLS>::*) (int), &TArray<CLS>::operator[])) \
.Method("Num", MakeFunction(&TArray<CLS>::Num)) \
.Method("Contains", MakeFunction(&TArray<CLS>::Contains<CLS>)) \
.Method("FindIndex", SelectFunction(int (TArray<CLS>::*)(CLS const&) const, &TArray<CLS>::Find)) \
.Method("RemoveAt", SelectFunction(void (TArray<CLS>::*)(int), &TArray<CLS>::RemoveAt)) \
.Method("IsValidIndex", MakeFunction(&TArray<CLS>::IsValidIndex)) \
.Method("Empty", MakeFunction(&TArray<CLS>::Empty)) \
.Register()
#endif
#define UsingUStruct(CLS) UsingUClass(CLS)
#define UsingContainer(CLS) __DefObjectType(CLS) __DefCDataPointerConverter(CLS)
#define UsingTSharedPtr(ITEMCLS) __DefObjectType(TSharedPtr<ITEMCLS>) __DefCDataPointerConverter(TSharedPtr<ITEMCLS>)
template <class T>
struct TSharedPtrExtension
{
static bool Equals(const TSharedPtr<T> Lhs, const TSharedPtr<T> Rhs)
{
return Lhs == Rhs;
}
};
#define RegisterTSharedPtr(ITEMCLS) \
PUERTS_NAMESPACE::DefineClass<TSharedPtr<ITEMCLS>>() \
.Method("Equals", MakeExtension(&TSharedPtrExtension<ITEMCLS>::Equals)) \
.Register();
namespace PUERTS_NAMESPACE
{
namespace v8_impl
{
class TCharStringHolder
{
public:
TCharStringHolder()
{
}
TCharStringHolder(v8::Local<v8::Context> context, const v8::Local<v8::Value> value)
{
Str = FV8Utils::ToFString(context->GetIsolate(), value);
}
const TCHAR* Data() const
{
return *Str;
}
private:
FString Str;
};
template <>
struct CustomArgumentBufferType<const TCHAR*>
{
using type = TCharStringHolder;
static constexpr bool enable = true;
};
template <>
struct Converter<FString>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, FString value)
{
return FV8Utils::ToV8String(context->GetIsolate(), value);
}
static FString toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return FV8Utils::ToFString(context->GetIsolate(), value);
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return value->IsString();
}
};
template <>
struct Converter<FName>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, FName value)
{
return FV8Utils::ToV8String(context->GetIsolate(), value.ToString());
}
static FName toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
if (value->IsArrayBuffer())
{
auto Ab = v8::Local<v8::ArrayBuffer>::Cast(value);
size_t ByteLength;
auto Data = DataTransfer::GetArrayBufferData(Ab, ByteLength);
if (ByteLength == sizeof(FName))
{
return *static_cast<FName*>(Data);
}
}
return FV8Utils::ToFName(context->GetIsolate(), value);
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return value->IsString();
}
};
template <>
struct Converter<const TCHAR*>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, const TCHAR* value)
{
return FV8Utils::ToV8String(context->GetIsolate(), value);
}
static TCharStringHolder toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return TCharStringHolder(context, value);
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return value->IsString();
}
};
#ifndef PUERTS_FTEXT_AS_OBJECT
template <>
struct Converter<FText>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, FText value)
{
return FV8Utils::ToV8String(context->GetIsolate(), value.ToString());
}
static FText toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return FText::FromString(FV8Utils::ToFString(context->GetIsolate(), value));
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return value->IsString();
}
};
#endif
template <>
struct Converter<FArrayBuffer>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, FArrayBuffer value)
{
return DataTransfer::NewArrayBuffer(context, value.Data, value.Length);
}
static FArrayBuffer toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
FArrayBuffer Ret = {nullptr, 0};
if (value->IsArrayBufferView())
{
v8::Local<v8::ArrayBufferView> BuffView = value.As<v8::ArrayBufferView>();
auto Ab = BuffView->Buffer();
Ret.Data = static_cast<char*>(DataTransfer::GetArrayBufferData(Ab)) + BuffView->ByteOffset();
Ret.Length = BuffView->ByteLength();
}
else if (value->IsArrayBuffer())
{
auto Ab = v8::Local<v8::ArrayBuffer>::Cast(value);
size_t ByteLength;
Ret.Data = static_cast<char*>(DataTransfer::GetArrayBufferData(Ab, ByteLength));
Ret.Length = ByteLength;
}
return Ret;
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return value->IsArrayBuffer() || value->IsArrayBufferView();
}
};
template <>
struct Converter<FArrayBufferValue>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, FArrayBufferValue& value)
{
v8::Local<v8::ArrayBuffer> Ab = v8::ArrayBuffer::New(context->GetIsolate(), value.Data.Num());
void* Buff = static_cast<char*>(DataTransfer::GetArrayBufferData(Ab));
::memcpy(Buff, value.Data.GetData(), value.Data.Num());
return Ab;
}
static FArrayBufferValue toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
FArrayBufferValue Ret;
size_t Len = 0;
void* Data = nullptr;
if (value->IsArrayBufferView())
{
v8::Local<v8::ArrayBufferView> BuffView = value.As<v8::ArrayBufferView>();
auto Ab = BuffView->Buffer();
Data = static_cast<char*>(DataTransfer::GetArrayBufferData(Ab)) + BuffView->ByteOffset();
Len = BuffView->ByteLength();
}
else if (value->IsArrayBuffer())
{
auto Ab = v8::Local<v8::ArrayBuffer>::Cast(value);
Data = DataTransfer::GetArrayBufferData(Ab, Len);
}
if (Len > 0 && Data)
{
Ret.Data.AddUninitialized(Len);
::memcpy(Ret.Data.GetData(), Data, Len);
}
return Ret;
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return value->IsArrayBuffer() || value->IsArrayBufferView();
}
};
template <typename T>
struct Converter<T*, typename std::enable_if<std::is_convertible<T*, const UObject*>::value>::type>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, T* value)
{
using TypeWithoutConst = typename std::remove_const<T>::type;
return DataTransfer::FindOrAddObject<TypeWithoutConst>(context->GetIsolate(), context, (TypeWithoutConst*) (value));
}
static T* toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
T* Ret = DataTransfer::GetPointerFast<T>(value.As<v8::Object>());
return (!Ret || Ret == RELEASED_UOBJECT_MEMBER || !Ret->IsValidLowLevelFast() || UEObjectIsPendingKill(Ret)) ? nullptr
: Ret;
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
if (value.As<v8::Object>()->IsNullOrUndefined())
return true;
return DataTransfer::IsInstanceOf(context->GetIsolate(), T::StaticClass(), value.As<v8::Object>());
}
};
template <typename T>
struct Converter<T*, typename std::enable_if<!std::is_convertible<T*, const UObject*>::value &&
std::is_convertible<T*, const UObjectBase*>::value>::type>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, T* value)
{
return DataTransfer::FindOrAddObject<UObject>(context->GetIsolate(), context, static_cast<UObject*>(value));
}
static T* toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
T* Ret = DataTransfer::GetPointerFast<T>(value.As<v8::Object>());
return (!Ret || Ret == RELEASED_UOBJECT_MEMBER || !Ret->IsValidLowLevelFast()) ? nullptr : Ret;
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return DataTransfer::IsInstanceOf(context->GetIsolate(), UObject::StaticClass(), value.As<v8::Object>());
}
};
} // namespace v8_impl
template <>
struct ScriptTypeName<FString>
{
static constexpr auto value()
{
return internal::Literal("string");
}
};
template <>
struct ScriptTypeName<FName>
{
static constexpr auto value()
{
return internal::Literal("string");
}
};
template <>
struct ScriptTypeName<const TCHAR*>
{
static constexpr auto value()
{
return internal::Literal("string");
}
};
#ifndef PUERTS_FTEXT_AS_OBJECT
template <>
struct ScriptTypeName<FText>
{
static constexpr auto value()
{
return internal::Literal("string");
}
};
#endif
template <>
struct ScriptTypeName<FArrayBuffer>
{
static constexpr auto value()
{
return internal::Literal("ArrayBuffer");
}
};
template <>
struct ScriptTypeName<FArrayBufferValue>
{
static constexpr auto value()
{
return internal::Literal("ArrayBuffer");
}
};
template <typename T>
struct ScriptTypeNameWithNamespace<T,
typename std::enable_if<is_objecttype<typename std::remove_pointer<typename std::decay<T>::type>::type>::value>::type>
{
static constexpr auto value()
{
return internal::Literal("cpp.") + ScriptTypeName<T>::value();
}
};
template <typename T>
struct ScriptTypeNameWithNamespace<T,
typename std::enable_if<is_uetype<typename std::remove_pointer<typename std::decay<T>::type>::type>::value>::type>
{
static constexpr auto value()
{
return internal::Literal("UE.") + ScriptTypeName<T>::value();
}
};
template <typename T>
struct ScriptTypeName<TSharedPtr<T>>
{
static constexpr auto value()
{
return internal::Literal("UE.TSharedPtr<") + ScriptTypeNameWithNamespace<T>::value() + internal::Literal(">");
}
};
template <typename T>
struct ScriptTypeName<TArray<T>>
{
static constexpr auto value()
{
return internal::Literal("UE.TArray<") + ScriptTypeNameWithNamespace<T>::value() + internal::Literal(">");
}
};
template <typename T>
struct ScriptTypeName<TSet<T>>
{
static constexpr auto value()
{
return internal::Literal("UE.TSet<") + ScriptTypeNameWithNamespace<T>::value() + internal::Literal(">");
}
};
template <typename TKey, typename TValue>
struct ScriptTypeName<TMap<TKey, TValue>>
{
static constexpr auto value()
{
return internal::Literal("UE.TMap<") + ScriptTypeNameWithNamespace<TKey>::value() + internal::Literal(", ") +
ScriptTypeNameWithNamespace<TValue>::value() + internal::Literal(">");
}
};
namespace internal
{
template <typename T, typename = void>
struct IsUStructHelper : std::false_type
{
};
template <typename T>
struct IsUStructHelper<T, Void_t<decltype(&TScriptStructTraits<T>::Get)>> : std::true_type
{
};
} // namespace internal
namespace v8_impl
{
template <typename T>
struct Converter<T*, typename std::enable_if<!std::is_const<T>::value && !std::is_convertible<T*, const UObject*>::value &&
internal::IsUStructHelper<T>::value>::type>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, const T* value)
{
return DataTransfer::FindOrAddStruct<T>(context->GetIsolate(), context, (void*) value, true);
}
static T* toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return DataTransfer::GetPointerFast<T>(value.As<v8::Object>());
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return DataTransfer::IsInstanceOf<T>(context->GetIsolate(), value.As<v8::Object>());
}
};
template <typename T>
struct Converter<const T*,
typename std::enable_if<!std::is_convertible<T*, const UObject*>::value && internal::IsUStructHelper<T>::value>::type>
: Converter<T*>
{
};
template <typename T>
struct Converter<T, typename std::enable_if<internal::IsUStructHelper<T>::value>::type>
{
static v8::Local<v8::Value> toScript(v8::Local<v8::Context> context, const T value)
{
return DataTransfer::FindOrAddStruct<T>(context->GetIsolate(), context, new T(value), false);
}
static T toCpp(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
T* ptr = DataTransfer::GetPointerFast<T>(value.As<v8::Object>());
return ptr ? *ptr : T{};
}
static bool accept(v8::Local<v8::Context> context, const v8::Local<v8::Value>& value)
{
return DataTransfer::IsInstanceOf<T>(context->GetIsolate(), value.As<v8::Object>());
}
};
template <typename T>
struct Converter<const T, typename std::enable_if<internal::IsUStructHelper<T>::value>::type> : Converter<T>
{
};
} // namespace v8_impl
template <typename T>
struct ScriptTypeName<const T, typename std::enable_if<internal::IsUStructHelper<T>::value>::type> : ScriptTypeName<T>
{
};
} // namespace PUERTS_NAMESPACE