summaryrefslogtreecommitdiff
path: root/public/movieobjects/dmemakefile.h
blob: 527b410ba6524616e96bfab070673560317beb97 (plain) (blame)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Describes the way to compile a MDL file (eventual replacement for qc)
//
//===========================================================================//

#ifndef DMEMAKEFILE_H
#define DMEMAKEFILE_H

#ifdef _WIN32
#pragma once
#endif

#include "datamodel/dmelement.h"
#include "datamodel/dmattribute.h"
#include "datamodel/dmattributevar.h"
#include "datamodel/dmehandle.h"
#include "vstdlib/iprocessutils.h"


//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CDmeMakefile;


//-----------------------------------------------------------------------------
// Returns a list of source types and whether there can be only 1 or not
//-----------------------------------------------------------------------------
struct DmeMakefileType_t
{
	const char *m_pTypeName;
	const char *m_pHumanReadableName;
	bool m_bIsSingleton;
	const char *m_pDefaultDirectoryID;	// NOTE: Use CDmeMakefile::GetDefaultDirectory, passing this in to crack it.
	const char *m_pFileFilter;
	const char *m_pFileFilterString;
};


//-----------------------------------------------------------------------------
// Describes an asset source; contains a source name + options
//-----------------------------------------------------------------------------
class CDmeSource : public CDmElement
{
	DEFINE_ELEMENT( CDmeSource, CDmElement );

public:
	// NOTE: Filenames are stored as relative file names in dmesource
	// To resolve them to full paths, use CDmeMakefile::GetSourceFullPath
	const char *GetRelativeFileName() const;
	void SetRelativeFileName( const char *pFileName );

	// If this source can be built by another makefile, return the type of makefile
	// NOTE: This can be a base class of a number of makefile types
	virtual const char **GetSourceMakefileTypes() { return NULL; }

	// Sets/gets the makefile that was used to build this source
	// NOTE: This information isn't saved and must be reconstructed each frame
	void SetDependentMakefile( CDmeMakefile *pMakeFile );
	CDmeMakefile *GetDependentMakefile();

	// Call this to open the source file in an editor
	void OpenEditor();

private:
	// The makefile that built this source
	CDmeHandle< CDmeMakefile > m_DependentMakefile;	
};


inline const char *CDmeSource::GetRelativeFileName() const
{
	return m_Name;
}

inline void CDmeSource::SetRelativeFileName( const char *pName )
{
	m_Name = pName;
}


//-----------------------------------------------------------------------------
// Describes an asset: something that is compiled from sources 
//-----------------------------------------------------------------------------
class CDmeMakefile : public CDmElement
{
	DEFINE_ELEMENT( CDmeMakefile, CDmElement );

public:
	// NOTE: Adding or removing sources of the specified type will invalidate the index
	// NOTE: This index is the same index used in GetSources()
	CDmeSource *AddSource( const char *pSourceType, const char *pFullPath );
	template< class T >
	T* AddSource( const char *pFullPath );
	CDmeSource *SetSingleSource( const char *pSourceType, const char *pFullPath );
	template< class T >
	T* SetSingleSource( const char *pFullPath );
	CDmeSource *FindSource( const char *pSourceType, const char *pFullPath );
	void RemoveSource( const char *pSourceType, const char *pFullPath );
	void RemoveSource( CDmeSource *pSource );
	void RemoveAllSources( const char *pSourceType );
	bool HasSourceOfType( const char *pSourceType );

	// Gets/sets paths associated with sources
	void SetSourceFullPath( CDmeSource *pSource, const char *pFullPath );
	void GetSourceFullPath( CDmeSource *pSource, char *pFullPath, int nBufLen );

	// Returns the output directory we expect to compile files into
	bool GetOutputDirectory( char *pFullPath, int nBufLen );

	// Returns the output name (output directory + filename, no extension)
	bool GetOutputName( char *pFullPath, int nBufLen );

	// Call this to change the file the makefile is stored in
	// Will make all sources be relative to this path
	bool SetFileName( const char *pFileName );
	const char *GetFileName() const;

	// Gets a list of all sources of a particular type
	void GetSources( const char *pSourceType, CUtlVector< CDmeHandle< CDmeSource > > &sources );
	template< class T >
	void GetSources( CUtlVector< CDmeHandle<T> > &sources );

