#include "../../Async/Async.h"
#include "../../FileSystemWatcher/FileSystemWatcher.h"
namespace SC
{
struct IPluginContract
{
static constexpr auto InterfaceHash =
PluginHash(
"IPluginContract");
Function<void(void)> onDraw;
};
struct PluginClient : public IPluginContract
{
PluginClient()
{
IPluginContract::onDraw = []()
{
};
}
bool init() { return true; }
bool close() { return true; }
};
SC_PLUGIN_DEFINE(PluginClient);
SC_PLUGIN_EXPORT_INTERFACES(PluginClient, IPluginContract);
struct PluginHost
{
String executablePath;
String libraryRootDirectory;
String someLibraryDirectory;
String pluginsPath;
PluginRegistry registry;
Result create(AsyncEventLoop& loop)
{
eventLoop = &loop;
SC_TRY(compiler.includePaths.push_back(libraryRootDirectory.view()));
SC_TRY(compiler.includePaths.push_back(someLibraryDirectory.view()));
SC_TRY(fileSystemWatcher.init(fileSystemWatcherRunner, *eventLoop));
watcher.notifyCallback.bind<PluginHost, &PluginHost::onFileChanged>(*this);
SC_TRY(fileSystemWatcher.watch(watcher, pluginsPath.view()));
return Result(true);
}
Result close()
{
SC_TRY(fileSystemWatcher.close());
eventLoop = nullptr;
return Result(true);
}
Result syncRegistry()
{
Vector<PluginDefinition> definitions;
SC_TRY(registry.replaceDefinitions(
move(definitions)));
return Result(true);
}
Result load(StringView identifier)
{
SC_TRY(registry.loadPlugin(identifier, compiler, sysroot, executablePath.view(),
PluginRegistry::LoadMode::Reload));
const PluginDynamicLibrary* plugin = registry.findPlugin(identifier);
SC_TRY(plugin->queryInterface(contract));
return Result(true);
}
void draw()
{
if (contract)
{
contract->onDraw();
}
}
private:
AsyncEventLoop* eventLoop;
PluginCompiler compiler;
PluginSysroot sysroot;
IPluginContract* contract = nullptr;
FileSystemWatcher fileSystemWatcher;
FileSystemWatcher::FolderWatcher watcher;
FileSystemWatcher::EventLoopRunner fileSystemWatcherRunner;
void onFileChanged(const FileSystemWatcher::Notification& notification)
{
auto reload = [this](const PluginIdentifier& plugin) { (void)load(plugin.view()); };
registry.getPluginsToReloadBecauseOf(notification.relativePath, Time::Milliseconds(500), reload);
}
};
}
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition: Compiler.h:269
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition: Result.h:48
constexpr unsigned int PluginHash(const char(&str)[N])
Compute compile time FNV hash for a char array.
Definition: PluginHash.h:33
static Result findBestCompiler(PluginCompiler &compiler)
Look for best compiler on current system.
static Result scanDirectory(const StringView directory, Vector< PluginDefinition > &definitions)
Scans a directory for PluginDefinition.
static Result findBestSysroot(PluginCompiler::Type compiler, PluginSysroot &sysroot)
Finds a reasonable sysroot for the given compiler.