Add plugin dependencies

master
Elias Fleckenstein 2021-06-09 20:08:50 +02:00
parent 3dcf2f7307
commit 98e09a9f51
6 changed files with 56 additions and 11 deletions

View File

@ -6,7 +6,7 @@ You might want to include the game.h file from plugins/game/game.h. Have a look
Controls: WASD to move, Q to quit.
To build the loader and the plugins in the plugins/ folder, simply type `make` or `make all`. There are separate targets for the loader (`dungeon`) and the plugins. All Makefiles that are placed in plugin directories, so you might want to include a makefile in your plugin. The plugins target simply depends on ${PLUGINS}, so just add things to this in your plugin Makefile to add them to the plugins target (usually your plugin.so)
To build the loader and the plugins in the plugins/ folder, simply type `make` or `make all`. There are separate targets for the loader (`dungeon`) and the plugins. All Makefiles that are placed in plugin directories, so you might want to include a makefile in your plugin. The plugins target simply depends on ${PLUGINS}, so just add things to this in your plugin Makefile to add them to the plugins target (usually your plugin.so)
To run the loader, type `./dungeon`. It will load all plugins including the game itself dynamically and run the game.
Plugins are loaded in alphabethical order, with the exception of the game plugin that is loaded first. If you want to make a plugin that depends on another plugin, make sure the other plugin is loaded first by setting the name of your plugin accordingly. A cleaner solution to this is coming soon.
If you want to make a plugin that depends on another plugin (including the game itself), make sure to depend on that plugin. To add dependencies to a plugin, create a file named dependencies.txt in the plugin folder. Put the names of all plugins your plugin depends on into that file. You can use spaces or newlines as seperators.

View File

@ -5,20 +5,63 @@
#include <dirent.h>
#include <string.h>
struct plugin_list
{
char *name;
void *handle;
struct plugin_list *next;
};
struct plugin_list *plugins = NULL;
struct plugin_list **next = &plugins;
static void *load_plugin(const char *name)
{
for (struct plugin_list *ptr = plugins; ptr != NULL; ptr = ptr->next) {
if (strcmp(ptr->name, name) == 0)
return ptr->handle;
}
size_t len = strlen(name);
char filename[1 + 1 + 7 + 1 + len + 1 + len + 1 + 2 + 1];
sprintf(filename, "./plugins/%s/%s.so", name, name);
void *plugin_handle = dlmopen(LM_ID_BASE, filename, RTLD_NOW | RTLD_GLOBAL);
char dependency_file_name[1 + 1 + 7 + 1 + len + 1 + 12 + 1 + 3 + 1];
sprintf(dependency_file_name, "./plugins/%s/dependencies.txt", name);
if (! plugin_handle) {
FILE *dependency_file = fopen(dependency_file_name, "r");
if (dependency_file) {
char dependency[BUFSIZ];
while (fscanf(dependency_file, "%s", dependency) != EOF)
load_plugin(dependency);
fclose(dependency_file);
}
char library_name[1 + 1 + 7 + 1 + len + 1 + len + 1 + 2 + 1];
sprintf(library_name, "./plugins/%s/%s.so", name, name);
void *handle = dlmopen(LM_ID_BASE, library_name, RTLD_NOW | RTLD_GLOBAL);
if (! handle) {
printf("%s\n", dlerror());
exit(EXIT_FAILURE);
}
return plugin_handle;
char *namebuf = malloc(len + 1);
strcpy(namebuf, name);
*next = malloc(sizeof(struct plugin_list));
**next = (struct plugin_list) {
.name = namebuf,
.handle = handle,
.next = NULL,
};
next = &(*next)->next;
printf("Loaded %s\n", name);
return handle;
}
int main()
@ -30,11 +73,9 @@ int main()
struct dirent *dp;
while (dp = readdir(dir)) {
if (dp->d_name[0] != '.' && strcmp(dp->d_name, "game") != 0) {
while (dp = readdir(dir))
if (dp->d_name[0] != '.')
load_plugin(dp->d_name);
}
}
closedir(dir);

View File

@ -0,0 +1 @@
game

View File

@ -0,0 +1 @@
game

View File

@ -0,0 +1 @@
game

View File

@ -0,0 +1 @@
game