Skip to content

Commit

Permalink
[unreal]UClass,UStruct对象push到js,直接用InstanceTemplate创建,省一次js构造函数调用
Browse files Browse the repository at this point in the history
  • Loading branch information
chexiongsheng committed Feb 28, 2023
1 parent 929769d commit 5d239cd
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 47 deletions.
51 changes: 24 additions & 27 deletions unreal/Puerts/Source/JsEnv/Private/JsEnvImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ FJsEnvImpl::~FJsEnvImpl()
v8::Isolate::Scope IsolateScope(Isolate);
v8::HandleScope HandleScope(Isolate);

ClassToTemplateMap.Empty();
TypeToTemplateInfoMap.Empty();

CppObjectMapper.UnInitialize(Isolate);

Expand Down Expand Up @@ -1624,9 +1624,11 @@ v8::Local<v8::Value> FJsEnvImpl::FindOrAdd(v8::Isolate* Isolate, v8::Local<v8::C
auto PersistentValuePtr = ObjectMap.Find(UEObject);
if (!PersistentValuePtr) // create and link
{
auto BindTo = v8::External::New(Context->GetIsolate(), UEObject);
v8::Handle<v8::Value> Args[] = {BindTo};
return GetJsClass(Class, Context)->NewInstance(Context, 1, Args).ToLocalChecked();
bool Existed;
auto TemplateInfoPtr = GetTemplateInfoOfType(Class, Existed);
auto Result = TemplateInfoPtr->Template.Get(Isolate)->InstanceTemplate()->NewInstance(Context).ToLocalChecked();
Bind(static_cast<FClassWrapper*>(TemplateInfoPtr->StructWrapper.get()), UEObject, Result);
return Result;
}
else
{
Expand All @@ -1650,9 +1652,11 @@ v8::Local<v8::Value> FJsEnvImpl::FindOrAddStruct(
}

// create and link
auto BindTo = v8::External::New(Context->GetIsolate(), Ptr);
v8::Handle<v8::Value> Args[] = {BindTo, v8::Boolean::New(Isolate, PassByPointer)};
return GetJsClass(ScriptStruct, Context)->NewInstance(Context, 2, Args).ToLocalChecked();
bool Existed;
auto TemplateInfoPtr = GetTemplateInfoOfType(ScriptStruct, Existed);
auto Result = TemplateInfoPtr->Template.Get(Isolate)->InstanceTemplate()->NewInstance(Context).ToLocalChecked();
BindStruct(static_cast<FScriptStructWrapper*>(TemplateInfoPtr->StructWrapper.get()), Ptr, Result, PassByPointer);
return Result;
}

v8::Local<v8::Value> FJsEnvImpl::FindOrAddCppObject(
Expand Down Expand Up @@ -1942,12 +1946,7 @@ void FJsEnvImpl::NotifyUObjectDeleted(const class UObjectBase* ObjectBase, int32

void FJsEnvImpl::TryReleaseType(UStruct* Struct)
{
if (ClassToTemplateMap.Find(Struct))
{
// Logger->Warn(FString::Printf(TEXT("release class: %s"), *Struct->GetName()));
ClassToTemplateMap[Struct].Reset();
ClassToTemplateMap.Remove(Struct);
}
TypeToTemplateInfoMap.Remove(Struct);
}

// fix ScriptCore.cpp UObject::SkipFunction crash when Function has no parameters
Expand Down Expand Up @@ -2706,11 +2705,11 @@ std::shared_ptr<FStructWrapper> FJsEnvImpl::GetStructWrapper(UStruct* InStruct,
}
}

v8::Local<v8::FunctionTemplate> FJsEnvImpl::GetTemplateOfClass(UStruct* InStruct, bool& Existed)
FJsEnvImpl::FTemplateInfo* FJsEnvImpl::GetTemplateInfoOfType(UStruct* InStruct, bool& Existed)
{
auto Isolate = MainIsolate;
auto TemplatePtr = ClassToTemplateMap.Find(InStruct);
if (!TemplatePtr)
auto TemplateInfoPtr = TypeToTemplateInfoMap.Find(InStruct);
if (!TemplateInfoPtr)
{
if (!ExtensionMethodsMapInited)
{
Expand Down Expand Up @@ -2756,9 +2755,9 @@ v8::Local<v8::FunctionTemplate> FJsEnvImpl::GetTemplateOfClass(UStruct* InStruct
{
bool Dummy;
if (IsReuseTemplate)
__USE(GetTemplateOfClass(SuperStruct, Dummy));
__USE(GetTemplateInfoOfType(SuperStruct, Dummy));
else
Template->Inherit(GetTemplateOfClass(SuperStruct, Dummy));
Template->Inherit(GetTemplateInfoOfType(SuperStruct, Dummy)->Template.Get(Isolate));
}
}
else
Expand Down Expand Up @@ -2786,28 +2785,26 @@ v8::Local<v8::FunctionTemplate> FJsEnvImpl::GetTemplateOfClass(UStruct* InStruct
{
bool Dummy;
if (IsReuseTemplate)
__USE(GetTemplateOfClass(SuperClass, Dummy));
__USE(GetTemplateInfoOfType(SuperClass, Dummy));
else
Template->Inherit(GetTemplateOfClass(SuperClass, Dummy));
Template->Inherit(GetTemplateInfoOfType(SuperClass, Dummy)->Template.Get(Isolate));
}
}

ClassToTemplateMap.Emplace(InStruct, v8::UniquePersistent<v8::FunctionTemplate>(Isolate, Template));

Existed = false;
return HandleScope.Escape(Template);
return &TypeToTemplateInfoMap.Add(InStruct, {v8::UniquePersistent<v8::FunctionTemplate>(Isolate, Template), StructWrapper});
}
else
{
Existed = true;
return v8::Local<v8::FunctionTemplate>::New(Isolate, *TemplatePtr);
return TemplateInfoPtr;
}
}

v8::Local<v8::Function> FJsEnvImpl::GetJsClass(UStruct* InStruct, v8::Local<v8::Context> Context)
{
bool Existed;
auto Ret = GetTemplateOfClass(InStruct, Existed)->GetFunction(Context).ToLocalChecked();
auto Ret = GetTemplateInfoOfType(InStruct, Existed)->Template.Get(MainIsolate)->GetFunction(Context).ToLocalChecked();

if (UNLIKELY(!Existed)) // first create
{
Expand Down Expand Up @@ -2836,7 +2833,7 @@ v8::Local<v8::Function> FJsEnvImpl::GetJsClass(UStruct* InStruct, v8::Local<v8::
bool FJsEnvImpl::IsInstanceOf(UStruct* Struct, v8::Local<v8::Object> JsObject)
{
bool Dummy;
return GetTemplateOfClass(Struct, Dummy)->HasInstance(JsObject);
return GetTemplateInfoOfType(Struct, Dummy)->Template.Get(MainIsolate)->HasInstance(JsObject);
}

bool FJsEnvImpl::IsInstanceOfCppObject(const void* TypeId, v8::Local<v8::Object> JsObject)
Expand Down Expand Up @@ -4003,7 +4000,7 @@ void FJsEnvImpl::Mixin(const v8::FunctionCallbackInfo<v8::Value>& Info)
MixinClasses.Add(New);

bool Existed = false;
GetTemplateOfClass(New, Existed);
__USE(GetTemplateInfoOfType(New, Existed));
bool IsReuseTemplate = false;
auto StructWrapper = GetStructWrapper(New, IsReuseTemplate);
StructWrapper->IsNativeTakeJsRef = TakeJsObjectRef;
Expand Down
10 changes: 8 additions & 2 deletions unreal/Puerts/Source/JsEnv/Private/JsEnvImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,13 @@ class FJsEnvImpl : public IJsEnv, IObjectMapper, public FUObjectArray::FUObjectD

std::shared_ptr<FStructWrapper> GetStructWrapper(UStruct* InStruct, bool& IsReuseTemplate);

v8::Local<v8::FunctionTemplate> GetTemplateOfClass(UStruct* Class, bool& Existed);
struct FTemplateInfo
{
v8::UniquePersistent<v8::FunctionTemplate> Template;
std::shared_ptr<FStructWrapper> StructWrapper;
};

FTemplateInfo* GetTemplateInfoOfType(UStruct* Class, bool& Existed);

v8::Local<v8::Function> GetJsClass(UStruct* Class, v8::Local<v8::Context> Context);

Expand Down Expand Up @@ -500,7 +506,7 @@ class FJsEnvImpl : public IJsEnv, IObjectMapper, public FUObjectArray::FUObjectD

v8::Global<v8::Function> ReloadJs;

TMap<UStruct*, v8::UniquePersistent<v8::FunctionTemplate>> ClassToTemplateMap;
TMap<UStruct*, FTemplateInfo> TypeToTemplateInfoMap;

TMap<FString, std::shared_ptr<FStructWrapper>> TypeReflectionMap;

Expand Down
19 changes: 1 addition & 18 deletions unreal/Puerts/Source/JsEnv/Private/StructWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,14 +484,6 @@ void FScriptStructWrapper::New(
auto Self = Info.This();
void* Memory = nullptr;

bool PassByPointer = false;

if (Info.Length() == 2 && Info[0]->IsExternal()) // Call by Native
{
Memory = v8::Local<v8::External>::Cast(Info[0])->Value();
PassByPointer = Info[1]->BooleanValue(Isolate);
}
else
{
if (ExternalInitialize)
{
Expand All @@ -511,7 +503,7 @@ void FScriptStructWrapper::New(
}
}
}
FV8Utils::IsolateData<IObjectMapper>(Isolate)->BindStruct(this, Memory, Self, PassByPointer);
FV8Utils::IsolateData<IObjectMapper>(Isolate)->BindStruct(this, Memory, Self, false);
}
else
{
Expand Down Expand Up @@ -582,15 +574,6 @@ void FClassWrapper::New(v8::Isolate* Isolate, v8::Local<v8::Context>& Context, c
UObject* Object = nullptr;
auto Class = static_cast<UClass*>(Struct.Get());

if (Info.Length() == 1 && Info[0]->IsExternal()) // Call by Native
{
Object = reinterpret_cast<UObject*>(v8::Local<v8::External>::Cast(Info[0])->Value());
if (!Object->IsValidLowLevel())
{
Object = nullptr;
}
}
else // Call by js new
{
UObject* Outer = GetTransientPackage();
FName Name = NAME_None;
Expand Down

0 comments on commit 5d239cd

Please sign in to comment.