etqw-sdk/source/game/guis/UserInterfaceExpressions.h

991 lines
49 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __GAME_GUIS_USERINTERFACEEXPRESSIONS_H__
#define __GAME_GUIS_USERINTERFACEEXPRESSIONS_H__
#include "UserInterfaceTypes.h"
class sdFloatParmExpression;
class sdUIExpression {
protected:
virtual ~sdUIExpression( void ) { ; }
public:
virtual void Free( void ) = 0;
virtual void InputChanged( void ) = 0;
virtual void SetProperty( sdProperties::sdProperty* output, int index, int key, sdUserInterfaceScope* outputScope ) { assert( false ); }
virtual void Attach( sdUIExpression* output ) = 0;
virtual void Detach( void ) = 0;
virtual sdProperties::ePropertyType GetType( void ) const = 0;
virtual bool UpdateValue( void ) { return false; } // for transitions
virtual void Evaluate( void ) { assert( false ); }
virtual int GetIntValue( void ) { assert( false ); return 0; }
virtual float GetFloatValue( void ) { assert( false ); return 0.f; }
virtual const idStr & GetStringValue( idStr &temp ) { static idStr empty = ""; assert( false ); return empty; }
virtual const idWStr & GetWStringValue( idWStr &temp ) { static idWStr empty = L""; assert( false ); return empty; }
virtual const idVec2 & GetVec2Value( idVec2 &temp ) { assert( false ); return vec2_zero; }
virtual const idVec3 & GetVec3Value( idVec3 &temp ) { assert( false ); return vec3_zero; }
virtual const idVec4 & GetVec4Value( idVec4 &temp ) { assert( false ); return vec4_zero; }
virtual void OnSnapshotHitch( int delta ) {}
virtual void OnOnChangedOverflow( void ) = 0;
static sdUIExpression* AllocIntExpression( sdUserInterfaceScope* scope, const char* text );
static sdUIExpression* AllocFloatExpression( sdUserInterfaceScope* scope, const char* text );
static sdUIExpression* AllocStringExpression( sdUserInterfaceScope* scope, const char* text );
static sdUIExpression* AllocWStringExpression( sdUserInterfaceScope* scope, const char* text );
static sdUIExpression* AllocSingleParmExpression( sdProperties::ePropertyType type, sdUserInterfaceScope* scope, const char* text );
static sdUIExpression* AllocFunctionExpression( const char* functionName, sdUIFunctionInstance* function, sdUserInterfaceScope* scope, idLexer* src );
static sdUIExpression* AllocTransition( sdProperties::ePropertyType type, sdUserInterfaceScope* scope, idLexer* src );
static void IncActiveOnChangeHandlers( sdUIExpression* expression );
static void DecActiveOnChangeHandlers( void );
private:
static const int MAX_ACTIVE_ONCHANGED_HANDLERS = 256;
static idStaticList< sdUIExpression*, MAX_ACTIVE_ONCHANGED_HANDLERS > activeOnChangedHandlers;
};
template< typename T, sdProperties::ePropertyType TYPE, int COUNT >
class sdUITransition : public sdUIExpression {
public:
sdUITransition( sdUserInterfaceScope* scope, idStrList& list );
virtual ~sdUITransition( void );
virtual void OnOnChangedOverflow( void ) { ; }
virtual void InputChanged( void ) { assert( false ); }
virtual bool UpdateValue( void );
virtual void Detach( void );
virtual sdProperties::ePropertyType GetType( void ) const { return TYPE; }
virtual void OnSnapshotHitch( int delta );
protected:
const idDeclTable* table;
T start;
T end;
T value;
idVec2 accelTimes;
idInterpolateAccelDecelLinear< T >* interpolator;
sdUIExpression* startExpressions[ COUNT ];
sdUIExpression* endExpressions[ COUNT ];
int startTime;
sdUIExpression* duration;
sdUIExpression* outputExpression;
float _cachedDuration;
sdUserInterfaceLocal* ui;
static idBlockAlloc< idInterpolateAccelDecelLinear< T >, 32 > interpolatorAllocator;
};
template< typename T, sdProperties::ePropertyType TYPE, int COUNT > idBlockAlloc< idInterpolateAccelDecelLinear< T >, 32 > sdUITransition< T, TYPE, COUNT >::interpolatorAllocator;
extern const char sdUITransitionFloat_Identifier[];
class sdUITransitionFloat :
public sdUITransition< float, sdProperties::PT_FLOAT, 1 >,
public sdPoolAllocator< sdUITransitionFloat, sdUITransitionFloat_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdUITransitionFloat, sdUITransitionFloat_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdUITransitionFloat( sdUserInterfaceScope* scope, idStrList& list ) : sdUITransition< float, sdProperties::PT_FLOAT, 1 >( scope, list ) { }
virtual ~sdUITransitionFloat( void ) {}
virtual void Attach( sdUIExpression* output );
virtual float GetFloatValue( void ) { return value; }
virtual void Free( void ) { delete this; }
private:
};
extern const char sdUITransitionVec2_Identifier[];
class sdUITransitionVec2 :
public sdUITransition< idVec2, sdProperties::PT_VEC2, 2 >,
public sdPoolAllocator< sdUITransitionVec2, sdUITransitionVec2_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdUITransitionVec2, sdUITransitionVec2_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdUITransitionVec2( sdUserInterfaceScope* scope, idStrList& list ) : sdUITransition< idVec2, sdProperties::PT_VEC2, 2 >( scope, list ) { }
virtual ~sdUITransitionVec2( void ) {}
virtual void Attach( sdUIExpression* output );
virtual const idVec2 & GetVec2Value( idVec2 &temp ) { return value; }
virtual void Free( void ) { delete this; }
private:
};
extern const char sdUITransitionVec3_Identifier[];
class sdUITransitionVec3 :
public sdUITransition< idVec3, sdProperties::PT_VEC3, 3 >,
public sdPoolAllocator< sdUITransitionVec3, sdUITransitionVec3_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdUITransitionVec3, sdUITransitionVec3_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdUITransitionVec3( sdUserInterfaceScope* scope, idStrList& list ) : sdUITransition< idVec3, sdProperties::PT_VEC3, 3 >( scope, list ) { }
virtual ~sdUITransitionVec3( void ) {}
virtual void Attach( sdUIExpression* output );
virtual const idVec3 & GetVec3Value( idVec3 &temp ) { return value; }
virtual void Free( void ) { delete this; }
private:
};
extern const char sdUITransitionVec4_Identifier[];
class sdUITransitionVec4 :
public sdUITransition< idVec4, sdProperties::PT_VEC4, 4 >,
public sdPoolAllocator< sdUITransitionVec4, sdUITransitionVec4_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdUITransitionVec4, sdUITransitionVec4_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdUITransitionVec4( sdUserInterfaceScope* scope, idStrList& list ) : sdUITransition< idVec4, sdProperties::PT_VEC4, 4 >( scope, list ) { }
virtual ~sdUITransitionVec4( void ) {}
virtual void Attach( sdUIExpression* output );
virtual const idVec4 & GetVec4Value( idVec4 &temp ) { return value; }
virtual void Free( void ) { delete this; }
private:
};
extern const char sdFunctionExpression_Identifier[];
class sdFunctionExpression :
public sdUIExpression,
public sdPoolAllocator< sdFunctionExpression, sdFunctionExpression_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdFunctionExpression, sdFunctionExpression_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdFunctionExpression( const char* functionName, sdUserInterfaceScope* scope, sdUIFunctionInstance* _function, idStrList& list );
virtual ~sdFunctionExpression( void );
virtual void InputChanged( void ) { assert( false ); }
virtual void Attach( sdUIExpression* output ) { }
virtual void Detach( void ) {}
virtual sdProperties::ePropertyType GetType( void ) const { return function->GetFunctionInfo()->GetReturnType(); }
virtual void OnOnChangedOverflow( void ) { ; }
virtual int GetIntValue( void );
virtual float GetFloatValue( void );
virtual const idStr & GetStringValue( idStr &temp );
virtual const idWStr & GetWStringValue( idWStr &temp );
virtual const idVec2 & GetVec2Value( idVec2 &temp );
virtual const idVec3 & GetVec3Value( idVec3 &temp );
virtual const idVec4 & GetVec4Value( idVec4 &temp );
virtual void Evaluate( void );
virtual void Free( void ) { delete this; }
private:
void AllocStack( void );
void FreeStack( void );
void EvaluateInternal( bool maintainStack );
sdUIFunctionInstance* function;
sdUIFunctionStack *_stack;
idList< sdUIExpression* > expressions;
};
extern const char sdFloatParmExpression_Identifier[];
class sdFloatParmExpression :
public sdUIExpression,
public sdPoolAllocator< sdFloatParmExpression, sdFloatParmExpression_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdFloatParmExpression, sdFloatParmExpression_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdFloatParmExpression( sdUserInterfaceScope* _scope, idLexer* src );
virtual ~sdFloatParmExpression( void );
virtual void Attach( sdUIExpression* output );
virtual void Detach( void );
virtual sdProperties::ePropertyType GetType( void ) const { return sdProperties::PT_FLOAT; }
virtual float GetFloatValue( void ) { EvaluateRegisters(); return registers[ valueRegister ].value; }
virtual void InputChanged( void );
virtual void Free( void ) { delete this; }
void SetValue( int index, const float newValue ) {
registers[ index ].value = newValue;
Update();
}
bool IsConstant( void ) const {
return symbols.Num() == 0;
}
private:
typedef enum {
WOP_TYPE_ADD,
WOP_TYPE_SUBTRACT,
WOP_TYPE_MULTIPLY,
WOP_TYPE_DIVIDE,
WOP_TYPE_TABLE,
WOP_TYPE_GT,
WOP_TYPE_GE,
WOP_TYPE_LT,
WOP_TYPE_LE,
WOP_TYPE_EQ,
WOP_TYPE_NE,
WOP_TYPE_BIT_AND,
WOP_TYPE_BIT_XOR,
WOP_TYPE_BIT_OR,
WOP_TYPE_AND,
WOP_TYPE_OR,
WOP_TYPE_MOD,
WOP_TYPE_NOT,
WOP_TYPE_BIT_COMP,
} wexpOpType_t;
typedef struct {
unsigned char opType;
unsigned char a;
unsigned char b;
unsigned char c;
} wexpOp_t;
int ExpressionConstant( float f );
int ExpressionTemporary( void );
wexpOp_t& ExpressionOp( void );
int ExpressionExpression( sdUIExpression* expression );
int EmitOp( int a, int b, wexpOpType_t opType, wexpOp_t** opp = NULL );
int ParseEmitOp( idLexer *src, int a, wexpOpType_t opType, int priority, const char* delimiter, sdUserInterfaceScope* scope, wexpOp_t** opp = NULL );
void Parse( idLexer* src, sdUserInterfaceScope* scope );
int ParseTerm( idLexer *src, const char* delimiter, sdUserInterfaceScope* scope );
int ParseExpression( idLexer *src, const char* delimiter, sdUserInterfaceScope* scope );
int ParseExpressionPriority( idLexer *src, int priority, const char* delimiter, sdUserInterfaceScope* scope );
void EvaluateRegisters( void );
void Update( void );
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); }
typedef struct expressionRegister_s {
float value;
} expressionRegister_t;
typedef struct expressionSymbol_s {
sdUIExpression* expression;
short position;
short immediate;
} expressionSymbol_t;
idList< expressionSymbol_t > symbols;
idList< expressionRegister_t > registers;
idList< wexpOp_t > ops;
int valueRegister;
sdUIExpression* outputExpression;
bool immediate;
int inImmediate;
};
#if 0
extern const char sdIntParmExpression_Identifier[];
class sdIntParmExpression :
public sdUIExpression,
public sdPoolAllocator< sdIntParmExpression, sdIntParmExpression_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdIntParmExpression, sdIntParmExpression_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdIntParmExpression( sdUserInterfaceScope* _scope, idLexer* src );
virtual ~sdIntParmExpression( void );
virtual void Attach( sdUIExpression* output );
virtual void Detach( void );
virtual sdProperties::ePropertyType GetType( void ) const { return sdProperties::PT_INT; }
virtual int GetIntValue( void ) { EvaluateRegisters(); return registers[ valueRegister ].value; }
virtual void InputChanged( void );
void SetValue( int index, const int newValue ) {
assert( registers[ index ].temporary );
registers[ index ].value = newValue;
Update();
}
private:
typedef enum {
WOP_TYPE_ADD,
WOP_TYPE_SUBTRACT,
WOP_TYPE_MULTIPLY,
WOP_TYPE_DIVIDE,
WOP_TYPE_TABLE,
WOP_TYPE_GT,
WOP_TYPE_GE,
WOP_TYPE_LT,
WOP_TYPE_LE,
WOP_TYPE_EQ,
WOP_TYPE_NE,
WOP_TYPE_BIT_AND,
WOP_TYPE_BIT_XOR,
WOP_TYPE_BIT_OR,
WOP_TYPE_AND,
WOP_TYPE_OR,
WOP_TYPE_MOD,
} wexpOpType_t;
typedef struct {
wexpOpType_t opType;
int a, b, c, d;
} wexpOp_t;
int ExpressionConstant( float f );
int ExpressionTemporary( void );
wexpOp_t& ExpressionOp( void );
int ExpressionExpression( sdUIExpression* expression );
int EmitOp( int a, int b, wexpOpType_t opType, wexpOp_t** opp = NULL );
int ParseEmitOp( idLexer *src, int a, wexpOpType_t opType, int priority, const char* delimiter, sdUserInterfaceScope* scope, wexpOp_t** opp = NULL );
void Parse( idLexer* src, sdUserInterfaceScope* scope );
int ParseTerm( idLexer *src, const char* delimiter, sdUserInterfaceScope* scope );
int ParseExpression( idLexer *src, const char* delimiter, sdUserInterfaceScope* scope );
int ParseExpressionPriority( idLexer *src, int priority, const char* delimiter, sdUserInterfaceScope* scope );
void EvaluateRegisters( void );
void Update( void );
typedef struct expressionRegister_s {
int value;
bool temporary;
} expressionRegister_t;
typedef struct expressionSymbol_s {
sdUIExpression* expression;
int position;
bool immediate;
} expressionSymbol_t;
idList< expressionSymbol_t > symbols;
idList< expressionRegister_t > registers;
idList< wexpOp_t > ops;
int valueRegister;
sdUIExpression* outputExpression;
bool immediate;
int inImmediate;
};
#endif
extern const char sdStringParmExpression_Identifier[];
class sdStringParmExpression :
public sdUIExpression,
public sdPoolAllocator< sdStringParmExpression, sdStringParmExpression_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdStringParmExpression, sdStringParmExpression_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdStringParmExpression( sdUserInterfaceScope* _scope, idLexer* src );
virtual ~sdStringParmExpression( void );
virtual void Attach( sdUIExpression* output );
virtual void Detach( void );
virtual sdProperties::ePropertyType GetType( void ) const { return sdProperties::PT_STRING; }
virtual const idStr & GetStringValue( idStr &temp ) { EvaluateRegisters(); return registers[ valueRegister ].value; }
virtual void InputChanged( void );
virtual void Free( void ) { delete this; }
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); }
bool IsConstant( void ) const {
return symbols.Num() == 0;
}
void SetValue( int index, const char* newValue ) {
assert( registers[ index ].temporary );
registers[ index ].value = newValue;
Update();
}
private:
typedef enum {
WOP_TYPE_ADD,
WOP_TYPE_EQ,
WOP_TYPE_NE,
} wexpOpType_t;
typedef struct {
unsigned char opType;
unsigned char a;
unsigned char b;
unsigned char c;
} wexpOp_t;
int ExpressionConstant( const char* str );
int ExpressionTemporary( void );
wexpOp_t& ExpressionOp( void );
int ExpressionExpression( sdUIExpression* expression );
int EmitOp( int a, int b, wexpOpType_t opType, wexpOp_t** opp = NULL );
int ParseEmitOp( idLexer *src, int a, wexpOpType_t opType, int priority, const char* delimiter, sdUserInterfaceScope* scope, wexpOp_t** opp = NULL );
void Parse( idLexer* src, sdUserInterfaceScope* scope );
int ParseTerm( idLexer *src, const char* delimiter, sdUserInterfaceScope* scope );
int ParseExpression( idLexer *src, const char* delimiter, sdUserInterfaceScope* scope );
int ParseExpressionPriority( idLexer *src, int priority, const char* delimiter, sdUserInterfaceScope* scope );
void EvaluateRegisters( void );
void Update( void );
typedef struct expressionRegister_s {
idStr value;
bool temporary;
} expressionRegister_t;
typedef struct expressionSymbol_s {
sdUIExpression* expression;
short position;
short immediate;
} expressionSymbol_t;
idList< expressionSymbol_t > symbols;
idList< expressionRegister_t > registers;
idList< wexpOp_t > ops;
int valueRegister;
sdUIExpression* outputExpression;
bool immediate;
int inImmediate;
};
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
#define UI_SINGLEPARM_EXPRESSION( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdSingleParmExpression##TYPENAME##_Identifier[];\
class sdSingleParmExpression##TYPENAME : \
public sdUIExpression, \
public sdPoolAllocator< sdSingleParmExpression##TYPENAME, sdSingleParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdSingleParmExpression##TYPENAME, sdSingleParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
sdSingleParmExpression##TYPENAME( sdProperties::sdProperty* input ) { assert( !callbackHandle.IsValid() ); inputProperty = input; outputExpression = NULL; } \
virtual ~sdSingleParmExpression##TYPENAME( void ) { Detach(); } \
virtual void Attach( sdUIExpression* output ) { assert( !callbackHandle.IsValid() ); outputExpression = output; callbackHandle = inputProperty->value.VALUENAME->AddOnChangeHandler( sdFunctions::sdBindMem0< void, const TYPE&, const TYPE&, sdFunctions::sdEmptyType >( &sdSingleParmExpression##TYPENAME::OnChanged, this ) ); } \
virtual void Detach( void ) { if( callbackHandle.IsValid() ) { inputProperty->value.VALUENAME->RemoveOnChangeHandler( callbackHandle ); }} \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
void OnChanged( const TYPE& oldValue, const TYPE& newValue ) { IncActiveOnChangeHandlers( this ); assert( outputExpression ); outputExpression->InputChanged(); DecActiveOnChangeHandlers(); } \
virtual TYPE Get##TYPENAME##Value( void ) { assert( inputProperty->GetValueType() == VALUETYPE ); return inputProperty->value.VALUENAME->GetValue(); } \
virtual void InputChanged( void ) { assert( false ); } \
virtual void Free( void ) { delete this; } \
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); } \
\
private: \
sdProperties::sdProperty* inputProperty; \
sdUIExpression* outputExpression; \
sdProperties::CallbackHandle callbackHandle; \
};
#define UI_SINGLEPARM_EXPRESSION_REF( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdSingleParmExpression##TYPENAME##_Identifier[];\
class sdSingleParmExpression##TYPENAME : \
public sdUIExpression, \
public sdPoolAllocator< sdSingleParmExpression##TYPENAME, sdSingleParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdSingleParmExpression##TYPENAME, sdSingleParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
sdSingleParmExpression##TYPENAME( sdProperties::sdProperty* input ) { assert( !callbackHandle.IsValid() ); inputProperty = input; outputExpression = NULL; } \
virtual ~sdSingleParmExpression##TYPENAME( void ) { Detach(); } \
virtual void Attach( sdUIExpression* output ) { assert( !callbackHandle.IsValid() ); outputExpression = output; callbackHandle = inputProperty->value.VALUENAME->AddOnChangeHandler( sdFunctions::sdBindMem0< void, const TYPE&, const TYPE&, sdFunctions::sdEmptyType >( &sdSingleParmExpression##TYPENAME::OnChanged, this ) ); } \
virtual void Detach( void ) { if( callbackHandle.IsValid() ) { inputProperty->value.VALUENAME->RemoveOnChangeHandler( callbackHandle ); }} \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
void OnChanged( const TYPE& oldValue, const TYPE& newValue ) { IncActiveOnChangeHandlers( this ); assert( outputExpression ); outputExpression->InputChanged(); DecActiveOnChangeHandlers(); } \
virtual const TYPE & Get##TYPENAME##Value( TYPE& temp ) { assert( inputProperty->GetValueType() == VALUETYPE ); return inputProperty->value.VALUENAME->GetValue(); } \
virtual void InputChanged( void ) { assert( false ); } \
virtual void Free( void ) { delete this; } \
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); } \
\
private: \
sdProperties::sdProperty* inputProperty; \
sdUIExpression* outputExpression; \
sdProperties::CallbackHandle callbackHandle; \
};
UI_SINGLEPARM_EXPRESSION( Int, int, intValue, sdProperties::PT_INT )
UI_SINGLEPARM_EXPRESSION( Float, float, floatValue, sdProperties::PT_FLOAT )
UI_SINGLEPARM_EXPRESSION_REF( Vec2, idVec2, vec2Value, sdProperties::PT_VEC2 )
UI_SINGLEPARM_EXPRESSION_REF( Vec3, idVec3, vec3Value, sdProperties::PT_VEC3 )
UI_SINGLEPARM_EXPRESSION_REF( Vec4, idVec4, vec4Value, sdProperties::PT_VEC4 )
UI_SINGLEPARM_EXPRESSION_REF( String, idStr, stringValue, sdProperties::PT_STRING )
UI_SINGLEPARM_EXPRESSION_REF( WString, idWStr, wstringValue, sdProperties::PT_WSTRING)
#define UI_SINGLEPARM_EXPRESSION_FIELD( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdSingleParmExpression##TYPENAME##_Identifier[]; \
class sdSingleParmExpressionField##TYPENAME : \
public sdUIExpression, \
public sdPoolAllocator< sdSingleParmExpressionField##TYPENAME, sdSingleParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdSingleParmExpressionField##TYPENAME, sdSingleParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
sdSingleParmExpressionField##TYPENAME( sdProperties::sdProperty* input, int index ) { assert( !callbackHandle.IsValid() ); inputIndex = index; inputProperty = input; outputExpression = NULL; }\
virtual ~sdSingleParmExpressionField##TYPENAME( void ) { Detach(); } \
virtual void Attach( sdUIExpression* output ) { assert( !callbackHandle.IsValid() ); outputExpression = output; callbackHandle = inputProperty->value.VALUENAME->AddOnChangeHandler( sdFunctions::sdBindMem0< void, const TYPE&, const TYPE&, sdFunctions::sdEmptyType >( &sdSingleParmExpressionField##TYPENAME::OnChanged, this )); } \
virtual void Detach( void ) { if( callbackHandle.IsValid() ) { inputProperty->value.VALUENAME->RemoveOnChangeHandler( callbackHandle ); }} \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
void OnChanged( const TYPE& oldValue, const TYPE& newValue ) { IncActiveOnChangeHandlers( this ); assert( outputExpression ); outputExpression->InputChanged(); DecActiveOnChangeHandlers(); } \
virtual float GetFloatValue( void ) { assert( inputProperty->GetValueType() == VALUETYPE ); return inputProperty->value.VALUENAME->GetValue()[ inputIndex ]; } \
virtual void InputChanged( void ) { assert( false ); } \
virtual void Free( void ) { delete this; } \
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); } \
private: \
sdProperties::sdProperty* inputProperty; \
int inputIndex; \
sdUIExpression* outputExpression; \
sdProperties::CallbackHandle callbackHandle; \
};
UI_SINGLEPARM_EXPRESSION_FIELD( Vec2, idVec2, vec2Value, sdProperties::PT_VEC2 )
UI_SINGLEPARM_EXPRESSION_FIELD( Vec3, idVec3, vec3Value, sdProperties::PT_VEC3 )
UI_SINGLEPARM_EXPRESSION_FIELD( Vec4, idVec4, vec4Value, sdProperties::PT_VEC4 )
#define UI_CONST_EXPRESSION( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdConstParmExpression##TYPENAME##_Identifier[]; \
class sdConstParmExpression##TYPENAME : public sdUIExpression, public sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
\
private: \
sdConstParmExpression##TYPENAME( const TYPE& inputValue ) { value = inputValue; } \
virtual ~sdConstParmExpression##TYPENAME( void ) { } \
\
public: \
static sdConstParmExpression##TYPENAME* Alloc( const TYPE& inputValue ) { \
return new sdConstParmExpression##TYPENAME( inputValue ); \
} \
\
virtual void OnOnChangedOverflow( void ) { \
} \
virtual void Free( void ) { delete this; } \
\
virtual void Attach( sdUIExpression* output ) { } \
virtual void Detach( void ) { } \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
virtual TYPE Get##TYPENAME##Value( void ) { return value; } \
virtual void InputChanged( void ) { assert( false ); } \
\
private: \
TYPE value; \
};
#define UI_CONST_EXPRESSION_REF( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdConstParmExpression##TYPENAME##_Identifier[]; \
class sdConstParmExpression##TYPENAME : public sdUIExpression, public sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
\
private: \
sdConstParmExpression##TYPENAME( const TYPE& inputValue ) { value = inputValue; } \
virtual ~sdConstParmExpression##TYPENAME( void ) { } \
\
public: \
static sdConstParmExpression##TYPENAME* Alloc( const TYPE& inputValue ) { \
return new sdConstParmExpression##TYPENAME( inputValue ); \
} \
\
virtual void OnOnChangedOverflow( void ) { \
} \
virtual void Free( void ) { delete this; } \
\
virtual void Attach( sdUIExpression* output ) { } \
virtual void Detach( void ) { } \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
virtual const TYPE & Get##TYPENAME##Value( TYPE &temp ) { return value; } \
virtual void InputChanged( void ) { assert( false ); } \
\
private: \
TYPE value; \
};
#define UI_CONST_EXPRESSION_HASH( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdConstParmExpression##TYPENAME##_Identifier[]; \
class sdConstParmExpression##TYPENAME : public sdUIExpression, public sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
\
private: \
sdConstParmExpression##TYPENAME( const TYPE& inputValue ) { value = inputValue; refCount = 1; } \
virtual ~sdConstParmExpression##TYPENAME( void ) { } \
\
public: \
static sdConstParmExpression##TYPENAME* Alloc( const TYPE& inputValue ) { \
int key = hashIndex.GenerateKey( inputValue ); \
for ( int index = hashIndex.GetFirst( key ); index != idHashIndex::NULL_INDEX; index = hashIndex.GetNext( index ) ) { \
if ( linearList[ index ]->Get##TYPENAME##Value() == inputValue ) { \
linearList[ index ]->IncRef(); \
return linearList[ index ]; \
} \
} \
int index = linearList.FindNull(); \
if ( index == -1 ) { \
index = linearList.Num(); \
linearList.Alloc() = NULL; \
} \
\
linearList[ index ] = new sdConstParmExpression##TYPENAME( inputValue ); \
hashIndex.Add( key, index ); \
return linearList[ index ]; \
} \
\
virtual void OnOnChangedOverflow( void ) { \
} \
static void DeAlloc( sdConstParmExpression##TYPENAME* value ) { \
int index = linearList.FindIndex( value ); \
assert( index != -1 ); \
int key = hashIndex.GenerateKey( value->Get##TYPENAME##Value() ); \
hashIndex.Remove( key, index ); \
linearList[ index ] = NULL; \
delete value; \
} \
\
void IncRef( void ) { refCount++; } \
void DecRef( void ) { refCount--; if ( refCount == 0 ) { DeAlloc( this ); } } \
\
virtual void Free( void ) { DecRef(); } \
\
virtual void Attach( sdUIExpression* output ) { } \
virtual void Detach( void ) { } \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
virtual TYPE Get##TYPENAME##Value( void ) { return value; } \
virtual void InputChanged( void ) { assert( false ); } \
\
private: \
TYPE value; \
int refCount; \
\
static idHashIndex hashIndex; \
static idList< sdConstParmExpression##TYPENAME* > linearList; \
};
#define UI_CONST_EXPRESSION_HASH_REF( TYPENAME, TYPE, VALUENAME, VALUETYPE ) \
extern const char sdConstParmExpression##TYPENAME##_Identifier[]; \
class sdConstParmExpression##TYPENAME : public sdUIExpression, public sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdConstParmExpression##TYPENAME, sdConstParmExpression##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
\
private: \
sdConstParmExpression##TYPENAME( const TYPE& inputValue ) { value = inputValue; refCount = 1; } \
virtual ~sdConstParmExpression##TYPENAME( void ) { } \
\
public: \
static sdConstParmExpression##TYPENAME* Alloc( const TYPE& inputValue ) { \
int key = hashIndex.GenerateKey( inputValue ); \
for ( int index = hashIndex.GetFirst( key ); index != idHashIndex::NULL_INDEX; index = hashIndex.GetNext( index ) ) { \
TYPE temp; \
if ( linearList[ index ]->Get##TYPENAME##Value( temp ) == inputValue ) { \
linearList[ index ]->IncRef(); \
return linearList[ index ]; \
} \
} \
int index = linearList.FindNull(); \
if ( index == -1 ) { \
index = linearList.Num(); \
linearList.Alloc() = NULL; \
} \
\
linearList[ index ] = new sdConstParmExpression##TYPENAME( inputValue ); \
hashIndex.Add( key, index ); \
return linearList[ index ]; \
} \
\
virtual void OnOnChangedOverflow( void ) { \
} \
static void DeAlloc( sdConstParmExpression##TYPENAME* value ) { \
int index = linearList.FindIndex( value ); \
assert( index != -1 ); \
TYPE temp; \
int key = hashIndex.GenerateKey( value->Get##TYPENAME##Value( temp ) ); \
hashIndex.Remove( key, index ); \
linearList[ index ] = NULL; \
delete value; \
} \
\
void IncRef( void ) { refCount++; } \
void DecRef( void ) { refCount--; if ( refCount == 0 ) { DeAlloc( this ); } } \
\
virtual void Free( void ) { DecRef(); } \
\
virtual void Attach( sdUIExpression* output ) { } \
virtual void Detach( void ) { } \
virtual sdProperties::ePropertyType GetType( void ) const { return VALUETYPE; } \
virtual const TYPE & Get##TYPENAME##Value( TYPE &temp ) { return value; } \
virtual void InputChanged( void ) { assert( false ); } \
\
private: \
TYPE value; \
int refCount; \
\
static idHashIndex hashIndex; \
static idList< sdConstParmExpression##TYPENAME* > linearList; \
};
#define UI_CONST_EXPRESSION_HASH_IMPL( TYPENAME ) \
idHashIndex sdConstParmExpression##TYPENAME::hashIndex; \
idList< sdConstParmExpression##TYPENAME* > sdConstParmExpression##TYPENAME::linearList;
UI_CONST_EXPRESSION( Int, int, intValue, sdProperties::PT_INT )
UI_CONST_EXPRESSION_HASH( Float, float, floatValue, sdProperties::PT_FLOAT )
UI_CONST_EXPRESSION_REF( Vec2, idVec2, vec2Value, sdProperties::PT_VEC2 )
UI_CONST_EXPRESSION_REF( Vec3, idVec3, vec3Value, sdProperties::PT_VEC3 )
UI_CONST_EXPRESSION_REF( Vec4, idVec4, vec4Value, sdProperties::PT_VEC4 )
UI_CONST_EXPRESSION_HASH_REF( String, idStr, stringValue, sdProperties::PT_STRING )
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
extern const char sdPropertyExpressionSingle_Identifier[];
class sdPropertyExpressionSingle :
public sdUIExpression,
public sdPoolAllocator< sdPropertyExpressionSingle, sdPropertyExpressionSingle_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdPropertyExpressionSingle, sdPropertyExpressionSingle_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdPropertyExpressionSingle( const char* name, sdUIExpression* input );
virtual ~sdPropertyExpressionSingle( void );
virtual void SetProperty( sdProperties::sdProperty* output, int index, int key, sdUserInterfaceScope* outputScope );
virtual sdProperties::ePropertyType GetType( void ) const { return inputExpression->GetType(); }
virtual void Attach( sdUIExpression* ) { assert( false ); }
virtual void Detach( void );
virtual void InputChanged( void );
virtual void OnOnChangedOverflow( void );
virtual void Update( void );
virtual void Free( void ) { delete this; }
protected:
sdProperties::sdProperty* outputProperty;
sdUIExpression* inputExpression;
int scopeIndex;
int scopeKey;
sdUserInterfaceScope* scope;
};
extern const char sdPropertyExpressionField_Identifier[];
class sdPropertyExpressionField :
public sdPropertyExpressionSingle,
public sdPoolAllocator< sdPropertyExpressionField, sdPropertyExpressionField_Identifier, 1024 > {
public:
typedef sdPoolAllocator< sdPropertyExpressionField, sdPropertyExpressionField_Identifier, 1024 > allocator_t;
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
sdPropertyExpressionField( const char* name, sdUIExpression* input, int index );
virtual ~sdPropertyExpressionField() {}
virtual sdProperties::ePropertyType GetType( void ) const { return sdProperties::PT_FLOAT; }
void Update( void );
virtual void Free( void ) { delete this; }
protected:
int outputField;
};
class sdUIEvaluator;
class sdUIEvaluatorTypeBase {
public:
virtual ~sdUIEvaluatorTypeBase( void ) { ; }
virtual int GetIntValue( sdUIEvaluator* ) { assert( false ); return 0; }
virtual float GetFloatValue( sdUIEvaluator* ) { assert( false ); return 0.f; }
virtual idStr GetStringValue( sdUIEvaluator* ) { assert( false ); return ""; }
virtual idWStr GetWStringValue( sdUIEvaluator* ) { assert( false ); return L""; }
virtual idVec2 GetVec2Value( sdUIEvaluator* ) { assert( false ); return vec2_zero; }
virtual idVec3 GetVec3Value( sdUIEvaluator* ) { assert( false ); return vec3_zero; }
virtual idVec4 GetVec4Value( sdUIEvaluator* ) { assert( false ); return vec4_zero; }
virtual sdProperties::ePropertyType GetReturnType( void ) const = 0;
virtual int GetNumParms( void ) const = 0;
virtual bool IsVariadic( void ) const = 0;
virtual sdProperties::ePropertyType GetParmType( int index ) const = 0;
virtual const char* GetName( void ) const = 0;
};
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
#define UI_EVALUATOR_TYPE_DECLARATION( TYPENAME, TYPE, VALUETYPE ) \
extern const char sdUIEvaluatorType##TYPENAME##_Identifier[];\
class sdUIEvaluatorType##TYPENAME : public sdUIEvaluatorTypeBase, public sdPoolAllocator< sdUIEvaluatorType##TYPENAME, sdUIEvaluatorType##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdUIEvaluatorType##TYPENAME, sdUIEvaluatorType##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
typedef TYPE ( *evaluationFunc_t )( const sdUIEvaluator* ); \
sdUIEvaluatorType##TYPENAME( const char* parms, const char* name, evaluationFunc_t func ); \
virtual ~sdUIEvaluatorType##TYPENAME( void ) {} \
virtual sdProperties::ePropertyType GetReturnType( void ) const { return VALUETYPE; } \
virtual int GetNumParms( void ) const { return parms.Num(); } \
virtual bool IsVariadic( void ) const { return isVariadic; } \
virtual sdProperties::ePropertyType GetParmType( int index ) const { return parms[ index ]; } \
virtual TYPE Get##TYPENAME##Value( sdUIEvaluator* evaluator ) { return function( evaluator ); } \
virtual const char* GetName( void ) const { return name; } \
\
private: \
idList< sdProperties::ePropertyType > parms; \
evaluationFunc_t function; \
idStr name; \
bool isVariadic; \
};
UI_EVALUATOR_TYPE_DECLARATION( Int, int, sdProperties::PT_INT )
UI_EVALUATOR_TYPE_DECLARATION( Float, float, sdProperties::PT_FLOAT )
UI_EVALUATOR_TYPE_DECLARATION( Vec2, idVec2, sdProperties::PT_VEC2 )
UI_EVALUATOR_TYPE_DECLARATION( Vec3, idVec3, sdProperties::PT_VEC3 )
UI_EVALUATOR_TYPE_DECLARATION( Vec4, idVec4, sdProperties::PT_VEC4 )
UI_EVALUATOR_TYPE_DECLARATION( String, idStr, sdProperties::PT_STRING )
UI_EVALUATOR_TYPE_DECLARATION( WString, idWStr, sdProperties::PT_WSTRING)
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
class sdUIEvaluator : public sdUIExpression {
public:
sdUIEvaluator( sdUIEvaluatorTypeBase* type, sdUserInterfaceScope* _scope, idLexer* src );
virtual sdUIEvaluator::~sdUIEvaluator( void );
virtual sdProperties::ePropertyType GetType( void ) const { return type->GetReturnType(); }
virtual void SetProperty( sdProperties::sdProperty* output ) { assert( false ); }
virtual void Attach( sdUIExpression* );
virtual void Detach( void );
sdUIExpression* GetParm( int index ) const { return parms[ index ]; }
int GetNumParms() const { return parms.Num(); }
bool IsVariadic() const { return type->IsVariadic(); }
sdUserInterfaceScope* GetScope() const { return scope; }
protected:
sdUIEvaluatorTypeBase* type;
sdUIExpression* outputExpression;
idList< sdUIExpression* > parms;
sdUserInterfaceScope* scope;
};
#ifdef ID_REDIRECT_NEWDELETE
#undef new
#endif
#define UI_EVALUATOR( TYPENAME, TYPE ) \
extern const char sdUIEvaluator##TYPENAME##_Identifier[]; \
class sdUIEvaluator##TYPENAME : public sdUIEvaluator, public sdPoolAllocator< sdUIEvaluator##TYPENAME, sdUIEvaluator##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdUIEvaluator##TYPENAME, sdUIEvaluator##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
sdUIEvaluator##TYPENAME( sdUIEvaluatorTypeBase* type, sdUserInterfaceScope* _scope, idLexer* src ) : sdUIEvaluator( type, _scope, src ) { } \
virtual ~sdUIEvaluator##TYPENAME( void ) {} \
\
virtual TYPE Get##TYPENAME##Value( void ) { value = type->Get##TYPENAME##Value( this ); return value; } \
virtual void InputChanged( void ) { outputExpression->InputChanged(); } \
virtual void Attach( sdUIExpression* expression ) { sdUIEvaluator::Attach( expression ); } \
virtual void Free( void ) { delete this; } \
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); } \
protected: \
TYPE value; \
};
#define UI_EVALUATOR_REF( TYPENAME, TYPE ) \
extern const char sdUIEvaluator##TYPENAME##_Identifier[]; \
class sdUIEvaluator##TYPENAME : public sdUIEvaluator, public sdPoolAllocator< sdUIEvaluator##TYPENAME, sdUIEvaluator##TYPENAME##_Identifier, 1024 > { \
public: \
typedef sdPoolAllocator< sdUIEvaluator##TYPENAME, sdUIEvaluator##TYPENAME##_Identifier, 1024 > allocator_t; \
SD_DISAMBIGUATE_POOL_ALLOCATOR( allocator_t ) \
sdUIEvaluator##TYPENAME( sdUIEvaluatorTypeBase* type, sdUserInterfaceScope* _scope, idLexer* src ) : sdUIEvaluator( type, _scope, src ) { } \
virtual ~sdUIEvaluator##TYPENAME( void ) {} \
\
virtual const TYPE & Get##TYPENAME##Value( TYPE &temp ) { value = type->Get##TYPENAME##Value( this ); return value; } \
virtual void InputChanged( void ) { outputExpression->InputChanged(); } \
virtual void Attach( sdUIExpression* expression ) { sdUIEvaluator::Attach( expression ); } \
virtual void Free( void ) { delete this; } \
virtual void OnOnChangedOverflow( void ) { outputExpression->OnOnChangedOverflow(); } \
protected: \
TYPE value; \
};
UI_EVALUATOR( Int, int )
UI_EVALUATOR( Float, float )
UI_EVALUATOR_REF( Vec2, idVec2 )
UI_EVALUATOR_REF( Vec3, idVec3 )
UI_EVALUATOR_REF( Vec4, idVec4 )
UI_EVALUATOR_REF( String, idStr )
UI_EVALUATOR_REF( WString, idWStr )
#ifdef ID_REDIRECT_NEWDELETE
#define new ID_DEBUG_NEW
#endif
#endif // __GAME_GUIS_USERINTERFACEEXPRESSIONS_H__