1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #ifndef __DECLMANAGER_H__
30 #define __DECLMANAGER_H__
31
32 #include "idlib/Lexer.h"
33
34 class idFile;
35
36 /*
37 ===============================================================================
38
39 Declaration Manager
40
41 All "small text" data types, like materials, sound shaders, fx files,
42 entity defs, etc. are managed uniformly, allowing reloading, purging,
43 listing, printing, etc. All "large text" data types that never have more
44 than one declaration in a given file, like maps, models, AAS files, etc.
45 are not handled here.
46
47 A decl will never, ever go away once it is created. The manager is
48 garranteed to always return the same decl pointer for a decl type/name
49 combination. The index of a decl in the per type list also stays the
50 same throughout the lifetime of the engine. Although the pointer to
51 a decl always stays the same, one should never maintain pointers to
52 data inside decls. The data stored in a decl is not garranteed to stay
53 the same for more than one engine frame.
54
55 The decl indexes of explicitely defined decls are garrenteed to be
56 consistent based on the parsed decl files. However, the indexes of
57 implicit decls may be different based on the order in which levels
58 are loaded.
59
60 The decl namespaces are separate for each type. Comments for decls go
61 above the text definition to keep them associated with the proper decl.
62
63 During decl parsing, errors should never be issued, only warnings
64 followed by a call to MakeDefault().
65
66 ===============================================================================
67 */
68
69 typedef enum {
70 DECL_TABLE = 0,
71 DECL_MATERIAL,
72 DECL_SKIN,
73 DECL_SOUND,
74 DECL_ENTITYDEF,
75 DECL_MODELDEF,
76 DECL_FX,
77 DECL_PARTICLE,
78 DECL_AF,
79 DECL_PDA,
80 DECL_VIDEO,
81 DECL_AUDIO,
82 DECL_EMAIL,
83 DECL_MODELEXPORT,
84 DECL_MAPDEF,
85
86 // new decl types can be added here
87
88 DECL_MAX_TYPES = 32
89 } declType_t;
90
91 typedef enum {
92 DS_UNPARSED,
93 DS_DEFAULTED, // set if a parse failed due to an error, or the lack of any source
94 DS_PARSED
95 } declState_t;
96
97 const int DECL_LEXER_FLAGS = LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated
98 LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings
99 LEXFL_ALLOWPATHNAMES | // allow path seperators in names
100 LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals
101 LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated
102 LEXFL_NOFATALERRORS; // just set a flag instead of fatal erroring
103
104
105 class idDeclBase {
106 public:
~idDeclBase()107 virtual ~idDeclBase() {};
108 virtual const char * GetName( void ) const = 0;
109 virtual declType_t GetType( void ) const = 0;
110 virtual declState_t GetState( void ) const = 0;
111 virtual bool IsImplicit( void ) const = 0;
112 virtual bool IsValid( void ) const = 0;
113 virtual void Invalidate( void ) = 0;
114 virtual void Reload( void ) = 0;
115 virtual void EnsureNotPurged( void ) = 0;
116 virtual int Index( void ) const = 0;
117 virtual int GetLineNum( void ) const = 0;
118 virtual const char * GetFileName( void ) const = 0;
119 virtual void GetText( char *text ) const = 0;
120 virtual int GetTextLength( void ) const = 0;
121 virtual void SetText( const char *text ) = 0;
122 virtual bool ReplaceSourceFileText( void ) = 0;
123 virtual bool SourceFileChanged( void ) const = 0;
124 virtual void MakeDefault( void ) = 0;
125 virtual bool EverReferenced( void ) const = 0;
126 virtual bool SetDefaultText( void ) = 0;
127 virtual const char * DefaultDefinition( void ) const = 0;
128 virtual bool Parse( const char *text, const int textLength ) = 0;
129 virtual void FreeData( void ) = 0;
130 virtual size_t Size( void ) const = 0;
131 virtual void List( void ) const = 0;
132 virtual void Print( void ) const = 0;
133 };
134
135
136 class idDecl {
137 public:
138 // The constructor should initialize variables such that
139 // an immediate call to FreeData() does no harm.
idDecl(void)140 idDecl( void ) { base = NULL; }
~idDecl(void)141 virtual ~idDecl( void ) {};
142
143 // Returns the name of the decl.
GetName(void)144 const char * GetName( void ) const { return base->GetName(); }
145
146 // Returns the decl type.
GetType(void)147 declType_t GetType( void ) const { return base->GetType(); }
148
149 // Returns the decl state which is usefull for finding out if a decl defaulted.
GetState(void)150 declState_t GetState( void ) const { return base->GetState(); }
151
152 // Returns true if the decl was defaulted or the text was created with a call to SetDefaultText.
IsImplicit(void)153 bool IsImplicit( void ) const { return base->IsImplicit(); }
154
155 // The only way non-manager code can have an invalid decl is if the *ByIndex()
156 // call was used with forceParse = false to walk the lists to look at names
157 // without touching the media.
IsValid(void)158 bool IsValid( void ) const { return base->IsValid(); }
159
160 // Sets state back to unparsed.
161 // Used by decl editors to undo any changes to the decl.
Invalidate(void)162 void Invalidate( void ) { base->Invalidate(); }
163
164 // if a pointer might possible be stale from a previous level,
165 // call this to have it re-parsed
EnsureNotPurged(void)166 void EnsureNotPurged( void ) { base->EnsureNotPurged(); }
167
168 // Returns the index in the per-type list.
Index(void)169 int Index( void ) const { return base->Index(); }
170
171 // Returns the line number the decl starts.
GetLineNum(void)172 int GetLineNum( void ) const { return base->GetLineNum(); }
173
174 // Returns the name of the file in which the decl is defined.
GetFileName(void)175 const char * GetFileName( void ) const { return base->GetFileName(); }
176
177 // Returns the decl text.
GetText(char * text)178 void GetText( char *text ) const { base->GetText( text ); }
179
180 // Returns the length of the decl text.
GetTextLength(void)181 int GetTextLength( void ) const { return base->GetTextLength(); }
182
183 // Sets new decl text.
SetText(const char * text)184 void SetText( const char *text ) { base->SetText( text ); }
185
186 // Saves out new text for the decl.
187 // Used by decl editors to replace the decl text in the source file.
ReplaceSourceFileText(void)188 bool ReplaceSourceFileText( void ) { return base->ReplaceSourceFileText(); }
189
190 // Returns true if the source file changed since it was loaded and parsed.
SourceFileChanged(void)191 bool SourceFileChanged( void ) const { return base->SourceFileChanged(); }
192
193 // Frees data and makes the decl a default.
MakeDefault(void)194 void MakeDefault( void ) { base->MakeDefault(); }
195
196 // Returns true if the decl was ever referenced.
EverReferenced(void)197 bool EverReferenced( void ) const { return base->EverReferenced(); }
198
199 public:
200 // Sets textSource to a default text if necessary.
201 // This may be overridden to provide a default definition based on the
202 // decl name. For instance materials may default to an implicit definition
203 // using a texture with the same name as the decl.
SetDefaultText(void)204 virtual bool SetDefaultText( void ) { return base->SetDefaultText(); }
205
206 // Each declaration type must have a default string that it is guaranteed
207 // to parse acceptably. When a decl is not explicitly found, is purged, or
208 // has an error while parsing, MakeDefault() will do a FreeData(), then a
209 // Parse() with DefaultDefinition(). The defaultDefintion should start with
210 // an open brace and end with a close brace.
DefaultDefinition(void)211 virtual const char * DefaultDefinition( void ) const { return base->DefaultDefinition(); }
212
213 // The manager will have already parsed past the type, name and opening brace.
214 // All necessary media will be touched before return.
215 // The manager will have called FreeData() before issuing a Parse().
216 // The subclass can call MakeDefault() internally at any point if
217 // there are parse errors.
Parse(const char * text,const int textLength)218 virtual bool Parse( const char *text, const int textLength ) { return base->Parse( text, textLength ); }
219
220 // Frees any pointers held by the subclass. This may be called before
221 // any Parse(), so the constructor must have set sane values. The decl will be
222 // invalid after issuing this call, but it will always be immediately followed
223 // by a Parse()
FreeData(void)224 virtual void FreeData( void ) { base->FreeData(); }
225
226 // Returns the size of the decl in memory.
Size(void)227 virtual size_t Size( void ) const { return base->Size(); }
228
229 // If this isn't overridden, it will just print the decl name.
230 // The manager will have printed 7 characters on the line already,
231 // containing the reference state and index number.
List(void)232 virtual void List( void ) const { base->List(); }
233
234 // The print function will already have dumped the text source
235 // and common data, subclasses can override this to dump more
236 // explicit data.
Print(void)237 virtual void Print( void ) const { base->Print(); }
238
239 public:
240 idDeclBase * base;
241 };
242
243
244 template< class type >
idDeclAllocator(void)245 ID_INLINE idDecl *idDeclAllocator( void ) {
246 return new type;
247 }
248
249
250 class idMaterial;
251 class idDeclSkin;
252 class idSoundShader;
253
254 class idDeclManager {
255 public:
~idDeclManager(void)256 virtual ~idDeclManager( void ) {}
257
258 virtual void Init( void ) = 0;
259 virtual void Shutdown( void ) = 0;
260 virtual void Reload( bool force ) = 0;
261
262 virtual void BeginLevelLoad() = 0;
263 virtual void EndLevelLoad() = 0;
264
265 // Registers a new decl type.
266 virtual void RegisterDeclType( const char *typeName, declType_t type, idDecl *(*allocator)( void ) ) = 0;
267
268 // Registers a new folder with decl files.
269 virtual void RegisterDeclFolder( const char *folder, const char *extension, declType_t defaultType ) = 0;
270
271 // Returns a checksum for all loaded decl text.
272 virtual int GetChecksum( void ) const = 0;
273
274 // Returns the number of decl types.
275 virtual int GetNumDeclTypes( void ) const = 0;
276
277 // Returns the type name for a decl type.
278 virtual const char * GetDeclNameFromType( declType_t type ) const = 0;
279
280 // Returns the decl type for a type name.
281 virtual declType_t GetDeclTypeFromName( const char *typeName ) const = 0;
282
283 // If makeDefault is true, a default decl of appropriate type will be created
284 // if an explicit one isn't found. If makeDefault is false, NULL will be returned
285 // if the decl wasn't explcitly defined.
286 virtual const idDecl * FindType( declType_t type, const char *name, bool makeDefault = true ) = 0;
287
288 virtual const idDecl* FindDeclWithoutParsing( declType_t type, const char *name, bool makeDefault = true ) = 0;
289
290 virtual void ReloadFile( const char* filename, bool force ) = 0;
291
292 // Returns the number of decls of the given type.
293 virtual int GetNumDecls( declType_t type ) = 0;
294
295 // The complete lists of decls can be walked to populate editor browsers.
296 // If forceParse is set false, you can get the decl to check name / filename / etc.
297 // without causing it to parse the source and load media.
298 virtual const idDecl * DeclByIndex( declType_t type, int index, bool forceParse = true ) = 0;
299
300 // List and print decls.
301 virtual void ListType( const idCmdArgs &args, declType_t type ) = 0;
302 virtual void PrintType( const idCmdArgs &args, declType_t type ) = 0;
303
304 // Creates a new default decl of the given type with the given name in
305 // the given file used by editors to create a new decls.
306 virtual idDecl * CreateNewDecl( declType_t type, const char *name, const char *fileName ) = 0;
307
308 // BSM - Added for the material editors rename capabilities
309 virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ) = 0;
310
311 // When media files are loaded, a reference line can be printed at a
312 // proper indentation if decl_show is set
313 virtual void MediaPrint( const char *fmt, ... ) id_attribute((format(printf,2,3))) = 0;
314
315 virtual void WritePrecacheCommands( idFile *f ) = 0;
316
317 // Convenience functions for specific types.
318 virtual const idMaterial * FindMaterial( const char *name, bool makeDefault = true ) = 0;
319 virtual const idDeclSkin * FindSkin( const char *name, bool makeDefault = true ) = 0;
320 virtual const idSoundShader * FindSound( const char *name, bool makeDefault = true ) = 0;
321
322 virtual const idMaterial * MaterialByIndex( int index, bool forceParse = true ) = 0;
323 virtual const idDeclSkin * SkinByIndex( int index, bool forceParse = true ) = 0;
324 virtual const idSoundShader * SoundByIndex( int index, bool forceParse = true ) = 0;
325 };
326
327 extern idDeclManager * declManager;
328
329
330 template< declType_t type >
idListDecls_f(const idCmdArgs & args)331 ID_INLINE void idListDecls_f( const idCmdArgs &args ) {
332 declManager->ListType( args, type );
333 }
334
335 template< declType_t type >
idPrintDecls_f(const idCmdArgs & args)336 ID_INLINE void idPrintDecls_f( const idCmdArgs &args ) {
337 declManager->PrintType( args, type );
338 }
339
340 #endif /* !__DECLMANAGER_H__ */
341