00001 // mfc_dlog_modl_base.h: interface for the CMFCDialogModuleBase class. 00002 // 00004 00005 #if !defined(AFX_MFC_DLOG_MODL_BASE_H__5F18DF8E_C017_46E1_8328_7C2D2BBAA0C1__INCLUDED_) 00006 #define AFX_MFC_DLOG_MODL_BASE_H__5F18DF8E_C017_46E1_8328_7C2D2BBAA0C1__INCLUDED_ 00007 00008 #if _MSC_VER > 1000 00009 #pragma once 00010 #endif // _MSC_VER > 1000 00011 00012 #define _USING_EW_XPORT 1 // avoid earthworm<-->magworm conflict 00013 00014 #include "mfc_dlog_app_base.h" 00015 00016 extern "C" { 00017 #include <transport.h> 00018 } 00019 00020 // sacred definitions for message types to report to heartbeat/status ring 00021 // 00022 #define ERR_MISSMSG 0 /* message missed in transport ring */ 00023 #define ERR_TOOBIG 1 /* retreived msg too large for buffer */ 00024 #define ERR_NOTRACK 2 /* severe weirdness in the cellar */ 00025 #define ERR_QUEUE 3 /* error queueing message for sending */ 00026 00027 00028 #define SERVE_MAX_LOGOS 20 // maximum incoming logo ids 00029 00031 00032 class CMFCDialogModuleBase : public CMFCDialogAppBase 00033 { 00034 public: 00035 // ------------------------ FOR CMFCDialogAppBase --------------------- 00036 // 00037 /* 00038 ** StartWorkerThread -- The point at which worker threads reenter 00039 ** derived classes. 00040 ** The derived class should have class/instance 00041 ** variable(s) which are set (to indicate work 00042 ** to be done) prior to calling AfxBeginThread() 00043 ** and a sleep should imposed between such a 00044 ** call and any subsequent changes to the variables 00045 ** (to give the spawned thread a chance to read them). 00046 ** 00047 ** 00048 ** OVERRIDE This method in derived classes as needed. 00049 */ 00050 UINT StartWorkerThread(); 00051 00052 // ------------------------ FOR CMFCDialogModuleBase --------------------- 00053 // 00054 00055 CMFCDialogModuleBase(); 00056 00057 virtual ~CMFCDialogModuleBase(); 00058 00059 protected: 00060 00061 // ------------------------ FOR TConfigurable --------------------- 00062 // 00063 /* 00064 ** HandleConfigLine() 00065 ** 00066 ** PARMS: 00067 ** p_parser -- the parser being used, command string already 00068 ** in the current token for comparison with Its() 00069 ** 00070 ** RETURN: 00071 ** HANDLE_INVALID -- line invalid 00072 ** HANDLE_UNUSED -- line not used 00073 ** HANDLE_USED -- line used okay 00074 ** 00075 ** OVERRIDE for child classes to handle command (.d) lines 00076 ** always call <super_class>::HandleConfigLine() when overridden 00077 ** (except when super class is CMFCDialogAppBase). 00078 ** 00079 */ 00080 HANDLE_STATUS HandleConfigLine( ConfigSource * p_parser ); 00081 00082 /* CheckConfig() -- allows derivative classes to report the status of their 00083 ** the lookup values. 00084 ** 00085 ** From within any deriving class, or further derivation, ALWAYS contain a call to 00086 ** <super_class>::CheckConfig() in their own CheckConfig() method... 00087 ** this ensures that all classes in the heirarchy get their chance to report status. 00088 ** 00089 ** All implementations should set ConfigStatus value to WORM_STAT_BADSTATE if there 00090 ** is a configuration problem, otherwise leave it alone. 00091 */ 00092 void CheckConfig(); 00093 00094 // ------------------------ FOR CMFCDialogAppBase --------------------- 00095 // 00096 00097 /* 00098 ** PrepApp -- actions to be taken to prepare a specific application 00099 ** for parsing the command file. 00100 ** 00101 ** OVERRIDE in deriving classes as needed, 00102 ** MUST always call <super_class>::PrepApp() when overridden 00103 ** (Except when parent is CMFCDialogAppBase). 00104 ** 00105 ** For CMFCDialogAppBase, this: instantiates MyGlobalUtils, 00106 ** sets the logging level 00107 ** changes the working directory 00108 */ 00109 bool PrepApp(const char * p_configfilename); 00110 00111 00112 /* 00113 ** InitApp -- actions to be taken to initialize a specific application 00114 ** including the creation of the main form 00115 ** 00116 ** For CMFCDialogAppBase: starts the worker thread that loops in 00117 ** StatusAndReadLoop() to: 00118 ** 1. check for shutdown flag in command ring 00119 ** 2. call CheckForFatal() 00120 ** 3. if input ring specified, checks for message 00121 ** and passes any with accepted logo 00122 ** to HandleMessage() 00123 ** 00124 ** OVERRIDE in deriving classes as needed, 00125 ** always call <super_class>::InitApp() when overridden. 00126 ** IT IS GENERALLY APPROPRIATE TO call <super_class>::InitApp() 00127 ** at end of deriviative classe's implementation. 00128 ** 00129 */ 00130 bool InitApp(); 00131 00132 /* 00133 ** BeforeMessage -- actions before the first message is handled 00134 */ 00135 virtual bool BeforeMessage(); 00136 00137 00138 00139 // ------------------------ FOR CMFCDialogModuleBase --------------------- 00140 // 00141 00142 TGlobalUtils * MyGlobalUtils; 00143 00144 WORM_MSGTYPE_ID TYPE_ERROR 00145 , TYPE_HEARTBEAT 00146 ; 00147 00148 private: 00149 int MaxMessageLength; 00150 char * MessageBuffer; // buffer for arriving messages 00151 00152 protected: 00153 00154 // Ring to check for shutdown flags, to post heartbeats, etc. 00155 WORM_RING_NAME CommandRingName; // name of transport ring 00156 WORM_RING_ID CommandRingKey; // key to transport ring 00157 SHM_INFO CommandRegion; // Info structure for shared memory (command ring) 00158 00159 // Ring for incoming messages (may be the same as command ring) 00160 WORM_RING_NAME InputRingName; // name of transport ring 00161 WORM_RING_ID InputRingKey; // key to transport ring 00162 SHM_INFO InputRegion; // Info structure for shared memory (input ring) 00163 00164 MSG_LOGO AcceptLogo[SERVE_MAX_LOGOS]; 00165 short AcceptLogoCount; 00166 00167 /* 00168 ** HandleMessage() -- method for derivative classes to use to 00169 ** perform the actual handling of message 00170 ** as they arrive on the ring. 00171 ** 00172 ** OVERRIDE in derivative classes to as needed. 00173 */ 00174 virtual bool HandleMessage( const MSG_LOGO p_msglogo 00175 , const char * p_msg 00176 ) { return true; } 00177 00178 00179 CWinThread * StatusThread; 00180 00181 void SendStatus( WORM_MSGTYPE_ID p_type 00182 , short p_ierr = 0 00183 , const char * p_text = NULL 00184 ); 00185 00186 void HeartBeat(); 00187 00188 /* 00189 ** StatusAndReadLoop -- A worker thread enters this method to loop, looking 00190 ** for shutdown flag on the command ring, calling 00191 ** CheckForFatal() to check for fatal errors on other 00192 ** threads, and (if the input ring has been created) 00193 ** check for messages to pass to HandleMessage() 00194 */ 00195 UINT StatusAndReadLoop(); 00196 00197 00198 /* 00199 ** CheckForFatal -- check any other threads and states for fatal error 00200 ** 00201 ** RETURN: true on fatal error, false otherwise. 00202 ** 00203 ** OVERRIDE in deriving classes as needed. 00204 */ 00205 virtual bool CheckForFatal() { return false; } 00206 00207 }; 00208 00209 #endif // !defined(AFX_MFC_DLOG_MODL_BASE_H__5F18DF8E_C017_46E1_8328_7C2D2BBAA0C1__INCLUDED_)