srv-msg-router.h

Go to the documentation of this file.
00001 /*
00002  * srv-msg-router.h
00003  *
00004  * Copyright (C) 2008  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Message router for the aesop server.  Manages connection/user state to
00032  * determine what messages are allowed, and provides handlers.
00033  */
00034 
00035 #ifndef AESOP_SRV_MESSAGE_ROUTER_H__
00036 #define AESOP_SRV_MESSAGE_ROUTER_H__
00037 
00038 // includes --------------------------------------------------------------------
00039 #include "aesop-proto/message.h"
00040 #include "story/story.h"
00041 
00042 
00043 namespace aesop {
00044 
00045 /// \ingroup aesop_srv
00046 /*@{*/
00047 
00048 
00049 typedef netlib::conn_id_t conn_id_t;
00050 typedef netlib::envelope_t envelope_t;
00051 typedef netlib::MessageBuffer MessageBuffer;
00052 
00053 
00054 /// state update callback interface
00055 /// \n
00056 /// \b WARNING: all of these interfaces must be threadsafe!
00057 ///
00058 /// All APIs have "TS" appended as a reminder...
00059 ///
00060 /// \n
00061 /// \b TODO: this interface should probably move to \ref aesop_interface.
00062 class StateUpdates {
00063 public:
00064         // aesop::StateUpdates class interface methods -------------------------
00065         virtual void newTcpConnectionTS(IN conn_id_t tcp_connId,
00066                                 IN long token) = 0;
00067         virtual void enqueueMessageTS(IN conn_id_t tcp_connId,
00068                                 IN smart_ptr<MessageBuffer>& msg) = 0;
00069         virtual void notifyDialogReplyTS(IN conn_id_t tcp_conn_id,
00070                                 IN const char * conversationGuid,
00071                                 IN int dialogId,
00072                                 IN int playerId,
00073                                 IN const Datahash * reply) = 0;
00074         virtual bool setPlayerUserAccountTS(IN conn_id_t tcp_conn_id,
00075                                 IN int playerId,
00076                                 IN const char * username,
00077                                 IN const char * usertag,
00078                                 OUT std::string& diagnostic) = 0;
00079         virtual void newGameTS(IN conn_id_t tcp_conn_id,
00080                                 IN int playerId) = 0;
00081         virtual void requestShutdownTS(void) = 0;
00082 
00083 protected:
00084         /// can't delete through this interface
00085         virtual ~StateUpdates(void) throw();
00086 };
00087 
00088 
00089 /// handler function and state
00090 struct handler_state_t {
00091         // constructor, manipulators
00092         handler_state_t(void) throw() { this->clear(); }
00093         void clear(void) throw() {
00094                         src_env.clear();
00095                         payload.clear();
00096                         story = NULL;           // free our reference
00097                         updates = NULL;
00098                 }
00099 
00100         // data fields
00101         envelope_t              src_env;        // source of message
00102         tcp_payload_t           payload;        // payload
00103         smart_ptr<story::Story> story;
00104         StateUpdates *          updates;        // ouch! object lifetime?
00105 };
00106 
00107 
00108 /// handler callback
00109 typedef void (*msg_handler_fn)(IN handler_state_t& state);
00110 
00111 
00112 
00113 ///     The name may be a misnomer.  Given a message, it returns the appropriate
00114 ///     handler (or not).  But you could call the determination of what to do
00115 ///     next "routing".
00116 class MessageRouter {
00117 public:
00118         // virtual destructor --------------------------------------------------
00119         virtual ~MessageRouter(void) throw() = 0;
00120 
00121         // aesop::MessageRouter class interface methods -----------------------
00122         virtual msg_handler_fn getHandler(IN const tcp_payload_t& payload) = 0;
00123 
00124         // static factory methods ----------------------------------------------
00125         static smart_ptr<MessageRouter> create(void);
00126 };
00127 
00128 
00129 
00130 };      // aesop namespace
00131 
00132 #endif  // AESOP_SRV_MESSAGE_ROUTER_H__
00133