443 lines
11 KiB
C++
443 lines
11 KiB
C++
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
|
||
|
#include "../precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
#include "Script_Helper.h"
|
||
|
#include "Script_Program.h"
|
||
|
#include "Script_ScriptObject.h"
|
||
|
#include "../Entity.h"
|
||
|
#include "../structures/TeamManager.h"
|
||
|
#include "../../idlib/PropertiesImpl.h"
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::sdScriptHelper
|
||
|
============
|
||
|
*/
|
||
|
sdScriptHelper::sdScriptHelper( void ) {
|
||
|
thread = NULL;
|
||
|
Clear();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::~sdScriptHelper
|
||
|
============
|
||
|
*/
|
||
|
sdScriptHelper::~sdScriptHelper( void ) {
|
||
|
Clear();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Clear
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Clear( bool free ) {
|
||
|
if ( thread != NULL && free ) {
|
||
|
gameLocal.program->FreeThread( thread );
|
||
|
}
|
||
|
thread = NULL;
|
||
|
function = NULL;
|
||
|
object = NULL;
|
||
|
size = type_object.Size();
|
||
|
args.Clear();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Init
|
||
|
============
|
||
|
*/
|
||
|
bool sdScriptHelper::Init( idScriptObject* obj, const char* functionName ) {
|
||
|
if ( thread != NULL ) {
|
||
|
gameLocal.Warning( "sdScriptHelper::Init ScriptHelper reused without being cleared" );
|
||
|
assert( false );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( !obj || !functionName || !*functionName ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
object = obj;
|
||
|
|
||
|
function = obj->GetFunction( functionName );
|
||
|
if ( !function ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Init
|
||
|
============
|
||
|
*/
|
||
|
bool sdScriptHelper::Init( idScriptObject* obj, const sdProgram::sdFunction* _function ) {
|
||
|
if ( !obj || !_function ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
object = obj;
|
||
|
function = _function;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Done
|
||
|
============
|
||
|
*/
|
||
|
bool sdScriptHelper::Done( void ) const {
|
||
|
return !thread || thread->IsDying();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( int value ) {
|
||
|
float fvalue = static_cast< float >( value );
|
||
|
Push( fvalue );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( const char* value ) {
|
||
|
parms_t* arg = args.Alloc();
|
||
|
if ( arg == NULL ) {
|
||
|
gameLocal.Error( "sdScriptHelper::Push - args.Alloc() returned NULL - number of arguments overflowed" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
arg->integer = 0;
|
||
|
arg->string = value;
|
||
|
|
||
|
size += MAX_STRING_LEN;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( float value ) {
|
||
|
parms_t* arg = args.Alloc();
|
||
|
if ( arg == NULL ) {
|
||
|
gameLocal.Error( "sdScriptHelper::Push - args.Alloc() returned NULL - number of arguments overflowed" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
arg->integer = *reinterpret_cast< int* >( &value );
|
||
|
arg->string = NULL;
|
||
|
|
||
|
size += sizeof( int );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( idScriptObject* obj ) {
|
||
|
parms_t* arg = args.Alloc();
|
||
|
if ( arg == NULL ) {
|
||
|
gameLocal.Error( "sdScriptHelper::Push - args.Alloc() returned NULL - number of arguments overflowed" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
arg->integer = obj->GetHandle();
|
||
|
arg->string = NULL;
|
||
|
|
||
|
size += sizeof( int );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( sdTeamInfo* team ) {
|
||
|
Push( team ? team->GetScriptObject() : NULL );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( const idVec3& vec ) {
|
||
|
Push( vec[ 0 ] );
|
||
|
Push( vec[ 1 ] );
|
||
|
Push( vec[ 2 ] );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Push
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Push( const idAngles& angles ) {
|
||
|
Push( angles.pitch );
|
||
|
Push( angles.yaw );
|
||
|
Push( angles.roll );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::Run
|
||
|
============
|
||
|
*/
|
||
|
void sdScriptHelper::Run( void ) {
|
||
|
if ( !function ) {
|
||
|
assert( false );
|
||
|
return;
|
||
|
}
|
||
|
thread = gameLocal.program->CreateThread( *this );
|
||
|
if ( thread == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
assert( !thread->IsDying() );
|
||
|
#ifdef _DEBUG
|
||
|
thread->SetName( "sdScriptHelper" );
|
||
|
#endif // _DEBUG
|
||
|
thread->ManualDelete();
|
||
|
thread->Execute();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::GetReturnedFloat
|
||
|
============
|
||
|
*/
|
||
|
float sdScriptHelper::GetReturnedFloat( void ) {
|
||
|
return gameLocal.program->GetReturnedFloat();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::GetReturnedInteger
|
||
|
============
|
||
|
*/
|
||
|
int sdScriptHelper::GetReturnedInteger( void ) {
|
||
|
return gameLocal.program->GetReturnedInteger();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdScriptHelper::GetReturnedString
|
||
|
============
|
||
|
*/
|
||
|
const char* sdScriptHelper::GetReturnedString( void ) {
|
||
|
return gameLocal.program->GetReturnedString();
|
||
|
}
|
||
|
|
||
|
|
||
|
const idEventDef EV_CVar_GetFloatValue( "getFloatValue", 'f', DOC_TEXT( "Returns a float representation of the cvar's current value." ), 0, "If the value cannot be converted to a float, the result will be 0." );
|
||
|
const idEventDef EV_CVar_GetStringValue( "getStringValue", 's', DOC_TEXT( "Returns the cvar's current value." ), 0, NULL );
|
||
|
const idEventDef EV_CVar_GetVectorValue( "getVectorValue", 'v', DOC_TEXT( "Returns a vector representation of the cvar's current value." ), 0, "If the value cannot be converted to a vector, the result will be '0 0 0'." );
|
||
|
const idEventDef EV_CVar_GetIntValue( "getIntValue", 'd', DOC_TEXT( "Returns an integer representation of the cvar's current value." ), 0, "If the value cannot be converted to an integer, the result will be 0." );
|
||
|
const idEventDef EV_CVar_GetBoolValue( "getBoolValue", 'b', DOC_TEXT( "Returns a boolean representation of the cvar's current value." ), 0, "If the value cannot be converted to a boolean, the result will be false." );
|
||
|
|
||
|
const idEventDef EV_CVar_SetFloatValue( "setFloatValue", '\0', DOC_TEXT( "Converts the given value to a string and sets it as the cvar's value." ), 1, NULL, "f", "value", "Value to set." );
|
||
|
const idEventDef EV_CVar_SetStringValue( "setStringValue", '\0', DOC_TEXT( "Sets the cvar's value." ), 1, NULL, "s", "value", "Value to set." );
|
||
|
const idEventDef EV_CVar_SetVectorValue( "setVectorValue", '\0', DOC_TEXT( "Converts the given value to a string and sets it as the cvar's value." ), 1, NULL, "v", "value", "Value to set." );
|
||
|
const idEventDef EV_CVar_SetIntValue( "setIntValue", '\0', DOC_TEXT( "Converts the given value to a string and sets it as the cvar's value." ), 1, NULL, "d", "value", "Value to set." );
|
||
|
const idEventDef EV_CVar_SetBoolValue( "setBoolValue", '\0', DOC_TEXT( "Converts the given value to a string and sets it as the cvar's value." ), 1, NULL, "b", "value", "Value to set." );
|
||
|
|
||
|
const idEventDef EV_CVar_SetCallback( "setCallback", '\0', DOC_TEXT( "Specifies a global namespace function to be called whenever the value of this cvar changes." ), 1, "Only one callback may be active per wrapper at a time.\nSupplying a class method as the callback will have undefined behaviour.", "s", "name", "Name of the function to use as a callback." );
|
||
|
|
||
|
CLASS_DECLARATION( idClass, sdCVarWrapper )
|
||
|
EVENT( EV_CVar_GetFloatValue, sdCVarWrapper::Event_GetFloatValue )
|
||
|
EVENT( EV_CVar_GetStringValue, sdCVarWrapper::Event_GetStringValue )
|
||
|
EVENT( EV_CVar_GetVectorValue, sdCVarWrapper::Event_GetVectorValue )
|
||
|
EVENT( EV_CVar_GetIntValue, sdCVarWrapper::Event_GetIntValue )
|
||
|
EVENT( EV_CVar_GetBoolValue, sdCVarWrapper::Event_GetBoolValue )
|
||
|
|
||
|
EVENT( EV_CVar_SetFloatValue, sdCVarWrapper::Event_SetFloatValue )
|
||
|
EVENT( EV_CVar_SetStringValue, sdCVarWrapper::Event_SetStringValue )
|
||
|
EVENT( EV_CVar_SetVectorValue, sdCVarWrapper::Event_SetVectorValue )
|
||
|
EVENT( EV_CVar_SetIntValue, sdCVarWrapper::Event_SetIntValue )
|
||
|
EVENT( EV_CVar_SetBoolValue, sdCVarWrapper::Event_SetBoolValue )
|
||
|
|
||
|
EVENT( EV_CVar_SetCallback, sdCVarWrapper::Event_SetCallback )
|
||
|
END_CLASS
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::sdCVarWrapper
|
||
|
============
|
||
|
*/
|
||
|
sdCVarWrapper::sdCVarWrapper( void ) : _scriptObject( NULL ), _cvar( NULL ), _callbackFunction( NULL ) {
|
||
|
_callback.Init( this );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Init
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Init( const char* cvarName, const char* defaultValue ) {
|
||
|
_cvar = cvarSystem->Find( cvarName );
|
||
|
if ( !_cvar ) {
|
||
|
cvarSystem->SetCVarString( cvarName, defaultValue, CVAR_GAME );
|
||
|
|
||
|
_cvar = cvarSystem->Find( cvarName );
|
||
|
if ( !_cvar ) {
|
||
|
gameLocal.Error( "sdCVarWrapper::sdCVarWrapper Failed to Create CVar '%s'", defaultValue );
|
||
|
}
|
||
|
}
|
||
|
_scriptObject = gameLocal.program->AllocScriptObject( this, "cvar" );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::~sdCVarWrapper
|
||
|
============
|
||
|
*/
|
||
|
sdCVarWrapper::~sdCVarWrapper( void ) {
|
||
|
if ( _callbackFunction ) {
|
||
|
_cvar->UnRegisterCallback( &_callback );
|
||
|
}
|
||
|
|
||
|
gameLocal.program->FreeScriptObject( _scriptObject );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::OnChanged
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::OnChanged( void ) {
|
||
|
assert( _callbackFunction );
|
||
|
gameLocal.CallFrameCommand( _callbackFunction );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_GetFloatValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_GetFloatValue( void ) {
|
||
|
sdProgram::ReturnFloat( _cvar->GetFloat() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_GetStringValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_GetStringValue( void ) {
|
||
|
sdProgram::ReturnString( _cvar->GetString() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_GetVectorValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_GetVectorValue( void ) {
|
||
|
idVec3 retVal;
|
||
|
sdProperties::sdFromString( retVal, _cvar->GetString() );
|
||
|
sdProgram::ReturnVector( retVal );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_GetIntValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_GetIntValue( void ) {
|
||
|
sdProgram::ReturnInteger( _cvar->GetInteger() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_GetBoolValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_GetBoolValue( void ) {
|
||
|
sdProgram::ReturnBoolean( _cvar->GetBool() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_SetBoolValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_SetFloatValue( float value ) {
|
||
|
_cvar->SetFloat( value );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_SetBoolValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_SetStringValue( const char* value ) {
|
||
|
_cvar->SetString( value );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_SetBoolValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_SetIntValue( int value ) {
|
||
|
_cvar->SetInteger( value );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_SetBoolValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_SetBoolValue( bool value ) {
|
||
|
_cvar->SetBool( value );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_SetVectorValue
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_SetVectorValue( const idVec3& value ) {
|
||
|
_cvar->SetString( value.ToString( 5 ) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===========
|
||
|
sdCVarWrapper::Event_SetCallback
|
||
|
============
|
||
|
*/
|
||
|
void sdCVarWrapper::Event_SetCallback( const char* callback ) {
|
||
|
if ( _callbackFunction ) {
|
||
|
_cvar->UnRegisterCallback( &_callback );
|
||
|
}
|
||
|
|
||
|
_callbackFunction = gameLocal.program->FindFunction( callback );
|
||
|
if ( !_callbackFunction ) {
|
||
|
gameLocal.Warning( "sdCVarWrapper::Event_SetCallback Failed to Find Callback '%s'", callback );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
_cvar->RegisterCallback( &_callback );
|
||
|
}
|