	// Gets a list of all sources, regardless of type
	int GetSourceCount();
	CDmeSource *GetSource( int nIndex );

	virtual DmeMakefileType_t *GetMakefileType() { return NULL; }
	virtual DmeMakefileType_t* GetSourceTypes() { Assert(0); return NULL; }

	// FIXME: Should we have output types? Not sure...
	virtual void GetOutputs( CUtlVector<CUtlString> &fullPaths ) { Assert(0); }

	// Converts the m_pDefaultDirectoryID field of the DmeMakefileType_t to a full path
	bool GetDefaultDirectory( const char *pDefaultDirectoryID, char *pFullPath, int nBufLen );

	// These methods are used to help traverse a dependency graph.
	// They work with information that is not saved.
	void SetAssociation( CDmeSource *pSource, CDmeMakefile *pSourceMakefile );
	CDmeMakefile *FindDependentMakefile( CDmeSource *pSource );
	CDmeSource *FindAssociatedSource( CDmeMakefile *pChildMakefile );
	CDmElement *GetOutputElement( bool bCreateIfNecessary = false );

	// Performs compilation steps
	void PreCompile( );
	void PostCompile( );

	// Dirty, dirty!
	bool IsDirty() const;
	void SetDirty( bool bDirty );

protected:
	// Make all outputs writeable
	void MakeOutputsWriteable( );

	// Gets the path of the makefile
	void GetMakefilePath( char *pFullPath, int nBufLen );

private:
	// Inherited classes should re-implement these methods
	virtual CDmElement *CreateOutputElement( ) { return NULL; }
	virtual void DestroyOutputElement( CDmElement *pOutput ) { }
	virtual ProcessHandle_t PerformCompilation() { Assert(0); return PROCESS_HANDLE_INVALID; }
	virtual const char *GetOutputDirectoryID() { return "makefilegamedir:"; }

private:
	// Relative path to full path
	void RelativePathToFullPath( const char *pRelativePath, char *pFullPath, int nBufLen );

	// Fullpath to relative path
	void FullPathToRelativePath( const char *pFullPath, char *pRelativePath, int nBufLen );

	// Updates the source names to be relative to a particular path
	bool UpdateSourceNames( const char *pOldRootDir, const char *pNewRootDir, bool bApplyChanges );

	CDmaElementArray< CDmeSource > m_Sources;
	CDmeHandle< CDmElement > m_hOutput;
	ProcessHandle_t m_hCompileProcess;
	bool m_bIsDirty;
};


//-----------------------------------------------------------------------------
// Dirty, dirty!
//-----------------------------------------------------------------------------
inline bool CDmeMakefile::IsDirty() const
{
	return m_bIsDirty;
}

inline void CDmeMakefile::SetDirty( bool bDirty )
{
	m_bIsDirty = bDirty;
}


//-----------------------------------------------------------------------------
// Gets a list of all sources of a particular type
//-----------------------------------------------------------------------------
template< class T >
void CDmeMakefile::GetSources( CUtlVector< CDmeHandle<T> > &sources )
{
	int nCount = m_Sources.Count();
	sources.EnsureCapacity( nCount );
	for ( int i = 0; i < nCount; ++i )
	{
		if ( m_Sources[i]->IsA( T::GetStaticTypeSymbol() ) )
		{
			int j = sources.AddToTail();
			sources[j] = CastElement<T>( m_Sources[i] );
		}
	}
}


//-----------------------------------------------------------------------------
// Template version to add a source
//-----------------------------------------------------------------------------
template< class T >
T* CDmeMakefile::AddSource( const char *pFullPath )
{
	return CastElement< T >( AddSource( g_pDataModel->GetString( T::GetStaticTypeSymbol() ), pFullPath ) );
}


//-----------------------------------------------------------------------------
// Template version to set a single source
//-----------------------------------------------------------------------------
template< class T >
T* CDmeMakefile::SetSingleSource( const char *pFullPath )
{
	return CastElement< T >( SetSingleSource( g_pDataModel->GetString( T::GetStaticTypeSymbol() ), pFullPath ) );
}


#endif // DMEMAKEFILE_H