Init
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "JSModuleLoader.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
#include "Algo/Reverse.h"
|
||||
#if (ENGINE_MAJOR_VERSION >= 5)
|
||||
#include "HAL/PlatformFileManager.h"
|
||||
#else
|
||||
#include "HAL/PlatformFilemanager.h"
|
||||
#endif
|
||||
|
||||
namespace PUERTS_NAMESPACE
|
||||
{
|
||||
static FString PathNormalize(const FString& PathIn)
|
||||
{
|
||||
TArray<FString> PathFrags;
|
||||
PathIn.ParseIntoArray(PathFrags, TEXT("/"));
|
||||
Algo::Reverse(PathFrags);
|
||||
TArray<FString> NewPathFrags;
|
||||
bool FromRoot = PathIn.StartsWith(TEXT("/"));
|
||||
while (PathFrags.Num() > 0)
|
||||
{
|
||||
FString E = PathFrags.Pop();
|
||||
if (E != TEXT("") && E != TEXT("."))
|
||||
{
|
||||
if (E == TEXT("..") && NewPathFrags.Num() > 0 && NewPathFrags.Last() != TEXT(".."))
|
||||
{
|
||||
NewPathFrags.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
NewPathFrags.Push(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FromRoot)
|
||||
{
|
||||
return TEXT("/") + FString::Join(NewPathFrags, TEXT("/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return FString::Join(NewPathFrags, TEXT("/"));
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultJSModuleLoader::CheckExists(const FString& PathIn, FString& Path, FString& AbsolutePath)
|
||||
{
|
||||
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
FString NormalizedPath = PathNormalize(PathIn);
|
||||
if (PlatformFile.FileExists(*NormalizedPath))
|
||||
{
|
||||
AbsolutePath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*NormalizedPath);
|
||||
Path = NormalizedPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DefaultJSModuleLoader::SearchModuleInDir(
|
||||
const FString& Dir, const FString& RequiredModule, FString& Path, FString& AbsolutePath)
|
||||
{
|
||||
FString Extension = FPaths::GetExtension(RequiredModule);
|
||||
bool IsJs = Extension == TEXT("js") || Extension == TEXT("mjs") || Extension == TEXT("cjs") || Extension == TEXT("json");
|
||||
if (IsJs && SearchModuleWithExtInDir(Dir, RequiredModule, Path, AbsolutePath))
|
||||
return true;
|
||||
return SearchModuleWithExtInDir(Dir, RequiredModule + ".js", Path, AbsolutePath) ||
|
||||
SearchModuleWithExtInDir(Dir, RequiredModule + ".mjs", Path, AbsolutePath) ||
|
||||
SearchModuleWithExtInDir(Dir, RequiredModule + ".cjs", Path, AbsolutePath) ||
|
||||
#if defined(WITH_V8_BYTECODE)
|
||||
SearchModuleWithExtInDir(Dir, RequiredModule + ".mbc", Path, AbsolutePath) ||
|
||||
SearchModuleWithExtInDir(Dir, RequiredModule + ".cbc", Path, AbsolutePath) ||
|
||||
#endif
|
||||
SearchModuleWithExtInDir(Dir, RequiredModule / "package.json", Path, AbsolutePath) ||
|
||||
SearchModuleWithExtInDir(Dir, RequiredModule / "index.js", Path, AbsolutePath);
|
||||
}
|
||||
|
||||
bool DefaultJSModuleLoader::SearchModuleWithExtInDir(
|
||||
const FString& Dir, const FString& RequiredModule, FString& Path, FString& AbsolutePath)
|
||||
{
|
||||
return CheckExists(Dir / RequiredModule, Path, AbsolutePath) ||
|
||||
(!Dir.EndsWith(TEXT("node_modules")) && CheckExists(Dir / TEXT("node_modules") / RequiredModule, Path, AbsolutePath));
|
||||
}
|
||||
|
||||
bool DefaultJSModuleLoader::Search(const FString& RequiredDir, const FString& RequiredModule, FString& Path, FString& AbsolutePath)
|
||||
{
|
||||
if (SearchModuleInDir(RequiredDir, RequiredModule, Path, AbsolutePath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (RequiredDir != TEXT("") && !RequiredModule.GetCharArray().Contains('/') && !RequiredModule.EndsWith(TEXT(".js")) &&
|
||||
!RequiredModule.EndsWith(TEXT(".mjs")))
|
||||
{
|
||||
// 调用require的文件所在的目录往上找
|
||||
TArray<FString> pathFrags;
|
||||
RequiredDir.ParseIntoArray(pathFrags, TEXT("/"));
|
||||
pathFrags.Pop(); // has try in "if (SearchModuleInDir(RequiredDir, RequiredModule, Path, AbsolutePath))"
|
||||
while (pathFrags.Num() > 0)
|
||||
{
|
||||
if (!pathFrags.Last().Equals(TEXT("node_modules")))
|
||||
{
|
||||
if (SearchModuleInDir(FString::Join(pathFrags, TEXT("/")), RequiredModule, Path, AbsolutePath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pathFrags.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
return SearchModuleInDir(FPaths::ProjectContentDir() / ScriptRoot, RequiredModule, Path, AbsolutePath) ||
|
||||
(ScriptRoot != TEXT("JavaScript") &&
|
||||
SearchModuleInDir(FPaths::ProjectContentDir() / TEXT("JavaScript"), RequiredModule, Path, AbsolutePath));
|
||||
}
|
||||
|
||||
bool DefaultJSModuleLoader::Load(const FString& Path, TArray<uint8>& Content)
|
||||
{
|
||||
// return (FPaths::FileExists(FullPath) && FFileHelper::LoadFileToString(Content, *FullPath));
|
||||
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
IFileHandle* FileHandle = PlatformFile.OpenRead(*Path);
|
||||
if (FileHandle)
|
||||
{
|
||||
int len = FileHandle->Size();
|
||||
Content.Reset(len + 2);
|
||||
Content.AddUninitialized(len);
|
||||
const bool Success = FileHandle->Read(Content.GetData(), len);
|
||||
delete FileHandle;
|
||||
|
||||
return Success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FString& DefaultJSModuleLoader::GetScriptRoot()
|
||||
{
|
||||
return ScriptRoot;
|
||||
}
|
||||
|
||||
} // namespace PUERTS_NAMESPACE
|
||||
Reference in New Issue
Block a user