88 lines
3.2 KiB
C++
88 lines
3.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "uLang/Toolchain/ToolchainPluginManager.h"
|
|
|
|
namespace uLang
|
|
{
|
|
class CLibAllocator : public ::uLang::CAllocatorInstance
|
|
{
|
|
public:
|
|
CLibAllocator()
|
|
: CAllocatorInstance(&Allocate, &Reallocate, &Deallocate)
|
|
{}
|
|
|
|
private:
|
|
static void* Allocate(const CAllocatorInstance* /*This*/, size_t NumBytes)
|
|
{
|
|
return CHeapRawAllocator::Allocate(NumBytes);
|
|
}
|
|
|
|
static void* Reallocate(const CAllocatorInstance* /*This*/, void* Memory, size_t NumBytes)
|
|
{
|
|
return CHeapRawAllocator::Reallocate(Memory, NumBytes);
|
|
}
|
|
|
|
static void Deallocate(const CAllocatorInstance* /*This*/, void* Memory)
|
|
{
|
|
CHeapRawAllocator::Deallocate(Memory);
|
|
}
|
|
};
|
|
|
|
IToolchainPlugin* CToolchainPluginManager::LoadPluginLib(const char* LibName)
|
|
{
|
|
ILibLoader::DyLibHandle LibHandle = _LibLoader->LoadLibrary(LibName);
|
|
|
|
IToolchainPlugin* LibInterface = nullptr;
|
|
if (ULANG_ENSUREF(LibHandle != ILibLoader::InvalidDyLibHandle, "Failed to load target library: %s", LibName))
|
|
{
|
|
SPluginInfo* ExistingDyLib = _LoadedLibs.FindByPredicate([LibHandle](const SPluginInfo* DyLib)->bool
|
|
{
|
|
return (LibHandle == DyLib->LibHandle);
|
|
});
|
|
if (ExistingDyLib)
|
|
{
|
|
LibInterface = ExistingDyLib->PluginInterface;
|
|
}
|
|
else
|
|
{
|
|
const char* GetVerProcName = ULANG_STRINGIFY(ULANG_PLUGIN_GETVER_PROCNAME);
|
|
::uLang::Private::ToolchainPluginGetVerPtr GetVerPtr = (::uLang::Private::ToolchainPluginGetVerPtr)_LibLoader->FindProcExport(LibHandle, GetVerProcName);
|
|
|
|
if (ULANG_ENSUREF(GetVerPtr, "Failed to find the expected version getter (%s), within the '%s' library.", GetVerProcName, LibName))
|
|
{
|
|
const int32_t LibVersion = GetVerPtr();
|
|
if (ULANG_ENSUREF(LibVersion == ULANG_API_VERSION,
|
|
"Mismatched API version -- %s lib (v%d) needs to be rebuilt with an updated core version (expected: v%d).",
|
|
LibName,
|
|
LibVersion,
|
|
ULANG_API_VERSION))
|
|
{
|
|
const char* InitProcName = ULANG_STRINGIFY(ULANG_PLUGIN_INIT_PROCNAME);
|
|
|
|
ILibLoader::DyLibProcPtr InitProcPtr = _LibLoader->FindProcExport(LibHandle, InitProcName);
|
|
if (ULANG_ENSUREF(InitProcPtr, "Failed to find expected entry point (%s), within the '%s' library.", InitProcName, LibName))
|
|
{
|
|
ULANG_ASSERTF(IsInitialized(), "Core should be properly initialized before loading any supplamentary libs.");
|
|
|
|
CLibAllocator Allocator;
|
|
Private::SToolchainPluginParams PluginParams(Allocator);
|
|
|
|
LibInterface = (::uLang::Private::ToolchainPluginInitPtr(InitProcPtr))(PluginParams);
|
|
|
|
if (ULANG_ENSUREF(LibInterface, "Library failed to produce the expected interface."))
|
|
{
|
|
LibInterface->OnLoad();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_LoadedLibs.AddNew(LibHandle, LibInterface);
|
|
}
|
|
}
|
|
|
|
return LibInterface;
|
|
}
|
|
|
|
} // namespace uLang
|