aboutsummaryrefslogtreecommitdiff
path: root/src/programchain.h
blob: 6d1666c9cbdbfa8fec5be8d9f313e04f3b0097ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
 *
 * This file is part of the libbu++ library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#ifndef BU_PROGRAMCHAIN_H
#define BU_PROGRAMCHAIN_H

#include "bu/list.h"
#include "bu/linkmessage.h"

namespace Bu
{
	class ProgramLink;
	/**
	 * The Program Chain links together program "chunks" to more easily facilitate
	 * a generalized program loop with modular extensions.
	 */
	class ProgramChain
	{
	public:
		/**
		 * Construct an empty chain.
		 */
		ProgramChain();

		/**
		 * Destroy your chain.
		 */
		virtual ~ProgramChain();

		/**
		 * Adds a link to the end of the chain.
		 *@param pLink A pointer to the link to add to the chain.
		 *@returns True if adding the link was successful, otherwise false
		 */
		bool addLink( Bu::ProgramLink *pLink );

		/**
		 * Gets a link by name.
		 *@param lpName The name of the link you're looking for.  Every link has a
		 * name, apparently.
		 *@returns A pointer to the specified ProgramLink, or NULL if none were
		 * found matching your criteria.
		 */
		class ProgramLink *getLink( const char *lpName );

		/**
		 * Gets the very first link in the chain.
		 *@returns A pointer to the first link in the chain.
		 */
		class ProgramLink *getBaseLink();

		/**
		 * Runs through the chain once.  Useful if you want to have more control
		 * over the operation of the chain.
		 *@returns true if every link returned true.  If at least one link returns
		 * false, then returns false.
		 */
		bool execChainOnce();

		/**
		 * Enters the master chain loop, looping over the entire chain and
		 * executing every link's TimeSlice routine in order, over and over, until
		 * a link returns a false value.
		 *@returns False, always.  It returns true unless a link returned false,
		 * but loops until a link does return false.
		 **/
		bool enterChainLoop();

		/**
		 * Broadcasts an Immediate Response Message to all active links, save the
		 * sender.  Whatever link first responds with a non-null response message
		 * will have it's messages sent back to the broadcasting link as the returns
		 * of this function call.  Therefore it is very important that all message
		 * processing code is handled in a fairly timely fasion.
		 *@param pMsgOut The message to broadcast in hopes of a response.
		 *@param pSender The message that sent out the message and doesn't want to
		 * receive it's own message.  This should always just be "this".
		 *@returns The message that was returned by the first link to return a
		 * non-null response.  If all messages return null responses then this also
		 * returns null.  Please note that whoever calls this will be responsible
		 * for deleting the message returned by it, if non-null.
		 */
		class LinkMessage *broadcastIRM( LinkMessage *pMsgOut, ProgramLink *pSender );

	private:
		/**
		 * Shuts down all operation no matter what point in the operation we were.
		 */
		void emergencyShutdown();
		Bu::List<Bu::ProgramLink *> lLink; /**< The linked list that contains all of the links. */
	};
}


#endif