mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-01-05 17:13:36 +08:00
877 lines
38 KiB
C++
877 lines
38 KiB
C++
//============ Copyright (c) Valve Corporation, All rights reserved. ============
|
|
//
|
|
// Definition of many useful tilegen expressions which can be
|
|
// evaluated to return values.
|
|
//
|
|
//===============================================================================
|
|
|
|
#ifndef TILEGEN_EXPRESSIONS_H
|
|
#define TILEGEN_EXPRESSIONS_H
|
|
|
|
#if defined( COMPILER_MSVC )
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "utldict.h"
|
|
#include "stringpool.h"
|
|
#include "tilegen_core.h"
|
|
#include "tilegen_class_interfaces.h"
|
|
#include "tilegen_class_factories.h"
|
|
|
|
class CRoom;
|
|
class CRoomTemplate;
|
|
class CRoomCandidate;
|
|
class CExit;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// A dictionary that maps variable names to void * values
|
|
// which represent "free variable" state used by expressions ("closures").
|
|
//-----------------------------------------------------------------------------
|
|
class CFreeVariableMap : public CUtlDict< void *, int >
|
|
{
|
|
public:
|
|
//-----------------------------------------------------------------------------
|
|
// Gets the value of a free variable and returns NULL if not present.
|
|
//-----------------------------------------------------------------------------
|
|
void *GetFreeVariableOrNULL( const char *pName ) const;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets the value of a free variable and reports an error if
|
|
// not present or NULL valued.
|
|
//-----------------------------------------------------------------------------
|
|
void *GetFreeVariable( const char *pName ) const;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets the value of a free variable and reports an error if
|
|
// not present or NULL valued.
|
|
//-----------------------------------------------------------------------------
|
|
void *GetFreeVariableDisallowNULL( const char *pName ) const;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Sets the value of an existing free variable or creates a
|
|
// new one if none is found.
|
|
//-----------------------------------------------------------------------------
|
|
void SetOrCreateFreeVariable( const char *pName, void *pValue );
|
|
|
|
// Actions/expressions that operate on string variables can ignore
|
|
// memory management and toss their data in the string pool.
|
|
CStringPool m_StringPool;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// A binary expression which evaluates two sub-expressions of the same type
|
|
// and returns a value of another type.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TReturn, typename TParam >
|
|
class CTilegenExpression_Binary : public ITilegenExpression< TReturn >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_Binary( ITilegenExpression< TParam > *pExpressionL = NULL, ITilegenExpression< TParam > *pExpressionR = NULL )
|
|
{
|
|
m_pExpression[0] = pExpressionL;
|
|
m_pExpression[1] = pExpressionR;
|
|
}
|
|
|
|
virtual ~CTilegenExpression_Binary() { delete m_pExpression[0]; delete m_pExpression[1]; }
|
|
|
|
// Used to initialize expressions by setting parameters in a general fashion
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
bool bSuccess = true;
|
|
bSuccess &= CreateExpressionFromKeyValuesBlock( pKeyValues, "param0", GetTypeName(), &m_pExpression[0] );
|
|
bSuccess &= CreateExpressionFromKeyValuesBlock( pKeyValues, "param1", GetTypeName(), &m_pExpression[1] );
|
|
return bSuccess;
|
|
}
|
|
|
|
virtual TReturn Evaluate( CFreeVariableMap *pContext ) { return DirectEvaluate( pContext, m_pExpression[0]->Evaluate( pContext ), m_pExpression[1]->Evaluate( pContext ) ); }
|
|
virtual TReturn DirectEvaluate( CFreeVariableMap *pContext, const TParam ¶m1, const TParam ¶m2 ) = 0;
|
|
|
|
protected:
|
|
ITilegenExpression< TParam > *m_pExpression[2];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Define common binary operators here.
|
|
//-----------------------------------------------------------------------------
|
|
#define DEFINE_BINARY_OPERATOR( OperatorName, ReturnType, ParameterType, Operator ) \
|
|
class OperatorName : public CTilegenExpression_Binary< ReturnType, ParameterType > \
|
|
{ \
|
|
public: \
|
|
explicit OperatorName( ITilegenExpression< ParameterType > *pL = NULL, ITilegenExpression< ParameterType > *pR = NULL ) : CTilegenExpression_Binary( pL, pR ) { } \
|
|
virtual ReturnType Evaluate( CFreeVariableMap *pContext ) { return m_pExpression[0]->Evaluate( pContext ) Operator m_pExpression[1]->Evaluate( pContext ); } \
|
|
virtual ReturnType DirectEvaluate( CFreeVariableMap *pContext, const ParameterType ¶m1, const ParameterType ¶m2 ) { return param1 Operator param2; } \
|
|
virtual const char *GetTypeName(); \
|
|
}
|
|
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_Greater, bool, int, > );
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_GreaterOrEqual, bool, int, >= );
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_Equal, bool, int, == );
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_NotEqual, bool, int, != );
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_Less, bool, int, < );
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_LessOrEqual, bool, int, <= );
|
|
DEFINE_BINARY_OPERATOR( CTilegenExpression_Subtract, int, int, - );
|
|
|
|
#undef DEFINE_BINARY_OPERATOR
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Tests two strings for equality (case insensitive).
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_StringEqual : public CTilegenExpression_Binary< bool, const char * >
|
|
{
|
|
public:
|
|
typedef const char * ParameterType;
|
|
CTilegenExpression_StringEqual( ITilegenExpression< const char * > *pL = NULL, ITilegenExpression< const char * > *pR = NULL ) : CTilegenExpression_Binary( pL, pR ) { }
|
|
virtual bool DirectEvaluate( CFreeVariableMap *pContext, const ParameterType ¶m1, const ParameterType ¶m2 ) { return Q_stricmp( param1, param2 ) == 0; }
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Tests two strings for inequality (case insensitive).
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_StringNotEqual : public CTilegenExpression_Binary< bool, const char * >
|
|
{
|
|
public:
|
|
typedef const char * ParameterType;
|
|
CTilegenExpression_StringNotEqual( ITilegenExpression< const char * > *pL = NULL, ITilegenExpression< const char * > *pR = NULL ) : CTilegenExpression_Binary( pL, pR ) { }
|
|
virtual bool DirectEvaluate( CFreeVariableMap *pContext, const ParameterType ¶m1, const ParameterType ¶m2 ) { return Q_stricmp( param1, param2 ) != 0; }
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Concatenates two strings, returns the result.
|
|
// The result is cached & stored in the string pool.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_StringConcatenate : public CTilegenExpression_Binary< const char *, const char * >
|
|
{
|
|
public:
|
|
typedef const char * ParameterType;
|
|
CTilegenExpression_StringConcatenate( ITilegenExpression< const char * > *pL = NULL, ITilegenExpression< const char * > *pR = NULL ) : CTilegenExpression_Binary( pL, pR ) { }
|
|
virtual const char *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType ¶m1, const ParameterType ¶m2 );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Define common binary operators here.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TParam >
|
|
class CTilegenExpression_Multi : public ITilegenExpression< TParam >
|
|
{
|
|
public:
|
|
CTilegenExpression_Multi() { }
|
|
|
|
virtual ~CTilegenExpression_Multi() { m_Expressions.PurgeAndDeleteElements(); }
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
for ( KeyValues *pSubKey = pKeyValues->GetFirstSubKey(); pSubKey != NULL; pSubKey = pSubKey->GetNextKey() )
|
|
{
|
|
if ( Q_stricmp( pSubKey->GetName(), "param" ) == 0 )
|
|
{
|
|
ITilegenExpression< TParam > *pExpression = CreateFromKeyValues< ITilegenExpression< TParam > >( pSubKey );
|
|
if ( !pExpression )
|
|
{
|
|
return false;
|
|
}
|
|
m_Expressions.AddToTail( pExpression );
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
virtual TParam Evaluate( CFreeVariableMap *pContext )
|
|
{
|
|
if ( m_Expressions.Count() == 0 )
|
|
{
|
|
return GetIdentityValue();
|
|
}
|
|
else if ( m_Expressions.Count() == 1 )
|
|
{
|
|
return m_Expressions[0]->Evaluate( pContext );
|
|
}
|
|
else
|
|
{
|
|
TParam currentValue = DirectEvaluate( pContext, m_Expressions[0]->Evaluate( pContext ), m_Expressions[1]->Evaluate( pContext ) );
|
|
for ( int i = 2; i < m_Expressions.Count(); ++ i )
|
|
{
|
|
currentValue = DirectEvaluate( pContext, currentValue, m_Expressions[i]->Evaluate( pContext ) );
|
|
}
|
|
return currentValue;
|
|
}
|
|
}
|
|
|
|
virtual TParam DirectEvaluate( CFreeVariableMap *pContext, const TParam ¶m1, const TParam ¶m2 ) = 0;
|
|
virtual TParam GetIdentityValue() = 0;
|
|
|
|
private:
|
|
CUtlVector< ITilegenExpression< TParam > * > m_Expressions;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Define common multi operators here.
|
|
//-----------------------------------------------------------------------------
|
|
#define DEFINE_MULTI_OPERATOR( OperatorName, ParameterType, Operator, IdentityValue ) \
|
|
class OperatorName : public CTilegenExpression_Multi< ParameterType > \
|
|
{ \
|
|
public: \
|
|
OperatorName() { } \
|
|
virtual ParameterType DirectEvaluate( CFreeVariableMap *pContext, const TExpressionValue ¶m1, const TExpressionValue ¶m2 ) { return param1 Operator param2; } \
|
|
virtual TExpressionValue GetIdentityValue() { return IdentityValue; } \
|
|
virtual const char *GetTypeName(); \
|
|
}
|
|
|
|
DEFINE_MULTI_OPERATOR( CTilegenExpression_Add, int, +, 0 );
|
|
|
|
// Floating point operators are in the minority, so they are preceded by "Float" (integers are the default)
|
|
DEFINE_MULTI_OPERATOR( CTilegenExpression_FloatMultiply, float, *, 0.0f );
|
|
|
|
DEFINE_MULTI_OPERATOR( CTilegenExpression_And, bool, &&, true );
|
|
DEFINE_MULTI_OPERATOR( CTilegenExpression_Or, bool, ||, false );
|
|
|
|
#undef DEFINE_MULTI_OPERATOR
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// A unary expression which evaluates one sub-expression of some type
|
|
// and returns a value of another type.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TReturn, typename TParam >
|
|
class CTilegenExpression_Unary : public ITilegenExpression< TReturn >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_Unary( ITilegenExpression< TParam > *pExpression = NULL ) :
|
|
m_pExpression( pExpression )
|
|
{
|
|
}
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
return CreateExpressionFromKeyValuesBlock( pKeyValues, "param", GetTypeName(), &m_pExpression );
|
|
}
|
|
|
|
virtual TReturn Evaluate( CFreeVariableMap *pContext ) { return DirectEvaluate( pContext, m_pExpression->Evaluate( pContext ) ); }
|
|
virtual TReturn DirectEvaluate( CFreeVariableMap *pContext, const TParam ¶m ) = 0;
|
|
|
|
virtual ~CTilegenExpression_Unary() { delete m_pExpression; }
|
|
|
|
protected:
|
|
ITilegenExpression< TParam > *m_pExpression;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Define common unary operators here.
|
|
//-----------------------------------------------------------------------------
|
|
#define DEFINE_UNARY_OPERATOR( OperatorName, ReturnType, ParameterType, Operator ) \
|
|
class OperatorName : public CTilegenExpression_Unary< ReturnType, ParameterType > \
|
|
{ \
|
|
public: \
|
|
explicit OperatorName( ITilegenExpression< ParameterType > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { } \
|
|
virtual ReturnType DirectEvaluate( CFreeVariableMap *pContext, const ParameterType ¶m ) { return Operator param; } \
|
|
virtual const char *GetTypeName(); \
|
|
}
|
|
|
|
DEFINE_UNARY_OPERATOR( CTilegenExpression_Not, bool, bool, ! );
|
|
DEFINE_UNARY_OPERATOR( CTilegenExpression_BoolToInt, int, bool, (int) );
|
|
DEFINE_UNARY_OPERATOR( CTilegenExpression_IntToBool, bool, int, !! );
|
|
DEFINE_UNARY_OPERATOR( CTilegenExpression_FloatToInt, int, float, (int) );
|
|
DEFINE_UNARY_OPERATOR( CTilegenExpression_IntToFloat, float, int, (float) );
|
|
|
|
#undef DEFINE_UNARY_OPERATOR
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the room name string from a room template.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_RoomName : public CTilegenExpression_Unary< const char *, const CRoomTemplate * >
|
|
{
|
|
public:
|
|
typedef const CRoomTemplate * ParameterType;
|
|
CTilegenExpression_RoomName( ITilegenExpression< const CRoomTemplate * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual const char *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pRoomTemplate );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the area of a room template.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_RoomArea : public CTilegenExpression_Unary< int, const CRoomTemplate * >
|
|
{
|
|
public:
|
|
typedef const CRoomTemplate * ParameterType;
|
|
CTilegenExpression_RoomArea( ITilegenExpression< const CRoomTemplate * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual int DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pRoomTemplate );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the room name string from a joint "Theme\RoomName" string
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_ExtractRoomName : public CTilegenExpression_Unary< const char *, const char * >
|
|
{
|
|
public:
|
|
typedef const char * ParameterType;
|
|
CTilegenExpression_ExtractRoomName( ITilegenExpression< const char * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual const char *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pFullRoomName );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the theme name string from a joint "Theme\RoomName" string
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_ExtractThemeName : public CTilegenExpression_Unary< const char *, const char * >
|
|
{
|
|
public:
|
|
typedef const char * ParameterType;
|
|
CTilegenExpression_ExtractThemeName( ITilegenExpression< const char * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual const char *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pFullRoomName );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the last placed room.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_LastPlacedRoom : public ITilegenExpression< const CRoom * >
|
|
{
|
|
public:
|
|
CTilegenExpression_LastPlacedRoom() { }
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues ) { return true; }
|
|
virtual const CRoom *Evaluate( CFreeVariableMap *pContext );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the source room from an exit.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_SourceRoomFromExit : public CTilegenExpression_Unary< const CRoom *, const CExit * >
|
|
{
|
|
public:
|
|
typedef const CExit * ParameterType;
|
|
CTilegenExpression_SourceRoomFromExit( ITilegenExpression< const CExit * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual const CRoom *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pExit );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the source room template from an exit.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_SourceRoomTemplateFromExit : public CTilegenExpression_Unary< const CRoomTemplate *, const CExit * >
|
|
{
|
|
public:
|
|
typedef const CExit * ParameterType;
|
|
CTilegenExpression_SourceRoomTemplateFromExit( ITilegenExpression< const CExit * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual const CRoomTemplate *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pExit );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a value indicating whether this room is a chokepoint grow source.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_ChokepointGrowSource : public CTilegenExpression_Unary< bool, const CExit * >
|
|
{
|
|
public:
|
|
typedef const CExit * ParameterType;
|
|
CTilegenExpression_ChokepointGrowSource( ITilegenExpression< const CExit * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual bool DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pExit );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the number of rooms which have sprouted from a given room.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_RoomChildCount : public CTilegenExpression_Unary< int, const CRoom * >
|
|
{
|
|
public:
|
|
typedef const CRoom * ParameterType;
|
|
CTilegenExpression_RoomChildCount( ITilegenExpression< const CRoom * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual int DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pRoom );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets a room template by name.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_RoomTemplateFromName : public CTilegenExpression_Unary< const CRoomTemplate *, const char * >
|
|
{
|
|
public:
|
|
typedef const char * ParameterType;
|
|
CTilegenExpression_RoomTemplateFromName( ITilegenExpression< const char * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual const CRoomTemplate *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pName );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
class CTilegenExpression_XPosition : public CTilegenExpression_Unary< int, const CRoomCandidate * >
|
|
{
|
|
public:
|
|
typedef const CRoomCandidate * ParameterType;
|
|
CTilegenExpression_XPosition( ITilegenExpression< const CRoomCandidate * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual int DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pRoomCandidate );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
class CTilegenExpression_YPosition : public CTilegenExpression_Unary< int, const CRoomCandidate * >
|
|
{
|
|
public:
|
|
typedef const CRoomCandidate * ParameterType;
|
|
CTilegenExpression_YPosition( ITilegenExpression< const CRoomCandidate * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual int DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pRoomCandidate );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a boolean value indicating whether a given room template
|
|
// has a given string tag.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_HasTag : public ITilegenExpression< bool >
|
|
{
|
|
public:
|
|
CTilegenExpression_HasTag( ITilegenExpression< const CRoomTemplate * > *pRoomTemplateExpression = NULL, ITilegenExpression< const char * > *pTagExpression = NULL );
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues );
|
|
virtual bool Evaluate( CFreeVariableMap *pContext );
|
|
virtual const char *GetTypeName();
|
|
|
|
private:
|
|
ITilegenExpression< const CRoomTemplate * > *m_pRoomTemplateExpression;
|
|
ITilegenExpression< const char * > *m_pTagExpression;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Tests for the presence of several known tags which imply
|
|
// that a room template should not be placed randomly.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_CanPlaceRandomly : public ITilegenExpression< bool >
|
|
{
|
|
public:
|
|
CTilegenExpression_CanPlaceRandomly( ITilegenExpression< const CRoomTemplate * > *pRoomTemplateExpression = NULL );
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues );
|
|
virtual bool Evaluate( CFreeVariableMap *pContext );
|
|
virtual const char *GetTypeName();
|
|
|
|
private:
|
|
ITilegenExpression< const CRoomTemplate * > *m_pRoomTemplateExpression;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the number of times a room template has already been placed.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_NumTimesPlaced : public CTilegenExpression_Unary< int, const CRoomTemplate * >
|
|
{
|
|
public:
|
|
typedef const CRoomTemplate * ParameterType;
|
|
CTilegenExpression_NumTimesPlaced( ITilegenExpression< const CRoomTemplate * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
virtual int DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pRoomTemplate );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the exit tag string from an exit.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_ExitTag : public CTilegenExpression_Unary< const char *, const CExit * >
|
|
{
|
|
public:
|
|
typedef const CExit * ParameterType;
|
|
|
|
CTilegenExpression_ExitTag( ITilegenExpression< const CExit * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
|
|
virtual const char *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pExit );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the exit direction (integer enumeration) from an exit.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_ExitDirection : public CTilegenExpression_Unary< int, const CExit * >
|
|
{
|
|
public:
|
|
typedef const CExit * ParameterType;
|
|
|
|
CTilegenExpression_ExitDirection( ITilegenExpression< const CExit * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
|
|
virtual int DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pExit );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets the parent of the given state object.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_ParentState : public CTilegenExpression_Unary< const CTilegenState *, const CTilegenState * >
|
|
{
|
|
public:
|
|
typedef const CTilegenState * ParameterType;
|
|
|
|
CTilegenExpression_ParentState( ITilegenExpression< const CTilegenState * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
|
|
virtual const CTilegenState *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pState );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets the name of the given state object.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_StateName : public CTilegenExpression_Unary< const char *, const CTilegenState * >
|
|
{
|
|
public:
|
|
typedef const CTilegenState * ParameterType;
|
|
CTilegenExpression_StateName( ITilegenExpression< const CTilegenState * > *pExpression = NULL ) : CTilegenExpression_Unary( pExpression ) { }
|
|
|
|
virtual const char *DirectEvaluate( CFreeVariableMap *pContext, const ParameterType &pState );
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a constant value.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TValue >
|
|
class CTilegenExpression_Literal : public ITilegenExpression< TValue >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_Literal( TValue value ) :
|
|
m_Value( value )
|
|
{
|
|
}
|
|
|
|
virtual const char *GetTypeName() { Assert( 0 ); return NULL; }
|
|
|
|
virtual TValue Evaluate( CFreeVariableMap *pContext ) { return m_Value; }
|
|
|
|
protected:
|
|
TValue m_Value;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a constant integer value.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_LiteralInt : public CTilegenExpression_Literal< int >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_LiteralInt( int nValue = 0 ) : CTilegenExpression_Literal< int >( nValue ) { }
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
m_Value = pKeyValues->GetInt( "value", 0 );
|
|
return true;
|
|
}
|
|
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a constant integer value.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_LiteralBool : public CTilegenExpression_Literal< bool >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_LiteralBool( bool bValue = false ) : CTilegenExpression_Literal< bool >( bValue ) { }
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
m_Value = pKeyValues->GetBool( "value", false );
|
|
return true;
|
|
}
|
|
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a constant float value.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_LiteralFloat : public CTilegenExpression_Literal< float >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_LiteralFloat( float flValue = 0.0f ) : CTilegenExpression_Literal< float >( flValue ) { }
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
m_Value = pKeyValues->GetFloat( "value", 0 );
|
|
return true;
|
|
}
|
|
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns a constant string value.
|
|
//
|
|
// @TODO: use a string pool so we can create new strings from
|
|
// script operations and not worry about lifetime.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_LiteralString : public CTilegenExpression_Literal< const char * >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_LiteralString( const char *pValue = NULL ) :
|
|
CTilegenExpression_Literal< const char * >( NULL )
|
|
{
|
|
if ( pValue == NULL ) pValue = "";
|
|
Q_strncpy( m_StringData, pValue, MAX_TILEGEN_IDENTIFIER_LENGTH );
|
|
m_Value = m_StringData;
|
|
}
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
const char *pValue = pKeyValues->GetString( "value", NULL );
|
|
if ( pValue == NULL )
|
|
{
|
|
Log_Warning( LOG_TilegenLayoutSystem, "No value specified for CTilegenExpression_Literal in key values.\n" );
|
|
return false;
|
|
}
|
|
Q_strncpy( m_StringData, pValue, MAX_TILEGEN_IDENTIFIER_LENGTH );
|
|
m_Value = m_StringData;
|
|
return true;
|
|
}
|
|
|
|
virtual const char *GetTypeName();
|
|
|
|
protected:
|
|
char m_StringData[MAX_TILEGEN_IDENTIFIER_LENGTH];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the value of a named free variable.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TValue >
|
|
class CTilegenExpression_Variable : public ITilegenExpression< TValue >
|
|
{
|
|
public:
|
|
CTilegenExpression_Variable( ITilegenExpression< const char * > *pVariableNameExpression = NULL, bool bDisallowNULL = true ) :
|
|
m_pVariableNameExpression( pVariableNameExpression ),
|
|
m_bDisallowNULL( bDisallowNULL )
|
|
{
|
|
}
|
|
|
|
virtual TValue Evaluate( CFreeVariableMap *pContext )
|
|
{
|
|
const char *pVariableName = m_pVariableNameExpression->Evaluate( pContext );
|
|
if ( m_bDisallowNULL )
|
|
{
|
|
return ( TValue )pContext->GetFreeVariableDisallowNULL( pVariableName );
|
|
}
|
|
else
|
|
{
|
|
return ( TValue )pContext->GetFreeVariableOrNULL( pVariableName );
|
|
}
|
|
}
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
if ( !CreateExpressionFromKeyValuesBlock( pKeyValues, "variable", GetTypeName(), &m_pVariableNameExpression ) )
|
|
{
|
|
Log_Warning( LOG_TilegenLayoutSystem, "No variable specified for CTilegenExpression_Variable in key values.\n" );
|
|
return false;
|
|
}
|
|
m_bDisallowNULL = pKeyValues->GetBool( "disallow_null", true );
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
ITilegenExpression< const char * > *m_pVariableNameExpression;
|
|
bool m_bDisallowNULL;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Define some common variable types.
|
|
//-----------------------------------------------------------------------------
|
|
#define DEFINE_EXPRESSION_VARIABLE( CType, TypeName ) \
|
|
class CTilegenExpression_Variable##TypeName : public CTilegenExpression_Variable< CType > \
|
|
{ \
|
|
public: \
|
|
CTilegenExpression_Variable##TypeName( ITilegenExpression< const char * > *pVariableNameExpression = NULL, bool bDisallowNULL = true ) : CTilegenExpression_Variable< CType >( pVariableNameExpression, bDisallowNULL ) { } \
|
|
virtual const char *GetTypeName(); \
|
|
}
|
|
|
|
DEFINE_EXPRESSION_VARIABLE( int, Int );
|
|
DEFINE_EXPRESSION_VARIABLE( const char *, String );
|
|
DEFINE_EXPRESSION_VARIABLE( const CExit *, Exit );
|
|
DEFINE_EXPRESSION_VARIABLE( const CRoomCandidate *, RoomCandidate );
|
|
DEFINE_EXPRESSION_VARIABLE( const CRoomTemplate *, RoomTemplate );
|
|
DEFINE_EXPRESSION_VARIABLE( const CTilegenState *, State );
|
|
|
|
#undef DEFINE_EXPRESSION_VARIABLE
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Applies a functional map and reduce operator to every element of a range.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TMapOutput, typename TMapInput >
|
|
class CTilegenExpression_MapReduce : public ITilegenExpression< TMapOutput >
|
|
{
|
|
public:
|
|
CTilegenExpression_MapReduce() :
|
|
m_pInputRangeExpression( NULL ),
|
|
m_pInputRange( NULL ),
|
|
m_pMapFunction( NULL ),
|
|
m_pReduceFunction( NULL )
|
|
{
|
|
m_IteratorName[0] = '\0';
|
|
}
|
|
|
|
CTilegenExpression_MapReduce( ITilegenRange< TMapInput > *pRange, ITilegenExpression< TMapOutput > *pMapFunction, CTilegenExpression_Multi< TMapOutput > *pReduceFunction, const char *pIteratorName ) :
|
|
m_pInputRangeExpression( NULL ),
|
|
m_pInputRange( pRange ),
|
|
m_pMapFunction( pMapFunction ),
|
|
m_pReduceFunction( pReduceFunction )
|
|
{
|
|
if ( pIteratorName == NULL ) pIteratorName = "";
|
|
Q_strncpy( m_IteratorName, pIteratorName, MAX_TILEGEN_IDENTIFIER_LENGTH );
|
|
}
|
|
|
|
CTilegenExpression_MapReduce( ITilegenExpression< ITilegenRange< TMapInput > * > *pRangeExpression, ITilegenExpression< TMapOutput > *pMapFunction, CTilegenExpression_Multi< TMapOutput > *pReduceFunction, const char *pIteratorName ) :
|
|
m_pInputRangeExpression( pRangeExpression ),
|
|
m_pInputRange( NULL ),
|
|
m_pMapFunction( pMapFunction ),
|
|
m_pReduceFunction( pReduceFunction )
|
|
{
|
|
if ( pIteratorName == NULL ) pIteratorName = "";
|
|
Q_strncpy( m_IteratorName, pIteratorName, MAX_TILEGEN_IDENTIFIER_LENGTH );
|
|
}
|
|
|
|
~CTilegenExpression_MapReduce()
|
|
{
|
|
// They can't both be non-NULL
|
|
Assert( m_pInputRangeExpression == NULL || m_pInputRange == NULL );
|
|
delete m_pInputRange;
|
|
delete m_pInputRangeExpression;
|
|
delete m_pMapFunction;
|
|
delete m_pReduceFunction;
|
|
}
|
|
|
|
virtual bool LoadFromKeyValues( KeyValues *pKeyValues )
|
|
{
|
|
// Allow derived class to partially specify members of this class and partially load some from disk
|
|
if ( m_pInputRangeExpression == NULL && m_pInputRange == NULL )
|
|
{
|
|
KeyValues *pRangeExpressionKV = pKeyValues->FindKey( "range_expression" );
|
|
KeyValues *pRangeKV = pKeyValues->FindKey( "range" );
|
|
if ( pRangeExpressionKV == NULL && pRangeKV == NULL )
|
|
{
|
|
Log_Warning( LOG_TilegenLayoutSystem, "Could not find 'range' or 'range_expression' subkey in CTilegenExpression_MapReduce in KeyValues file.\n" );
|
|
return false;
|
|
}
|
|
else if ( pRangeExpressionKV != NULL && pRangeKV != NULL )
|
|
{
|
|
Log_Warning( LOG_TilegenLayoutSystem, "Found both a 'range' and 'range_expression' subkey in CTilegenExpression_MapReduce in KeyValues file.\n" );
|
|
return false;
|
|
}
|
|
|
|
if ( pRangeExpressionKV != NULL )
|
|
{
|
|
if ( !CreateExpressionFromKeyValuesBlock( pKeyValues, "range_expression", GetTypeName(), &m_pInputRangeExpression ) )
|
|
return false;
|
|
}
|
|
else if ( pRangeKV != NULL)
|
|
{
|
|
if ( !CreateRangeFromKeyValuesBlock( pKeyValues, "range", GetTypeName(), &m_pInputRange ) )
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ( m_pMapFunction == NULL )
|
|
{
|
|
if ( !CreateExpressionFromKeyValuesBlock< TMapOutput >( pKeyValues, "map", GetTypeName(), &m_pMapFunction ) )
|
|
return false;
|
|
}
|
|
|
|
if ( m_pReduceFunction == NULL )
|
|
{
|
|
ITilegenExpression< TMapOutput > *pReduceFunction = NULL;
|
|
// Create an empty instance of the binary function since we will never call Evaluate on it (just DirectEvaluate)
|
|
CreateExpressionFromKeyValuesBlock< TMapOutput >( pKeyValues, "reduce", GetTypeName(), &pReduceFunction, false, true );
|
|
m_pReduceFunction = static_cast< CTilegenExpression_Multi< TMapOutput > * >( pReduceFunction );
|
|
}
|
|
|
|
if ( m_IteratorName[0] == '\0' )
|
|
{
|
|
const char *pIteratorName = pKeyValues->GetString( "iterator", NULL );
|
|
if ( pIteratorName == NULL )
|
|
{
|
|
Log_Warning( LOG_TilegenLayoutSystem, "No iterator name specified for CTilegenExpression_MapReduce in Key Values.\n" );
|
|
return false;
|
|
}
|
|
Q_strncpy( m_IteratorName, pIteratorName, MAX_TILEGEN_IDENTIFIER_LENGTH );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
virtual TMapOutput Evaluate( CFreeVariableMap *pContext )
|
|
{
|
|
TMapOutput reducedValue = TMapOutput( 0 );
|
|
int nValues = 0;
|
|
ITilegenRange< TMapInput > *pInputRange = m_pInputRange;
|
|
if ( m_pInputRangeExpression )
|
|
{
|
|
// Assume that the expression has already initialized the range.
|
|
pInputRange = m_pInputRangeExpression->Evaluate( pContext );
|
|
}
|
|
else
|
|
{
|
|
pInputRange->Initialize( pContext );
|
|
}
|
|
|
|
pInputRange->Reset();
|
|
while ( pInputRange->MoveNext() )
|
|
{
|
|
// The map function must use a CTilegenExpression_Variable (initialized to the range iterator variable name) to get at the current range value.
|
|
TMapInput currentValue = pInputRange->GetCurrent();
|
|
pContext->SetOrCreateFreeVariable( m_IteratorName, ( void * )currentValue );
|
|
TMapOutput mappedValue = m_pMapFunction->Evaluate( pContext );
|
|
if ( nValues == 0 )
|
|
{
|
|
reducedValue = mappedValue;
|
|
}
|
|
else
|
|
{
|
|
reducedValue = m_pReduceFunction->DirectEvaluate( pContext, reducedValue, mappedValue );
|
|
}
|
|
|
|
++ nValues;
|
|
}
|
|
return reducedValue;
|
|
}
|
|
|
|
protected:
|
|
ITilegenExpression< ITilegenRange< TMapInput > * > *m_pInputRangeExpression;
|
|
ITilegenRange< TMapInput > *m_pInputRange;
|
|
ITilegenExpression< TMapOutput > *m_pMapFunction;
|
|
CTilegenExpression_Multi< TMapOutput > *m_pReduceFunction;
|
|
char m_IteratorName[MAX_TILEGEN_IDENTIFIER_LENGTH];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Applies a functional map-reduce operator to a range of exits,
|
|
// returning an integer.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_MapReduceExits : public CTilegenExpression_MapReduce< int, const CExit * >
|
|
{
|
|
public:
|
|
CTilegenExpression_MapReduceExits( ITilegenRange< const CExit * > *pRange = NULL, ITilegenExpression< int > *pMapFunction = NULL, CTilegenExpression_Multi< int > *pReduceFunction = NULL, const char *pIteratorName = NULL ) :
|
|
CTilegenExpression_MapReduce< int, const CExit * >( pRange, pMapFunction, pReduceFunction, pIteratorName )
|
|
{
|
|
}
|
|
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Counts the number of elements in a range.
|
|
//-----------------------------------------------------------------------------
|
|
template< typename TInput >
|
|
class CTilegenExpression_CountRange : public CTilegenExpression_MapReduce< int, TInput >
|
|
{
|
|
public:
|
|
CTilegenExpression_CountRange( ITilegenRange< TInput > *pRange = NULL ) :
|
|
CTilegenExpression_MapReduce( pRange, new CTilegenExpression_LiteralInt( 1 ), new CTilegenExpression_Add(), "$$unused" )
|
|
{
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Counts the number of exits in a range of exits.
|
|
//-----------------------------------------------------------------------------
|
|
class CTilegenExpression_CountExits : public CTilegenExpression_CountRange< const CExit * >
|
|
{
|
|
public:
|
|
explicit CTilegenExpression_CountExits( ITilegenRange< const CExit * > *pRange = NULL ) :
|
|
CTilegenExpression_CountRange< const CExit * >( pRange )
|
|
{
|
|
}
|
|
|
|
virtual const char *GetTypeName();
|
|
};
|
|
|
|
#endif // TILEGEN_EXPRESSIONS_H
|