This commit is contained in:
2025-02-10 00:44:11 +08:00
parent ece733c0e5
commit 1e0c4b8d8c
1640 changed files with 1628924 additions and 0 deletions
@@ -0,0 +1,417 @@
/*
* 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 <memory>
#include <vector>
#include "CoreMinimal.h"
#include "CoreUObject.h"
#include "V8Utils.h"
#include "ObjectMapper.h"
#include "JSLogger.h"
#include "NamespaceDef.h"
PRAGMA_DISABLE_UNDEFINED_IDENTIFIER_WARNINGS
#pragma warning(push, 0)
#include "libplatform/libplatform.h"
#include "v8.h"
#pragma warning(pop)
PRAGMA_ENABLE_UNDEFINED_IDENTIFIER_WARNINGS
namespace PUERTS_NAMESPACE
{
class FPropertyTranslator;
FORCEINLINE int32 GetSizeWithAlignment(PropertyMacro* InProperty)
{
return Align(InProperty->GetSize(), InProperty->GetMinAlignment());
}
struct FScriptArrayEx
{
FScriptArray Data;
#if ENGINE_MINOR_VERSION < 25 && ENGINE_MAJOR_VERSION < 5
TWeakObjectPtr<PropertyMacro> PropertyPtr;
#else
TWeakFieldPtr<PropertyMacro> PropertyPtr;
#endif
FORCEINLINE FScriptArrayEx(PropertyMacro* InProperty)
{
// UE_LOG(LogTemp, Warning, TEXT("FScriptArrayEx:%p"), this);
PropertyPtr = InProperty;
}
FORCEINLINE ~FScriptArrayEx()
{
// UE_LOG(LogTemp, Warning, TEXT("~FScriptArrayEx:%p"), this);
if (PropertyPtr.IsValid())
{
Empty(&Data, PropertyPtr.Get());
}
else
{
UE_LOG(Puerts, Error, TEXT("~FScriptArrayEx: Property is invalid"));
}
}
FORCEINLINE static uint8* GetData(FScriptArray* ScriptArray, int32 ElementSize, int32 Index)
{
return static_cast<uint8*>(ScriptArray->GetData()) + Index * ElementSize;
}
FORCEINLINE static void Destruct(FScriptArray* ScriptArray, PropertyMacro* Property, int32 Index, int32 Count = 1)
{
const int32 ElementSize = GetSizeWithAlignment(Property);
uint8* Dest = GetData(ScriptArray, ElementSize, Index);
for (int32 i = 0; i < Count; ++i)
{
Property->DestroyValue(Dest);
Dest += ElementSize;
}
}
FORCEINLINE static void Empty(FScriptArray* ScriptArray, PropertyMacro* Property)
{
Destruct(ScriptArray, Property, 0, ScriptArray->Num());
#if ENGINE_MAJOR_VERSION > 4
ScriptArray->Empty(0, GetSizeWithAlignment(Property), __STDCPP_DEFAULT_NEW_ALIGNMENT__);
#else
ScriptArray->Empty(0, GetSizeWithAlignment(Property));
#endif
}
};
struct FScriptSetEx
{
FScriptSet Data;
#if ENGINE_MINOR_VERSION < 25 && ENGINE_MAJOR_VERSION < 5
TWeakObjectPtr<PropertyMacro> PropertyPtr;
#else
TWeakFieldPtr<PropertyMacro> PropertyPtr;
#endif
FORCEINLINE FScriptSetEx(PropertyMacro* InProperty)
{
// UE_LOG(LogTemp, Warning, TEXT("FScriptSetEx:%p"), this);
PropertyPtr = InProperty;
}
FORCEINLINE ~FScriptSetEx()
{
// UE_LOG(LogTemp, Warning, TEXT("~FScriptSetEx:%p"), this);
if (PropertyPtr.IsValid())
{
Empty(&Data, PropertyPtr.Get());
}
else
{
UE_LOG(Puerts, Error, TEXT("~FScriptSetEx: Property is invalid"));
}
}
FORCEINLINE static void Destruct(FScriptSet* ScriptSet, PropertyMacro* Property, int32 Index, int32 Count = 1)
{
auto SetLayout = ScriptSet->GetScriptLayout(Property->GetSize(), Property->GetMinAlignment());
for (int32 i = Index; i < Index + Count; ++i)
{
if (ScriptSet->IsValidIndex(i))
{
void* Data = ScriptSet->GetData(i, SetLayout);
Property->DestroyValue(Data);
}
}
}
FORCEINLINE static void Empty(FScriptSet* ScriptSet, PropertyMacro* Property)
{
auto SetLayout = FScriptSet::GetScriptLayout(Property->GetSize(), Property->GetMinAlignment());
Destruct(ScriptSet, Property, 0, ScriptSet->Num());
ScriptSet->Empty(0, SetLayout);
}
};
FORCEINLINE static int32 GetKeyOffset(const FScriptMapLayout& ScriptMapLayout)
{
#if ENGINE_MINOR_VERSION < 22 && ENGINE_MAJOR_VERSION < 5
return ScriptMapLayout.KeyOffset;
#else
return 0;
#endif
}
struct FScriptMapEx
{
FScriptMap Data;
#if ENGINE_MINOR_VERSION < 25 && ENGINE_MAJOR_VERSION < 5
TWeakObjectPtr<PropertyMacro> KeyPropertyPtr;
TWeakObjectPtr<PropertyMacro> ValuePropertyPtr;
#else
TWeakFieldPtr<PropertyMacro> KeyPropertyPtr;
TWeakFieldPtr<PropertyMacro> ValuePropertyPtr;
#endif
FORCEINLINE FScriptMapEx(PropertyMacro* InKeyProperty, PropertyMacro* InValueProperty)
{
// UE_LOG(LogTemp, Warning, TEXT("FScriptMapEx:%p"), this);
KeyPropertyPtr = InKeyProperty;
ValuePropertyPtr = InValueProperty;
}
FORCEINLINE ~FScriptMapEx()
{
// UE_LOG(LogTemp, Warning, TEXT("~FScriptMapEx:%p"), this);
if (KeyPropertyPtr.IsValid() && ValuePropertyPtr.IsValid())
{
Empty(&Data, KeyPropertyPtr.Get(), ValuePropertyPtr.Get());
}
else
{
UE_LOG(Puerts, Error, TEXT("~FScriptMapEx: Property is invalid"));
}
}
FORCEINLINE static FScriptMapLayout GetScriptLayout(const PropertyMacro* KeyProperty, const PropertyMacro* ValueProperty)
{
return FScriptMap::GetScriptLayout(
KeyProperty->GetSize(), KeyProperty->GetMinAlignment(), ValueProperty->GetSize(), ValueProperty->GetMinAlignment());
}
FORCEINLINE static void Destruct(
FScriptMap* ScriptMap, PropertyMacro* KeyProperty, PropertyMacro* ValueProperty, int32 Index, int32 Count = 1)
{
int32 MaxIndex = ScriptMap->GetMaxIndex();
auto MapLayout = GetScriptLayout(KeyProperty, ValueProperty);
for (int32 i = Index; i < Index + Count; ++i)
{
if (ScriptMap->IsValidIndex(i))
{
uint8* Data = reinterpret_cast<uint8*>(ScriptMap->GetData(i, MapLayout));
void* Key = Data + GetKeyOffset(MapLayout);
void* Value = Data + MapLayout.ValueOffset;
KeyProperty->DestroyValue(Key);
ValueProperty->DestroyValue(Value);
}
}
}
FORCEINLINE static void Empty(FScriptMap* ScriptMap, PropertyMacro* KeyProperty, PropertyMacro* ValueProperty)
{
auto MapLayout = GetScriptLayout(KeyProperty, ValueProperty);
Destruct(ScriptMap, KeyProperty, ValueProperty, 0, ScriptMap->Num());
ScriptMap->Empty(0, MapLayout);
}
};
template <typename T>
struct ContainerExTypeMapper;
template <>
struct ContainerExTypeMapper<FScriptArray>
{
using Type = FScriptArrayEx;
};
template <>
struct ContainerExTypeMapper<FScriptSet>
{
using Type = FScriptSetEx;
};
template <>
struct ContainerExTypeMapper<FScriptMap>
{
using Type = FScriptMapEx;
};
template <typename T>
class FContainerWrapper
{
public:
static void OnGarbageCollectedWithFree(const v8::WeakCallbackInfo<void>& Data)
{
typedef typename ContainerExTypeMapper<T>::Type ET;
ET* Container =
static_cast<ET*>(DataTransfer::MakeAddressWithHighPartOfTwo(Data.GetInternalField(0), Data.GetInternalField(1)));
FV8Utils::IsolateData<IObjectMapper>(Data.GetIsolate())->UnBindContainer(Container);
delete Container;
}
static void OnGarbageCollected(const v8::WeakCallbackInfo<void>& Data)
{
T* Container =
static_cast<T*>(DataTransfer::MakeAddressWithHighPartOfTwo(Data.GetInternalField(0), Data.GetInternalField(1)));
FV8Utils::IsolateData<IObjectMapper>(Data.GetIsolate())->UnBindContainer(Container);
}
static void New(const v8::FunctionCallbackInfo<v8::Value>& Info)
{
v8::Isolate* Isolate = Info.GetIsolate();
FV8Utils::ThrowException(Isolate, "Container Constructor no support yet");
}
// TODO - 用doxygen注释
// 参数:无
// 返回:容器内元素总数
static void Num(const v8::FunctionCallbackInfo<v8::Value>& Info)
{
v8::Isolate* Isolate = Info.GetIsolate();
v8::HandleScope HandleScope(Isolate);
v8::Local<v8::Context> Context = Isolate->GetCurrentContext();
auto Self = FV8Utils::GetPointerFast<T>(Info.Holder());
Info.GetReturnValue().Set(Self->Num());
}
};
class FScriptArrayWrapper : public FContainerWrapper<FScriptArray>
{
public:
static v8::Local<v8::FunctionTemplate> ToFunctionTemplate(v8::Isolate* Isolate);
private:
// 参数:一到多个容器元素
// 返回:无
// 作用:追加新元素到容器
static void Add(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:索引
// 返回:元素(值类型,有内存拷贝)
// 作用:获取索引对应的元素,如果索引越界则抛出异常
static void Get(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:索引
// 返回:元素(引用类型)
// 作用:获取索引对应的元素,如果索引越界则抛出异常
static void GetRef(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数1:索引;参数2:元素
// 返回:无
// 作用:设置容器中索引对应的元素值,如果索引越界则抛出异常
static void Set(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:元素
// 返回:bool
// 作用:查询容器是否包含该元素,若是则返回true,否则返回false
static void Contains(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:元素
// 返回:索引
// 作用:返回容器中第一次出现该元素的索引,若元素不存在则返回INDEX_NONE(-1)
static void FindIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:索引
// 返回:无
// 作用:移除索引对应的元素,被移除的位置之后的元素会自动前移,如果索引越界则抛出异常
static void RemoveAt(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:索引
// 返回:bool
// 作用:如果参数是有效索引,返回true,否则返回false
static void IsValidIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
// 参数:无
// 返回:无
// 作用:清空容器
static void Empty(const v8::FunctionCallbackInfo<v8::Value>& Info);
FORCEINLINE static int32 AddUninitialized(FScriptArray* ScriptArray, int32 ElementSize, int32 Count = 1);
FORCEINLINE static uint8* GetData(FScriptArray* ScriptArray, int32 ElementSize, int32 Index);
FORCEINLINE static void Construct(FScriptArray* ScriptArray, FPropertyTranslator* Inner, int32 Index, int32 Count = 1);
static int32 FindIndexInner(const v8::FunctionCallbackInfo<v8::Value>& Info);
FORCEINLINE static void InternalGet(const v8::FunctionCallbackInfo<v8::Value>& Info, bool PassByPointer);
};
class FScriptSetWrapper : public FContainerWrapper<FScriptSet>
{
public:
static v8::Local<v8::FunctionTemplate> ToFunctionTemplate(v8::Isolate* Isolate);
private:
static void Add(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Get(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void GetRef(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Contains(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void FindIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void RemoveAt(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void GetMaxIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void IsValidIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Empty(const v8::FunctionCallbackInfo<v8::Value>& Info);
FORCEINLINE static int32 FindIndexInner(const v8::FunctionCallbackInfo<v8::Value>& Info);
FORCEINLINE static void InternalGet(const v8::FunctionCallbackInfo<v8::Value>& Info, bool PassByPointer);
};
class FScriptMapWrapper : public FContainerWrapper<FScriptMap>
{
public:
static v8::Local<v8::FunctionTemplate> ToFunctionTemplate(v8::Isolate* Isolate);
private:
static void Add(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Get(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void GetRef(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Set(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Remove(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void GetMaxIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void IsValidIndex(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void GetKey(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Empty(const v8::FunctionCallbackInfo<v8::Value>& Info);
FORCEINLINE static FScriptMapLayout GetScriptLayout(const PropertyMacro* KeyProperty, const PropertyMacro* ValueProperty);
FORCEINLINE static void InternalGet(const v8::FunctionCallbackInfo<v8::Value>& Info, bool PassByPointer);
};
class FFixSizeArrayWrapper
{
public:
static v8::Local<v8::FunctionTemplate> ToFunctionTemplate(v8::Isolate* Isolate);
private:
static void New(const v8::FunctionCallbackInfo<v8::Value>& Info)
{
}
static void Num(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Get(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void GetRef(const v8::FunctionCallbackInfo<v8::Value>& Info);
static void Set(const v8::FunctionCallbackInfo<v8::Value>& Info);
FORCEINLINE static void InternalGet(const v8::FunctionCallbackInfo<v8::Value>& Info, bool PassByPointer);
};
} // namespace PUERTS_NAMESPACE