etqw-sdk/source/game/script/Script_Helper.cpp

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 );
}