Access Notification


Introduction
All API's provide some mechanism of allowing 3rd party plugins to be notified when they need to do something or when a particular internal event of interest has occured. In messiah we refer to this as Access Notifications (AN), because you are gaining access to notification of things that happen inside of messiah. Groups of related AN's are called Access Levels (AL). In many cases you can think of AN's as notification of an event, such as the time changing. In other cases the AN could be telling you that you need to perform some action, like loading your module's data from an object. In either case, think of AN's as gaining access to very specific parts of messiah's internals.
The Access Levels are as follows:
Note:
There are too many Access Notifications to list above, each is documented in messiah_access.h
Requesting Access Notification Messages
Use the fxModuleAccess() API function, found in the MODULE Component, to request specific AN messages. For example to request the P_POST_MOTION() and P_POST_POINT_DISPLACE() AN messages, you would use the following call:

fxModuleAccess( ACCESS_PROCESS, P_POST_MOTION|P_POST_POINT_DISPLACE, FX_NO );
Because you request AN messages for your Module prior to it's registration, you need to do so in your plugin's messiahEntry() function.
Who Get's What?
You'll notice in the above example that fxModuleAccess() does not take an FXmodule as an argument. So what happens if you have several Modules in your plugin? When you make a call to fxModuleAccess() you are requesting that AN messages be sent to the message handler of the next Module to be registered. Therefore the process is to request all desired AN messages, then register the Module. Repeat this process for each remaining Module:

// Register first module, requesting only P_POST_MOTION AN messages
fxModuleAccess( ACCESS_PROCESS, P_POST_MOTION, FX_NO );
fxModuleRegister(...);
//...
// Register second module, requesting both P_POST_MOTION and O_CREATE AN messages
fxModuleAccess( ACCESS_PROCESS, P_POST_MOTION, FX_NO );
fxModuleAccess( ACCESS_OBJECT, O_CREATE, FX_NO );
fxModuleRegister(...);
Note:
You cannot request AN messages for all module types, namely messiah functions and messiah commands do not respond to Access Notification.
Responding to Access Notifications
Part of the Module registration process is passing messiah the address of a callback that will act as your AN message handler. You should use the FX_ACCESSFUNC() macro to declare/define your Callback like so:

FX_ACCESSFUNC(MyAccessFunc);
//...
FX_ACCESSFUNC(MyAccessFunc)
{
        //...
        return ENTRY_OK;
}
Note:
We will refer to functions defined using FX_ACCESSFUNC() as access_func()'s, though you may name them anything you like.
You pass the address of your access_func() to fxModuleRegister() in your messiahEntry() function, for example:

fxModuleRegister( FX_MODTYPE_EFFECT, "MyEffectModule", &MyAccessFunc, FX_NOFLAG );
Your access_func() will then respond to each AN message passed to it. You will determine which AN message is being sent to your access_func() by both it's AL and AN. The reson for this is that each AN identifier is really only (at the time of writing) a 64 bit integer, meaning that there are only 64 possible values it can have. Sixty four values is not enough to cover all of the messages that messiah will send to plugins, therefore we use the combination of the AL and AN to uniquely identify a specific AN message. The AL is passed in as level and the AN is passed in as entry. You can use a nested switch statement to filter each AN message like so:

// user defined access_func()
FX_ACCESSFUNC(MyAccessFunc)
// FXint f(FX_AccessInfo *ai, FXentity ID, FXint level, FXint64 entry)
{
        switch( level )
        {
                // All O_* Access Notifications
                case ACCESS_OBJECT:
                        switch( entry )
                        {
                                case O_CREATE:
                                // respond to O_CREATE
                                break;
                                case O_DESTROY:
                                // respond to O_DESTROY
                                break;
                        }
                break;
                // All P_* Access Notifications
                case ACCESS_PROCESS:
                        switch( entry )
                        {
                                //...
                        }
                break;
                //...
        }
        return ENTRY_OK;
}
If you find that your access_func() is getting too large to deal with, the API provides another Callback Signature Macro called FX_ENTRYFUNC()
Note:
We will refer to functions defined with FX_ENTRYFUNC() as entry_func()'s, though you may call them anything you like.
In this case you don't actually register a Callback, you simply call these functions from your access_func(). The idea is that you create one entry_func() for each AL, then in your access_func() you would just pass all messages for a given AL to the appropriate entry_func(). The example below creates an entry_func() for both the ACCESS_OBJECT and ACCESS_PROCESS AL called MyObjectAccess and MyProcessAccess respectively. All messages matching those AL's recieved by the access_func() (MyAccessFunc) are passed to MyObjectAccess or MyProcessAccess.

// user defined entry_func()
FX_ENTRYFUNC(MyObjectAccess)
// FXint f(FX_AccessInfo *ai, FXentity ID, FXint64 entry)
{
        switch( entry )
        {
                case O_CREATE:
                //...
                break;
                case O_DESTROY:
                //...
                break;
                //...
        }
        return ENTRY_OK;
}

// another user defined entry_func()
FX_ENTRYFUNC(MyProcessAccess)
{
        //...
}

// user defined access_func()
FX_ACCESSFUNC(MyAccessFunc)
// FXint f(FX_AccessInfo *ai, FXentity ID, FXint level, FXint64 entry)
{
        switch( level )
        {
                case ACCESS_OBJECT:
                        return MyObjectAccess( ai, ID, entry );

                case ACCESS_PROCESS:
                        return MyProcessAccess( ai, ID, entry );
                
                //...
        }
        return ENTRY_OK;
}


© 2003 pmG WorldWide, LLC.


www.projectmessiah.com

groups.yahoo.com/pmGmessiah

Last Updated on Thu Jul 10 04:49:36 2003