NOTE: this documentation talks a lot about "clients" and "servers". More...
|anyone that wants to start a conversation must supply one of these. More...|
|Object that knows how to route conversation dialogs. More...|
|object that manages conversations on the server This object must be threadsafe! More...|
|The connection ID used by the Conversation library is used for validation (client can ensure that only the proper endpoint is participating in conversations) but is otherwise not used. |
|virtual int||converse::ConversationHost::getCurrentDialogIdTS (void)=0|
|The host should return the current dialog ID -- 0 to end. |
|virtual void||converse::ConversationHost::handleReplyTS (int dialogId, const Datahash *reply)=0|
|This method is called when the player has completed a given dialog and has sent the reply back to the ConversationManager. |
|virtual std::string||converse::ConversationHost::getDialogDataTS (void)=0|
|Host should return the raw dialog data for the current dialog ID (dialog data is a text string -- see Dialog Library). |
|virtual bool||converse::ConversationManager::updateConversationTS (const char *guid, conn_id_t connId, int playerId, smart_ptr< ConversationHost > host)=0|
|virtual bool||converse::ConversationManager::handleDialogReplyTS (const char *guid, int dialogId, conn_id_t connId, int playerId, const Datahash *reply)=0|
|virtual void||converse::ConversationManager::updateAll (void)=0|
|virtual bool||converse::ConversationHost::updateState (void)|
|This is called "frequently", on the order of 100 times/second, although no particular rate is guaranteed. |
|virtual||converse::ConversationRouter::~ConversationRouter (void) throw ()|
|cannot delete through this interface! |
< ConversationManager >
|converse::ConversationManager::create (ConversationRouter *router)|
|virtual||converse::ConversationHost::~ConversationHost (void) throw ()|
NOTE: this documentation talks a lot about "clients" and "servers".
That's because the original implementation was in fact designed with a particular remote client/server use case in mind. However, the concept has broadened significantly since then. At this point, the Conversation Library is a convenient way to help the user through multiple dialogs related to a particular task (signing into a remote server, configuration local hardware, etc.). The library also has a few concepts (unique IDs and central state management) that makes it easer to drive dialogs remotely, but many use cases involve the client (user-displayed dialogs) and server (conversation management) all on the same machine.
This library helps track conversations (chains of dialogs) but does not manage any rendering itself! That is up to the client.
A Conversation is a long-running communication channel between the server and a player. The concept of a Conversation exists so that client machines can be sure to keep in sync even during network or other communication drops.
Some properties of Conversations:
The fact that Conversations are between the server and human players means that the contents of conversations are always Dialogs (see Dialog Library). The server will always send dialogs to the player, and the player will always send dialog responses back to the server.
Just as Dialogs can be thought of as HTML pages (or forms), a Conversation can be thought of as a series of forms. The ConversationManager helps coordinate general state and flow of a player moving through a series of forms, and the ConversationHost object manages form handling for the specific conversation.
The fact that only the server can initiate Conversations, and maintains all Conversation state, helps minimize race conditions and makes synchronization easy. As a consequence, however, all clients should be aware that they may have stale Conversation state and should occasionally refresh (to pick up any new conversations they missed), and pay attention to return codes in case their local view of a particular conversation is out-of-date.
Clients may receive duplicate messages about a conversation, and so should de-dupe messages based on the conversation and dialog GUIDs supplied. The server's latest message should be considered authoritative if the client discovers that the server's dialog ID is different than the local dialog ID for a given conversation.
Note that conversations must have a globally unique identifier (GUID). Dialog identifiers are only unique within a particular conversation, and so dialogs just have regular IDs (no need to be globally unique). Hence the key variables conversationGuid (globally-unique conversation identifier) and dialogId (identifier for dialog that is unique within the context of a particular conversation).
A player may have multiple conversations going at once! For instance, they may be conversing with another player in one, buying items from a shop in another, and overhearing other people talking nearby in another. However, a given conversation will only have one dialog active at any one time.
There are three main objects in the Conversation data model:
Host objects are the most common objects, since any kind of conversation (player joining a game, chat, local system menus, buying from a shop) will require a dedicated host.
Hosts do not need to know how to get the dialogs passed over the network or displayed to the client. The ConversationRouter will do that. On the server, the ConversationRouter knows how to send dialog messages over the network. On the client, the ConversationRouter can get them displayed.
Although we say "Conversations are between the server and a player", conversations can also be run on the client. This is helpful to present the player with local dialogs such as system menus etc. In this case, the client often runs its own ConversationManager with a local ConversationRouter.
|virtual int converse::ConversationHost::getCurrentDialogIdTS||(||void||)||
The host should return the current dialog ID -- 0 to end.
|virtual void converse::ConversationHost::handleReplyTS||(||int||dialogId,|
|const Datahash *||reply|
This method is called when the player has completed a given dialog and has sent the reply back to the ConversationManager.
The Manager forwards the reply to the host so it can take a look at the reply and figure out the next step. After this, the host will be called on getCurrentDialogIdTS() so the conversation can continue.
|virtual std::string converse::ConversationHost::getDialogDataTS||(||void||)||
Host should return the raw dialog data for the current dialog ID (dialog data is a text string -- see Dialog Library).
This is called "frequently", on the order of 100 times/second, although no particular rate is guaranteed.
The Host should update internal state as necessary, and return true if the Host would like the client to refresh its view of the conversation. Default implementation simply returns false.
|converse::ConversationRouter::~ConversationRouter||(||void||)|| throw ()
|virtual bool converse::ConversationManager::updateConversationTS||(||const char *||guid,|
|smart_ptr< ConversationHost >||host|
|virtual bool converse::ConversationManager::handleDialogReplyTS||(||const char *||guid,|
|const Datahash *||reply|
|virtual void converse::ConversationManager::updateAll||(||void||)||
|smart_ptr< ConversationManager > converse::ConversationManager::create||(||ConversationRouter *||router||)||