Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
EventLogger.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_EventLogger_h_ 00003 #define INCLUDED_EventLogger_h_ 00004 00005 #include "ControlBase.h" 00006 #include "Events/EventListener.h" 00007 #include <fstream> 00008 #include <set> 00009 #include <queue> 00010 #include <stack> 00011 00012 class FilterBankGenerator; 00013 class BehaviorBase; 00014 class StateNode; 00015 00016 //! allows logging of events to the console or a file, also provides some remote logging facilities over #logSocket, required by Storyboard tool 00017 /*! Users' behaviors can call logMessage(), logImage(), and logWebcam() to insert the corresponding data into #logSocket via an XML 'event' node. 00018 * 00019 * The protocol used with #logSocket is: 00020 * - '<tt>list</tt>' - send list of all instantiated StateNodes 00021 * - '<tt>spider </tt><i>name</i>' - spider the current structure of StateNode named <i>name</i> 00022 * - '<tt>listen </tt><i>name</i>' - send updates regarding the activation status of <i>name</i> and its subnodes; you can specify a state which is not yet running 00023 * - '<tt>ignore </tt><i>name</i>' - cancels a previous listen command 00024 * - '<tt>clear</tt>' - cancels all previous listen commands; should be called at the beginning or end of each connection, preferably both 00025 * 00026 * Each of those commands should be terminated with a newline - 00027 * i.e. one command per line 00028 * 00029 * After a <tt>list</tt> command, the first line will be the number 00030 * of StateNodes, followed by that number of lines, one StateNode 00031 * name per line. 00032 * 00033 * After a <tt>spider</tt> command, an XML description of the model 00034 * will be sent. If no matching StateNode is found, an warning will 00035 * be displayed on #serr, and an empty model 00036 * ("<model></model>") returned over the network 00037 * connection. 00038 * 00039 * All other commands give no direct response - listen can be 00040 * executed before the specified StateNode is yet running, and ignore 00041 * doesn't care whether or not the specified StateNode was actually 00042 * being listened for. 00043 * 00044 * The format of the model is: 00045 @verbatim 00046 <!DOCTYPE model [ 00047 <!ELEMENT model (state*, transition*)> 00048 <!ELEMENT state (state*, transition*)> 00049 <!ELEMENT transition (source+, dest+)> 00050 <!ELEMENT source (#PCDATA)> 00051 <!ELEMENT dest (#PCDATA)> 00052 00053 <!ATTLIST state id CDATA #REQUIRED> 00054 <!ATTLIST state class CDATA #REQUIRED> 00055 <!ATTLIST transition id CDATA #REQUIRED> 00056 <!ATTLIST transition class CDATA #REQUIRED> 00057 ]>@endverbatim 00058 * 00059 * The format of status updates following a listen command is: 00060 @verbatim 00061 <!DOCTYPE event [ 00062 <!ELEMENT event (fire*, statestart*, statestop*)> 00063 <!ELEMENT fire (EMPTY)> 00064 <!ELEMENT statestart (EMPTY)> 00065 <!ELEMENT statestop (EMPTY)> 00066 00067 <!ATTLIST fire id CDATA #REQUIRED> 00068 <!ATTLIST fire time CDATA #REQUIRED> 00069 <!ATTLIST statestart id CDATA #REQUIRED> 00070 <!ATTLIST statestart time CDATA #REQUIRED> 00071 <!ATTLIST statestop id CDATA #REQUIRED> 00072 <!ATTLIST statestop time CDATA #REQUIRED> 00073 ]>@endverbatim 00074 * 00075 * The 'event' node is also used for the results of logImage(), logMessage(), and logWebcam(). 00076 */ 00077 class EventLogger : public ControlBase, public EventListener { 00078 public: 00079 //!constructor 00080 EventLogger(); 00081 //!destructor 00082 virtual ~EventLogger(); 00083 00084 //!opens a custom (embedded) menu to toggle individual EGIDs 00085 virtual ControlBase* doSelect(); 00086 00087 virtual void refresh(); 00088 00089 //!sends all events received to stdout and/or logfile 00090 virtual void processEvent(const EventBase& event); 00091 00092 //!returns #logSocket 00093 static class Socket* getLogSocket() { return logSocket; } 00094 00095 //! returns #port 00096 static int getLogSocketPort() { return port; } 00097 00098 //! sets #port 00099 static void setLogSocketPort(int p) { port=p; } 00100 00101 //! send the current camera image over the log socket 00102 static void logImage(FilterBankGenerator& fbg, unsigned int layer, unsigned int channel, const BehaviorBase* source=NULL); 00103 00104 //! send a string over the log socket 00105 static void logMessage(std::string msg, const BehaviorBase* source=NULL, const char* icon=NULL, unsigned int placement=0); 00106 00107 //! request that the desktop side take a picture with the webcam (if available) 00108 static void logWebcam(const BehaviorBase* source=NULL); 00109 00110 static int callback(char *buf, int bytes); //!< called by wireless when there's new data 00111 00112 protected: 00113 static EventLogger * theOne; //!< the instance which will handle network communication 00114 00115 //! a separate processEvent to distinguish between events requested for logging and events requested by a remote monitor 00116 class StateMachineListener : public EventListener { 00117 //! forwards any events received to EventLogger::theOne's EventLogger::processStateMachineEvent() 00118 /*! EventLogger::runCommand() is responsible for maintaining which events this is listening to */ 00119 virtual void processEvent(const EventBase& event) { 00120 EventLogger::theOne->processStateMachineEvent(event); 00121 } 00122 }; 00123 static class StateMachineListener smProcess; //!< handles state machine transitions if the Storyboard GUI (or other remote monitor) is listening for state machine events 00124 00125 virtual void clearSlots(); 00126 00127 //!sets the status char of slot @a i to @a c 00128 void setStatus(unsigned int i, char c); 00129 00130 //!checks to see if logfilePath differs from the StringInputControl's value and switches it if it is 00131 void checkLogFile(); 00132 00133 //! dumps all of the transitions and subnodes of a given statenode 00134 /*! if parent is NULL, will dump the results over #logSocket, otherwise adds the xml tree as a child of @a parent */ 00135 void spider(const StateNode* n, xmlNode* parent=NULL); 00136 00137 //! returns true iff @a n or one of its parents is found in #listen 00138 bool isListening(const StateNode* n); 00139 00140 //! parses commands sent from callback() 00141 void runCommand(const std::string& s); 00142 00143 //!just to prettify the data sent out - probably should make this a null-op to save bandwidth after debugging is done 00144 void indent(unsigned int level); 00145 00146 //!searches currently instantiated StateNodes to find the one named @a name 00147 const StateNode * find(const std::string& name); 00148 00149 //!if there is a remote monitor listening for state machine transitions, this will send them over 00150 /*!this is called by the StateMachineListener, which is subscribed to only 00151 * those machines which have been requested by the remote monitor */ 00152 virtual void processStateMachineEvent(const EventBase& event); 00153 00154 //! dumps elements of #queuedEvents over #logSocket, popping and freeing as it goes 00155 static void dumpQueuedEvents(); 00156 00157 //! writes an xmlNode out over #logSocket, freeing @a node when complete 00158 /*! uses @a doc if provided, otherwise makes a new temporary one which is then deleted again before the function returns */ 00159 static void dumpNode(xmlNode* node, xmlDoc* doc=NULL); 00160 00161 //!address of the logfile, if any (empty string is no logfile) 00162 std::string logfilePath; 00163 00164 //!if a filename is given, events are logged to here 00165 std::ofstream logfile; 00166 00167 //! events which are logged will be sent over this port in an xml format. See eventlog.dtd in the docs directory 00168 static class Socket* logSocket; 00169 00170 //! port number #logSocket will listen on 00171 static int port; 00172 00173 //! reference count for #logSocket -- when this hits 0, close the socket 00174 static unsigned int logSocketRefCount; 00175 00176 //!controls the level of verbosity - currently 0 through 2 00177 unsigned int verbosity; 00178 00179 typedef std::set<BehaviorBase*> registry_t; //!< the type of the behavior registry (BehaviorBase::registry) 00180 00181 typedef std::set<std::string> listen_t; //!< the type of #listen 00182 listen_t listen; //!< a set of state machine names which should have their subnodes monitored 00183 00184 typedef std::queue<xmlNode*> queuedEvents_t; //!< the type of #queuedEvents 00185 static queuedEvents_t queuedEvents; //!< if logImage/logMessage/etc. are called during a transition, need to queue them until the transition event is complete 00186 00187 typedef std::stack<xmlNode*> transStack_t; //!< the type of #transStack 00188 static transStack_t transStack; //!< if another transition occurs during the processing of another, have to recurse on processing the new transition first 00189 }; 00190 00191 /*! @file 00192 * @brief Describes EventLogger, which allows logging of events to the console or a file 00193 * @author ejt (Creator) 00194 * 00195 * $Author: ejt $ 00196 * $Name: tekkotsu-4_0 $ 00197 * $Revision: 1.10 $ 00198 * $State: Exp $ 00199 * $Date: 2007/03/02 17:20:48 $ 00200 */ 00201 00202 #endif |
Tekkotsu v4.0 |
Generated Thu Nov 22 00:54:53 2007 by Doxygen 1.5.4 |