Skip to content

Commit

Permalink
libobs: Add obs_load_all_modules2 and obs_find_modules2
Browse files Browse the repository at this point in the history
obs_find_modules2 allows the ability to get the module name in the
callback, and the change to obs_find_modules2 also adds the ability to
find out whether any modules failed to load or not.
  • Loading branch information
jp9000 committed Jul 28, 2022
1 parent a0eae6f commit 23c3ad4
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 8 deletions.
50 changes: 50 additions & 0 deletions docs/sphinx/reference-modules.rst
Expand Up @@ -246,6 +246,36 @@ plugin modules.

---------------------

.. function:: void obs_load_all_modules2(struct obs_module_failure_info *mfi)

Automatically loads all modules from module paths (convenience function).
Additionally gives you information about modules that fail to load.

:param mfi: Provides module failure information. The *failed_modules*
member is a string list via a pointer to pointers of
strings of modules that failed to load. Can be freed
either with :c:func:`obs_module_failure_info_free()` or
by simply calling :c:func:`bfree()` on the
*failed_modules* member variable.

Relevant data types used with this function:

.. code:: cpp
struct obs_module_failure_info {
char **failed_modules;
size_t count;
};
---------------------

.. function:: void obs_module_failure_info_free(struct obs_module_failure_info *mfi)

Frees data allocated data used in the *mfi* parameter (calls
:c:func:`bfree()` on the *failed_modules* member variable).

---------------------

.. function:: void obs_post_load_modules(void)

Notifies modules that all modules have been loaded.
Expand All @@ -271,6 +301,26 @@ plugin modules.
---------------------

.. function:: void obs_find_modules2(obs_find_module_callback_t callback, void *param)

Finds all modules within the search paths added by
:c:func:`obs_add_module_path()`.

Relevant data types used with this function:

.. code:: cpp
struct obs_module_info2 {
const char *bin_path;
const char *data_path;
const char *name;
};
typedef void (*obs_find_module_callback2_t)(void *param,
const struct obs_module_info2 *info);
---------------------

.. function:: void obs_enum_modules(obs_enum_module_callback_t callback, void *param)

Enumerates all loaded modules.
Expand Down
81 changes: 73 additions & 8 deletions libobs/obs-module.c
Expand Up @@ -274,27 +274,55 @@ void obs_add_module_path(const char *bin, const char *data)
da_push_back(obs->module_paths, &omp);
}

static void load_all_callback(void *param, const struct obs_module_info *info)
extern void get_plugin_info(const char *path, bool *is_obs_plugin,
bool *can_load);

struct fail_info {
struct dstr fail_modules;
size_t fail_count;
};

