The SHSorter class defines an interface that tells a node on SockHop's virtual tree where any given BMessage should be forwarded to. While most SockHop programs won't need to implement subclasses of SHSorter (because every node comes with a handy default SHSorter object already installed), more adventurous types who wish to write their own BMessage routing algorithms can subclass SHSorter to do so.
Here are the methods that your SHSorter subclass is required to implement:
You must create a constructor for your class that can create an object
from the data contained in the passed-in BMessage. This constructor
essentially does the opposite of your Archive() method; instead of
converting an object to a BMessage, it converts a BMessage back to an object.
Make sure your constructor calls SHSorter(archive) in its initialization
list!
This static method is also used to turn BMessages back into real objects, and should be implemented like this:
This method (from the SHDistributableObject API) should be overridden to return an SHFileSpec that indicates where the add-on executable file for this class can be found:
This method (from the SHDistributableObject
API) should be overridden to supply an identifying text string for your
SHSorter object. There are no conditions imposed on what this name
is, in particular it is not required (by SockHop) to be unique in any way.
However, when SockHop gets a message with the SH_NAME_SORTER
field present, it will iterate through its list of loaded SHSorters and
use the first one it finds with the name specified. This means that
if there are two SHSorters loaded on the same node with the same name,
one of them will never be used!
This method must be overridden to store all relevant state for your SHSorter into (archive). This method helps fulfill the SHSorter's BArchivable interface, and is how your SHSorter object gets transported over the TCP streams. At a bare minimum, your Archive() method should look like this:
Whenever a node wants to know where a BMessage should be forwarded to, it asks the appropriate SHSorter object by calling this method. In fact, for each received BMessage, the node calls this method once for every child node it has, plus once for its parent node. Your SHSorters' pattern of true/false replies to this method will determine how BMessages propagate throughout the tree.
You must override this method to decide: Should the BMessage (msg) be sent to the node represented by (child)? If so, you should return true; otherwise, return false.
The (flags) argument is a bit-chord that is composed of some combination
of the following constants:
SH_FLAG_IS_PARENT | This target is the parent of the current node. |
SH_FLAG_IS_LOCAL | This target is running in the same address space as the current node. |
SH_FLAG_IS_SYMLINK | This target is not a real child, but just a symbolic link to some other node. |
Every time a BMessage is received by a node, this method is called once.
Its job is to decide if the BMessage should be given to the SHWorkers who
live on this node. If so, this method should return true; if not,
it should return false.
And there are two methods which you may override if you wish, but don't have to:
This method is called once for every BMessage that is received.
It is called after all the calls to DoesMessageGoTo() and DoesMessageDistributeLocally()
have been made, but before the BMessage has actually been forwarded to
any other nodes or been given to any SHWorkers. By default, this
method does nothing, but you can override it to do various things, such
as modify the BMessage before it gets forwarded out.
Once the sorter has determined that a BMessage should be given to the
local node (i.e., once DoesMessageDistributeLocally() has returned true),
this method will be called to determine which SHWorkers
the BMessage should be given to. This method is implemented by default
to always return true--so, unless you override this method, any user BMessage
given to this node will go to all SHWorkers
living on this node. If you do override this method, have it return
(true) if the worker with name (workerName) is to be given a copy of (msg),
false if not. Note that the SHWorker must
be interested in (msg), or it
will not be sent a copy even this method returns true!