mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-03-03 17:25:27 +03:00
Merge pull request #331 from samisalreadytaken/vscript-leak-fixes
VScript leak fixes
This commit is contained in:
commit
a8283a8b11
@ -1531,35 +1531,32 @@ float C_BaseAnimating::ClampCycle( float flCycle, bool isLooping )
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vector& C_BaseAnimating::ScriptGetAttachmentOrigin( int iAttachment )
|
||||
{
|
||||
|
||||
static Vector absOrigin;
|
||||
static QAngle qa;
|
||||
QAngle qa;
|
||||
|
||||
C_BaseAnimating::GetAttachment( iAttachment, absOrigin, qa );
|
||||
|
||||
return absOrigin;
|
||||
}
|
||||
|
||||
const Vector& C_BaseAnimating::ScriptGetAttachmentAngles( int iAttachment )
|
||||
const QAngle& C_BaseAnimating::ScriptGetAttachmentAngles( int iAttachment )
|
||||
{
|
||||
|
||||
static Vector absOrigin;
|
||||
static Vector absAngles;
|
||||
static QAngle qa;
|
||||
Vector absOrigin;
|
||||
|
||||
C_BaseAnimating::GetAttachment( iAttachment, absOrigin, qa );
|
||||
absAngles.x = qa.x;
|
||||
absAngles.y = qa.y;
|
||||
absAngles.z = qa.z;
|
||||
return absAngles;
|
||||
return qa;
|
||||
}
|
||||
|
||||
HSCRIPT C_BaseAnimating::ScriptGetAttachmentMatrix( int iAttachment )
|
||||
HSCRIPT_RC C_BaseAnimating::ScriptGetAttachmentMatrix( int iAttachment )
|
||||
{
|
||||
static matrix3x4_t matrix;
|
||||
matrix3x4_t *matrix = new matrix3x4_t;
|
||||
|
||||
C_BaseAnimating::GetAttachment( iAttachment, matrix );
|
||||
return g_pScriptVM->RegisterInstance( &matrix );
|
||||
if ( C_BaseAnimating::GetAttachment( iAttachment, *matrix ) )
|
||||
return g_pScriptVM->RegisterInstance( matrix, true );
|
||||
|
||||
delete matrix;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void C_BaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform )
|
||||
|
@ -464,8 +464,8 @@ public:
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
int ScriptLookupAttachment( const char *pAttachmentName ) { return LookupAttachment( pAttachmentName ); }
|
||||
const Vector& ScriptGetAttachmentOrigin(int iAttachment);
|
||||
const Vector& ScriptGetAttachmentAngles(int iAttachment);
|
||||
HSCRIPT ScriptGetAttachmentMatrix(int iAttachment);
|
||||
const QAngle& ScriptGetAttachmentAngles(int iAttachment);
|
||||
HSCRIPT_RC ScriptGetAttachmentMatrix(int iAttachment);
|
||||
|
||||
void ScriptGetBoneTransform( int iBone, HSCRIPT hTransform );
|
||||
void ScriptSetBoneTransform( int iBone, HSCRIPT hTransform );
|
||||
|
@ -2610,9 +2610,17 @@ public:
|
||||
|
||||
static inline void SetHScript( HSCRIPT &var, HSCRIPT val )
|
||||
{
|
||||
if ( var && g_pScriptVM )
|
||||
g_pScriptVM->ReleaseScript( var );
|
||||
var = val;
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
if ( var )
|
||||
g_pScriptVM->ReleaseScript( var );
|
||||
|
||||
var = g_pScriptVM->CopyObject( val );
|
||||
}
|
||||
else
|
||||
{
|
||||
var = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define CheckCallback(s)\
|
||||
|
@ -317,7 +317,7 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceActivity, "GetSequenceActivity", "Gets the activity ID of the specified sequence index" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSelectWeightedSequence, "SelectWeightedSequence", "Selects a sequence for the specified activity ID" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSelectHeaviestSequence, "SelectHeaviestSequence", "Selects the sequence with the heaviest weight for the specified activity ID" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceKeyValues, "GetSequenceKeyValues", "Get a KeyValue class instance on the specified sequence. WARNING: This uses the same KeyValue pointer as GetModelKeyValues!" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceKeyValues, "GetSequenceKeyValues", "Get a KeyValue class instance on the specified sequence" )
|
||||
DEFINE_SCRIPTFUNC( ResetSequenceInfo, "" )
|
||||
DEFINE_SCRIPTFUNC( StudioFrameAdvance, "" )
|
||||
DEFINE_SCRIPTFUNC( GetPlaybackRate, "" )
|
||||
@ -2306,21 +2306,14 @@ void CBaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VScript access to sequence's key values
|
||||
// for iteration and value access, use:
|
||||
// ScriptFindKey, ScriptGetFirstSubKey, ScriptGetString,
|
||||
// ScriptGetInt, ScriptGetFloat, ScriptGetNextKey
|
||||
// NOTE: This is recycled from ScriptGetModelKeyValues() and uses its pointer!!!
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseAnimating::ScriptGetSequenceKeyValues( int iSequence )
|
||||
HSCRIPT_RC CBaseAnimating::ScriptGetSequenceKeyValues( int iSequence )
|
||||
{
|
||||
KeyValues *pSeqKeyValues = GetSequenceKeyValues( iSequence );
|
||||
HSCRIPT hScript = NULL;
|
||||
if ( pSeqKeyValues )
|
||||
{
|
||||
// UNDONE: how does destructor get called on this
|
||||
m_pScriptModelKeyValues = hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pSeqKeyValues, true );
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??? Does name need to be unique???
|
||||
hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pSeqKeyValues );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
|
@ -211,7 +211,7 @@ public:
|
||||
int ScriptSelectHeaviestSequence( int activity ) { return SelectHeaviestSequence( (Activity)activity ); }
|
||||
int ScriptSelectWeightedSequence( int activity, int curSequence ) { return SelectWeightedSequence( (Activity)activity, curSequence ); }
|
||||
|
||||
HSCRIPT ScriptGetSequenceKeyValues( int iSequence );
|
||||
HSCRIPT_RC ScriptGetSequenceKeyValues( int iSequence );
|
||||
|
||||
// For VScript
|
||||
int GetSkin() { return m_nSkin; }
|
||||
|
@ -10153,7 +10153,7 @@ void CBaseEntity::SetScriptOwnerEntity(HSCRIPT pOwner)
|
||||
// ScriptFindKey, ScriptGetFirstSubKey, ScriptGetString,
|
||||
// ScriptGetInt, ScriptGetFloat, ScriptGetNextKey
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::ScriptGetModelKeyValues( void )
|
||||
HSCRIPT_RC CBaseEntity::ScriptGetModelKeyValues( void )
|
||||
{
|
||||
KeyValues *pModelKeyValues = new KeyValues("");
|
||||
HSCRIPT hScript = NULL;
|
||||
@ -10162,16 +10162,12 @@ HSCRIPT CBaseEntity::ScriptGetModelKeyValues( void )
|
||||
|
||||
if ( pModelKeyValues->LoadFromBuffer( pszModelName, pBuffer ) )
|
||||
{
|
||||
// UNDONE: how does destructor get called on this
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
m_pScriptModelKeyValues = hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pModelKeyValues, true ); // Allow VScript to delete this when the instance is removed.
|
||||
hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pModelKeyValues );
|
||||
#else
|
||||
// UNDONE: how does destructor get called on this
|
||||
m_pScriptModelKeyValues = new CScriptKeyValues( pModelKeyValues );
|
||||
#endif
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??? Does name need to be unique???
|
||||
|
||||
#ifndef MAPBASE_VSCRIPT
|
||||
hScript = g_pScriptVM->RegisterInstance( m_pScriptModelKeyValues );
|
||||
#endif
|
||||
|
||||
|
@ -2114,7 +2114,7 @@ public:
|
||||
#endif
|
||||
|
||||
const char* ScriptGetModelName(void) const;
|
||||
HSCRIPT ScriptGetModelKeyValues(void);
|
||||
HSCRIPT_RC ScriptGetModelKeyValues(void);
|
||||
|
||||
void ScriptStopSound(const char* soundname);
|
||||
void ScriptEmitSound(const char* soundname);
|
||||
@ -2188,9 +2188,7 @@ public:
|
||||
CScriptScope m_ScriptScope;
|
||||
HSCRIPT m_hScriptInstance;
|
||||
string_t m_iszScriptId;
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT m_pScriptModelKeyValues;
|
||||
#else
|
||||
#ifndef MAPBASE_VSCRIPT
|
||||
CScriptKeyValues* m_pScriptModelKeyValues;
|
||||
#endif
|
||||
};
|
||||
|
@ -38,8 +38,8 @@ public:
|
||||
void InputReload( inputdata_t &inputdata );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT ScriptGetKeyValues( void );
|
||||
HSCRIPT ScriptGetKeyValueBlock( void );
|
||||
HSCRIPT_RC ScriptGetKeyValues( void );
|
||||
HSCRIPT_RC ScriptGetKeyValueBlock( void );
|
||||
|
||||
void ScriptSetKeyValues( HSCRIPT hKV );
|
||||
void ScriptSetKeyValueBlock( HSCRIPT hKV );
|
||||
@ -275,7 +275,7 @@ void CLogicExternalData::InputReload( inputdata_t &inputdata )
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CLogicExternalData::ScriptGetKeyValues( void )
|
||||
HSCRIPT_RC CLogicExternalData::ScriptGetKeyValues( void )
|
||||
{
|
||||
if (m_bReloadBeforeEachAction)
|
||||
LoadFile();
|
||||
@ -283,8 +283,9 @@ HSCRIPT CLogicExternalData::ScriptGetKeyValues( void )
|
||||
HSCRIPT hScript = NULL;
|
||||
if (m_pRoot)
|
||||
{
|
||||
// Does this need to be destructed or freed? m_pScriptModelKeyValues apparently doesn't.
|
||||
hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, m_pRoot, false );
|
||||
KeyValues *pCopy = new KeyValues( NULL );
|
||||
*pCopy = *m_pRoot;
|
||||
hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pCopy );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
@ -292,7 +293,7 @@ HSCRIPT CLogicExternalData::ScriptGetKeyValues( void )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CLogicExternalData::ScriptGetKeyValueBlock( void )
|
||||
HSCRIPT_RC CLogicExternalData::ScriptGetKeyValueBlock( void )
|
||||
{
|
||||
if (m_bReloadBeforeEachAction)
|
||||
LoadFile();
|
||||
@ -300,8 +301,9 @@ HSCRIPT CLogicExternalData::ScriptGetKeyValueBlock( void )
|
||||
HSCRIPT hScript = NULL;
|
||||
if (m_pBlock)
|
||||
{
|
||||
// Does this need to be destructed or freed? m_pScriptModelKeyValues apparently doesn't.
|
||||
hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, m_pBlock, false );
|
||||
KeyValues *pCopy = new KeyValues( NULL );
|
||||
*pCopy = *m_pBlock;
|
||||
hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pCopy );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
@ -321,7 +323,8 @@ void CLogicExternalData::ScriptSetKeyValues( HSCRIPT hKV )
|
||||
KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hKV );
|
||||
if (pKV)
|
||||
{
|
||||
m_pRoot = pKV;
|
||||
m_pRoot = new KeyValues( NULL );
|
||||
*m_pRoot = *pKV;
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +339,8 @@ void CLogicExternalData::ScriptSetKeyValueBlock( HSCRIPT hKV )
|
||||
KeyValues *pKV = scriptmanager->GetKeyValuesFromScriptKV( g_pScriptVM, hKV );
|
||||
if (pKV)
|
||||
{
|
||||
m_pBlock = pKV;
|
||||
m_pBlock = new KeyValues( NULL );
|
||||
*m_pBlock = *pKV;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3033,7 +3033,7 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
|
||||
|
||||
float nextthink = gpGlobals->curtime + flTime;
|
||||
|
||||
pf->m_hfnThink = hFunc;
|
||||
pf->m_hfnThink = g_pScriptVM->CopyObject( hFunc );
|
||||
pf->m_flNextThink = nextthink;
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
@ -255,11 +255,10 @@ void ScriptDispatchSpawn( HSCRIPT hEntity )
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
static HSCRIPT CreateDamageInfo( HSCRIPT hInflictor, HSCRIPT hAttacker, const Vector &vecForce, const Vector &vecDamagePos, float flDamage, int iDamageType )
|
||||
static HSCRIPT_RC CreateDamageInfo( HSCRIPT hInflictor, HSCRIPT hAttacker, const Vector &vecForce, const Vector &vecDamagePos, float flDamage, int iDamageType )
|
||||
{
|
||||
// The script is responsible for deleting this via DestroyDamageInfo().
|
||||
CTakeDamageInfo *damageInfo = new CTakeDamageInfo( ToEnt(hInflictor), ToEnt(hAttacker), flDamage, iDamageType );
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( damageInfo );
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( damageInfo, true );
|
||||
|
||||
damageInfo->SetDamagePosition( vecDamagePos );
|
||||
damageInfo->SetDamageForce( vecForce );
|
||||
@ -267,14 +266,8 @@ static HSCRIPT CreateDamageInfo( HSCRIPT hInflictor, HSCRIPT hAttacker, const Ve
|
||||
return hScript;
|
||||
}
|
||||
|
||||
static void DestroyDamageInfo( HSCRIPT hDamageInfo )
|
||||
static void DestroyDamageInfo( HSCRIPT )
|
||||
{
|
||||
CTakeDamageInfo *pInfo = HScriptToClass< CTakeDamageInfo >( hDamageInfo );
|
||||
if ( pInfo )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( hDamageInfo );
|
||||
delete pInfo;
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCalculateExplosiveDamageForce( HSCRIPT info, const Vector &vecDir, const Vector &vecForceOrigin, float flScale )
|
||||
@ -317,6 +310,8 @@ void ScriptGuessDamageForce( HSCRIPT info, const Vector &vecForceDir, const Vect
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptGameTrace, "CGameTrace", "trace_t" )
|
||||
DEFINE_SCRIPT_REFCOUNTED_INSTANCE()
|
||||
|
||||
DEFINE_SCRIPTFUNC( DidHitWorld, "Returns whether the trace hit the world entity or not." )
|
||||
DEFINE_SCRIPTFUNC( DidHitNonWorldEntity, "Returns whether the trace hit something other than the world entity." )
|
||||
DEFINE_SCRIPTFUNC( GetEntityIndex, "Returns the index of whatever entity this trace hit." )
|
||||
@ -347,7 +342,7 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptGameTrace, "CGameTrace", "trace_t" )
|
||||
DEFINE_SCRIPTFUNC( Surface, "" )
|
||||
DEFINE_SCRIPTFUNC( Plane, "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( Destroy, "Deletes this instance. Important for preventing memory leaks." )
|
||||
DEFINE_SCRIPTFUNC( Destroy, SCRIPT_HIDE )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( scriptsurfacedata_t, "surfacedata_t", "" )
|
||||
@ -379,33 +374,25 @@ CPlaneTInstanceHelper g_PlaneTInstanceHelper;
|
||||
BEGIN_SCRIPTDESC_ROOT_WITH_HELPER( cplane_t, "", &g_PlaneTInstanceHelper )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
static HSCRIPT ScriptTraceLineComplex( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
||||
static HSCRIPT_RC ScriptTraceLineComplex( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
||||
{
|
||||
// The script is responsible for deleting this via Destroy().
|
||||
CScriptGameTrace *tr = new CScriptGameTrace();
|
||||
|
||||
CBaseEntity *pIgnore = ToEnt( entIgnore );
|
||||
UTIL_TraceLine( vecStart, vecEnd, iMask, pIgnore, iCollisionGroup, tr );
|
||||
|
||||
tr->RegisterSurface();
|
||||
tr->RegisterPlane();
|
||||
|
||||
return tr->GetScriptInstance();
|
||||
return g_pScriptVM->RegisterInstance( tr, true );
|
||||
}
|
||||
|
||||
static HSCRIPT ScriptTraceHullComplex( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin, const Vector &hullMax,
|
||||
static HSCRIPT_RC ScriptTraceHullComplex( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin, const Vector &hullMax,
|
||||
HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
||||
{
|
||||
// The script is responsible for deleting this via Destroy().
|
||||
CScriptGameTrace *tr = new CScriptGameTrace();
|
||||
|
||||
CBaseEntity *pIgnore = ToEnt( entIgnore );
|
||||
UTIL_TraceHull( vecStart, vecEnd, hullMin, hullMax, iMask, pIgnore, iCollisionGroup, tr );
|
||||
|
||||
tr->RegisterSurface();
|
||||
tr->RegisterPlane();
|
||||
|
||||
return tr->GetScriptInstance();
|
||||
return g_pScriptVM->RegisterInstance( tr, true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -476,12 +463,11 @@ void FireBulletsInfo_t::ScriptSetAdditionalIgnoreEnt( HSCRIPT value )
|
||||
m_pAdditionalIgnoreEnt = ToEnt( value );
|
||||
}
|
||||
|
||||
static HSCRIPT CreateFireBulletsInfo( int cShots, const Vector &vecSrc, const Vector &vecDirShooting,
|
||||
static HSCRIPT_RC CreateFireBulletsInfo( int cShots, const Vector &vecSrc, const Vector &vecDirShooting,
|
||||
const Vector &vecSpread, float iDamage, HSCRIPT pAttacker )
|
||||
{
|
||||
// The script is responsible for deleting this via DestroyFireBulletsInfo().
|
||||
FireBulletsInfo_t *info = new FireBulletsInfo_t();
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( info );
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( info, true );
|
||||
|
||||
info->SetShots( cShots );
|
||||
info->SetSource( vecSrc );
|
||||
@ -493,14 +479,8 @@ static HSCRIPT CreateFireBulletsInfo( int cShots, const Vector &vecSrc, const Ve
|
||||
return hScript;
|
||||
}
|
||||
|
||||
static void DestroyFireBulletsInfo( HSCRIPT hBulletsInfo )
|
||||
static void DestroyFireBulletsInfo( HSCRIPT )
|
||||
{
|
||||
FireBulletsInfo_t *pInfo = HScriptToClass< FireBulletsInfo_t >( hBulletsInfo );
|
||||
if ( pInfo )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( hBulletsInfo );
|
||||
delete pInfo;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1053,14 +1033,14 @@ void RegisterSharedScriptFunctions()
|
||||
#endif
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, CreateDamageInfo, "" );
|
||||
ScriptRegisterFunction( g_pScriptVM, DestroyDamageInfo, "" );
|
||||
ScriptRegisterFunction( g_pScriptVM, DestroyDamageInfo, SCRIPT_HIDE );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateExplosiveDamageForce, "CalculateExplosiveDamageForce", "Fill out a damage info handle with a damage force for an explosive." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateBulletDamageForce, "CalculateBulletDamageForce", "Fill out a damage info handle with a damage force for a bullet impact." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateMeleeDamageForce, "CalculateMeleeDamageForce", "Fill out a damage info handle with a damage force for a melee impact." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGuessDamageForce, "GuessDamageForce", "Try and guess the physics force to use." );
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, CreateFireBulletsInfo, "" );
|
||||
ScriptRegisterFunction( g_pScriptVM, DestroyFireBulletsInfo, "" );
|
||||
ScriptRegisterFunction( g_pScriptVM, DestroyFireBulletsInfo, SCRIPT_HIDE );
|
||||
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLineComplex, "TraceLineComplex", "Complex version of TraceLine which takes 2 points, an ent to ignore, a trace mask, and a collision group. Returns a handle which can access all trace info." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceHullComplex, "TraceHullComplex", "Takes 2 points, min/max hull bounds, an ent to ignore, a trace mask, and a collision group to trace to a point using a hull. Returns a handle which can access all trace info." );
|
||||
|
@ -46,12 +46,14 @@ public:
|
||||
class CSurfaceScriptHelper
|
||||
{
|
||||
public:
|
||||
// This class is owned by CScriptGameTrace, and cannot be accessed without being initialised in CScriptGameTrace::RegisterSurface()
|
||||
//CSurfaceScriptHelper() : m_pSurface(NULL), m_hSurfaceData(NULL) {}
|
||||
CSurfaceScriptHelper() : m_pSurface(NULL), m_hSurfaceData(NULL) {}
|
||||
|
||||
~CSurfaceScriptHelper()
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hSurfaceData );
|
||||
if ( m_hSurfaceData )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hSurfaceData );
|
||||
}
|
||||
}
|
||||
|
||||
void Init( csurface_t *surf )
|
||||
@ -98,16 +100,10 @@ class CScriptGameTrace : public CGameTrace
|
||||
public:
|
||||
CScriptGameTrace() : m_surfaceAccessor(NULL), m_planeAccessor(NULL)
|
||||
{
|
||||
m_hScriptInstance = g_pScriptVM->RegisterInstance( this );
|
||||
}
|
||||
|
||||
~CScriptGameTrace()
|
||||
{
|
||||
if ( m_hScriptInstance )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hScriptInstance );
|
||||
}
|
||||
|
||||
if ( m_surfaceAccessor )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_surfaceAccessor );
|
||||
@ -119,22 +115,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterSurface()
|
||||
{
|
||||
m_surfaceHelper.Init( &surface );
|
||||
m_surfaceAccessor = g_pScriptVM->RegisterInstance( &m_surfaceHelper );
|
||||
}
|
||||
|
||||
void RegisterPlane()
|
||||
{
|
||||
m_planeAccessor = g_pScriptVM->RegisterInstance( &plane );
|
||||
}
|
||||
|
||||
HSCRIPT GetScriptInstance() const
|
||||
{
|
||||
return m_hScriptInstance;
|
||||
}
|
||||
|
||||
public:
|
||||
float FractionLeftSolid() const { return fractionleftsolid; }
|
||||
int HitGroup() const { return hitgroup; }
|
||||
@ -154,15 +134,30 @@ public:
|
||||
bool AllSolid() const { return allsolid; }
|
||||
bool StartSolid() const { return startsolid; }
|
||||
|
||||
HSCRIPT Surface() const { return m_surfaceAccessor; }
|
||||
HSCRIPT Plane() const { return m_planeAccessor; }
|
||||
HSCRIPT Surface()
|
||||
{
|
||||
if ( !m_surfaceAccessor )
|
||||
{
|
||||
m_surfaceHelper.Init( &surface );
|
||||
m_surfaceAccessor = g_pScriptVM->RegisterInstance( &m_surfaceHelper );
|
||||
}
|
||||
|
||||
void Destroy() { delete this; }
|
||||
return m_surfaceAccessor;
|
||||
}
|
||||
|
||||
HSCRIPT Plane()
|
||||
{
|
||||
if ( !m_planeAccessor )
|
||||
m_planeAccessor = g_pScriptVM->RegisterInstance( &plane );
|
||||
|
||||
return m_planeAccessor;
|
||||
}
|
||||
|
||||
void Destroy() {}
|
||||
|
||||
private:
|
||||
HSCRIPT m_surfaceAccessor;
|
||||
HSCRIPT m_planeAccessor;
|
||||
HSCRIPT m_hScriptInstance;
|
||||
|
||||
CSurfaceScriptHelper m_surfaceHelper;
|
||||
|
||||
|
@ -2920,7 +2920,7 @@ int CScriptGameEventListener::ListenToGameEvent( const char* szEvent, HSCRIPT hF
|
||||
if ( bValid )
|
||||
{
|
||||
m_iContextHash = HashContext( szContext );
|
||||
m_hCallback = hFunc;
|
||||
m_hCallback = g_pScriptVM->CopyObject( hFunc );
|
||||
m_bActive = true;
|
||||
|
||||
s_Listeners.AddToTail( this );
|
||||
@ -3247,7 +3247,7 @@ public:
|
||||
|
||||
// NOTE: These two functions are new with Mapbase and have no Valve equivalent
|
||||
static bool KeyValuesWrite( const char *szFile, HSCRIPT hInput );
|
||||
static HSCRIPT KeyValuesRead( const char *szFile );
|
||||
static HSCRIPT_RC KeyValuesRead( const char *szFile );
|
||||
|
||||
void LevelShutdownPostEntity()
|
||||
{
|
||||
@ -3433,7 +3433,7 @@ bool CScriptReadWriteFile::KeyValuesWrite( const char *szFile, HSCRIPT hInput )
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CScriptReadWriteFile::KeyValuesRead( const char *szFile )
|
||||
HSCRIPT_RC CScriptReadWriteFile::KeyValuesRead( const char *szFile )
|
||||
{
|
||||
char pszFullName[MAX_PATH];
|
||||
V_snprintf( pszFullName, sizeof(pszFullName), SCRIPT_RW_FULL_PATH_FMT, szFile );
|
||||
@ -3458,7 +3458,7 @@ HSCRIPT CScriptReadWriteFile::KeyValuesRead( const char *szFile )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HSCRIPT hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV, true ); // bAllowDestruct is supposed to automatically remove the involved KV
|
||||
HSCRIPT hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV );
|
||||
|
||||
return hScript;
|
||||
}
|
||||
@ -4609,9 +4609,9 @@ public:
|
||||
CScriptConCommand( const char *name, HSCRIPT fn, const char *helpString, int flags, ConCommand *pLinked = NULL )
|
||||
: BaseClass( name, this, helpString, flags, 0 ),
|
||||
m_pLinked(pLinked),
|
||||
m_hCallback(fn),
|
||||
m_hCompletionCallback(NULL)
|
||||
{
|
||||
m_hCallback = g_pScriptVM->CopyObject( fn );
|
||||
m_nCmdNameLen = V_strlen(name) + 1;
|
||||
Assert( m_nCmdNameLen - 1 <= 128 );
|
||||
}
|
||||
@ -4701,7 +4701,7 @@ public:
|
||||
|
||||
BaseClass::m_pCommandCompletionCallback = this;
|
||||
BaseClass::m_bHasCompletionCallback = true;
|
||||
m_hCompletionCallback = fn;
|
||||
m_hCompletionCallback = g_pScriptVM->CopyObject( fn );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4720,7 +4720,8 @@ public:
|
||||
|
||||
if ( m_hCallback )
|
||||
g_pScriptVM->ReleaseScript( m_hCallback );
|
||||
m_hCallback = fn;
|
||||
|
||||
m_hCallback = g_pScriptVM->CopyObject( fn );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4781,7 +4782,7 @@ public:
|
||||
|
||||
if (fn)
|
||||
{
|
||||
m_hCallback = fn;
|
||||
m_hCallback = g_pScriptVM->CopyObject( fn );
|
||||
BaseClass::InstallChangeCallback( (FnChangeCallback_t)ScriptConVarCallback );
|
||||
}
|
||||
else
|
||||
|
@ -33,6 +33,8 @@ END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CTakeDamageInfo, "Damage information handler." )
|
||||
DEFINE_SCRIPT_REFCOUNTED_INSTANCE()
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetInflictor, "GetInflictor", "Gets the inflictor." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetInflictor, "SetInflictor", "Sets the inflictor." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetWeapon, "GetWeapon", "Gets the weapon." )
|
||||
@ -590,4 +592,4 @@ void CTakeDamageInfo::DebugGetDamageTypeString(unsigned int damageType, char *ou
|
||||
#define DMG_BLAST_SURFACE (1<<27) // A blast on the surface of water that cannot harm things underwater
|
||||
#define DMG_DIRECT (1<<28)
|
||||
#define DMG_BUCKSHOT (1<<29) // not quite a bullet. Little, rounder, different.
|
||||
*/
|
||||
*/
|
||||
|
@ -141,6 +141,20 @@ class KeyValues;
|
||||
DECLARE_POINTER_HANDLE( HSCRIPT );
|
||||
#define INVALID_HSCRIPT ((HSCRIPT)-1)
|
||||
|
||||
// Reference counted HSCRIPT return value
|
||||
//
|
||||
// This is an alias for HSCRIPT that is converted back to HSCRIPT on return
|
||||
// from vscript function bindings; it signals the vscript implementation to
|
||||
// release its hold and let the script control the lifetime
|
||||
// of the registered instance.
|
||||
struct HSCRIPT_RC
|
||||
{
|
||||
HSCRIPT val;
|
||||
HSCRIPT_RC( HSCRIPT v ) { val = v; }
|
||||
HSCRIPT operator=( HSCRIPT v ) { val = v; return val; }
|
||||
operator HSCRIPT() { return val; }
|
||||
};
|
||||
|
||||
typedef unsigned int HScriptRaw;
|
||||
#endif
|
||||
|
||||
@ -162,7 +176,7 @@ public:
|
||||
virtual void DestroyVM( IScriptVM * ) = 0;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual HSCRIPT CreateScriptKeyValues( IScriptVM *pVM, KeyValues *pKV, bool bAllowDestruct ) = 0;
|
||||
virtual HSCRIPT CreateScriptKeyValues( IScriptVM *pVM, KeyValues *pKV, bool bBorrow = false ) = 0;
|
||||
virtual KeyValues *GetKeyValuesFromScriptKV( IScriptVM *pVM, HSCRIPT hSKV ) = 0;
|
||||
#endif
|
||||
};
|
||||
@ -177,6 +191,9 @@ enum ExtendedFieldType
|
||||
FIELD_CSTRING,
|
||||
FIELD_HSCRIPT,
|
||||
FIELD_VARIANT,
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
FIELD_HSCRIPT_RC,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef int ScriptDataType_t;
|
||||
@ -197,6 +214,7 @@ DECLARE_DEDUCE_FIELDTYPE( FIELD_CHARACTER, char );
|
||||
DECLARE_DEDUCE_FIELDTYPE( FIELD_HSCRIPT, HSCRIPT );
|
||||
DECLARE_DEDUCE_FIELDTYPE( FIELD_VARIANT, ScriptVariant_t );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_DEDUCE_FIELDTYPE( FIELD_HSCRIPT_RC, HSCRIPT_RC );
|
||||
DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, QAngle );
|
||||
DECLARE_DEDUCE_FIELDTYPE( FIELD_VECTOR, const QAngle& );
|
||||
#endif
|
||||
@ -298,6 +316,9 @@ struct ScriptMemberDesc_t
|
||||
enum ScriptFuncBindingFlags_t
|
||||
{
|
||||
SF_MEMBER_FUNC = 0x01,
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
SF_REFCOUNTED_RET = 0x02,
|
||||
#endif
|
||||
};
|
||||
|
||||
union ScriptVariantTemporaryStorage_t;
|
||||
@ -616,6 +637,15 @@ struct ScriptEnumDesc_t
|
||||
#define ScriptInitMemberFunctionBindingNamed( pScriptFunction, class, func, scriptName ) ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName )
|
||||
#define ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName ) do { ScriptInitMemberFuncDescriptor_( (&(pScriptFunction)->m_desc), class, func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( ((class *)0), &class::func ); (pScriptFunction)->m_pFunction = ScriptConvertFuncPtrToVoid( &class::func ); (pScriptFunction)->m_flags = SF_MEMBER_FUNC; } while (0)
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// Convert HSCRIPT_RC return type into HSCRIPT return with SF_REFCOUNTED_RET binding flag
|
||||
#undef ScriptInitFunctionBindingNamed
|
||||
#define ScriptInitFunctionBindingNamed( pScriptFunction, func, scriptName ) do { ScriptInitFuncDescriptorNamed( (&(pScriptFunction)->m_desc), func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( &func ); (pScriptFunction)->m_pFunction = (void *)&func; if ( (pScriptFunction)->m_desc.m_ReturnType == FIELD_HSCRIPT_RC ) { (pScriptFunction)->m_desc.m_ReturnType = FIELD_HSCRIPT; (pScriptFunction)->m_flags |= SF_REFCOUNTED_RET; } } while (0)
|
||||
|
||||
#undef ScriptInitMemberFunctionBinding_
|
||||
#define ScriptInitMemberFunctionBinding_( pScriptFunction, class, func, scriptName ) do { ScriptInitMemberFuncDescriptor_( (&(pScriptFunction)->m_desc), class, func, scriptName ); (pScriptFunction)->m_pfnBinding = ScriptCreateBinding( ((class *)0), &class::func ); (pScriptFunction)->m_pFunction = ScriptConvertFuncPtrToVoid( &class::func ); (pScriptFunction)->m_flags = SF_MEMBER_FUNC; if ( (pScriptFunction)->m_desc.m_ReturnType == FIELD_HSCRIPT_RC ) { (pScriptFunction)->m_desc.m_ReturnType = FIELD_HSCRIPT; (pScriptFunction)->m_flags |= SF_REFCOUNTED_RET; } } while (0)
|
||||
#endif
|
||||
|
||||
#define ScriptInitClassDesc( pClassDesc, class, pBaseClassDesc ) ScriptInitClassDescNamed( pClassDesc, class, pBaseClassDesc, #class )
|
||||
#define ScriptInitClassDescNamed( pClassDesc, class, pBaseClassDesc, scriptName ) ScriptInitClassDescNamed_( pClassDesc, class, pBaseClassDesc, scriptName )
|
||||
#define ScriptInitClassDescNoBase( pClassDesc, class ) ScriptInitClassDescNoBaseNamed( pClassDesc, class, #class )
|
||||
@ -748,6 +778,10 @@ static inline int ToConstantVariant(int value)
|
||||
#define DEFINE_SCRIPT_INSTANCE_HELPER( p ) MUST_USE_BEGIN_SCRIPTDESC_WITH_HELPER_INSTEAD
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// Allow instance to be deleted but not constructed
|
||||
// Not needed if the class has a constructor
|
||||
#define DEFINE_SCRIPT_REFCOUNTED_INSTANCE() do { pDesc->m_pfnDestruct = &CScriptConstructor<_className>::Destruct; } while (0);
|
||||
|
||||
// Use this for hooks which have no parameters
|
||||
#define DEFINE_SIMPLE_SCRIPTHOOK( hook, hookName, returnType, description ) \
|
||||
if (!hook.m_bDefined) \
|
||||
@ -940,14 +974,13 @@ public:
|
||||
//--------------------------------------------------------
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// When a RegisterInstance instance is deleted, VScript normally treats it as a strong reference and only deregisters the instance itself, preserving the registered data
|
||||
// it points to so the game can continue to use it.
|
||||
// bAllowDestruct is supposed to allow VScript to treat it as a weak reference created by the script, destructing the registered data automatically like any other type.
|
||||
// This is useful for classes pretending to be primitive types.
|
||||
virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance, bool bAllowDestruct = false ) = 0;
|
||||
// if bRefCounted is true, pInstance memory will be deleted by the script,
|
||||
// returning the result will then behave as if the instance was constructed in script.
|
||||
// Functions that return the result of this need to return HSCRIPT_RC
|
||||
virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance, bool bRefCounted = false ) = 0;
|
||||
virtual void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) = 0;
|
||||
template <typename T> HSCRIPT RegisterInstance( T *pInstance, bool bAllowDestruct = false ) { return RegisterInstance( GetScriptDesc( pInstance ), pInstance, bAllowDestruct ); }
|
||||
template <typename T> HSCRIPT RegisterInstance( T *pInstance, const char *pszInstance, HSCRIPT hScope = NULL, bool bAllowDestruct = false) { HSCRIPT hInstance = RegisterInstance( GetScriptDesc( pInstance ), pInstance, bAllowDestruct ); SetValue( hScope, pszInstance, hInstance ); return hInstance; }
|
||||
template <typename T> HSCRIPT RegisterInstance( T *pInstance, bool bRefCounted = false ) { return RegisterInstance( GetScriptDesc( pInstance ), pInstance, bRefCounted ); }
|
||||
template <typename T> HSCRIPT RegisterInstance( T *pInstance, const char *pszInstance, HSCRIPT hScope = NULL, bool bRefCounted = false) { HSCRIPT hInstance = RegisterInstance( GetScriptDesc( pInstance ), pInstance, bRefCounted ); SetValue( hScope, pszInstance, hInstance ); return hInstance; }
|
||||
#else
|
||||
virtual HSCRIPT RegisterInstance( ScriptClassDesc_t *pDesc, void *pInstance ) = 0;
|
||||
virtual void SetInstanceUniqeId( HSCRIPT hInstance, const char *pszId ) = 0;
|
||||
@ -996,6 +1029,8 @@ public:
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0;
|
||||
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) = 0;
|
||||
// To hold strong references to script objects
|
||||
virtual HSCRIPT CopyObject(HSCRIPT obj) = 0;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -18,7 +18,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static HSCRIPT VMFKV_CreateBlank()
|
||||
static HSCRIPT_RC VMFKV_CreateBlank()
|
||||
{
|
||||
KeyValues *pKV = new KeyValues("VMF");
|
||||
|
||||
@ -28,7 +28,7 @@ static HSCRIPT VMFKV_CreateBlank()
|
||||
pWorld->SetString( "classname", "worldspawn" );
|
||||
}
|
||||
|
||||
return scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV, true );
|
||||
return scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV );
|
||||
}
|
||||
|
||||
static bool VMFKV_SaveToFile( const char *szFile, HSCRIPT hKV )
|
||||
@ -69,7 +69,7 @@ static bool VMFKV_SaveToFile( const char *szFile, HSCRIPT hKV )
|
||||
return res;
|
||||
}
|
||||
|
||||
static HSCRIPT VMFKV_LoadFromFile( const char *szFile )
|
||||
static HSCRIPT_RC VMFKV_LoadFromFile( const char *szFile )
|
||||
{
|
||||
char pszFullName[MAX_PATH];
|
||||
V_snprintf( pszFullName, sizeof(pszFullName), NULL, szFile );
|
||||
@ -87,7 +87,7 @@ static HSCRIPT VMFKV_LoadFromFile( const char *szFile )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HSCRIPT hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV, true ); // bAllowDestruct is supposed to automatically remove the involved KV
|
||||
HSCRIPT hScript = scriptmanager->CreateScriptKeyValues( g_pScriptVM, pKV );
|
||||
|
||||
return hScript;
|
||||
}
|
||||
@ -142,7 +142,7 @@ static HSCRIPT VMFKV_AddEntityFromTables( HSCRIPT hVMF, HSCRIPT hKV, HSCRIPT hIO
|
||||
}
|
||||
}
|
||||
|
||||
return scriptmanager->CreateScriptKeyValues( g_pScriptVM, pEnt, false );
|
||||
return scriptmanager->CreateScriptKeyValues( g_pScriptVM, pEnt, true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -61,10 +61,14 @@ public:
|
||||
}
|
||||
|
||||
// Mapbase moves CScriptKeyValues into the library so it could be used elsewhere
|
||||
virtual HSCRIPT CreateScriptKeyValues( IScriptVM *pVM, KeyValues *pKV, bool bAllowDestruct ) override
|
||||
|
||||
// if bBorrow is false, CScriptKeyValues owns pKV memory
|
||||
// Functions returning the result need to return HSCRIPT_RC
|
||||
// see comment on IScriptVM::RegisterInstance()
|
||||
virtual HSCRIPT CreateScriptKeyValues( IScriptVM *pVM, KeyValues *pKV, bool bBorrow ) override
|
||||
{
|
||||
CScriptKeyValues *pSKV = new CScriptKeyValues( pKV );
|
||||
HSCRIPT hSKV = pVM->RegisterInstance( pSKV, bAllowDestruct );
|
||||
CScriptKeyValues *pSKV = new CScriptKeyValues( pKV, bBorrow );
|
||||
HSCRIPT hSKV = pVM->RegisterInstance( pSKV, true );
|
||||
return hSKV;
|
||||
}
|
||||
|
||||
@ -73,7 +77,7 @@ public:
|
||||
CScriptKeyValues *pSKV = (hSKV ? (CScriptKeyValues*)pVM->GetInstanceValue( hSKV, GetScriptDesc( (CScriptKeyValues*)NULL ) ) : nullptr);
|
||||
if (pSKV)
|
||||
{
|
||||
return pSKV->m_pKeyValues;
|
||||
return pSKV->GetKeyValues();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -106,7 +106,7 @@ BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance"
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueBool, "GetKeyBool", "Given a KeyValues object and a key name, return associated bool value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueString, "GetKeyString", "Given a KeyValues object and a key name, return associated string value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsKeyValueEmpty, "IsKeyEmpty", "Given a KeyValues object and a key name, return true if key name has no value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptReleaseKeyValues, "ReleaseKeyValues", "Given a root KeyValues object, release its contents" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptReleaseKeyValues, "ReleaseKeyValues", SCRIPT_HIDE );
|
||||
|
||||
DEFINE_SCRIPTFUNC( TableToSubKeys, "Converts a script table to KeyValues." );
|
||||
DEFINE_SCRIPTFUNC( SubKeysToTable, "Converts to script table." );
|
||||
@ -131,79 +131,84 @@ BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance"
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetString, "SetString", "Given a KeyValues object, set its own associated string value" );
|
||||
END_SCRIPTDESC();
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptFindKey( const char *pszName )
|
||||
HSCRIPT_RC CScriptKeyValues::ScriptFindKey( const char *pszName )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName);
|
||||
KeyValues *pKeyValues = GetKeyValues()->FindKey(pszName);
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues, true );
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey, true );
|
||||
|
||||
pScriptKey->m_pBase = m_pSelf;
|
||||
pScriptKey->m_pBase->AddRef();
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptGetFirstSubKey( void )
|
||||
HSCRIPT_RC CScriptKeyValues::ScriptGetFirstSubKey( void )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->GetFirstSubKey();
|
||||
KeyValues *pKeyValues = GetKeyValues()->GetFirstSubKey();
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues, true );
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey, true );
|
||||
|
||||
pScriptKey->m_pBase = m_pSelf;
|
||||
pScriptKey->m_pBase->AddRef();
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptGetNextKey( void )
|
||||
HSCRIPT_RC CScriptKeyValues::ScriptGetNextKey( void )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->GetNextKey();
|
||||
KeyValues *pKeyValues = GetKeyValues()->GetNextKey();
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues, true );
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey, true );
|
||||
|
||||
// if I don't have a parent, then I own my siblings
|
||||
pScriptKey->m_pBase = m_pBase ? m_pBase : m_pSelf;
|
||||
pScriptKey->m_pBase->AddRef();
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
int CScriptKeyValues::ScriptGetKeyValueInt( const char *pszName )
|
||||
{
|
||||
int i = m_pKeyValues->GetInt( pszName );
|
||||
int i = GetKeyValues()->GetInt( pszName );
|
||||
return i;
|
||||
}
|
||||
|
||||
float CScriptKeyValues::ScriptGetKeyValueFloat( const char *pszName )
|
||||
{
|
||||
float f = m_pKeyValues->GetFloat( pszName );
|
||||
float f = GetKeyValues()->GetFloat( pszName );
|
||||
return f;
|
||||
}
|
||||
|
||||
const char *CScriptKeyValues::ScriptGetKeyValueString( const char *pszName )
|
||||
{
|
||||
const char *psz = m_pKeyValues->GetString( pszName );
|
||||
const char *psz = GetKeyValues()->GetString( pszName );
|
||||
return psz;
|
||||
}
|
||||
|
||||
bool CScriptKeyValues::ScriptIsKeyValueEmpty( const char *pszName )
|
||||
{
|
||||
bool b = m_pKeyValues->IsEmpty( pszName );
|
||||
bool b = GetKeyValues()->IsEmpty( pszName );
|
||||
return b;
|
||||
}
|
||||
|
||||
bool CScriptKeyValues::ScriptGetKeyValueBool( const char *pszName )
|
||||
{
|
||||
bool b = m_pKeyValues->GetBool( pszName );
|
||||
bool b = GetKeyValues()->GetBool( pszName );
|
||||
return b;
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptReleaseKeyValues( )
|
||||
{
|
||||
m_pKeyValues->deleteThis();
|
||||
m_pKeyValues = NULL;
|
||||
}
|
||||
|
||||
void KeyValues_TableToSubKeys( HSCRIPT hTable, KeyValues *pKV )
|
||||
@ -259,125 +264,134 @@ void KeyValues_SubKeysToTable( KeyValues *pKV, HSCRIPT hTable )
|
||||
|
||||
void CScriptKeyValues::TableToSubKeys( HSCRIPT hTable )
|
||||
{
|
||||
KeyValues_TableToSubKeys( hTable, m_pKeyValues );
|
||||
KeyValues_TableToSubKeys( hTable, GetKeyValues() );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::SubKeysToTable( HSCRIPT hTable )
|
||||
{
|
||||
KeyValues_SubKeysToTable( m_pKeyValues, hTable );
|
||||
KeyValues_SubKeysToTable( GetKeyValues(), hTable );
|
||||
}
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptFindOrCreateKey( const char *pszName )
|
||||
HSCRIPT_RC CScriptKeyValues::ScriptFindOrCreateKey( const char *pszName )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName, true);
|
||||
KeyValues *pKeyValues = GetKeyValues()->FindKey(pszName, true);
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues, true );
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey, true );
|
||||
|
||||
pScriptKey->m_pBase = m_pSelf;
|
||||
pScriptKey->m_pBase->AddRef();
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
const char *CScriptKeyValues::ScriptGetName()
|
||||
{
|
||||
const char *psz = m_pKeyValues->GetName();
|
||||
const char *psz = GetKeyValues()->GetName();
|
||||
return psz;
|
||||
}
|
||||
|
||||
int CScriptKeyValues::ScriptGetInt()
|
||||
{
|
||||
int i = m_pKeyValues->GetInt();
|
||||
int i = GetKeyValues()->GetInt();
|
||||
return i;
|
||||
}
|
||||
|
||||
float CScriptKeyValues::ScriptGetFloat()
|
||||
{
|
||||
float f = m_pKeyValues->GetFloat();
|
||||
float f = GetKeyValues()->GetFloat();
|
||||
return f;
|
||||
}
|
||||
|
||||
const char *CScriptKeyValues::ScriptGetString()
|
||||
{
|
||||
const char *psz = m_pKeyValues->GetString();
|
||||
const char *psz = GetKeyValues()->GetString();
|
||||
return psz;
|
||||
}
|
||||
|
||||
bool CScriptKeyValues::ScriptGetBool()
|
||||
{
|
||||
bool b = m_pKeyValues->GetBool();
|
||||
bool b = GetKeyValues()->GetBool();
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueInt( const char *pszName, int iValue )
|
||||
{
|
||||
m_pKeyValues->SetInt( pszName, iValue );
|
||||
GetKeyValues()->SetInt( pszName, iValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueFloat( const char *pszName, float flValue )
|
||||
{
|
||||
m_pKeyValues->SetFloat( pszName, flValue );
|
||||
GetKeyValues()->SetFloat( pszName, flValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueString( const char *pszName, const char *pszValue )
|
||||
{
|
||||
m_pKeyValues->SetString( pszName, pszValue );
|
||||
GetKeyValues()->SetString( pszName, pszValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueBool( const char *pszName, bool bValue )
|
||||
{
|
||||
m_pKeyValues->SetBool( pszName, bValue );
|
||||
GetKeyValues()->SetBool( pszName, bValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetName( const char *pszValue )
|
||||
{
|
||||
m_pKeyValues->SetName( pszValue );
|
||||
GetKeyValues()->SetName( pszValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetInt( int iValue )
|
||||
{
|
||||
m_pKeyValues->SetInt( NULL, iValue );
|
||||
GetKeyValues()->SetInt( NULL, iValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetFloat( float flValue )
|
||||
{
|
||||
m_pKeyValues->SetFloat( NULL, flValue );
|
||||
GetKeyValues()->SetFloat( NULL, flValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetString( const char *pszValue )
|
||||
{
|
||||
m_pKeyValues->SetString( NULL, pszValue );
|
||||
GetKeyValues()->SetString( NULL, pszValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetBool( bool bValue )
|
||||
{
|
||||
m_pKeyValues->SetBool( NULL, bValue );
|
||||
GetKeyValues()->SetBool( NULL, bValue );
|
||||
}
|
||||
|
||||
|
||||
// constructors
|
||||
CScriptKeyValues::CScriptKeyValues( KeyValues *pKeyValues = NULL )
|
||||
CScriptKeyValues::CScriptKeyValues( KeyValues *pKeyValues = NULL, bool bBorrow = false ) :
|
||||
m_pBase( NULL )
|
||||
{
|
||||
if (pKeyValues == NULL)
|
||||
{
|
||||
m_pKeyValues = new KeyValues("CScriptKeyValues");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pKeyValues = pKeyValues;
|
||||
pKeyValues = new KeyValues("CScriptKeyValues");
|
||||
// Borrowed new memory doesn't make sense, are you trying to leak?
|
||||
Assert( !bBorrow );
|
||||
}
|
||||
|
||||
m_pSelf = new KeyValues_RC( pKeyValues, bBorrow );
|
||||
}
|
||||
|
||||
// destructor
|
||||
CScriptKeyValues::~CScriptKeyValues( )
|
||||
{
|
||||
if (m_pKeyValues)
|
||||
Assert( m_pSelf != m_pBase );
|
||||
|
||||
// Children are always borrowed
|
||||
Assert( !m_pBase || m_pSelf->borrow );
|
||||
|
||||
m_pSelf->Release();
|
||||
|
||||
if ( m_pBase )
|
||||
{
|
||||
m_pKeyValues->deleteThis();
|
||||
m_pBase->Release();
|
||||
}
|
||||
m_pKeyValues = NULL;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -20,12 +20,12 @@
|
||||
class CScriptKeyValues
|
||||
{
|
||||
public:
|
||||
CScriptKeyValues( KeyValues *pKeyValues );
|
||||
CScriptKeyValues( KeyValues *pKeyValues, bool bBorrow );
|
||||
~CScriptKeyValues( );
|
||||
|
||||
HSCRIPT ScriptFindKey( const char *pszName );
|
||||
HSCRIPT ScriptGetFirstSubKey( void );
|
||||
HSCRIPT ScriptGetNextKey( void );
|
||||
HSCRIPT_RC ScriptFindKey( const char *pszName );
|
||||
HSCRIPT_RC ScriptGetFirstSubKey( void );
|
||||
HSCRIPT_RC ScriptGetNextKey( void );
|
||||
int ScriptGetKeyValueInt( const char *pszName );
|
||||
float ScriptGetKeyValueFloat( const char *pszName );
|
||||
const char *ScriptGetKeyValueString( const char *pszName );
|
||||
@ -37,7 +37,7 @@ public:
|
||||
void TableToSubKeys( HSCRIPT hTable );
|
||||
void SubKeysToTable( HSCRIPT hTable );
|
||||
|
||||
HSCRIPT ScriptFindOrCreateKey( const char *pszName );
|
||||
HSCRIPT_RC ScriptFindOrCreateKey( const char *pszName );
|
||||
|
||||
const char *ScriptGetName();
|
||||
int ScriptGetInt();
|
||||
@ -55,9 +55,54 @@ public:
|
||||
void ScriptSetString( const char *pszValue );
|
||||
void ScriptSetBool( bool bValue );
|
||||
|
||||
KeyValues *GetKeyValues() { return m_pKeyValues; }
|
||||
KeyValues *GetKeyValues() { return m_pSelf->ptr; }
|
||||
|
||||
KeyValues *m_pKeyValues; // actual KeyValue entity
|
||||
// The lifetime of the KeyValues pointer needs to be decoupled from refcounted script objects
|
||||
// because base kv script objects can be released while their children live: kv = kv.GetFirstSubKey()
|
||||
// Refcounting externally allows children to extend the lifetime of KeyValues while
|
||||
// being able to automatically dispose of CScriptKeyValues and HSCRIPT objects with
|
||||
// script refcounted HSCRIPT_RC
|
||||
|
||||
struct KeyValues_RC
|
||||
{
|
||||
KeyValues *ptr;
|
||||
unsigned int refs;
|
||||
// Wheter KeyValues memory is borrowed or owned by CScriptKeyValues
|
||||
// if not borrowed, it is deleted on release
|
||||
bool borrow;
|
||||
|
||||
KeyValues_RC( KeyValues *pKeyValues, bool bBorrow ) :
|
||||
ptr( pKeyValues ),
|
||||
refs( 1 ),
|
||||
borrow( bBorrow )
|
||||
{
|
||||
}
|
||||
|
||||
void AddRef()
|
||||
{
|
||||
Assert( refs < (unsigned int)-1 );
|
||||
refs++;
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
Assert( refs > 0 );
|
||||
refs--;
|
||||
|
||||
if ( refs == 0 )
|
||||
{
|
||||
if ( !borrow )
|
||||
{
|
||||
ptr->deleteThis();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
KeyValues_RC *m_pSelf;
|
||||
KeyValues_RC *m_pBase;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -196,7 +196,7 @@ public:
|
||||
// External instances. Note class will be auto-registered.
|
||||
//--------------------------------------------------------
|
||||
|
||||
virtual HSCRIPT RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bAllowDestruct = false) override;
|
||||
virtual HSCRIPT RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bRefCounted = false) override;
|
||||
virtual void SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId) override;
|
||||
virtual void RemoveInstance(HSCRIPT hInstance) override;
|
||||
|
||||
@ -227,6 +227,7 @@ public:
|
||||
|
||||
virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override;
|
||||
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override;
|
||||
virtual HSCRIPT CopyObject(HSCRIPT obj) override;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@ -1094,19 +1095,19 @@ namespace SQVector
|
||||
|
||||
struct ClassInstanceData
|
||||
{
|
||||
ClassInstanceData(void* instance, ScriptClassDesc_t* desc, const char* instanceId = nullptr, bool allowDestruct = false) :
|
||||
ClassInstanceData(void* instance, ScriptClassDesc_t* desc, const char* instanceId = nullptr, bool refCounted = false) :
|
||||
instance(instance),
|
||||
desc(desc),
|
||||
instanceId(instanceId),
|
||||
allowDestruct(allowDestruct)
|
||||
refCounted(refCounted)
|
||||
{}
|
||||
|
||||
void* instance;
|
||||
ScriptClassDesc_t* desc;
|
||||
CUtlConstString instanceId;
|
||||
|
||||
// Indicates this game-created instance is a weak reference and can be destructed (Blixibon)
|
||||
bool allowDestruct;
|
||||
// keep for setting instance release hook in save/restore
|
||||
bool refCounted;
|
||||
};
|
||||
|
||||
bool CreateParamCheck(const ScriptFunctionBinding_t& func, char* output)
|
||||
@ -1329,7 +1330,8 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
||||
|
||||
ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr;
|
||||
|
||||
auto nargs = pFunc->m_desc.m_Parameters.Count();
|
||||
int nargs = pFunc->m_desc.m_Parameters.Count();
|
||||
int nLastHScriptIdx = -1;
|
||||
|
||||
if (nargs > top)
|
||||
{
|
||||
@ -1406,9 +1408,10 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
||||
{
|
||||
HSQOBJECT* pObject = new HSQOBJECT;
|
||||
*pObject = val;
|
||||
sq_addref(vm, pObject);
|
||||
params[i] = (HSCRIPT)pObject;
|
||||
}
|
||||
|
||||
nLastHScriptIdx = i;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1471,6 +1474,23 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
||||
// everything else is stored inline, so there should be no memory to free
|
||||
Assert(!(script_retval.m_flags & SV_FREE));
|
||||
|
||||
Assert( ( pFunc->m_desc.m_ReturnType != FIELD_VOID ) || !( pFunc->m_flags & SF_REFCOUNTED_RET ) );
|
||||
|
||||
if ( ( pFunc->m_flags & SF_REFCOUNTED_RET ) && script_retval.m_hScript )
|
||||
{
|
||||
Assert( script_retval.m_type == FIELD_HSCRIPT );
|
||||
|
||||
// Release the intermediary ref held from RegisterInstance
|
||||
sq_release(vm, (HSQOBJECT*)script_retval.m_hScript);
|
||||
delete (HSQOBJECT*)script_retval.m_hScript;
|
||||
}
|
||||
|
||||
for ( int i = 0; i <= nLastHScriptIdx; ++i )
|
||||
{
|
||||
if ( pFunc->m_desc.m_Parameters[i] == FIELD_HSCRIPT )
|
||||
delete (HSQOBJECT*)params[i].m_hScript;
|
||||
}
|
||||
|
||||
return sq_retval;
|
||||
}
|
||||
|
||||
@ -1479,6 +1499,10 @@ SQInteger destructor_stub(SQUserPointer p, SQInteger size)
|
||||
{
|
||||
auto classInstanceData = (ClassInstanceData*)p;
|
||||
|
||||
// if instance is not deleted, then it's leaking
|
||||
// this should never happen
|
||||
Assert( classInstanceData->desc->m_pfnDestruct );
|
||||
|
||||
if (classInstanceData->desc->m_pfnDestruct)
|
||||
classInstanceData->desc->m_pfnDestruct(classInstanceData->instance);
|
||||
|
||||
@ -1489,7 +1513,7 @@ SQInteger destructor_stub(SQUserPointer p, SQInteger size)
|
||||
SQInteger destructor_stub_instance(SQUserPointer p, SQInteger size)
|
||||
{
|
||||
auto classInstanceData = (ClassInstanceData*)p;
|
||||
// We don't call destructor here because this is owned by the game
|
||||
// This instance is owned by the game, don't delete it
|
||||
classInstanceData->~ClassInstanceData();
|
||||
return 0;
|
||||
}
|
||||
@ -2627,7 +2651,7 @@ void SquirrelVM::RegisterHook(ScriptHook_t* pHookDesc)
|
||||
RegisterHookDocumentation(vm_, pHookDesc, pHookDesc->m_desc, nullptr);
|
||||
}
|
||||
|
||||
HSCRIPT SquirrelVM::RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bAllowDestruct)
|
||||
HSCRIPT SquirrelVM::RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance, bool bRefCounted)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
|
||||
@ -2649,15 +2673,19 @@ HSCRIPT SquirrelVM::RegisterInstance(ScriptClassDesc_t* pDesc, void* pInstance,
|
||||
}
|
||||
|
||||
{
|
||||
SQUserPointer p;
|
||||
sq_getinstanceup(vm_, -1, &p, 0);
|
||||
new(p) ClassInstanceData(pInstance, pDesc, nullptr, bAllowDestruct);
|
||||
ClassInstanceData *self;
|
||||
sq_getinstanceup(vm_, -1, (SQUserPointer*)&self, 0);
|
||||
new(self) ClassInstanceData(pInstance, pDesc, nullptr, bRefCounted);
|
||||
|
||||
// can't delete the instance if it doesn't have a destructor
|
||||
// if the instance doesn't have a constructor,
|
||||
// the class needs to register the destructor with DEFINE_SCRIPT_REFCOUNTED_INSTANCE()
|
||||
Assert( !bRefCounted || self->desc->m_pfnDestruct );
|
||||
}
|
||||
|
||||
sq_setreleasehook(vm_, -1, bAllowDestruct ? &destructor_stub : &destructor_stub_instance);
|
||||
sq_setreleasehook(vm_, -1, bRefCounted ? &destructor_stub : &destructor_stub_instance);
|
||||
|
||||
HSQOBJECT* obj = new HSQOBJECT;
|
||||
sq_resetobject(obj);
|
||||
sq_getstackobj(vm_, -1, obj);
|
||||
sq_addref(vm_, obj);
|
||||
sq_pop(vm_, 3);
|
||||
@ -2685,22 +2713,22 @@ void SquirrelVM::SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId)
|
||||
|
||||
void SquirrelVM::RemoveInstance(HSCRIPT hInstance)
|
||||
{
|
||||
if (!hInstance)
|
||||
return;
|
||||
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
|
||||
if (!hInstance) return;
|
||||
HSQOBJECT* obj = (HSQOBJECT*)hInstance;
|
||||
ClassInstanceData *self;
|
||||
|
||||
sq_pushobject(vm_, *obj);
|
||||
|
||||
SQUserPointer self;
|
||||
sq_getinstanceup(vm_, -1, &self, nullptr);
|
||||
|
||||
((ClassInstanceData*)self)->~ClassInstanceData();
|
||||
|
||||
sq_getinstanceup(vm_, -1, (SQUserPointer*)&self, nullptr);
|
||||
sq_setinstanceup(vm_, -1, nullptr);
|
||||
sq_setreleasehook(vm_, -1, nullptr);
|
||||
sq_pop(vm_, 1);
|
||||
|
||||
sq_release(vm_, obj);
|
||||
|
||||
self->~ClassInstanceData();
|
||||
delete obj;
|
||||
}
|
||||
|
||||
@ -3134,6 +3162,17 @@ bool SquirrelVM::ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
HSCRIPT SquirrelVM::CopyObject(HSCRIPT obj)
|
||||
{
|
||||
if ( !obj )
|
||||
return NULL;
|
||||
|
||||
HSQOBJECT *ret = new HSQOBJECT;
|
||||
*ret = *(HSQOBJECT*)obj;
|
||||
sq_addref( vm_, ret );
|
||||
return (HSCRIPT)ret;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
//-------------------------------------------------------------
|
||||
|
||||
@ -3563,7 +3602,7 @@ void SquirrelVM::WriteObject( const SQObjectPtr &obj, CUtlBuffer* pBuffer, Write
|
||||
{
|
||||
Assert( strlen(pData->instanceId.Get()) < NATIVE_NAME_READBUF_SIZE );
|
||||
pBuffer->PutString( pData->instanceId );
|
||||
pBuffer->PutChar( pData->allowDestruct ? 1 : 0 );
|
||||
pBuffer->PutChar( pData->refCounted ? 1 : 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4174,7 +4213,7 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
||||
|
||||
if ( pszInstanceName[0] )
|
||||
{
|
||||
bool allowDestruct = ( pBuffer->GetChar() != 0 );
|
||||
bool refCounted = ( pBuffer->GetChar() != 0 );
|
||||
|
||||
HSQOBJECT *hInstance = new HSQOBJECT;
|
||||
hInstance->_type = OT_INSTANCE;
|
||||
@ -4186,8 +4225,8 @@ void SquirrelVM::ReadObject( SQObjectPtr &pObj, CUtlBuffer* pBuffer, ReadStateMa
|
||||
if ( pInstance )
|
||||
{
|
||||
sq_addref( vm_, hInstance );
|
||||
new( pThis->_userpointer ) ClassInstanceData( pInstance, pDesc, pszInstanceName, allowDestruct );
|
||||
pThis->_hook = allowDestruct ? &destructor_stub : &destructor_stub_instance;
|
||||
new( pThis->_userpointer ) ClassInstanceData( pInstance, pDesc, pszInstanceName, refCounted );
|
||||
pThis->_hook = refCounted ? &destructor_stub : &destructor_stub_instance;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user