static void load_all_callback(void *param, const struct obs_module_info2 *info)
{
struct fail_info *fail_info = param;
obs_module_t *module;

if (!os_is_obs_plugin(info->bin_path)) {
bool is_obs_plugin;
bool can_load_obs_plugin;

get_plugin_info(info->bin_path, &is_obs_plugin, &can_load_obs_plugin);

if (!is_obs_plugin) {
blog(LOG_WARNING, "Skipping module '%s', not an OBS plugin",
info->bin_path);
return;
}

if (!can_load_obs_plugin) {
blog(LOG_WARNING, "Skipping module '%s' due to possible "
"import conflicts");
goto load_failure;
}

int code = obs_open_module(&module, info->bin_path, info->data_path);
if (code != MODULE_SUCCESS) {
blog(LOG_DEBUG, "Failed to load module file '%s': %d",
info->bin_path, code);
return;
goto load_failure;
}

if (!obs_init_module(module))
free_module(module);

UNUSED_PARAMETER(param);
return;

load_failure:
if (fail_info) {
dstr_cat(&fail_info->fail_modules, info->name);
dstr_cat(&fail_info->fail_modules, ";");
fail_info->fail_count++;
}
}

static const char *obs_load_all_modules_name = "obs_load_all_modules";
Expand All @@ -305,7 +333,7 @@ static const char *reset_win32_symbol_paths_name = "reset_win32_symbol_paths";
void obs_load_all_modules(void)
{
profile_start(obs_load_all_modules_name);
obs_find_modules(load_all_callback, NULL);
obs_find_modules2(load_all_callback, NULL);
#ifdef _WIN32
profile_start(reset_win32_symbol_paths_name);
reset_win32_symbol_paths();
Expand All @@ -314,6 +342,36 @@ void obs_load_all_modules(void)
profile_end(obs_load_all_modules_name);
}

static const char *obs_load_all_modules2_name = "obs_load_all_modules2";

void obs_load_all_modules2(struct obs_module_failure_info *mfi)
{
struct fail_info fail_info = {0};
memset(mfi, 0, sizeof(*mfi));

profile_start(obs_load_all_modules2_name);
obs_find_modules2(load_all_callback, &fail_info);
#ifdef _WIN32
profile_start(reset_win32_symbol_paths_name);
reset_win32_symbol_paths();
profile_end(reset_win32_symbol_paths_name);
#endif
profile_end(obs_load_all_modules2_name);

mfi->count = fail_info.fail_count;
mfi->failed_modules =
strlist_split(fail_info.fail_modules.array, ';', false);
dstr_free(&fail_info.fail_modules);
}

void obs_module_failure_info_free(struct obs_module_failure_info *mfi)
{
if (mfi->failed_modules) {
bfree(mfi->failed_modules);
mfi->failed_modules = NULL;
}
}

void obs_post_load_modules(void)
{
for (obs_module_t *mod = obs->first_module; !!mod; mod = mod->next)
Expand Down Expand Up @@ -388,10 +446,10 @@ static bool parse_binary_from_directory(struct dstr *parsed_bin_path,

static void process_found_module(struct obs_module_path *omp, const char *path,
bool directory,
obs_find_module_callback_t callback,
obs_find_module_callback2_t callback,
void *param)
{
struct obs_module_info info;
struct obs_module_info2 info;
struct dstr name = {0};
struct dstr parsed_bin_path = {0};
const char *file;
Expand Down Expand Up @@ -421,6 +479,7 @@ static void process_found_module(struct obs_module_path *omp, const char *path,
if (parsed_data_dir && bin_found) {
info.bin_path = parsed_bin_path.array;
info.data_path = parsed_data_dir;
info.name = name.array;
callback(param, &info);
}

Expand All @@ -430,7 +489,7 @@ static void process_found_module(struct obs_module_path *omp, const char *path,
}

static void find_modules_in_path(struct obs_module_path *omp,
obs_find_module_callback_t callback,
obs_find_module_callback2_t callback,
void *param)
{
struct dstr search_path = {0};
Expand Down Expand Up @@ -467,7 +526,7 @@ static void find_modules_in_path(struct obs_module_path *omp,
dstr_free(&search_path);
}

void obs_find_modules(obs_find_module_callback_t callback, void *param)
void obs_find_modules2(obs_find_module_callback2_t callback, void *param)
{
if (!obs)
return;
Expand All @@ -478,6 +537,12 @@ void obs_find_modules(obs_find_module_callback_t callback, void *param)
}
}

void obs_find_modules(obs_find_module_callback_t callback, void *param)
{
/* the structure is ABI compatible so we can just cast the callback */
obs_find_modules2((obs_find_module_callback2_t)callback, param);
}

void obs_enum_modules(obs_enum_module_callback_t callback, void *param)
{
struct obs_module *module;
Expand Down
21 changes: 21 additions & 0 deletions libobs/obs.h
Expand Up @@ -520,6 +520,14 @@ EXPORT void obs_add_module_path(const char *bin, const char *data);
/** Automatically loads all modules from module paths (convenience function) */
EXPORT void obs_load_all_modules(void);

struct obs_module_failure_info {
char **failed_modules;
size_t count;
};

EXPORT void obs_module_failure_info_free(struct obs_module_failure_info *mfi);
EXPORT void obs_load_all_modules2(struct obs_module_failure_info *mfi);

/** Notifies modules that all modules have been loaded. This function should
* be called after all modules have been loaded. */
EXPORT void obs_post_load_modules(void);
Expand All @@ -534,6 +542,19 @@ typedef void (*obs_find_module_callback_t)(void *param,

/** Finds all modules within the search paths added by obs_add_module_path. */
EXPORT void obs_find_modules(obs_find_module_callback_t callback, void *param);

struct obs_module_info2 {
const char *bin_path;
const char *data_path;
const char *name;
};

typedef void (*obs_find_module_callback2_t)(
void *param, const struct obs_module_info2 *info);

/** Finds all modules within the search paths added by obs_add_module_path. */
EXPORT void obs_find_modules2(obs_find_module_callback2_t callback,
void *param);
#endif

typedef void (*obs_enum_module_callback_t)(void *param, obs_module_t *module);
Expand Down

0 comments on commit 23c3ad4

Please sign in to comment.