diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2007-06-25 21:15:55 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2007-06-25 21:15:55 +0000 |
| commit | 3f26c19b0b7a9fa73c58189788972ea43b72f014 (patch) | |
| tree | 8f34928a267fb35becdf939d21187a526f235869 /src | |
| parent | 2b0fa89df615cb4789668014475ae64d99e773b5 (diff) | |
| download | libbu++-3f26c19b0b7a9fa73c58189788972ea43b72f014.tar.gz libbu++-3f26c19b0b7a9fa73c58189788972ea43b72f014.tar.bz2 libbu++-3f26c19b0b7a9fa73c58189788972ea43b72f014.tar.xz libbu++-3f26c19b0b7a9fa73c58189788972ea43b72f014.zip | |
I think the plugger and programchain are all up to date to work with the new
libbu++. The program chain may undergo heavy changes still, or be removed
entirely, but we need it for congo and squirrelmud, so here it is for a while
longer.
The TafWriter isn't much closer, you still only get the groups in the output.
Diffstat (limited to '')
| -rw-r--r-- | src/linkmessage.cpp (renamed from src/old/linkmessage.cpp) | 7 | ||||
| -rw-r--r-- | src/linkmessage.h | 42 | ||||
| -rw-r--r-- | src/old/linkmessage.h | 39 | ||||
| -rw-r--r-- | src/old/plugger.h | 198 | ||||
| -rw-r--r-- | src/old/programchain.cpp | 96 | ||||
| -rw-r--r-- | src/old/programchain.h | 95 | ||||
| -rw-r--r-- | src/old/programlink.h | 99 | ||||
| -rw-r--r-- | src/plugger.cpp (renamed from src/old/plugger.cpp) | 0 | ||||
| -rw-r--r-- | src/plugger.h | 196 | ||||
| -rw-r--r-- | src/programchain.cpp | 97 | ||||
| -rw-r--r-- | src/programchain.h | 98 | ||||
| -rw-r--r-- | src/programlink.cpp (renamed from src/old/programlink.cpp) | 14 | ||||
| -rw-r--r-- | src/programlink.h | 100 | ||||
| -rw-r--r-- | src/tafwriter.cpp | 25 | ||||
| -rw-r--r-- | src/tafwriter.h | 10 |
15 files changed, 576 insertions, 540 deletions
diff --git a/src/old/linkmessage.cpp b/src/linkmessage.cpp index cf3df42..abe113c 100644 --- a/src/old/linkmessage.cpp +++ b/src/linkmessage.cpp | |||
| @@ -1,12 +1,11 @@ | |||
| 1 | #include "linkmessage.h" | 1 | #include "bu/linkmessage.h" |
| 2 | #include <string.h> | ||
| 3 | 2 | ||
| 4 | LinkMessage::LinkMessage( int nNewMsg ) | 3 | Bu::LinkMessage::LinkMessage( int nNewMsg ) |
| 5 | { | 4 | { |
| 6 | nMsg = nNewMsg; | 5 | nMsg = nNewMsg; |
| 7 | } | 6 | } |
| 8 | 7 | ||
| 9 | LinkMessage::~LinkMessage() | 8 | Bu::LinkMessage::~LinkMessage() |
| 10 | { | 9 | { |
| 11 | } | 10 | } |
| 12 | 11 | ||
diff --git a/src/linkmessage.h b/src/linkmessage.h new file mode 100644 index 0000000..64b8bc2 --- /dev/null +++ b/src/linkmessage.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /**\file linkmessage.h | ||
| 2 | */ | ||
| 3 | |||
| 4 | #ifndef LINKMESSAGE_H | ||
| 5 | #define LINKMESSAGE_H | ||
| 6 | |||
| 7 | namespace Bu | ||
| 8 | { | ||
| 9 | /** | ||
| 10 | * A message to be broadcast accross ProgramLinks in a ProgramChain. Generally | ||
| 11 | * one would make a subclass of this in order to transmit more useful | ||
| 12 | * information, but sometimes it isn't necesarry. | ||
| 13 | *@author Mike Buland | ||
| 14 | */ | ||
| 15 | class LinkMessage | ||
| 16 | { | ||
| 17 | public: | ||
| 18 | /** | ||
| 19 | * Construct a blank LinkMessage. | ||
| 20 | */ | ||
| 21 | LinkMessage() {}; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Deconstruct a LinkMessage. | ||
| 25 | */ | ||
| 26 | virtual ~LinkMessage(); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Create a LinkMessage object with a specific message assosiated with it | ||
| 30 | * to start with. | ||
| 31 | *@param nNewMsg The message to use in the Message object. | ||
| 32 | */ | ||
| 33 | LinkMessage( int nNewMsg ); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * The message contained in the Message object. | ||
| 37 | */ | ||
| 38 | int nMsg; | ||
| 39 | }; | ||
| 40 | } | ||
| 41 | |||
| 42 | #endif | ||
diff --git a/src/old/linkmessage.h b/src/old/linkmessage.h deleted file mode 100644 index 6cdfb2f..0000000 --- a/src/old/linkmessage.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | /**\file linkmessage.h | ||
| 2 | */ | ||
| 3 | |||
| 4 | #ifndef LINKMESSAGE_H | ||
| 5 | #define LINKMESSAGE_H | ||
| 6 | |||
| 7 | /** | ||
| 8 | * A message to be broadcast accross ProgramLinks in a ProgramChain. Generally | ||
| 9 | * one would make a subclass of this in order to transmit more useful | ||
| 10 | * information, but sometimes it isn't necesarry. | ||
| 11 | *@author Mike Buland | ||
| 12 | */ | ||
| 13 | class LinkMessage | ||
| 14 | { | ||
| 15 | public: | ||
| 16 | /** | ||
| 17 | * Construct a blank LinkMessage. | ||
| 18 | */ | ||
| 19 | LinkMessage() {}; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Deconstruct a LinkMessage. | ||
| 23 | */ | ||
| 24 | virtual ~LinkMessage(); | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Create a LinkMessage object with a specific message assosiated with it | ||
| 28 | * to start with. | ||
| 29 | *@param nNewMsg The message to use in the Message object. | ||
| 30 | */ | ||
| 31 | LinkMessage( int nNewMsg ); | ||
| 32 | |||
| 33 | /** | ||
| 34 | * The message contained in the Message object. | ||
| 35 | */ | ||
| 36 | int nMsg; | ||
| 37 | }; | ||
| 38 | |||
| 39 | #endif | ||
diff --git a/src/old/plugger.h b/src/old/plugger.h deleted file mode 100644 index d92f194..0000000 --- a/src/old/plugger.h +++ /dev/null | |||
| @@ -1,198 +0,0 @@ | |||
| 1 | #ifndef PLUGGER_H | ||
| 2 | #define PLUGGER_H | ||
| 3 | |||
| 4 | |||
| 5 | #include "hashtable.h" | ||
| 6 | #include "list" | ||
| 7 | #include "hashfunctionstring.h" | ||
| 8 | #include "hashfunctionint.h" | ||
| 9 | #include "dlfcn.h" | ||
| 10 | #include "exceptions.h" | ||
| 11 | |||
| 12 | typedef struct PluginInfo | ||
| 13 | { | ||
| 14 | const char *sID; | ||
| 15 | const char *sAuthor; | ||
| 16 | unsigned short nVersion; | ||
| 17 | unsigned short nRevision; | ||
| 18 | void *(*createPlugin)(); | ||
| 19 | void (*destroyPlugin)( void * ); | ||
| 20 | } PluginInfo; | ||
| 21 | |||
| 22 | typedef struct PluginReg | ||
| 23 | { | ||
| 24 | bool bBuiltin; | ||
| 25 | void *dlHandle; | ||
| 26 | PluginInfo *pInfo; | ||
| 27 | } PluginReg; | ||
| 28 | |||
| 29 | #define PluginInterface( classname, baseclass, name, ver, rev ) \ | ||
| 30 | extern "C" { \ | ||
| 31 | baseclass *create ##classname() \ | ||
| 32 | { \ | ||
| 33 | return new classname(); \ | ||
| 34 | } \ | ||
| 35 | void destroy ##classname( baseclass *pCls ) \ | ||
| 36 | { \ | ||
| 37 | delete pCls; \ | ||
| 38 | } \ | ||
| 39 | PluginInfo classname = { \ | ||
| 40 | #classname, name, ver, rev, \ | ||
| 41 | create ##classname, destroy ##classname }; \ | ||
| 42 | } | ||
| 43 | |||
| 44 | #define PluginInterface2( pluginname, classname, baseclass, name, ver, rev ) \ | ||
| 45 | extern "C" { \ | ||
| 46 | baseclass *create ##classname() \ | ||
| 47 | { \ | ||
| 48 | return new classname(); \ | ||
| 49 | } \ | ||
| 50 | void destroy ##classname( baseclass *pCls ) \ | ||
| 51 | { \ | ||
| 52 | delete pCls; \ | ||
| 53 | } \ | ||
| 54 | PluginInfo pluginname = { \ | ||
| 55 | #pluginname, name, ver, rev, \ | ||
| 56 | (void *(*)())(create ##classname), \ | ||
| 57 | (void (*)( void * ))(destroy ##classname) }; \ | ||
| 58 | } | ||
| 59 | |||
| 60 | #define PluginInterface3( structname, pluginname, classname, baseclass, name, ver, rev ) \ | ||
| 61 | extern "C" { \ | ||
| 62 | baseclass *create ##classname() \ | ||
| 63 | { \ | ||
| 64 | return new classname(); \ | ||
| 65 | } \ | ||
| 66 | void destroy ##classname( baseclass *pCls ) \ | ||
| 67 | { \ | ||
| 68 | delete pCls; \ | ||
| 69 | } \ | ||
| 70 | PluginInfo structname = { \ | ||
| 71 | #pluginname, name, ver, rev, \ | ||
| 72 | (void *(*)())(create ##classname), \ | ||
| 73 | (void (*)( void * ))(destroy ##classname) }; \ | ||
| 74 | } | ||
| 75 | |||
| 76 | template<class T> | ||
| 77 | class Plugger | ||
| 78 | { | ||
| 79 | public: | ||
| 80 | |||
| 81 | public: | ||
| 82 | Plugger() : | ||
| 83 | hPlugin( new HashFunctionString(), 11 ), | ||
| 84 | hObj( new HashFunctionInt(), 11 ) | ||
| 85 | { | ||
| 86 | } | ||
| 87 | |||
| 88 | virtual ~Plugger() | ||
| 89 | { | ||
| 90 | void *pos = hObj.getFirstItemPos(); | ||
| 91 | while( (pos = hObj.getNextItemPos( pos )) ) | ||
| 92 | { | ||
| 93 | T *pPlug = (T *)hObj.getItemID( pos ); | ||
| 94 | PluginReg *pReg = (PluginReg *)hObj.getItemData( pos ); | ||
| 95 | pReg->pInfo->destroyPlugin( pPlug ); | ||
| 96 | } | ||
| 97 | |||
| 98 | std::list<PluginReg *>::iterator i; | ||
| 99 | for( i = lPlugin.begin(); i != lPlugin.end(); i++ ) | ||
| 100 | { | ||
| 101 | if( (*i)->bBuiltin == false ) | ||
| 102 | { | ||
| 103 | dlclose( (*i)->dlHandle ); | ||
| 104 | } | ||
| 105 | delete (*i); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | void registerBuiltinPlugin( PluginInfo *pInfo ) | ||
| 110 | { | ||
| 111 | PluginReg *pReg = new PluginReg; | ||
| 112 | pReg->bBuiltin = true; | ||
| 113 | pReg->pInfo = pInfo; | ||
| 114 | lPlugin.insert( lPlugin.end(), pReg ); | ||
| 115 | hPlugin.insert( pInfo->sID, pReg ); | ||
| 116 | } | ||
| 117 | |||
| 118 | void registerExternalPlugin( const char *sFName, const char *sPluginName ) | ||
| 119 | { | ||
| 120 | PluginReg *pReg = (PluginReg *)hPlugin[sPluginName]; | ||
| 121 | if( pReg != NULL ) | ||
| 122 | { | ||
| 123 | hPlugin.del( sPluginName ); | ||
| 124 | dlclose( pReg->dlHandle ); | ||
| 125 | delete pReg; | ||
| 126 | pReg = NULL; | ||
| 127 | } | ||
| 128 | |||
| 129 | pReg = new PluginReg; | ||
| 130 | |||
| 131 | pReg->bBuiltin = false; | ||
| 132 | pReg->dlHandle = dlopen( sFName, RTLD_NOW ); | ||
| 133 | if( pReg->dlHandle == NULL ) | ||
| 134 | { | ||
| 135 | throw PluginException( 1, "Error on %s: %s", sFName, dlerror() ); | ||
| 136 | } | ||
| 137 | pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName ); | ||
| 138 | if( pReg->pInfo == NULL ) | ||
| 139 | { | ||
| 140 | throw PluginException( 2, "Error on %s: %s", sFName, dlerror() ); | ||
| 141 | } | ||
| 142 | hPlugin.insert( pReg->pInfo->sID, pReg ); | ||
| 143 | lPlugin.insert( lPlugin.end(), pReg ); | ||
| 144 | } | ||
| 145 | |||
| 146 | T *instantiate( const char *lpName ) | ||
| 147 | { | ||
| 148 | PluginReg *pReg = (PluginReg *)hPlugin[lpName]; | ||
| 149 | if( pReg == NULL ) | ||
| 150 | return NULL; | ||
| 151 | |||
| 152 | T *p = (T *)pReg->pInfo->createPlugin(); | ||
| 153 | hObj.insert( p, pReg ); | ||
| 154 | //printf("pReg: %08X, pPlug: %08X\n", pReg, p ); | ||
| 155 | |||
| 156 | return p; | ||
| 157 | } | ||
| 158 | |||
| 159 | bool hasPlugin( const char *lpName ) | ||
| 160 | { | ||
| 161 | if( hPlugin[lpName] == NULL ) | ||
| 162 | return false; | ||
| 163 | return true; | ||
| 164 | } | ||
| 165 | |||
| 166 | void destroy( T *pPlug ) | ||
| 167 | { | ||
| 168 | PluginReg *pReg = (PluginReg *)hObj[pPlug]; | ||
| 169 | //printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug ); | ||
| 170 | if( pReg == NULL ) | ||
| 171 | return; | ||
| 172 | |||
| 173 | pReg->pInfo->destroyPlugin( pPlug ); | ||
| 174 | |||
| 175 | hObj.del( pPlug ); | ||
| 176 | } | ||
| 177 | |||
| 178 | void unloadAll() | ||
| 179 | { | ||
| 180 | std::list<PluginReg *>::iterator i; | ||
| 181 | for( i = lPlugin.begin(); i != lPlugin.end(); i++ ) | ||
| 182 | { | ||
| 183 | if( (*i)->bBuiltin == false ) | ||
| 184 | { | ||
| 185 | dlclose( (*i)->dlHandle ); | ||
| 186 | } | ||
| 187 | delete (*i); | ||
| 188 | } | ||
| 189 | hPlugin.clear(); | ||
| 190 | } | ||
| 191 | |||
| 192 | private: | ||
| 193 | std::list<PluginReg *> lPlugin; | ||
| 194 | HashTable hPlugin; | ||
| 195 | HashTable hObj; | ||
| 196 | }; | ||
| 197 | |||
| 198 | #endif | ||
diff --git a/src/old/programchain.cpp b/src/old/programchain.cpp deleted file mode 100644 index 6120d58..0000000 --- a/src/old/programchain.cpp +++ /dev/null | |||
| @@ -1,96 +0,0 @@ | |||
| 1 | #include <stdlib.h> | ||
| 2 | #include "programchain.h" | ||
| 3 | |||
| 4 | ProgramChain::ProgramChain() : | ||
| 5 | xLog( MultiLog::getInstance() ) | ||
| 6 | { | ||
| 7 | xLog.LineLog( MultiLog::LStatus, "Program Chain Initialized." ); | ||
| 8 | } | ||
| 9 | |||
| 10 | ProgramChain::~ProgramChain() | ||
| 11 | { | ||
| 12 | } | ||
| 13 | |||
| 14 | bool ProgramChain::addLink( ProgramLink *pLink ) | ||
| 15 | { | ||
| 16 | if( pLink->init() == false ) | ||
| 17 | { | ||
| 18 | emergencyShutdown(); | ||
| 19 | return false; | ||
| 20 | } | ||
| 21 | |||
| 22 | lLink.append( pLink ); | ||
| 23 | |||
| 24 | pLink->setChain( this ); | ||
| 25 | |||
| 26 | return true; | ||
| 27 | } | ||
| 28 | |||
| 29 | ProgramLink *ProgramChain::getLink( const char *lpName ) | ||
| 30 | { | ||
| 31 | char a; | ||
| 32 | a = lpName[0]; | ||
| 33 | return NULL; | ||
| 34 | } | ||
| 35 | |||
| 36 | ProgramLink *ProgramChain::getBaseLink() | ||
| 37 | { | ||
| 38 | return NULL; | ||
| 39 | } | ||
| 40 | |||
| 41 | bool ProgramChain::execChainOnce() | ||
| 42 | { | ||
| 43 | int nLen = lLink.getSize(); | ||
| 44 | for( int j = 0; j < nLen; j++ ) | ||
| 45 | { | ||
| 46 | if( ((ProgramLink *)lLink[j])->timeSlice() == false ) | ||
| 47 | { | ||
| 48 | xLog.LineLog( MultiLog::LInfo, "Shutting down due to signal from link #%d", j ); | ||
| 49 | emergencyShutdown(); | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | return true; | ||
| 55 | } | ||
| 56 | |||
| 57 | bool ProgramChain::enterChainLoop() | ||
| 58 | { | ||
| 59 | for(;;) | ||
| 60 | { | ||
| 61 | if( execChainOnce() == false ) | ||
| 62 | { | ||
| 63 | return false; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | return true; | ||
| 68 | } | ||
| 69 | |||
| 70 | void ProgramChain::emergencyShutdown() | ||
| 71 | { | ||
| 72 | int nLen = lLink.getSize(); | ||
| 73 | for( int j = 0; j < nLen; j++ ) | ||
| 74 | { | ||
| 75 | ((ProgramLink *)lLink[j])->deInit(); | ||
| 76 | delete (ProgramLink *)lLink[j]; | ||
| 77 | } | ||
| 78 | lLink.empty(); | ||
| 79 | } | ||
| 80 | |||
| 81 | LinkMessage *ProgramChain::broadcastIRM( LinkMessage *pMsgOut, ProgramLink *pSender ) | ||
| 82 | { | ||
| 83 | int nLen = lLink.getSize(); | ||
| 84 | for( int j = 0; j < nLen; j++ ) | ||
| 85 | { | ||
| 86 | LinkMessage *pMsg = ((ProgramLink *)lLink[j])->processIRM( pMsgOut ); | ||
| 87 | if( pMsg != NULL ) | ||
| 88 | { | ||
| 89 | delete pMsgOut; | ||
| 90 | return pMsg; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | delete pMsgOut; | ||
| 95 | return NULL; | ||
| 96 | } | ||
diff --git a/src/old/programchain.h b/src/old/programchain.h deleted file mode 100644 index 2bdfeee..0000000 --- a/src/old/programchain.h +++ /dev/null | |||
| @@ -1,95 +0,0 @@ | |||
| 1 | #ifndef PROGRAMCHAIN_H | ||
| 2 | #define PROGRAMCHAIN_H | ||
| 3 | |||
| 4 | #include "linkedlist.h" | ||
| 5 | #include "multilog.h" | ||
| 6 | #include "programlink.h" | ||
| 7 | |||
| 8 | /** | ||
| 9 | * The Program Chain links together program "chunks" to more easily facilitate | ||
| 10 | * a generalized program loop with modular extensions. | ||
| 11 | *@author Mike Buland | ||
| 12 | */ | ||
| 13 | class ProgramChain | ||
| 14 | { | ||
| 15 | public: | ||
| 16 | /** | ||
| 17 | * Construct an empty chain. | ||
| 18 | */ | ||
| 19 | ProgramChain(); | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Destroy your chain. | ||
| 23 | */ | ||
| 24 | virtual ~ProgramChain(); | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Adds a link to the end of the chain. | ||
| 28 | *@param pLink A pointer to the link to add to the chain. | ||
| 29 | *@returns True if adding the link was successful, otherwise false | ||
| 30 | *@author Mike Buland | ||
| 31 | */ | ||
| 32 | bool addLink( ProgramLink *pLink ); | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Gets a link by name. | ||
| 36 | *@param lpName The name of the link you're looking for. Every link has a | ||
| 37 | * name, apparently. | ||
| 38 | *@returns A pointer to the specified ProgramLink, or NULL if none were | ||
| 39 | * found matching your criteria. | ||
| 40 | *@author Mike Buland | ||
| 41 | */ | ||
| 42 | class ProgramLink *getLink( const char *lpName ); | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Gets the very first link in the chain. | ||
| 46 | *@returns A pointer to the first link in the chain. | ||
| 47 | *@author Mike Buland | ||
| 48 | */ | ||
| 49 | class ProgramLink *getBaseLink(); | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Runs through the chain once. Useful if you want to have more control | ||
| 53 | * over the operation of the chain. | ||
| 54 | *@returns true if every link returned true. If at least one link returns | ||
| 55 | * false, then returns false. | ||
| 56 | *@author Mike Buland | ||
| 57 | */ | ||
| 58 | bool execChainOnce(); | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Enters the master chain loop, looping over the entire chain and | ||
| 62 | * executing every link's TimeSlice routine in order, over and over, until | ||
| 63 | * a link returns a false value. | ||
| 64 | *@returns False, always. It returns true unless a link returned false, | ||
| 65 | * but loops until a link does return false. | ||
| 66 | *@author Mike Buland | ||
| 67 | **/ | ||
| 68 | bool enterChainLoop(); | ||
| 69 | |||
| 70 | /** | ||
| 71 | * Broadcasts an Immediate Response Message to all active links, save the | ||
| 72 | * sender. Whatever link first responds with a non-null response message | ||
| 73 | * will have it's messages sent back to the broadcasting link as the returns | ||
| 74 | * of this function call. Therefore it is very important that all message | ||
| 75 | * processing code is handled in a fairly timely fasion. | ||
| 76 | *@param pMsgOut The message to broadcast in hopes of a response. | ||
| 77 | *@param pSender The message that sent out the message and doesn't want to | ||
| 78 | * receive it's own message. This should always just be "this". | ||
| 79 | *@returns The message that was returned by the first link to return a | ||
| 80 | * non-null response. If all messages return null responses then this also | ||
| 81 | * returns null. Please note that whoever calls this will be responsible | ||
| 82 | * for deleting the message returned by it, if non-null. | ||
| 83 | */ | ||
| 84 | class LinkMessage *broadcastIRM( LinkMessage *pMsgOut, ProgramLink *pSender ); | ||
| 85 | |||
| 86 | private: | ||
| 87 | /** | ||
| 88 | * Shuts down all operation no matter what point in the operation we were. | ||
| 89 | */ | ||
| 90 | void emergencyShutdown(); | ||
| 91 | MultiLog &xLog; /**< A reference to the log. */ | ||
| 92 | LinkedList lLink; /**< The linked list that contains all of the links. */ | ||
| 93 | }; | ||
| 94 | |||
| 95 | #endif | ||
diff --git a/src/old/programlink.h b/src/old/programlink.h deleted file mode 100644 index f93edcc..0000000 --- a/src/old/programlink.h +++ /dev/null | |||
| @@ -1,99 +0,0 @@ | |||
| 1 | #ifndef PROGRAMLINK_H | ||
| 2 | #define PROGRAMLINK_H | ||
| 3 | |||
| 4 | class ProgramLink; | ||
| 5 | #include "queue.h" | ||
| 6 | #include "linkmessage.h" | ||
| 7 | #include "programchain.h" | ||
| 8 | |||
| 9 | /** | ||
| 10 | * Program Link is the base class for any object that will be a piece of the | ||
| 11 | * main program chain loop. | ||
| 12 | *@author Mike Buland | ||
| 13 | */ | ||
| 14 | class ProgramLink | ||
| 15 | { | ||
| 16 | friend class ProgramChain; | ||
| 17 | public: | ||
| 18 | /** | ||
| 19 | * Construct a program link. | ||
| 20 | */ | ||
| 21 | ProgramLink(); | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Deconstruct. | ||
| 25 | */ | ||
| 26 | virtual ~ProgramLink(); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Initialization code required for a link that wasn't performed in the | ||
| 30 | * constructor. | ||
| 31 | *@returns true if initialization was successful. A false value will halt | ||
| 32 | * the chain. | ||
| 33 | */ | ||
| 34 | virtual bool init()=0; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * DeInitialization code that should happen, but doesn't belong in the | ||
| 38 | * destructor. | ||
| 39 | *@returns true means everything worked, false means failure, but is | ||
| 40 | * meaningless. | ||
| 41 | */ | ||
| 42 | virtual bool deInit()=0; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Executed once per link per chain pass. Contains the guts of the program. | ||
| 46 | *@returns true if everything went well. A false value will halt the chain. | ||
| 47 | */ | ||
| 48 | virtual bool timeSlice()=0; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * This must be handled in order to process Instant Response Messages. | ||
| 52 | * This function should return null on all messages that it doesn't | ||
| 53 | * understand how to handle, and construct new messages to return to sender | ||
| 54 | * in the cases where it does understand. | ||
| 55 | *@param pMsgIn The message that must be processed. | ||
| 56 | *@returns Either a new message in cases where a response is required, | ||
| 57 | * or null if nothing needs to be done by this link. | ||
| 58 | */ | ||
| 59 | virtual LinkMessage *processIRM( LinkMessage *pMsgIn ) = 0; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Broadcast a LinkMessage to all other links in the system. Each other | ||
| 63 | * link will get a call of their processIRM function. If the message gets | ||
| 64 | * a response then you will regain control immediately, otherwise the system | ||
| 65 | * will give all other Links a chance to respond before returning NULL. | ||
| 66 | *@param pMsgOut The message to broadcast. | ||
| 67 | *@returns The message response, or NULL if no Link understood your message. | ||
| 68 | */ | ||
| 69 | LinkMessage *sendIRM( LinkMessage *pMsgOut ); | ||
| 70 | |||
| 71 | private: | ||
| 72 | /** | ||
| 73 | * Set which chain we're assosiated with. This is how IRM messages make | ||
| 74 | * it out to the rest of the world. | ||
| 75 | *@param pNewChain A pointer to the containing program chain. | ||
| 76 | */ | ||
| 77 | void setChain( class ProgramChain *pNewChain ); | ||
| 78 | |||
| 79 | /** | ||
| 80 | * The pointer to the containing chain. | ||
| 81 | */ | ||
| 82 | class ProgramChain *pChain; | ||
| 83 | /* | ||
| 84 | void postMessage( LinkMessage *pMsg, int nLvl ); | ||
| 85 | LinkMessage *getMessage( int nLvl ); | ||
| 86 | |||
| 87 | enum | ||
| 88 | { | ||
| 89 | msgToChain, | ||
| 90 | msgToLink | ||
| 91 | }; | ||
| 92 | |||
| 93 | private: | ||
| 94 | Queue qMsgToChain; | ||
| 95 | Queue qMsgToLink; | ||
| 96 | */ | ||
| 97 | }; | ||
| 98 | |||
| 99 | #endif | ||
diff --git a/src/old/plugger.cpp b/src/plugger.cpp index f3bfa67..f3bfa67 100644 --- a/src/old/plugger.cpp +++ b/src/plugger.cpp | |||
diff --git a/src/plugger.h b/src/plugger.h new file mode 100644 index 0000000..98d4ecc --- /dev/null +++ b/src/plugger.h | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | #ifndef PLUGGER_H | ||
| 2 | #define PLUGGER_H | ||
| 3 | |||
| 4 | |||
| 5 | #include "bu/hash.h" | ||
| 6 | #include "bu/list.h" | ||
| 7 | #include <dlfcn.h> | ||
| 8 | #include "bu/exceptions.h" | ||
| 9 | #include "bu/fstring.h" | ||
| 10 | |||
| 11 | namespace Bu | ||
| 12 | { | ||
| 13 | typedef struct PluginInfo | ||
| 14 | { | ||
| 15 | const char *sID; | ||
| 16 | const char *sAuthor; | ||
| 17 | unsigned short nVersion; | ||
| 18 | unsigned short nRevision; | ||
| 19 | void *(*createPlugin)(); | ||
| 20 | void (*destroyPlugin)( void * ); | ||
| 21 | } PluginInfo; | ||
| 22 | |||
| 23 | typedef struct PluginReg | ||
| 24 | { | ||
| 25 | bool bBuiltin; | ||
| 26 | void *dlHandle; | ||
| 27 | PluginInfo *pInfo; | ||
| 28 | } PluginReg; | ||
| 29 | |||
| 30 | #define PluginInterface( classname, baseclass, name, ver, rev ) \ | ||
| 31 | extern "C" { \ | ||
| 32 | baseclass *create ##classname() \ | ||
| 33 | { \ | ||
| 34 | return new classname(); \ | ||
| 35 | } \ | ||
| 36 | void destroy ##classname( baseclass *pCls ) \ | ||
| 37 | { \ | ||
| 38 | delete pCls; \ | ||
| 39 | } \ | ||
| 40 | PluginInfo classname = { \ | ||
| 41 | #classname, name, ver, rev, \ | ||
| 42 | create ##classname, destroy ##classname }; \ | ||
| 43 | } | ||
| 44 | |||
| 45 | #define PluginInterface2( pluginname, classname, baseclass, name, ver, rev ) \ | ||
| 46 | extern "C" { \ | ||
| 47 | baseclass *create ##classname() \ | ||
| 48 | { \ | ||
| 49 | return new classname(); \ | ||
| 50 | } \ | ||
| 51 | void destroy ##classname( baseclass *pCls ) \ | ||
| 52 | { \ | ||
| 53 | delete pCls; \ | ||
| 54 | } \ | ||
| 55 | PluginInfo pluginname = { \ | ||
| 56 | #pluginname, name, ver, rev, \ | ||
| 57 | (void *(*)())(create ##classname), \ | ||
| 58 | (void (*)( void * ))(destroy ##classname) }; \ | ||
| 59 | } | ||
| 60 | |||
| 61 | #define PluginInterface3( structname, pluginname, classname, baseclass, name, ver, rev ) \ | ||
| 62 | extern "C" { \ | ||
| 63 | baseclass *create ##classname() \ | ||
| 64 | { \ | ||
| 65 | return new classname(); \ | ||
| 66 | } \ | ||
| 67 | void destroy ##classname( baseclass *pCls ) \ | ||
| 68 | { \ | ||
| 69 | delete pCls; \ | ||
| 70 | } \ | ||
| 71 | PluginInfo structname = { \ | ||
| 72 | #pluginname, name, ver, rev, \ | ||
| 73 | (void *(*)())(create ##classname), \ | ||
| 74 | (void (*)( void * ))(destroy ##classname) }; \ | ||
| 75 | } | ||
| 76 | |||
| 77 | template<class T> | ||
| 78 | class Plugger | ||
| 79 | { | ||
| 80 | public: | ||
| 81 | typedef Bu::Hash<Bu::FString, PluginReg *> PluginHash; | ||
| 82 | typedef Bu::Hash<int, void *> InstHash; | ||
| 83 | |||
| 84 | public: | ||
| 85 | Plugger() | ||
| 86 | { | ||
| 87 | } | ||
| 88 | |||
| 89 | virtual ~Plugger() | ||
| 90 | { | ||
| 91 | for( InstHash::iterator i = hObj.begin(); i != hObj.end(); i++ ) | ||
| 92 | { | ||
| 93 | T *pPlug = (T *)i.getKey(); | ||
| 94 | PluginReg *pReg = (PluginReg *)*i; | ||
| 95 | pReg->pInfo->destroyPlugin( pPlug ); | ||
| 96 | } | ||
| 97 | |||
| 98 | for( PluginHash::iterator i = hPlugin.begin(); | ||
| 99 | i != hPlugin.end(); i++ ) | ||
| 100 | { | ||
| 101 | if( (*i)->bBuiltin == false ) | ||
| 102 | { | ||
| 103 | dlclose( (*i)->dlHandle ); | ||
| 104 | } | ||
| 105 | delete (*i); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | void registerBuiltinPlugin( PluginInfo *pInfo ) | ||
| 110 | { | ||
| 111 | PluginReg *pReg = new PluginReg; | ||
| 112 | pReg->bBuiltin = true; | ||
| 113 | pReg->pInfo = pInfo; | ||
| 114 | hPlugin.insert( pInfo->sID, pReg ); | ||
| 115 | } | ||
| 116 | |||
| 117 | void registerExternalPlugin( const char *sFName, const char *sPluginName ) | ||
| 118 | { | ||
| 119 | PluginReg *pReg = (PluginReg *)hPlugin[sPluginName]; | ||
| 120 | if( pReg != NULL ) | ||
| 121 | { | ||
| 122 | hPlugin.erase( sPluginName ); | ||
| 123 | dlclose( pReg->dlHandle ); | ||
| 124 | delete pReg; | ||
| 125 | pReg = NULL; | ||
| 126 | } | ||
| 127 | |||
| 128 | pReg = new PluginReg; | ||
| 129 | |||
| 130 | pReg->bBuiltin = false; | ||
| 131 | pReg->dlHandle = dlopen( sFName, RTLD_NOW ); | ||
| 132 | if( pReg->dlHandle == NULL ) | ||
| 133 | { | ||
| 134 | throw PluginException( 1, "Error on %s: %s", sFName, dlerror() ); | ||
| 135 | } | ||
| 136 | pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName ); | ||
| 137 | if( pReg->pInfo == NULL ) | ||
| 138 | { | ||
| 139 | throw PluginException( 2, "Error on %s: %s", sFName, dlerror() ); | ||
| 140 | } | ||
| 141 | hPlugin.insert( pReg->pInfo->sID, pReg ); | ||
| 142 | } | ||
| 143 | |||
| 144 | T *instantiate( const char *lpName ) | ||
| 145 | { | ||
| 146 | PluginReg *pReg = (PluginReg *)hPlugin[lpName]; | ||
| 147 | if( pReg == NULL ) | ||
| 148 | return NULL; | ||
| 149 | |||
| 150 | T *p = (T *)pReg->pInfo->createPlugin(); | ||
| 151 | hObj.insert( p, pReg ); | ||
| 152 | //printf("pReg: %08X, pPlug: %08X\n", pReg, p ); | ||
| 153 | |||
| 154 | return p; | ||
| 155 | } | ||
| 156 | |||
| 157 | bool hasPlugin( const char *lpName ) | ||
| 158 | { | ||
| 159 | if( hPlugin[lpName] == NULL ) | ||
| 160 | return false; | ||
| 161 | return true; | ||
| 162 | } | ||
| 163 | |||
| 164 | void destroy( T *pPlug ) | ||
| 165 | { | ||
| 166 | PluginReg *pReg = (PluginReg *)hObj[pPlug]; | ||
| 167 | //printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug ); | ||
| 168 | if( pReg == NULL ) | ||
| 169 | return; | ||
| 170 | |||
| 171 | pReg->pInfo->destroyPlugin( pPlug ); | ||
| 172 | |||
| 173 | hObj.erase( pPlug ); | ||
| 174 | } | ||
| 175 | |||
| 176 | void unloadAll() | ||
| 177 | { | ||
| 178 | for( PluginHash::iterator i = hPlugin.begin(); | ||
| 179 | i != hPlugin.end(); i++ ) | ||
| 180 | { | ||
| 181 | if( (*i)->bBuiltin == false ) | ||
| 182 | { | ||
| 183 | dlclose( (*i)->dlHandle ); | ||
| 184 | } | ||
| 185 | delete (*i); | ||
| 186 | } | ||
| 187 | hPlugin.clear(); | ||
| 188 | } | ||
| 189 | |||
| 190 | private: | ||
| 191 | PluginHash hPlugin; | ||
| 192 | InstHash hObj; | ||
| 193 | }; | ||
| 194 | } | ||
| 195 | |||
| 196 | #endif | ||
diff --git a/src/programchain.cpp b/src/programchain.cpp new file mode 100644 index 0000000..0bb7a77 --- /dev/null +++ b/src/programchain.cpp | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | #include <stdlib.h> | ||
| 2 | #include "bu/programchain.h" | ||
| 3 | #include "bu/programlink.h" | ||
| 4 | |||
| 5 | using namespace Bu; | ||
| 6 | |||
| 7 | Bu::ProgramChain::ProgramChain() | ||
| 8 | { | ||
| 9 | } | ||
| 10 | |||
| 11 | Bu::ProgramChain::~ProgramChain() | ||
| 12 | { | ||
| 13 | } | ||
| 14 | |||
| 15 | bool Bu::ProgramChain::addLink( ProgramLink *pLink ) | ||
| 16 | { | ||
| 17 | if( pLink->init() == false ) | ||
| 18 | { | ||
| 19 | emergencyShutdown(); | ||
| 20 | return false; | ||
| 21 | } | ||
| 22 | |||
| 23 | lLink.append( pLink ); | ||
| 24 | |||
| 25 | pLink->setChain( this ); | ||
| 26 | |||
| 27 | return true; | ||
| 28 | } | ||
| 29 | |||
| 30 | ProgramLink *Bu::ProgramChain::getLink( const char *lpName ) | ||
| 31 | { | ||
| 32 | char a; | ||
| 33 | a = lpName[0]; | ||
| 34 | return NULL; | ||
| 35 | } | ||
| 36 | |||
| 37 | ProgramLink *Bu::ProgramChain::getBaseLink() | ||
| 38 | { | ||
| 39 | return NULL; | ||
| 40 | } | ||
| 41 | |||
| 42 | bool Bu::ProgramChain::execChainOnce() | ||
| 43 | { | ||
| 44 | for( Bu::List<Bu::ProgramLink *>::iterator i = lLink.begin(); | ||
| 45 | i != lLink.end(); i++ ) | ||
| 46 | { | ||
| 47 | if( (*i)->timeSlice() == false ) | ||
| 48 | { | ||
| 49 | emergencyShutdown(); | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | return true; | ||
| 55 | } | ||
| 56 | |||
| 57 | bool Bu::ProgramChain::enterChainLoop() | ||
| 58 | { | ||
| 59 | for(;;) | ||
| 60 | { | ||
| 61 | if( execChainOnce() == false ) | ||
| 62 | { | ||
| 63 | return false; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | return true; | ||
| 68 | } | ||
| 69 | |||
| 70 | void Bu::ProgramChain::emergencyShutdown() | ||
| 71 | { | ||
| 72 | for( Bu::List<Bu::ProgramLink *>::iterator i = lLink.begin(); | ||
| 73 | i != lLink.end(); i++ ) | ||
| 74 | { | ||
| 75 | (*i)->deInit(); | ||
| 76 | delete *i; | ||
| 77 | } | ||
| 78 | lLink.clear(); | ||
| 79 | } | ||
| 80 | |||
| 81 | LinkMessage *Bu::ProgramChain::broadcastIRM( LinkMessage *pMsgOut, ProgramLink *pSender ) | ||
| 82 | { | ||
| 83 | for( Bu::List<Bu::ProgramLink *>::iterator i = lLink.begin(); | ||
| 84 | i != lLink.end(); i++ ) | ||
| 85 | { | ||
| 86 | LinkMessage *pMsg = (*i)->processIRM( pMsgOut ); | ||
| 87 | if( pMsg != NULL ) | ||
| 88 | { | ||
| 89 | delete pMsgOut; | ||
| 90 | return pMsg; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | delete pMsgOut; | ||
| 95 | return NULL; | ||
| 96 | } | ||
| 97 | |||
diff --git a/src/programchain.h b/src/programchain.h new file mode 100644 index 0000000..e73d659 --- /dev/null +++ b/src/programchain.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | #ifndef PROGRAMCHAIN_H | ||
| 2 | #define PROGRAMCHAIN_H | ||
| 3 | |||
| 4 | #include "bu/list.h" | ||
| 5 | #include "bu/linkmessage.h" | ||
| 6 | |||
| 7 | namespace Bu | ||
| 8 | { | ||
| 9 | class ProgramLink; | ||
| 10 | /** | ||
| 11 | * The Program Chain links together program "chunks" to more easily facilitate | ||
| 12 | * a generalized program loop with modular extensions. | ||
| 13 | *@author Mike Buland | ||
| 14 | */ | ||
| 15 | class ProgramChain | ||
| 16 | { | ||
| 17 | public: | ||
| 18 | /** | ||
| 19 | * Construct an empty chain. | ||
| 20 | */ | ||
| 21 | ProgramChain(); | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Destroy your chain. | ||
| 25 | */ | ||
| 26 | virtual ~ProgramChain(); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Adds a link to the end of the chain. | ||
| 30 | *@param pLink A pointer to the link to add to the chain. | ||
| 31 | *@returns True if adding the link was successful, otherwise false | ||
| 32 | *@author Mike Buland | ||
| 33 | */ | ||
| 34 | bool addLink( Bu::ProgramLink *pLink ); | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Gets a link by name. | ||
| 38 | *@param lpName The name of the link you're looking for. Every link has a | ||
| 39 | * name, apparently. | ||
| 40 | *@returns A pointer to the specified ProgramLink, or NULL if none were | ||
| 41 | * found matching your criteria. | ||
| 42 | *@author Mike Buland | ||
| 43 | */ | ||
| 44 | class ProgramLink *getLink( const char *lpName ); | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Gets the very first link in the chain. | ||
| 48 | *@returns A pointer to the first link in the chain. | ||
| 49 | *@author Mike Buland | ||
| 50 | */ | ||
| 51 | class ProgramLink *getBaseLink(); | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Runs through the chain once. Useful if you want to have more control | ||
| 55 | * over the operation of the chain. | ||
| 56 | *@returns true if every link returned true. If at least one link returns | ||
| 57 | * false, then returns false. | ||
| 58 | *@author Mike Buland | ||
| 59 | */ | ||
| 60 | bool execChainOnce(); | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Enters the master chain loop, looping over the entire chain and | ||
| 64 | * executing every link's TimeSlice routine in order, over and over, until | ||
| 65 | * a link returns a false value. | ||
| 66 | *@returns False, always. It returns true unless a link returned false, | ||
| 67 | * but loops until a link does return false. | ||
| 68 | *@author Mike Buland | ||
| 69 | **/ | ||
| 70 | bool enterChainLoop(); | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Broadcasts an Immediate Response Message to all active links, save the | ||
| 74 | * sender. Whatever link first responds with a non-null response message | ||
| 75 | * will have it's messages sent back to the broadcasting link as the returns | ||
| 76 | * of this function call. Therefore it is very important that all message | ||
| 77 | * processing code is handled in a fairly timely fasion. | ||
| 78 | *@param pMsgOut The message to broadcast in hopes of a response. | ||
| 79 | *@param pSender The message that sent out the message and doesn't want to | ||
| 80 | * receive it's own message. This should always just be "this". | ||
| 81 | *@returns The message that was returned by the first link to return a | ||
| 82 | * non-null response. If all messages return null responses then this also | ||
| 83 | * returns null. Please note that whoever calls this will be responsible | ||
| 84 | * for deleting the message returned by it, if non-null. | ||
| 85 | */ | ||
| 86 | class LinkMessage *broadcastIRM( LinkMessage *pMsgOut, ProgramLink *pSender ); | ||
| 87 | |||
| 88 | private: | ||
| 89 | /** | ||
| 90 | * Shuts down all operation no matter what point in the operation we were. | ||
| 91 | */ | ||
| 92 | void emergencyShutdown(); | ||
| 93 | Bu::List<Bu::ProgramLink *> lLink; /**< The linked list that contains all of the links. */ | ||
| 94 | }; | ||
| 95 | } | ||
| 96 | |||
| 97 | |||
| 98 | #endif | ||
diff --git a/src/old/programlink.cpp b/src/programlink.cpp index 21c6fe4..e5c624c 100644 --- a/src/old/programlink.cpp +++ b/src/programlink.cpp | |||
| @@ -1,20 +1,22 @@ | |||
| 1 | #include "programlink.h" | 1 | #include "bu/programlink.h" |
| 2 | #include "programchain.h" | 2 | #include "bu/programchain.h" |
| 3 | 3 | ||
| 4 | ProgramLink::ProgramLink() | 4 | using namespace Bu; |
| 5 | |||
| 6 | Bu::ProgramLink::ProgramLink() | ||
| 5 | { | 7 | { |
| 6 | } | 8 | } |
| 7 | 9 | ||
| 8 | ProgramLink::~ProgramLink() | 10 | Bu::ProgramLink::~ProgramLink() |
| 9 | { | 11 | { |
| 10 | } | 12 | } |
| 11 | 13 | ||
| 12 | LinkMessage *ProgramLink::sendIRM( LinkMessage *pMsgOut ) | 14 | LinkMessage *Bu::ProgramLink::sendIRM( LinkMessage *pMsgOut ) |
| 13 | { | 15 | { |
| 14 | return pChain->broadcastIRM( pMsgOut, this ); | 16 | return pChain->broadcastIRM( pMsgOut, this ); |
| 15 | } | 17 | } |
| 16 | 18 | ||
| 17 | void ProgramLink::setChain( ProgramChain *pNewChain ) | 19 | void Bu::ProgramLink::setChain( ProgramChain *pNewChain ) |
| 18 | { | 20 | { |
| 19 | pChain = pNewChain; | 21 | pChain = pNewChain; |
| 20 | } | 22 | } |
diff --git a/src/programlink.h b/src/programlink.h new file mode 100644 index 0000000..7c31a18 --- /dev/null +++ b/src/programlink.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | #ifndef PROGRAMLINK_H | ||
| 2 | #define PROGRAMLINK_H | ||
| 3 | |||
| 4 | #include "bu/linkmessage.h" | ||
| 5 | #include "bu/programchain.h" | ||
| 6 | |||
| 7 | namespace Bu | ||
| 8 | { | ||
| 9 | /** | ||
| 10 | * Program Link is the base class for any object that will be a piece of the | ||
| 11 | * main program chain loop. | ||
| 12 | *@author Mike Buland | ||
| 13 | */ | ||
| 14 | class ProgramLink | ||
| 15 | { | ||
| 16 | friend class Bu::ProgramChain; | ||
| 17 | public: | ||
| 18 | /** | ||
| 19 | * Construct a program link. | ||
| 20 | */ | ||
| 21 | ProgramLink(); | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Deconstruct. | ||
| 25 | */ | ||
| 26 | virtual ~ProgramLink(); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Initialization code required for a link that wasn't performed in the | ||
| 30 | * constructor. | ||
| 31 | *@returns true if initialization was successful. A false value will halt | ||
| 32 | * the chain. | ||
| 33 | */ | ||
| 34 | virtual bool init()=0; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * DeInitialization code that should happen, but doesn't belong in the | ||
| 38 | * destructor. | ||
| 39 | *@returns true means everything worked, false means failure, but is | ||
| 40 | * meaningless. | ||
| 41 | */ | ||
| 42 | virtual bool deInit()=0; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Executed once per link per chain pass. Contains the guts of the program. | ||
| 46 | *@returns true if everything went well. A false value will halt the chain. | ||
| 47 | */ | ||
| 48 | virtual bool timeSlice()=0; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * This must be handled in order to process Instant Response Messages. | ||
| 52 | * This function should return null on all messages that it doesn't | ||
| 53 | * understand how to handle, and construct new messages to return to sender | ||
| 54 | * in the cases where it does understand. | ||
| 55 | *@param pMsgIn The message that must be processed. | ||
| 56 | *@returns Either a new message in cases where a response is required, | ||
| 57 | * or null if nothing needs to be done by this link. | ||
| 58 | */ | ||
| 59 | virtual LinkMessage *processIRM( LinkMessage *pMsgIn ) = 0; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Broadcast a LinkMessage to all other links in the system. Each other | ||
| 63 | * link will get a call of their processIRM function. If the message gets | ||
| 64 | * a response then you will regain control immediately, otherwise the system | ||
| 65 | * will give all other Links a chance to respond before returning NULL. | ||
| 66 | *@param pMsgOut The message to broadcast. | ||
| 67 | *@returns The message response, or NULL if no Link understood your message. | ||
| 68 | */ | ||
| 69 | LinkMessage *sendIRM( LinkMessage *pMsgOut ); | ||
| 70 | |||
| 71 | private: | ||
| 72 | /** | ||
| 73 | * Set which chain we're assosiated with. This is how IRM messages make | ||
| 74 | * it out to the rest of the world. | ||
| 75 | *@param pNewChain A pointer to the containing program chain. | ||
| 76 | */ | ||
| 77 | void setChain( class ProgramChain *pNewChain ); | ||
| 78 | |||
| 79 | /** | ||
| 80 | * The pointer to the containing chain. | ||
| 81 | */ | ||
| 82 | class ProgramChain *pChain; | ||
| 83 | /* | ||
| 84 | void postMessage( LinkMessage *pMsg, int nLvl ); | ||
| 85 | LinkMessage *getMessage( int nLvl ); | ||
| 86 | |||
| 87 | enum | ||
| 88 | { | ||
| 89 | msgToChain, | ||
| 90 | msgToLink | ||
| 91 | }; | ||
| 92 | |||
| 93 | private: | ||
| 94 | Queue qMsgToChain; | ||
| 95 | Queue qMsgToLink; | ||
| 96 | */ | ||
| 97 | }; | ||
| 98 | } | ||
| 99 | |||
| 100 | #endif | ||
diff --git a/src/tafwriter.cpp b/src/tafwriter.cpp index 3e6c025..ac42d3d 100644 --- a/src/tafwriter.cpp +++ b/src/tafwriter.cpp | |||
| @@ -1,9 +1,32 @@ | |||
| 1 | #include "tafwriter.h" | 1 | #include "tafwriter.h" |
| 2 | 2 | ||
| 3 | Bu::TafWriter::TafWriter() | 3 | Bu::TafWriter::TafWriter( Bu::Stream &sOut ) : |
| 4 | sOut( sOut ) | ||
| 4 | { | 5 | { |
| 5 | } | 6 | } |
| 6 | 7 | ||
| 7 | Bu::TafWriter::~TafWriter() | 8 | Bu::TafWriter::~TafWriter() |
| 8 | { | 9 | { |
| 9 | } | 10 | } |
| 11 | |||
| 12 | void Bu::TafWriter::writeNode( Bu::TafNode *pRoot ) | ||
| 13 | { | ||
| 14 | sOut.write("{", 1 ); | ||
| 15 | writeString( pRoot->getName().getStr() ); | ||
| 16 | sOut.write(": ", 2 ); | ||
| 17 | sOut.write("}", 1 ); | ||
| 18 | } | ||
| 19 | |||
| 20 | void Bu::TafWriter::writeString( const Bu::FString &str ) | ||
| 21 | { | ||
| 22 | sOut.write("\"", 1 ); | ||
| 23 | for( const char *s = str.getStr(); *s; s++ ) | ||
| 24 | { | ||
| 25 | if( *s == '\"' ) | ||
| 26 | sOut.write("\\\"", 2 ); | ||
| 27 | else | ||
| 28 | sOut.write( s, 1 ); | ||
| 29 | } | ||
| 30 | sOut.write("\"", 1 ); | ||
| 31 | } | ||
| 32 | |||
diff --git a/src/tafwriter.h b/src/tafwriter.h index 7057d62..4310e62 100644 --- a/src/tafwriter.h +++ b/src/tafwriter.h | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | #define BU_TAF_WRITER_H | 2 | #define BU_TAF_WRITER_H |
| 3 | 3 | ||
| 4 | #include <stdint.h> | 4 | #include <stdint.h> |
| 5 | #include "bu/tafnode.h" | ||
| 6 | #include "bu/stream.h" | ||
| 7 | #include "bu/fstring.h" | ||
| 5 | 8 | ||
| 6 | namespace Bu | 9 | namespace Bu |
| 7 | { | 10 | { |
| @@ -11,11 +14,14 @@ namespace Bu | |||
| 11 | class TafWriter | 14 | class TafWriter |
| 12 | { | 15 | { |
| 13 | public: | 16 | public: |
| 14 | TafWriter(); | 17 | TafWriter( Bu::Stream &sOut ); |
| 15 | virtual ~TafWriter(); | 18 | virtual ~TafWriter(); |
| 16 | 19 | ||
| 17 | private: | 20 | void writeNode( Bu::TafNode *pRoot ); |
| 18 | 21 | ||
| 22 | private: | ||
| 23 | void writeString( const Bu::FString &str ); | ||
| 24 | Bu::Stream &sOut; | ||
| 19 | }; | 25 | }; |
| 20 | } | 26 | } |
| 21 | 27 | ||
