FmModule

FmModule — Simple external modules handler.

Functions

Description

include : libfm/fm.h

This implementation allows applications to use external modules and select which ones application wants to use (from none to all).

The naming scheme in examples below is strict. Replace "dummy" part in them with your real name when you trying to use those examples. Those strict example names are:

  • FM_MODULE_dummy_VERSION

  • fm_module_init_dummy

  • fm_module_callback_dummy

  • fm_module_register_dummy

To use modules application should make few things. Let say, there is some FmDummyWidget which wants to use "dummy" type of modules. First thing application should do is create a header file which all modules of that type should include:

Example 1. Sample of fm-dummy.h

1
2
3
4
5
6
7
8
9
#include <libfm/fm.h>

#define FM_MODULE_dummy_VERSION 1

typedef struct _FmDummyInit {
    int (*get_new)(const char *name);
} FmDummyInit;

extern FmDummyInit fm_module_init_dummy;

The FM_MODULE_dummy_VERSION is a number which should be increased each time something in FmDummyInit structure is changed. The FmDummyInit represents an interface to module. It is specific for said module type. The fm_module_init_dummy usage see below.

Second thing application should do is to create implementation of the module handling in your code:

Example 2. Sample of fm-dummy-widget.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "fm-dummy.h"

FM_MODULE_DEFINE_TYPE(dummy, FmDummyInit, 1)

static gboolean fm_module_callback_dummy(const char *name, gpointer init, int ver)
{
    /&ast; add module callbacks into own data list &ast;/
    .......
}

.......
{
    FmDummyInit *module;
    int result = -1;

    CHECK_MODULES();
    module = _find_module("test");
    if (module)
        result = module->get_new("test sample");
    return result;
}

Third thing application should do is to register module type on the application start, the same way as application calls fm_init() on the start:

1
fm_module_register_dummy();

On application terminate it is adviced to unregister module type by calling API fm_module_unregister_type() the same way as application calls fm_finalize() on exit:

1
fm_module_unregister_type("dummy");

The module itself will be easy to make. All you should do is to use FM_DEFINE_MODULE() macro and implement callbacks for the module interface (see the fm-dummy.h header example above):

Example 3. Sample of module dummy/test

1
2
3
4
5
6
7
8
9
10
11
12
#include "fm-dummy.h"

FM_DEFINE_MODULE(dummy, test)

static int fm_dummy_test_get_new(const char *name)
{
    /&ast; implementation &ast;/
}

FmDummyInit fm_module_init_dummy = {
    fm_dummy_test_get_new;
};

The fm_module_init_dummy should be exactly the same structure that is defined in the header file above.

Note that modules are scanned and loaded only once per application run for simplicity and reliability reasons (in fact, deletion of a module that have some code running in another thread may lead to some unpredictable problems). Therefore if you have any module changed you have to restart the application before it see your change.

Functions

CHECK_MODULES()

#define CHECK_MODULES(...) if(G_UNLIKELY(!fm_modules_loaded)) fm_modules_load()

FM_DEFINE_MODULE()

#define             FM_DEFINE_MODULE(_type_, _name_)

Macro used in module definition. Module should have module specific structure: if type is vfs then it should be fm_module_init_vfs. See specific header file for some `extern' definition.

Parameters

_type_

type of module (e.g. `vfs')

 

_name_

module type specific key (e.g. `menu')

 

FM_MODULE_DEFINE_TYPE()

#define             FM_MODULE_DEFINE_TYPE(_type_, _struct_, _minver_)

Macro used in module caller. Callback is ran when matched module is found, it should return TRUE on success.

Parameters

_type_

type of module (e.g. `vfs')

 

_struct_

type of struct with module callbacks

 

_minver_

minimum version supported

 

FmModuleInitCallback ()

gboolean
(*FmModuleInitCallback) (const char *key,
                         gpointer init_data,
                         int version);

This API is used to make callback from the modules loader to the implementation which uses module so the implementation may do required checks and add module to own list of supported data. This callback will be done in default main context.

Parameters

key

the module name as key value for the type

 

init_data

module type specific initialization data

 

version

version of loaded module

 

Returns

TRUE if module was accepted by implementation.

Since: 1.2.0


fm_module_is_in_use ()

gboolean
fm_module_is_in_use (const char *type,
                     const char *name);

Checks if specified module is found and successfully loaded.

Parameters

type

module type

 

name

module key.

[allow-none]

Returns

TRUE if module is in use.

Since: 1.2.0


fm_module_register_type ()

void
fm_module_register_type (const char *type,
                         int minver,
                         int maxver,
                         FmModuleInitCallback cb);

Registers type into the modules loader. The modules loader will call cb routine when module that supports the type was found within the libfm modules directory. The scanning for modules will be done after some timeout after last call to fm_module_register_type() so this API should be used at application start before any possible modules usage may appear.

Parameters

type

module type, unique for the application

 

minver

minimum supported module version

 

maxver

maximum supported module version

 

cb

the callback used to inform about found module

 

Since: 1.2.0


fm_module_unregister_type ()

void
fm_module_unregister_type (const char *type);

Frees any resources that were allocated previously on the call to fm_module_register_type() API, including code of the modules. After this call any usage of data from callbacks will be invalid and the most possibly lead to crash so it might be called only on finalizing the application data.

Parameters

type

module type, unique for the application

 

Since: 1.2.0


fm_modules_add_directory ()

gboolean
fm_modules_add_directory (const char *path);

Adds an application-specific directory path to be used later for scanning for modules. The path should be absolute UNIX path.

Parameters

path

absolute path to modules directory

 

Returns

TRUE if path was added successfully.

Since: 1.2.0


fm_modules_load ()

void
fm_modules_load (void);

Forces scanning the libfm modules for existing modules. Any calls to fm_module_register_type() after this will have no effect.

Since: 1.2.0