diff --git a/source/ps/ConfigDB.cpp b/source/ps/ConfigDB.cpp index 2158c9ddf6..df66fad6b7 100755 --- a/source/ps/ConfigDB.cpp +++ b/source/ps/ConfigDB.cpp @@ -246,20 +246,20 @@ bool CConfigDB::Reload(EConfigNamespace ns) FileIOBuf buffer; uint buflen; File f; - Handle fh; + LibError ret; if (m_UseVFS[ns]) { // Open file with VFS - fh=vfs_load(m_ConfigFile[ns], buffer, buflen); - if (fh <= 0) + ret = vfs_load(m_ConfigFile[ns], buffer, buflen); + if(ret != ERR_OK) { - LOG(ERROR, LOG_CATEGORY, "vfs_load for \"%s\" failed: return was %lld", m_ConfigFile[ns].c_str(), fh); + LOG(ERROR, LOG_CATEGORY, "vfs_load for \"%s\" failed: return was %lld", m_ConfigFile[ns].c_str(), ret); return false; } } else { - if (file_open(m_ConfigFile[ns], 0, &f)!=0) + if (file_open(m_ConfigFile[ns], 0, &f)!=ERR_OK) { LOG(ERROR, LOG_CATEGORY, "file_open for \"%s\" failed", m_ConfigFile[ns].c_str()); return false; diff --git a/source/scripting/ScriptableComplex.cpp b/source/scripting/ScriptableComplex.cpp new file mode 100644 index 0000000000..b571631cf5 --- /dev/null +++ b/source/scripting/ScriptableComplex.cpp @@ -0,0 +1,38 @@ +#include "precompiled.h" +#include "ScriptableComplex.h" + +// suballocator for CJSComplex.m_Properties elements +static Bucket bucket; +// HACK: it needs to be created/destroyed; since there is no +// global init/shutdown call here, we keep a refcnt. this assumes that +// going to 0 <==> shutdown! if that proves wrong, bucket_alloc will warn. +static uint suballoc_refs; // initialized in suballoc_attach + +void jscomplexproperty_suballoc_attach() +{ + ONCE(\ + size_t el_size = MAX(sizeof(CJSValComplexProperty), sizeof(CJSComplexProperty));\ + (void)bucket_create(&bucket, el_size);\ + suballoc_refs = 0;\ + ); + suballoc_refs++; +} + +void jscomplexproperty_suballoc_detach() +{ + suballoc_refs--; + if(suballoc_refs == 0) + bucket_destroy(&bucket); +} + +void* jscomplexproperty_suballoc() +{ + return bucket_alloc(&bucket, 0); +} + +void jscomplexproperty_suballoc_free(IJSComplexProperty* p) +{ + // explicit dtor since caller uses placement new + p->~IJSComplexProperty(); + bucket_free(&bucket, p); +} diff --git a/source/scripting/ScriptableComplex.h b/source/scripting/ScriptableComplex.h index acebb4fcf3..de4f5afe8d 100644 --- a/source/scripting/ScriptableComplex.h +++ b/source/scripting/ScriptableComplex.h @@ -6,6 +6,8 @@ #include "scripting/ScriptingHost.h" #include "JSConversions.h" +#include "lib/allocators.h" + #include #ifndef SCRIPTABLE_COMPLEX_INCLUDED @@ -470,6 +472,13 @@ public: } }; + + +extern void jscomplexproperty_suballoc_attach(); +extern void jscomplexproperty_suballoc_detach(); +extern void* jscomplexproperty_suballoc(); +extern void jscomplexproperty_suballoc_free(IJSComplexProperty* p); + template class CJSComplex : public IJSComplex { typedef STL_HASH_MAP ReflectorTable; @@ -480,6 +489,7 @@ template class CJSComplex : public IJSComplex ReflectorTable m_Reflectors; + public: static JSClass JSI_class; @@ -760,6 +770,8 @@ private: public: CJSComplex() { + jscomplexproperty_suballoc_attach(); + m_Parent = NULL; m_JS = NULL; m_EngineOwned = true; @@ -767,6 +779,8 @@ public: virtual ~CJSComplex() { Shutdown(); + + jscomplexproperty_suballoc_detach(); } void Shutdown() { @@ -785,7 +799,8 @@ public: JS_RemoveRoot( g_ScriptingHost.GetContext(), &( extProp->m_JSAccessor ) ); } } - delete( it->second ); + + jscomplexproperty_suballoc_free(it->second); } @@ -899,8 +914,11 @@ public: } void AddProperty( CStrW PropertyName, jsval Value ) { - debug_assert( !HasProperty( PropertyName ) ); - CJSDynamicComplexProperty* newProp = new CJSValComplexProperty( Value, false ); + DeletePreviouslyAssignedProperty( PropertyName ); + void* mem = jscomplexproperty_suballoc(); +#include "nommgr.h" + CJSDynamicComplexProperty* newProp = new(mem) CJSValComplexProperty( Value, false ); +#include "mmgr.h" m_Properties[PropertyName] = newProp; ReflectorTable::iterator it; @@ -938,13 +956,43 @@ public: { T::m_IntrinsicProperties[PropertyName] = new CJSSharedProperty( (PropType IJSComplex::*)Native, PropAllowInheritance, Update, Refresh ); } + + // helper routine for Add*Property. Their interface requires the + // property not already exist; we check for this (in non-final builds) + // and if so, warn and free the previously new-ed memory in + // m_Properties[PropertyName] (avoids mem leak). + void DeletePreviouslyAssignedProperty( CStrW PropertyName ) + { +#ifndef FINAL + PropertyTable::iterator it; + it = m_Properties.find( PropertyName ); + if( it != m_Properties.end() ) + { + debug_warn("BUG: CJSComplexProperty added but already existed!"); + jscomplexproperty_suballoc_free(it->second); + } +#else + UNUSED2(PropertyName); +#endif + } + + // PropertyName must not already exist! (verified in non-final release) template void AddProperty( CStrW PropertyName, PropType* Native, bool PropAllowInheritance = true, NotifyFn Update = NULL, NotifyFn Refresh = NULL ) { - m_Properties[PropertyName] = new CJSComplexProperty( Native, PropAllowInheritance, Update, Refresh ); + DeletePreviouslyAssignedProperty( PropertyName ); + void* mem = jscomplexproperty_suballoc(); +#include "nommgr.h" + m_Properties[PropertyName] = new(mem) CJSComplexProperty( Native, PropAllowInheritance, Update, Refresh ); +#include "mmgr.h" } + // PropertyName must not already exist! (verified in non-final release) template void AddReadOnlyProperty( CStrW PropertyName, PropType* Native, bool PropAllowInheritance = true, NotifyFn Update = NULL, NotifyFn Refresh = NULL ) { - m_Properties[PropertyName] = new CJSComplexProperty( Native, PropAllowInheritance, Update, Refresh ); + DeletePreviouslyAssignedProperty( PropertyName ); + void* mem = jscomplexproperty_suballoc(); +#include "nommgr.h" + m_Properties[PropertyName] = new(mem) CJSComplexProperty( Native, PropAllowInheritance, Update, Refresh ); +#include "mmgr.h" } }; diff --git a/source/simulation/BaseEntity.cpp b/source/simulation/BaseEntity.cpp index 5565b71e5d..22e6ad7e96 100755 --- a/source/simulation/BaseEntity.cpp +++ b/source/simulation/BaseEntity.cpp @@ -45,9 +45,6 @@ CBaseEntity::CBaseEntity() AddProperty( L"traits.anchor.type", &m_anchorType ); AddProperty( L"traits.vision.los", &m_los ); AddProperty( L"traits.vision.permanent", &m_permanent ); - AddProperty( L"traits.health.regen_rate", &m_healthRegenRate ); - AddProperty( L"traits.health.regen_start", &m_healthRegenStart ); - AddProperty( L"traits.health.decay_rate", &m_healthDecayRate ); for( int t = 0; t < EVENT_LAST; t++ ) { diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index f383e655e4..a43b9e7f91 100755 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -69,9 +69,6 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation ) AddProperty( L"traits.anchor.type", &m_anchorType ); AddProperty( L"traits.vision.los", &m_los ); AddProperty( L"traits.vision.permanent", &m_permanent ); - AddProperty( L"traits.health.regen_rate", &m_healthRegenRate ); - AddProperty( L"traits.health.regen_start", &m_healthRegenStart ); - AddProperty( L"traits.health.decay_rate", &m_healthDecayRate ); AddProperty( L"last_combat_time", &m_lastCombatTime ); for( int t = 0; t < EVENT_LAST; t++ )