BZFS API 2.4 Upgrade

From BZFlagWiki
Jump to: navigation, search

Overview

For version 2.4 the BZFS_API has undergone some restructuring. This document will go over the changes a plug-in developer must make in order to update to this new release.

Compatibility

In order to gain forward compatibility the API had to be changed in a way that broke backwards compatibility. This means that all plug-ins written for 2.0.x will not load in version 2.3.4 or later.

API Version Numbers

In the past the API version number represented the newest version of the API that the plug-in would run under. This caused plug-ins to have to be recompiled every time the API version changed.

In the new API the version number represents the minimum version required. This will ensure that plug-ins can be loaded in future versions. This also prevents plug-ins from running in versions older then they were written for. Due to the uni-directional nature of software upgrades this is a more useful feature.

Spelling Changes

Spelling errors and grammatical inconsistencies in the API have been fixed.

BZ string and list classes

The bzApiString and other associated basic types have been renamed to bz_ApiString to be more consistent with the rest of the API.

Player Records

The bz_PlayerRecord has been replaced with bz_BasePlayerRecord to allow for future derivation. Some of its members have been changed, mostly notably the player position information is now part of the lastKnownState member of type bz_PlayerUpdateState. This structure contains much more information about the player state.

Entry Points

The main entry points for the API have changed. The following entry points are no longer used.

BZF_PLUGIN_CALL int bz_Load ( const char* command );
BZF_PLUGIN_CALL int bz_Unload ( void );
BZF_PLUGIN_CALL int bz_GetVersion ( void );

The entry points are replaced with the following new items.

BZF_PLUGIN_CALL bz_Plugin*bz_getPlugin ( void );
BZF_PLUGIN_CALL void bz_freePlugin ( bz_Plugin*);
BZF_PLUGIN_CALL int bz_GetMinVersion ( void );

bz_GetMinVersion is called first to get the minimum API version. If the current BZFS supports this verison then the plug-in will be loaded and bz_getPlugin will be called. This function returns the Plug-in Class that BZFS will use to interact with the plug-in. When a plug-in is unloaded the function bz_freePlugin will be called.

A set of macros are provided in the bzAPI.h Header to simplify the calls for a plug-in.

The plugin can simply call the BZ_PLUGIN(n) macro and provide a classname that is derived from bz_Plugin. This will create and free a plug-in class automatically and return the version of the API that the plug-in was compiled with.

Plug-in Class

The plug-in class is defined by the base class bz_Plugin. It contains 2 methods that each plug-in must implement in a derived class,

 virtual const char* Name () = 0;
 virtual void Init(const char* config) = 0;

Name returns the human readable name for the plug-in as a null terminated ASCII string.

Init is called by BZFS after the plug-in is loaded and serves the same function as the bz_Load entry point in previous versions.

The derived class may also optionally provide versions of these additional methods

virtual void Cleanup() {Flush();}
virtual void Event(bz_EventData* /*eventData*/) { return; }

Cleanup is called when a plug-in is unloaded and replaces the [bz_Unload]] function in previous versions. By default Cleanup will automatically remove any events that the plug-in has registered.

Event is called whenever BZFS executes an event that the plug-in has requested to be informed of. This function replaces the bz_EventHandler class in older versions.

Events

Every plug-in now has a single callback method for all events that it registers. The functions bz_registerEvent and bz_removeEvent have been removed from the API. In their place the bz_Plugin class now implements its own Register and Remove methods.

These methods only take an event type and do not need a separate handler class, they will always use the Event method of the calling class.

A new method, Flush is provided to remove all events that the plug-in has registered. This method is automatically called by the default Cleanup method.

Event Data Classes

In addtion to the new Event handler system, all the event data classes have been changed. Each event data class is now versioned with a number in the class name, such as bz_PlayerSpawnEventData_V1. These event classes will never change and new versions will be derived from them with a higher version number. This allows a plug-in to always get the data it knows about, even as the BZAPI is enhanced to include more data for each event.

The base class for the Event Data Classes has also changed. bz_EventData now includes a timestamp for when the event was triggered in the eventTime data member.

Class Changes

Many of the events that returned some player data now simply return a bz_BasePlayerRecord. This player record will be automaticly freed when the event finishes and the plug-in does not have to call bz_freePlayerRecord on the pointer.

The events affected are

Callbacks

In order to reduce the number of callback classes that had name conflicts, call callback classes that used the handle method have had there methods renamed to be descriptive of the callback type. This is in order to make the use of multiple inheritance for callbacks simpler.

Idle Time

The function bz_setMaxWaitTime has been removed from the API. bz_Plugin contains a MaxWaitTime data member that can be set by each plug-in individually. BZFS will use the smallest time required by any plug-in. Setting the value to a negative number will indicate that the plug-in has no specific idle time needs.

Inter Plug-in Communication

bz_pluginExists and bz_getPlugin are provided to allow plug-ins to transfer data between themselves. the bz_Plugin class contains the GeneralCallback that can be used to call functions from one plug-in to the other.

Upgrade

Developers should take the following general steps to upgrade a plug-in from 2.0.x to 2.3/2.4; Individual results may vary depending on how different the plug-in is from the sample template.

  • Open the '.def file for the plug-in and replace the exported functions with the following
bz_GetPlugin
bz_FreePlugin
bz_GetMinVersion
  • Open the main file for the plug-in and remove the call to BZ_GET_PLUGIN_VERSION
  • Find the main event handler class and derive it from bz_Plugin instead of bz_EventHandler. If there is more then one event handler class, pick one to be the main class and delete the other classes.
  • Change the process method in your event handler to Event, the calling parameters are identical.
  • Add the following methods to your plug-in class
 virtual const char* Name (){return "NAME";}
 virtual void Init ( const char* config);
  • Replace the word NAME with the human readable name for your plug-in. This name will appear when a user types /listplugins while in the game.
  • Remove any global instances of your Plug-in object and replace it with a call to the BZ_PLUGIN(n) macro. There is no need to instantiate the object, the macro will do it for you.
  • Change the handle method in any bz_CustomSlashCommandHandler to SlashCommand
  • Change the handle method in any bz_CustomMapObjectInfo to MapObject
  • Find the bz_Load callback and replace it with the Init method from the plug-in class.
  • Replace calls to bz_registerEvent with calls to Register, and remove the second parameter.
  • If the plug-in used custom slash commands or custom map objects that need to be cleaned up then implement the Cleanup method for the plug-in class and replace the bz_Unload Callback with it. Calls to bz_removeEvent can be removed, and the method Flush can be called once for all events. If the plug-in only registers events then the bz_Unload callback can be removed.
  • Replace the following.
# bzApiString with bz_ApiString
# bzAPIIntList with bz_APIIntList
# bzAPIFloatList with bz_APIFloatList
# bzAPIStringList with bz_APIStringList
# bz_PlayerRecord with bz_BasePlayerRecord
  • Add _V1 to all event data classes, and adjust calls to members as needed, time to eventTime, etc...
  • If you had multiple event handler classes, have your main plug-in's Event method check the event type and call the required code.
  • Compile the plug-in and see what has been missed.

Assistance

If you require help with the upgrade please feel free to join the BZFlag developers on the development IRC channel. JeffM and Thumper will be more then willing to assist you in the upgrade.

Samples

All of the plug-ins in the source code distribution have been updated to the new format and can be used as examples.