Hustler Add-On API Documentation

Introduction
This document describes how to write add-ons for version 1 of the Hustler add-on API. Fortunately, writing Hustler add-ons is pretty easy. You have to implement two simple classes, derived from HustlerAddOn and HustlerPlayer, and one global function, called InstantiateAddOn.

You may want to take a quick peek at the HustlerAddOn.h and HustlerPlayer.h header files before you continue. After reading this document you may also want to look at the source code of the add-ons that come with the distribution.

Remember that all add-ons must be installed in the "/boot/home/config/add-ons/Hustler/" folder. Whenever you copy an add-on to this directory, Hustler will automatically load it, so there is no need to restart Hustler or the Deskbar.

The InstantiateAddOn function
After loading your add-on, Hustler first calls the InstantiateAddOn function, which should create and return an instance of the class that you derived from HustlerAddOn. From then on, Hustler will use this object to interact with the add-on.

For example:

    HustlerAddOn* 
    InstantiateHustlerAddOn()
    {
        return new MyAddOn();
    }

The HustlerAddOn.h header file already exports the InstantiateAddOn function for you, so you don't have to worry about that.

The HustlerAddOn class
You need to create a class that implements the GetInfo(), GetPlayerName(), and GetPlayer() methods from the abstract HustlerAddOn class. You don't need to override the GetVersion() method, because it is already implemented in HustlerAddOn.h, where it always returns 1.

The GetInfo() method must return a string with information about this add-on; what it does, which version it is, who wrote it, and so on. This information will be displayed inside Hustler's about box.

Creating players
Add-ons can create one or more players. The CDDA add-on, for example, scans the "/dev" directory hierarchy for installed CD players, and creates a CddaPlayer object (which derives from HustlerPlayer) for each CD player it finds.

Players are identified by their names. This means that no two players may have the same name, not even if they are created by different add-ons.

Each time the user clicks a mouse button on Hustler's view, Hustler calls the GetPlayerName() methods of all loaded add-ons to ask for the names of the players that they can create. This method is called repeatedly with an ever increasing index until it returns NAME_NO_MORE_NAMES. For valid indexes, GetPlayerName() will normally return NAME_OK, but if a player is (temporarily) not available (for whatever reason), it must return NAME_NOT_AVAILABLE instead, so Hustler can disable its entry in the Player menu.

For example:

    int32
    MyAddOn::GetPlayerName(int32 index, char* &name)
    {
        if (index < number of possible players)
        {
            name = name of player at index;
            if (player is available)
            {
                return NAME_OK;
            }
            else
            {
                return NAME_NOT_AVAILABLE;
            }
        }
        return NAME_NO_MORE_NAMES;
    }

Then, when the user selects a new player from the Player menu, Hustler calls the GetPlayer() method of that player's add-on. After determining that the name it was given is (still) valid, this method should create the corresponding player object and return it.

For example:

    HustlerPlayer* 
    MyAddOn::GetPlayer(const char* name)
    {
        for (all possible players)
        {
            if (name is found)
            {
                return new MyPlayer(name);
            }
        }
        return 0;
    }

The HustlerPlayer class
The HustlerPlayer class is larger than HustlerAddOn, but very straightforward nonetheless. It contains several methods that perform actions, such as Play() and Pause(), and a set of corresponding functions that determine whether these actions can actually be performed, such as CanPlay() and CanPause(). (For example, if the player is paused, CanPause() should return false, because the player is already in that state.)

You will find elaborate descriptions for these methods in their header files, but two are worth mentioning here: GetState() and GetPlaylist().

The GetState() method should return the current state of the player. Hustler can deal with four different states: STATE_NO_TRACKS, STATE_PLAYING, STATE_PAUSED, and STATE_STOPPED. The last three are too obvious to mention; STATE_NO_TRACKS means that no tracks are available (for example because no audio CD has been loaded).

GetPlaylist() returns a pointer to a BList object that stores pointers to the names of the tracks. I suggest that you check out the Support Kit chapter of the Be Book for more information on BList.

The end
Well, that's it. Have fun writing those add-ons! If you have any questions you can always email me.