/*
PluginFramework
by John Ryland
Copyright (c) 2023
*/
////////////////////////////////////////////////////////////////////////////////////
// Plugin Loader
#include "PluginManager.h"
#include "Library.h"
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#else //UNIX
# include <dlfcn.h>
#endif
namespace PluginFramework {
typedef void (*RegisterPluginFuncPtr)(PluginManager& pluginManager);
typedef void (*DeregisterPluginFuncPtr)(PluginManager& pluginManager);
Plugin::Plugin(std::string pluginName, const char* libraryFileName)
: mName(pluginName)
, mManager(nullptr)
, mLibrary(Library::Load(libraryFileName))
, mRegisterFuncPtr(nullptr)
{
Load();
}
Plugin::Plugin(Plugin&& other)
: mName(std::move(other.mName))
, mManager(std::move(other.mManager))
, mLibrary(std::move(other.mLibrary))
, mRegisterFuncPtr(std::move(other.mRegisterFuncPtr))
{
}
Plugin::~Plugin()
{
Deregister();
}
void Plugin::Load()
{
if (mLibrary.get() && mLibrary->Loaded())
{
mRegisterFuncPtr = mLibrary->GetFunctionAddress(STRINGIZE(PLUGIN_REGISTER_FUNCTION));
if (mRegisterFuncPtr)
printf("found RegisterPlugin function\n");
else
printf("didn't find RegisterPlugin function\n");
}
else
{
printf("plugin not loaded\n");
}
if (mLibrary.get() && mLibrary->Loaded() && !mRegisterFuncPtr)
mLibrary->Unload();
}
void Plugin::Deregister()
{
if (Registered())
{
void* deregisterFuncPtr = mLibrary->GetFunctionAddress(STRINGIZE(PLUGIN_DEREGISTER_FUNCTION));
if (deregisterFuncPtr)
((DeregisterPluginFuncPtr)deregisterFuncPtr)(*mManager);
}
}
void Plugin::HotEject()
{
Deregister();
if (Registered())
mManager->UnloadPlugin(*this);
if (mLibrary.get())
mLibrary->Unload();
}
bool Plugin::Loaded() const
{
return mLibrary.get() && mLibrary->Loaded() && mRegisterFuncPtr;
}
bool Plugin::Registered() const
{
return Loaded() && mManager;
}
std::string Plugin::Name() const
{
return mName;
}
std::string Plugin::FileName() const
{
if (mLibrary.get())
return mLibrary->FileName();
return "";
}
void Plugin::Register(PluginManager& pluginManager)
{
if (Loaded() && !Registered())
{
((RegisterPluginFuncPtr)mRegisterFuncPtr)(pluginManager);
mManager = &pluginManager;
}
}
} // PluginFramework namespace