mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-04-16 22:42:31 +03:00
Optimize squirrel function_stub() Vector/QAngle return value
Instead of temporary allocating dynamic memory, which subsequently is copied into another dynamically allocated piece of memory, provide a temporary buffer on the stack. The script value inserted into the VM still needs to allocate dynamically though... A few sites are adapted to not create a ScriptVariant_t from a temporary Vector to avoid dynamic allocation there too. cf. mapbase-source/source-sdk-2013#321
This commit is contained in:
parent
879b9e8d25
commit
99858e63f7
@ -2645,16 +2645,19 @@ Vector CProtoSniper::DesiredBodyTarget( CBaseEntity *pTarget )
|
||||
{
|
||||
// By default, aim for the center
|
||||
Vector vecTarget = pTarget->WorldSpaceCenter();
|
||||
const Vector vecBulletOrigin = GetBulletOrigin();
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (m_ScriptScope.IsInitialized() && g_Hook_GetActualShootPosition.CanRunInScope(m_ScriptScope))
|
||||
if ( m_ScriptScope.IsInitialized() && g_Hook_GetActualShootPosition.CanRunInScope( m_ScriptScope ) )
|
||||
{
|
||||
ScriptVariant_t functionReturn;
|
||||
ScriptVariant_t args[] = { GetBulletOrigin(), ToHScript( pTarget ) };
|
||||
if (g_Hook_GetActualShootPosition.Call( m_ScriptScope, &functionReturn, args ))
|
||||
ScriptVariant_t args[] = { vecBulletOrigin, ToHScript( pTarget ) };
|
||||
if ( g_Hook_GetActualShootPosition.Call( m_ScriptScope, &functionReturn, args ) )
|
||||
{
|
||||
if (functionReturn.m_type == FIELD_VECTOR && functionReturn.m_pVector->LengthSqr() != 0.0f)
|
||||
if ( functionReturn.m_type == FIELD_VECTOR && functionReturn.m_pVector->LengthSqr() != 0.0f )
|
||||
{
|
||||
return *functionReturn.m_pVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -2682,12 +2685,12 @@ Vector CProtoSniper::DesiredBodyTarget( CBaseEntity *pTarget )
|
||||
{
|
||||
if( flTimeSinceLastMiss > 0.0f && flTimeSinceLastMiss < 4.0f && hl2_episodic.GetBool() )
|
||||
{
|
||||
vecTarget = pTarget->BodyTarget( GetBulletOrigin(), false );
|
||||
vecTarget = pTarget->BodyTarget( vecBulletOrigin, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Shoot zombies in the headcrab
|
||||
vecTarget = pTarget->HeadTarget( GetBulletOrigin() );
|
||||
vecTarget = pTarget->HeadTarget( vecBulletOrigin );
|
||||
}
|
||||
}
|
||||
else if( pTarget->Classify() == CLASS_ANTLION )
|
||||
|
@ -346,7 +346,8 @@ void RegisterSharedScriptConstants()
|
||||
ScriptRegisterConstant( g_pScriptVM, ROPE_NO_GRAVITY, "Disable gravity on this rope. (for use in rope flags)" );
|
||||
ScriptRegisterConstant( g_pScriptVM, ROPE_NUMFLAGS, "The number of rope flags recognized by the game." );
|
||||
|
||||
ScriptRegisterConstantNamed( g_pScriptVM, Vector( ROPE_GRAVITY ), "ROPE_GRAVITY", "Default rope gravity vector." );
|
||||
static Vector vecRopeGravity( ROPE_GRAVITY );
|
||||
ScriptRegisterConstantNamed( g_pScriptVM, vecRopeGravity, "ROPE_GRAVITY", "Default rope gravity vector." );
|
||||
|
||||
//
|
||||
// Sounds
|
||||
|
@ -300,7 +300,8 @@ enum ScriptFuncBindingFlags_t
|
||||
SF_MEMBER_FUNC = 0x01,
|
||||
};
|
||||
|
||||
typedef bool (*ScriptBindingFunc_t)( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn );
|
||||
union ScriptVariantTemporaryStorage_t;
|
||||
typedef bool (*ScriptBindingFunc_t)( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage );
|
||||
|
||||
struct ScriptFunctionBinding_t
|
||||
{
|
||||
@ -389,52 +390,17 @@ struct ScriptVariant_t
|
||||
ScriptVariant_t( bool val ) : m_flags( 0 ), m_type( FIELD_BOOLEAN ) { m_bool = val; }
|
||||
ScriptVariant_t( HSCRIPT val ) : m_flags( 0 ), m_type( FIELD_HSCRIPT ) { m_hScript = val; }
|
||||
|
||||
ScriptVariant_t( const Vector &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR )
|
||||
{
|
||||
if ( !bCopy )
|
||||
{
|
||||
m_pVector = &val;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pVector = (Vector*)malloc( sizeof( Vector ) );
|
||||
new ( (Vector*)m_pVector ) Vector( val );
|
||||
m_flags |= SV_FREE;
|
||||
}
|
||||
}
|
||||
ScriptVariant_t( const Vector *val, bool bCopy = false ) : ScriptVariant_t( *val ) { }
|
||||
ScriptVariant_t( const Vector &val ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { m_pVector = &val; }
|
||||
ScriptVariant_t( const Vector *val ) : ScriptVariant_t( *val ) { }
|
||||
|
||||
ScriptVariant_t( const char *val , bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_CSTRING )
|
||||
{
|
||||
if ( !bCopy )
|
||||
{
|
||||
m_pszString = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pszString = strdup( val );
|
||||
m_flags |= SV_FREE;
|
||||
}
|
||||
}
|
||||
ScriptVariant_t( const char *val ) : m_flags( 0 ), m_type( FIELD_CSTRING ) { m_pszString = val; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
ScriptVariant_t( const QAngle &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR )
|
||||
{
|
||||
if ( !bCopy )
|
||||
{
|
||||
m_pAngle = &val;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pAngle = (QAngle*)malloc( sizeof( QAngle ) );
|
||||
new ( (QAngle*)m_pAngle ) QAngle( val );
|
||||
m_flags |= SV_FREE;
|
||||
}
|
||||
}
|
||||
ScriptVariant_t( const QAngle *val, bool bCopy = false ) : ScriptVariant_t( *val ) { }
|
||||
ScriptVariant_t( const QAngle &val ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { m_pAngle = &val; }
|
||||
ScriptVariant_t( const QAngle *val ) : ScriptVariant_t( *val ) { }
|
||||
|
||||
ScriptVariant_t( Vector &&val ) : ScriptVariant_t( val, true ) { }
|
||||
ScriptVariant_t( QAngle &&val ) : ScriptVariant_t( val, true ) { }
|
||||
ScriptVariant_t( Vector &&val ) = delete;
|
||||
ScriptVariant_t( QAngle &&val ) = delete;
|
||||
#endif
|
||||
|
||||
bool IsNull() const { return (m_type == FIELD_VOID ); }
|
||||
@ -442,42 +408,29 @@ struct ScriptVariant_t
|
||||
operator int() const { Assert( m_type == FIELD_INTEGER ); return m_int; }
|
||||
operator float() const { Assert( m_type == FIELD_FLOAT ); return m_float; }
|
||||
operator const char *() const { Assert( m_type == FIELD_CSTRING ); return ( m_pszString ) ? m_pszString : ""; }
|
||||
operator const Vector &() const { Assert( m_type == FIELD_VECTOR ); static Vector vecNull(0, 0, 0); return (m_pVector) ? *m_pVector : vecNull; }
|
||||
operator const Vector &() const { Assert( m_type == FIELD_VECTOR ); return (m_pVector) ? *m_pVector : vec3_origin; }
|
||||
operator char() const { Assert( m_type == FIELD_CHARACTER ); return m_char; }
|
||||
operator bool() const { Assert( m_type == FIELD_BOOLEAN ); return m_bool; }
|
||||
operator HSCRIPT() const { Assert( m_type == FIELD_HSCRIPT ); return m_hScript; }
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
operator const QAngle &() const { Assert( m_type == FIELD_VECTOR ); static QAngle vecNull(0, 0, 0); return (m_pAngle) ? *m_pAngle : vecNull; }
|
||||
operator const QAngle &() const { Assert( m_type == FIELD_VECTOR ); return (m_pAngle) ? *m_pAngle : vec3_angle; }
|
||||
#endif
|
||||
|
||||
void operator=( int i ) { m_type = FIELD_INTEGER; m_int = i; }
|
||||
void operator=( float f ) { m_type = FIELD_FLOAT; m_float = f; }
|
||||
void operator=( double f ) { m_type = FIELD_FLOAT; m_float = (float)f; }
|
||||
void operator=( const Vector &vec ) { m_type = FIELD_VECTOR; m_pVector = &vec; }
|
||||
void operator=( const Vector *vec ) { m_type = FIELD_VECTOR; m_pVector = vec; }
|
||||
void operator=( const char *psz ) { m_type = FIELD_CSTRING; m_pszString = psz; }
|
||||
void operator=( char c ) { m_type = FIELD_CHARACTER; m_char = c; }
|
||||
void operator=( bool b ) { m_type = FIELD_BOOLEAN; m_bool = b; }
|
||||
void operator=( HSCRIPT h ) { m_type = FIELD_HSCRIPT; m_hScript = h; }
|
||||
void operator=( int i ) { m_type = FIELD_INTEGER; m_flags = 0; m_int = i; }
|
||||
void operator=( float f ) { m_type = FIELD_FLOAT; m_flags = 0; m_float = f; }
|
||||
void operator=( double f ) { m_type = FIELD_FLOAT; m_flags = 0; m_float = (float)f; }
|
||||
void operator=( const Vector &vec ) { m_type = FIELD_VECTOR; m_flags = 0; m_pVector = &vec; }
|
||||
void operator=( const Vector *vec ) { m_type = FIELD_VECTOR; m_flags = 0; m_pVector = vec; }
|
||||
void operator=( const char *psz ) { m_type = FIELD_CSTRING; m_flags = 0; m_pszString = psz; }
|
||||
void operator=( char c ) { m_type = FIELD_CHARACTER; m_flags = 0; m_char = c; }
|
||||
void operator=( bool b ) { m_type = FIELD_BOOLEAN; m_flags = 0; m_bool = b; }
|
||||
void operator=( HSCRIPT h ) { m_type = FIELD_HSCRIPT; m_flags = 0; m_hScript = h; }
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void operator=( const QAngle &vec ) { m_type = FIELD_VECTOR; m_pAngle = &vec; }
|
||||
void operator=( const QAngle *vec ) { m_type = FIELD_VECTOR; m_pAngle = vec; }
|
||||
void operator=( const QAngle &ang ) { m_type = FIELD_VECTOR; m_flags = 0; m_pAngle = ∠ }
|
||||
void operator=( const QAngle *ang ) { m_type = FIELD_VECTOR; m_flags = 0; m_pAngle = ang; }
|
||||
|
||||
void operator=( Vector &&vec )
|
||||
{
|
||||
m_type = FIELD_VECTOR;
|
||||
m_pVector = (Vector*)malloc( sizeof( Vector ) );
|
||||
new ( (Vector*)m_pVector ) Vector( vec );
|
||||
m_flags |= SV_FREE;
|
||||
}
|
||||
|
||||
void operator=( QAngle &&ang )
|
||||
{
|
||||
m_type = FIELD_VECTOR;
|
||||
m_pAngle = (QAngle*)malloc( sizeof( QAngle ) );
|
||||
new ( (QAngle*)m_pAngle ) QAngle( ang );
|
||||
m_flags |= SV_FREE;
|
||||
}
|
||||
void operator=( Vector &&vec ) = delete;
|
||||
void operator=( QAngle &&ang ) = delete;
|
||||
#endif
|
||||
|
||||
void Free()
|
||||
@ -651,6 +604,16 @@ inline void ScriptVariant_t::EmplaceAllocedVector( const Vector &vec )
|
||||
|
||||
#define SCRIPT_VARIANT_NULL ScriptVariant_t()
|
||||
|
||||
union ScriptVariantTemporaryStorage_t
|
||||
{
|
||||
// members must be initialized via placement-new
|
||||
ScriptVariantTemporaryStorage_t() { }
|
||||
|
||||
// members must have trivial destructor, since no destructor will be invoked
|
||||
Vector m_vec;
|
||||
QAngle m_ang;
|
||||
};
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//---------------------------------------------------------
|
||||
struct ScriptConstantBinding_t
|
||||
@ -743,7 +706,7 @@ static inline int ToConstantVariant(int value)
|
||||
// This is used for registering variants (particularly vectors) not tied to existing variables.
|
||||
// The principal difference is that m_data is initted with bCopy set to true.
|
||||
#define ScriptRegisterConstantFromTemp( pVM, constant, description ) ScriptRegisterConstantFromTempNamed( pVM, constant, #constant, description )
|
||||
#define ScriptRegisterConstantFromTempNamed( pVM, constant, scriptName, description ) do { static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ScriptVariant_t( constant, true ); pVM->RegisterConstant( &binding ); } while (0)
|
||||
#define ScriptRegisterConstantFromTempNamed( pVM, constant, scriptName, description ) do { static const auto constantStorage = constant; static ScriptConstantBinding_t binding; binding.m_pszScriptName = scriptName; binding.m_pszDescription = description; binding.m_data = ScriptVariant_t( constantStorage ); pVM->RegisterConstant( &binding ); } while (0)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -326,8 +326,8 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
|
||||
class CNonMemberScriptBinding##N \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
{ \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( !pContext ); \
|
||||
@ -337,15 +337,15 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
|
||||
return false; \
|
||||
} \
|
||||
*pReturn = ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \
|
||||
return true; \
|
||||
} \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CNonMemberScriptBinding##N<FUNC_TYPE, void FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( !pReturn ); \
|
||||
@ -360,12 +360,52 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CNonMemberScriptBinding##N<FUNC_TYPE, Vector FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( !pContext ); \
|
||||
\
|
||||
if ( nArguments != N || !pReturn || pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
new ( &temporaryReturnStorage.m_vec ) Vector( ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ) ); \
|
||||
*pReturn = temporaryReturnStorage.m_vec; \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CNonMemberScriptBinding##N<FUNC_TYPE, QAngle FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( !pContext ); \
|
||||
\
|
||||
if ( nArguments != N || !pReturn || pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
new ( &temporaryReturnStorage.m_ang ) QAngle( ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ) ); \
|
||||
*pReturn = temporaryReturnStorage.m_ang; \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <class OBJECT_TYPE_PTR, typename FUNC_TYPE, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CMemberScriptBinding##N \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
{ \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( pContext ); \
|
||||
@ -375,15 +415,15 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
|
||||
return false; \
|
||||
} \
|
||||
*pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
|
||||
return true; \
|
||||
} \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <class OBJECT_TYPE_PTR, typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CMemberScriptBinding##N<OBJECT_TYPE_PTR, FUNC_TYPE, void FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( !pReturn ); \
|
||||
@ -398,6 +438,46 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <class OBJECT_TYPE_PTR, typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CMemberScriptBinding##N<OBJECT_TYPE_PTR, FUNC_TYPE, Vector FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( pContext ); \
|
||||
\
|
||||
if ( nArguments != N || !pReturn || !pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
new ( &temporaryReturnStorage.m_vec ) Vector( (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ) ); \
|
||||
*pReturn = temporaryReturnStorage.m_vec; \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <class OBJECT_TYPE_PTR, typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CMemberScriptBinding##N<OBJECT_TYPE_PTR, FUNC_TYPE, QAngle FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( void *pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn, ScriptVariantTemporaryStorage_t &temporaryReturnStorage ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( pContext ); \
|
||||
\
|
||||
if ( nArguments != N || !pReturn || !pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
new ( &temporaryReturnStorage.m_ang ) QAngle( (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ) ); \
|
||||
*pReturn = temporaryReturnStorage.m_ang; \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline ScriptBindingFunc_t ScriptCreateBinding(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
|
||||
{ \
|
||||
@ -419,7 +499,11 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
|
||||
return &CMemberScriptBinding##N<OBJECT_TYPE_PTR, Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
|
||||
}
|
||||
|
||||
//note: no memory is actually allocated in the functions that get defined,
|
||||
// it merely uses placement-new for which we need to disable this
|
||||
#include "tier0/memdbgoff.h"
|
||||
FUNC_GENERATE_ALL( DEFINE_SCRIPT_BINDINGS );
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -1399,6 +1399,7 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
||||
}
|
||||
|
||||
ScriptVariant_t retval;
|
||||
ScriptVariantTemporaryStorage_t retval_storage;
|
||||
|
||||
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getforeignptr(vm);
|
||||
assert(pSquirrelVM);
|
||||
@ -1406,7 +1407,7 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
||||
sq_resetobject(&pSquirrelVM->lastError_);
|
||||
|
||||
(*pFunc->m_pfnBinding)(pFunc->m_pFunction, instance, params.Base(), nargs,
|
||||
pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &retval);
|
||||
pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &retval, retval_storage);
|
||||
|
||||
if (!sq_isnull(pSquirrelVM->lastError_))
|
||||
{
|
||||
@ -1417,7 +1418,9 @@ SQInteger function_stub(HSQUIRRELVM vm)
|
||||
|
||||
PushVariant(vm, retval);
|
||||
|
||||
retval.Free();
|
||||
// strings never get copied here, Vector and QAngle are stored in script_retval_storage
|
||||
// everything else is stored inline, so there should be no memory to free
|
||||
Assert(!(retval.m_flags & SV_FREE));
|
||||
|
||||
return pFunc->m_desc.m_ReturnType != FIELD_VOID;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user