summaryrefslogtreecommitdiff
path: root/src/plugins.cpp
blob: aa7efd5f01cffc76461c00b1b950d3ae0b5037b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

#include "macros.hpp"
#include "plugins.hpp"

#include <cstdio>
#include <dlfcn.h>

PKEPluginInterface pkePlugin{};

void *loadedPlugin = nullptr;

void Pke_UpdatePlugin(const PKEPluginInterface &plugin) {
	pkePlugin.OnInit = plugin.OnInit;
	pkePlugin.OnTick = plugin.OnTick;
	pkePlugin.OnTeardown = plugin.OnTeardown;
	pkePlugin.OnImGuiRender = plugin.OnImGuiRender;
}

void Pke_LoadPlugin(const char *path) {
	if (loadedPlugin != nullptr || loadedPlugin != CAFE_BABE(void)) {
		return;
	}
	void *extension = dlopen(path, RTLD_NOW);
	char *err = dlerror();
	if (!extension) {
		fprintf(stderr, "Given plugin library (%s) failed to load: %s\n", path, err);
		return;
	}
	PKEPluginInterface *interface = reinterpret_cast<PKEPluginInterface *>(dlsym(extension, "pkePluginInterface"));
	err = dlerror();
	if (err != NULL) {
		fprintf(stderr, "Given plugin library (%s) did not contain 'pkePluginInterface': %s\n", path, err);
		dlclose(extension);
		return;
	}
	Pke_UpdatePlugin(*interface);
	loadedPlugin = interface;
}

void Pke_UnloadPlugin() {
	pkePlugin = {
		.OnInit = nullptr,
		.OnTick= nullptr,
		.OnTeardown= nullptr,
		.OnImGuiRender= nullptr,
	};
	if (loadedPlugin != nullptr && loadedPlugin != CAFE_BABE(void)) {
		dlclose(loadedPlugin);
		loadedPlugin = CAFE_BABE(void);
	}
}