Difference between revisions of "Plugin architecture Low-level Architecture"

From Second Life Wiki
Jump to navigation Jump to search
Line 20: Line 20:
PLUGIN_HOOK executes each function in turn; if it function returns FALSE, it just issues a 'return' in the context of the hooked function.  If all hooks return TRUE, control will eventually be passed to the hooked function.
PLUGIN_HOOK executes each function in turn; if it function returns FALSE, it just issues a 'return' in the context of the hooked function.  If all hooks return TRUE, control will eventually be passed to the hooked function.


[[hook example code]]
== Calls from plugin to viewer (exposing an API) ==
== Calls from plugin to viewer (exposing an API) ==
Most plugins will want to call into the client and have it do things like display dialog boxes, send IMs, etc.  Unfortunately, there's no simple way to do this.
Ideally, most interesting functions in the viewer would be broken out into dylibs / dlls so that plugins could link against them.  This probably isn't practical.
The alternate solution is to pick a number of useful functions, build a function pointer table, and allow plugins to ask for them by name.
[[function pointer example code]]

Revision as of 20:11, 12 February 2007

The three technical challenges for creating a plugin architecture are as follows:

Code loading

Dynamic loading of natively-compiled executable code can be accomplished with dlopen / dlsym in Linux and MacOSX and LoadLibrary on Win32.

dlopen code example

Calls from viewer to plugin (hooks)

In order to override or enhance existing functionality in the viewer, we need to be able to replace some code with our own. One way to do this would be to install "hooks" into commonly-used functions. In the example implementation code below, you can hook any function by adding 'PLUGIN_HOOK("function_name", data1, data2)' to the top of the function.

When that macro is called, it looks to see if any hooks have been registered with a name that matches "function_name". If so, it executes each one in turn.

Each hook function can affect program execution in one of three ways:

  • Pass event through -- a function might decide to ignore this hook based on the contents of data1 and data2, or it might do something which doesn't disrupt the program flow (such as adding data to an internal list for later use, or displaying a dialog box). In this case, it should just return TRUE.
  • Modify params, pass event through -- as above, except the hook function can modify the contents of data1 and/or data2 before returning TRUE
  • Swallow event: Sometimes, we want to completely override the function being hooked, for various reasons -- in this case, the plugin should return FALSE.

PLUGIN_HOOK executes each function in turn; if it function returns FALSE, it just issues a 'return' in the context of the hooked function. If all hooks return TRUE, control will eventually be passed to the hooked function.

hook example code

Calls from plugin to viewer (exposing an API)

Most plugins will want to call into the client and have it do things like display dialog boxes, send IMs, etc. Unfortunately, there's no simple way to do this.

Ideally, most interesting functions in the viewer would be broken out into dylibs / dlls so that plugins could link against them. This probably isn't practical.

The alternate solution is to pick a number of useful functions, build a function pointer table, and allow plugins to ask for them by name.

function pointer example code