aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/linkmessage.cpp (renamed from src/old/linkmessage.cpp)7
-rw-r--r--src/linkmessage.h42
-rw-r--r--src/old/linkmessage.h39
-rw-r--r--src/old/plugger.h198
-rw-r--r--src/old/programchain.cpp96
-rw-r--r--src/old/programchain.h95
-rw-r--r--src/old/programlink.h99
-rw-r--r--src/plugger.cpp (renamed from src/old/plugger.cpp)0
-rw-r--r--src/plugger.h196
-rw-r--r--src/programchain.cpp97
-rw-r--r--src/programchain.h98
-rw-r--r--src/programlink.cpp (renamed from src/old/programlink.cpp)14
-rw-r--r--src/programlink.h100
-rw-r--r--src/tafwriter.cpp25
-rw-r--r--src/tafwriter.h10
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
4LinkMessage::LinkMessage( int nNewMsg ) 3Bu::LinkMessage::LinkMessage( int nNewMsg )
5{ 4{
6 nMsg = nNewMsg; 5 nMsg = nNewMsg;
7} 6}
8 7
9LinkMessage::~LinkMessage() 8Bu::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
7namespace 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 */
13class LinkMessage
14{
15public:
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
12typedef 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
22typedef struct PluginReg
23{
24 bool bBuiltin;
25 void *dlHandle;
26 PluginInfo *pInfo;
27} PluginReg;
28
29#define PluginInterface( classname, baseclass, name, ver, rev ) \
30extern "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 ) \
45extern "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 ) \
61extern "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
76template<class T>
77class Plugger
78{
79public:
80
81public:
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
192private:
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
4ProgramChain::ProgramChain() :
5 xLog( MultiLog::getInstance() )
6{
7 xLog.LineLog( MultiLog::LStatus, "Program Chain Initialized." );
8}
9
10ProgramChain::~ProgramChain()
11{
12}
13
14bool 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
29ProgramLink *ProgramChain::getLink( const char *lpName )
30{
31 char a;
32 a = lpName[0];
33 return NULL;
34}
35
36ProgramLink *ProgramChain::getBaseLink()
37{
38 return NULL;
39}
40
41bool 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
57bool ProgramChain::enterChainLoop()
58{
59 for(;;)
60 {
61 if( execChainOnce() == false )
62 {
63 return false;
64 }
65 }
66
67 return true;
68}
69
70void 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
81LinkMessage *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 */
13class ProgramChain
14{
15public:
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
86private:
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
4class 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 */
14class ProgramLink
15{
16friend class ProgramChain;
17public:
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
71private:
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
93private:
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
11namespace 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
5using namespace Bu;
6
7Bu::ProgramChain::ProgramChain()
8{
9}
10
11Bu::ProgramChain::~ProgramChain()
12{
13}
14
15bool 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
30ProgramLink *Bu::ProgramChain::getLink( const char *lpName )
31{
32 char a;
33 a = lpName[0];
34 return NULL;
35}
36
37ProgramLink *Bu::ProgramChain::getBaseLink()
38{
39 return NULL;
40}
41
42bool 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
57bool Bu::ProgramChain::enterChainLoop()
58{
59 for(;;)
60 {
61 if( execChainOnce() == false )
62 {
63 return false;
64 }
65 }
66
67 return true;
68}
69
70void 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
81LinkMessage *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
7namespace 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
4ProgramLink::ProgramLink() 4using namespace Bu;
5
6Bu::ProgramLink::ProgramLink()
5{ 7{
6} 8}
7 9
8ProgramLink::~ProgramLink() 10Bu::ProgramLink::~ProgramLink()
9{ 11{
10} 12}
11 13
12LinkMessage *ProgramLink::sendIRM( LinkMessage *pMsgOut ) 14LinkMessage *Bu::ProgramLink::sendIRM( LinkMessage *pMsgOut )
13{ 15{
14 return pChain->broadcastIRM( pMsgOut, this ); 16 return pChain->broadcastIRM( pMsgOut, this );
15} 17}
16 18
17void ProgramLink::setChain( ProgramChain *pNewChain ) 19void 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
7namespace 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
3Bu::TafWriter::TafWriter() 3Bu::TafWriter::TafWriter( Bu::Stream &sOut ) :
4 sOut( sOut )
4{ 5{
5} 6}
6 7
7Bu::TafWriter::~TafWriter() 8Bu::TafWriter::~TafWriter()
8{ 9{
9} 10}
11
12void 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
20void 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
6namespace Bu 9namespace 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