1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 #pragma once
24 
25 // Sequencer Header File
26 #include "blockstream.h"
27 #include "interface.h"
28 #include "taskmanager.h"
29 #include "sequence.h"
30 
31 #include <list>
32 #include <vector>
33 #include <map>
34 
35 //Defines
36 #define SQ_COMMON		0x00000000 	//Common one-pass sequence
37 #define	SQ_LOOP			0x00000001 	//Looping sequence
38 #define SQ_RETAIN		0x00000002 	//Inside a looping sequence list, retain the information
39 #define SQ_AFFECT		0x00000004 	//Affect sequence
40 #define SQ_RUN			0x00000008	//A run block
41 #define SQ_PENDING		0x00000010	//Pending use, don't free when flushing the sequences
42 #define SQ_CONDITIONAL	0x00000020	//Conditional statement
43 #define SQ_TASK			0x00000040	//Task block
44 
45 #define	BF_ELSE			0x00000001	//Block has an else id	//FIXME: This was a sloppy fix for a problem that arose from conditionals
46 
47 #define S_FAILED(a) (a!=SEQ_OK)
48 
49 //const int MAX_ERROR_LENGTH	= 256;
50 
51 //Typedefs
52 
53 typedef struct bstream_s
54 {
55 	CBlockStream *stream;
56 	bstream_s	 *last;
57 } bstream_t;
58 
59 //Enumerations
60 
61 enum
62 {
63 	SEQ_OK,				//Command was successfully added
64 	SEQ_FAILED,			//An error occured while trying to insert the command
65 };
66 
67 // Sequencer
68 
69 class ICARUS_Instance;
70 
71 /*
72 ==================================================================================================
73 
74   CSequencer
75 
76 ==================================================================================================
77 */
78 
79 class CSequencer
80 {
81 //	typedef	map < int, CSequence * >			sequenceID_m;
82 	typedef std::list < CSequence * >				sequence_l;
83 	typedef std::map < CTaskGroup *, CSequence * >	taskSequence_m;
84 
85 public:
86 
87 	CSequencer();
88 	~CSequencer();
89 
90 	int Init( int ownerID, interface_export_t *ie, CTaskManager *taskManager, ICARUS_Instance *iCARUS );
91 	static CSequencer *Create ( void );
92 	int Free( void );
93 
94 	int Run( char *buffer, long size );
95 	int Callback( CTaskManager *taskManager, CBlock *block, int returnCode );
96 
GetOwner(void)97 	ICARUS_Instance	*GetOwner( void )	{	return m_owner;	}
98 
SetOwnerID(int owner)99 	void SetOwnerID( int owner )	{	m_ownerID = owner;}
100 
GetOwnerID(void)101 	int	GetOwnerID( void )						const	{	return m_ownerID;	}
GetInterface(void)102 	interface_export_t *GetInterface( void )	const	{	return m_ie;			}
GetTaskManager(void)103 	CTaskManager *GetTaskManager( void )		const	{	return m_taskManager;	}
104 
SetTaskManager(CTaskManager * tm)105 	void SetTaskManager( CTaskManager *tm)	{	if ( tm )	m_taskManager = tm;	}
106 
107 	int Save( void );
108 	int Load( void );
109 
110 	// Overloaded new operator.
new(size_t size)111 	inline void *operator new( size_t size )
112 	{	// Allocate the memory.
113 		return Z_Malloc( size, TAG_ICARUS2, qtrue );
114 	}
115 	// Overloaded delete operator.
delete(void * pRawData)116 	inline void operator delete( void *pRawData )
117 	{	// Free the Memory.
118 		Z_Free( pRawData );
119 	}
120 
121 // moved to public on 2/12/2 to allow calling during shutdown
122 	int Recall( void );
123 protected:
124 
125 	int EvaluateConditional( CBlock *block );
126 
127 	int Route( CSequence *sequence, bstream_t *bstream );
128 	int Flush( CSequence *owner );
129 	void Interrupt( void );
130 
131 	bstream_t *AddStream( void );
132 	void DeleteStream( bstream_t *bstream );
133 
134 	int AddAffect( bstream_t *bstream, int retain, int *id );
135 
136 	CSequence *AddSequence( void );
137 	CSequence *AddSequence( CSequence *parent, CSequence *returnSeq, int flags );
138 
139 	CSequence *GetSequence( int id );
140 
141 	//NOTENOTE: This only removes references to the sequence, IT DOES NOT FREE THE ALLOCATED MEMORY!
142 	int RemoveSequence( CSequence *sequence);
143 	int DestroySequence( CSequence *sequence);
144 
145 	int PushCommand( CBlock *command, int flag );
146 	CBlock *PopCommand( int flag );
147 
148 	inline CSequence *ReturnSequence( CSequence *sequence );
149 
150 	void CheckRun( CBlock ** );
151 	void CheckLoop( CBlock ** );
152 	void CheckAffect( CBlock ** );
153 	void CheckIf( CBlock ** );
154 	void CheckDo( CBlock ** );
155 	void CheckFlush( CBlock ** );
156 
157 	void Prep( CBlock ** );
158 
159 	int Prime( CTaskManager *taskManager, CBlock *command );
160 
161 	int ParseRun( CBlock *block );
162 	int ParseLoop( CBlock *block, bstream_t *bstream );
163 	int ParseAffect( CBlock *block, bstream_t *bstream );
164 	int ParseIf( CBlock *block, bstream_t *bstream );
165 	int ParseElse( CBlock *block, bstream_t *bstream );
166 	int ParseTask( CBlock *block, bstream_t *bstream );
167 
168 	int Affect( int id, int type );
169 
170 	void AddTaskSequence( CSequence *sequence, CTaskGroup *group );
171 	CSequence *GetTaskSequence( CTaskGroup *group );
172 
173 	//Member variables
174 
175 	ICARUS_Instance		*m_owner;
176 	int					m_ownerID;
177 
178 	CTaskManager		*m_taskManager;
179 	interface_export_t	*m_ie;				//This is unique to the sequencer so that client side and server side sequencers could both
180 											//operate under different interfaces (for client side scripting)
181 
182 	int					m_numCommands;		//Total number of commands for the sequencer (including all child sequences)
183 
184 //	sequenceID_m		m_sequenceMap;
185 	sequence_l			m_sequences;
186 	taskSequence_m		m_taskSequences;
187 
188 	CSequence			*m_curSequence;
189 	CTaskGroup			*m_curGroup;
190 
191 	bstream_t			*m_curStream;
192 
193 	int					m_elseValid;
194 	CBlock				*m_elseOwner;
195 	std::vector<bstream_t*>  m_streamsCreated;
196 };
197