mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2024-11-10 07:11:54 +00:00
issue #343 - was purging the wrong model from cache, causing pointers to freed memory
This commit is contained in:
parent
cc68a76900
commit
376eb6c0ac
3 changed files with 138 additions and 133 deletions
|
@ -27,129 +27,129 @@
|
|||
/*! simulates misc_model entity behaviours for rendering/selection/editing */
|
||||
class CEntityMiscModel : public IRender, public ISelect, public IEdit
|
||||
{
|
||||
public:
|
||||
CEntityMiscModel ( entity_t *e );
|
||||
virtual ~CEntityMiscModel ();
|
||||
public:
|
||||
CEntityMiscModel( entity_t *e );
|
||||
virtual ~CEntityMiscModel ();
|
||||
|
||||
void IncRef() { refCount++; }
|
||||
void DecRef() {
|
||||
if ( --refCount == 0 ) {
|
||||
delete this;
|
||||
void IncRef() { refCount++; }
|
||||
void DecRef() {
|
||||
if ( --refCount == 0 ) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IRender
|
||||
void Draw( int state, int rflags ) const;
|
||||
const aabb_t *GetAABB() const { return &m_BBox; }
|
||||
// IRender
|
||||
void Draw( int state, int rflags ) const;
|
||||
const aabb_t *GetAABB() const { return &m_BBox; }
|
||||
|
||||
// ISelect
|
||||
bool TestRay( const ray_t *ray, vec_t *dist ) const;
|
||||
//bool TestBox(const aabb_t aabb) const;
|
||||
// ISelect
|
||||
bool TestRay( const ray_t *ray, vec_t *dist ) const;
|
||||
//bool TestBox(const aabb_t aabb) const;
|
||||
|
||||
// ITransform
|
||||
void Translate( const vec3_t translation );
|
||||
void Rotate( const vec3_t pivot, const vec3_t rotation );
|
||||
const vec_t *GetTranslation() const { return m_translate; }
|
||||
const vec_t *GetRotation() const { return m_euler; }
|
||||
void OnKeyValueChanged( entity_t *e, const char *key, const char* value );
|
||||
// ITransform
|
||||
void Translate( const vec3_t translation );
|
||||
void Rotate( const vec3_t pivot, const vec3_t rotation );
|
||||
const vec_t *GetTranslation() const { return m_translate; }
|
||||
const vec_t *GetRotation() const { return m_euler; }
|
||||
void OnKeyValueChanged( entity_t *e, const char *key, const char* value );
|
||||
|
||||
void SetName( const char *name );
|
||||
private:
|
||||
void BuildCacheRequestString( const char *name );
|
||||
/*! updates the AABB and transformation matrix */
|
||||
void UpdateCachedData();
|
||||
entity_interfaces_t *m_model;
|
||||
void SetName( const char *name );
|
||||
private:
|
||||
void BuildCacheRequestString( const char *name );
|
||||
/*! updates the AABB and transformation matrix */
|
||||
void UpdateCachedData();
|
||||
entity_interfaces_t *m_model;
|
||||
|
||||
entity_t *m_entity;
|
||||
entity_t *m_entity;
|
||||
|
||||
int refCount;
|
||||
string_t m_version;
|
||||
int refCount;
|
||||
string_t m_version;
|
||||
|
||||
Str m_cachereq;
|
||||
Str m_cachereq;
|
||||
|
||||
/*! AABB in local space */
|
||||
aabb_t m_BBox;
|
||||
/*! AABB in local space */
|
||||
aabb_t m_BBox;
|
||||
|
||||
/*! worldspace-to-localspace translation */
|
||||
vec3_t m_translate;
|
||||
/*! worldspace-to-localspace translation */
|
||||
vec3_t m_translate;
|
||||
|
||||
/*! worldspace-to-localspace euler rotation angles */
|
||||
vec3_t m_euler;
|
||||
/*! worldspace-to-localspace euler rotation angles */
|
||||
vec3_t m_euler;
|
||||
|
||||
/*! worldspace-to-localspace scale */
|
||||
vec3_t m_scale;
|
||||
/*! worldspace-to-localspace scale */
|
||||
vec3_t m_scale;
|
||||
|
||||
/*! localspace origin, effectively rotation & scale pivot point */
|
||||
vec3_t m_pivot;
|
||||
/*! localspace origin, effectively rotation & scale pivot point */
|
||||
vec3_t m_pivot;
|
||||
|
||||
/*! worldspace-to-localspace transform, generated from translate/euler/scale/pivot */
|
||||
m4x4_t m_transform;
|
||||
/*! worldspace-to-localspace transform, generated from translate/euler/scale/pivot */
|
||||
m4x4_t m_transform;
|
||||
|
||||
/*! localspace-to-worldspace transform */
|
||||
m4x4_t m_inverse_transform;
|
||||
/*! localspace-to-worldspace transform */
|
||||
m4x4_t m_inverse_transform;
|
||||
};
|
||||
|
||||
/*! simulates eclass-model entity behaviours for rendering/selection/editing */
|
||||
class CEntityEclassModel : public IRender, public ISelect, public IEdit
|
||||
{
|
||||
public:
|
||||
CEntityEclassModel ();
|
||||
virtual ~CEntityEclassModel ();
|
||||
public:
|
||||
CEntityEclassModel();
|
||||
virtual ~CEntityEclassModel();
|
||||
|
||||
void IncRef() { refCount++; }
|
||||
void DecRef() {
|
||||
if ( --refCount == 0 ) {
|
||||
delete this;
|
||||
void IncRef() { refCount++; }
|
||||
void DecRef() {
|
||||
if ( --refCount == 0 ) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IRender
|
||||
void Draw( int state, int rflags ) const;
|
||||
const aabb_t *GetAABB() const { return &m_BBox; }
|
||||
// IRender
|
||||
void Draw( int state, int rflags ) const;
|
||||
const aabb_t *GetAABB() const { return &m_BBox; }
|
||||
|
||||
// ISelect
|
||||
bool TestRay( const ray_t *ray, vec_t *dist ) const;
|
||||
//bool TestBox(const aabb_t aabb) const;
|
||||
// ISelect
|
||||
bool TestRay( const ray_t *ray, vec_t *dist ) const;
|
||||
//bool TestBox(const aabb_t aabb) const;
|
||||
|
||||
// ITransform
|
||||
void Translate( const vec3_t translation );
|
||||
void Rotate( const vec3_t pivot, const vec3_t rotation );
|
||||
const vec_t *GetTranslation() const { return m_translate; }
|
||||
const vec_t *GetRotation() const { return m_euler; }
|
||||
void OnKeyValueChanged( entity_t *e, const char *key, const char* value );
|
||||
// ITransform
|
||||
void Translate( const vec3_t translation );
|
||||
void Rotate( const vec3_t pivot, const vec3_t rotation );
|
||||
const vec_t *GetTranslation() const { return m_translate; }
|
||||
const vec_t *GetRotation() const { return m_euler; }
|
||||
void OnKeyValueChanged( entity_t *e, const char *key, const char* value );
|
||||
|
||||
void SetName( const char *name );
|
||||
void SetEclass( const eclass_t* eclass );
|
||||
private:
|
||||
/*! updates the AABB and transformation matrix */
|
||||
void UpdateCachedData();
|
||||
entity_interfaces_t *m_model;
|
||||
void SetName( const char *name );
|
||||
void SetEclass( const eclass_t* eclass );
|
||||
private:
|
||||
/*! updates the AABB and transformation matrix */
|
||||
void UpdateCachedData();
|
||||
entity_interfaces_t *m_model;
|
||||
|
||||
int refCount;
|
||||
string_t m_name;
|
||||
string_t m_version;
|
||||
const eclass_t *m_eclass;
|
||||
int refCount;
|
||||
string_t m_name;
|
||||
string_t m_version;
|
||||
const eclass_t *m_eclass;
|
||||
|
||||
/*! AABB in local space */
|
||||
aabb_t m_BBox;
|
||||
/*! AABB in local space */
|
||||
aabb_t m_BBox;
|
||||
|
||||
/*! worldspace-to-localspace translation */
|
||||
vec3_t m_translate;
|
||||
/*! worldspace-to-localspace translation */
|
||||
vec3_t m_translate;
|
||||
|
||||
/*! worldspace-to-localspace euler rotation angles */
|
||||
vec3_t m_euler;
|
||||
/*! worldspace-to-localspace euler rotation angles */
|
||||
vec3_t m_euler;
|
||||
|
||||
/*! worldspace-to-localspace scale */
|
||||
vec3_t m_scale;
|
||||
/*! worldspace-to-localspace scale */
|
||||
vec3_t m_scale;
|
||||
|
||||
/*! localspace origin, effectively rotation & scale pivot point */
|
||||
vec3_t m_pivot;
|
||||
/*! localspace origin, effectively rotation & scale pivot point */
|
||||
vec3_t m_pivot;
|
||||
|
||||
/*! worldspace-to-localspace transform, generated from translate/euler/scale/pivot */
|
||||
m4x4_t m_transform;
|
||||
/*! worldspace-to-localspace transform, generated from translate/euler/scale/pivot */
|
||||
m4x4_t m_transform;
|
||||
|
||||
/*! localspace-to-worldspace transform */
|
||||
m4x4_t m_inverse_transform;
|
||||
/*! localspace-to-worldspace transform */
|
||||
m4x4_t m_inverse_transform;
|
||||
};
|
||||
|
||||
void pivot_draw( const vec3_t pivot );
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "entity_entitymodel.h"
|
||||
#include "entity.h"
|
||||
|
@ -62,7 +63,7 @@ void CEntityMiscModel::Draw( int state, int rflags ) const {
|
|||
|
||||
// draw children
|
||||
if ( m_model && m_model->pRender ) {
|
||||
m_model->pRender->Draw( state, rflags );
|
||||
m_model->pRender->Draw(state, rflags);
|
||||
}
|
||||
|
||||
g_QglTable.m_pfn_qglPopMatrix();
|
||||
|
@ -201,9 +202,11 @@ void CEntityMiscModel::SetName( const char *name ){
|
|||
return;
|
||||
}
|
||||
|
||||
if ( m_cachereq.GetBuffer()[0] != ':'
|
||||
if ( m_oldcachereq.GetBuffer()[0] != ':'
|
||||
&& m_version.c_str()[0] != '\0' ) {
|
||||
GetModelCache()->DeleteByID( m_cachereq.GetBuffer(), m_version.c_str() );
|
||||
GetModelCache()->DeleteByID( m_oldcachereq.GetBuffer(), m_version.c_str() );
|
||||
} else {
|
||||
assert(m_model == NULL);
|
||||
}
|
||||
|
||||
m_model = NULL;
|
||||
|
|
|
@ -236,55 +236,57 @@ int refcount;
|
|||
times an ID is being referenced, and destroys any instance that is no longer in use */
|
||||
class CModelManager : public IModelCache
|
||||
{
|
||||
public:
|
||||
CModelManager(){
|
||||
m_ptrs = g_ptr_array_new();
|
||||
}
|
||||
virtual ~CModelManager(){
|
||||
g_ptr_array_free( m_ptrs, FALSE );
|
||||
}
|
||||
|
||||
virtual void DeleteByID( const char *id, const char* version ){
|
||||
unsigned int i;
|
||||
CModelWrapper *elem;
|
||||
for ( i = 0; i < m_ptrs->len; i++ )
|
||||
{
|
||||
elem = (CModelWrapper*)m_ptrs->pdata[i];
|
||||
if ( strcmp( elem->m_version.c_str(), version ) == 0
|
||||
&& strcmp( elem->m_id.c_str(), id ) == 0
|
||||
&& --elem->refcount == 0 ) {
|
||||
g_ptr_array_remove_index_fast( m_ptrs, i );
|
||||
delete elem;
|
||||
return;
|
||||
}
|
||||
public:
|
||||
CModelManager(){
|
||||
m_ptrs = g_ptr_array_new();
|
||||
}
|
||||
virtual ~CModelManager(){
|
||||
g_ptr_array_free( m_ptrs, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
virtual entity_interfaces_t *GetByID( const char *id, const char* version ){
|
||||
unsigned int i;
|
||||
CModelWrapper *elem;
|
||||
for ( i = 0; i < m_ptrs->len; i++ )
|
||||
{
|
||||
elem = (CModelWrapper*)m_ptrs->pdata[i];
|
||||
if ( strcmp( elem->m_version.c_str(), version ) == 0
|
||||
&& strcmp( elem->m_id.c_str(), id ) == 0 ) {
|
||||
elem->refcount++;
|
||||
return &elem->m_model;
|
||||
virtual void DeleteByID( const char *id, const char* version ){
|
||||
unsigned int i;
|
||||
CModelWrapper *elem;
|
||||
for ( i = 0; i < m_ptrs->len; i++ )
|
||||
{
|
||||
elem = (CModelWrapper*)m_ptrs->pdata[i];
|
||||
if (strcmp(elem->m_version.c_str(), version) == 0
|
||||
&& strcmp(elem->m_id.c_str(), id) == 0) {
|
||||
elem->refcount--;
|
||||
if (elem->refcount == 0) {
|
||||
g_ptr_array_remove_index_fast(m_ptrs, i);
|
||||
delete elem;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elem = new CModelWrapper( id, version );
|
||||
g_ptr_array_add( m_ptrs, elem );
|
||||
virtual entity_interfaces_t *GetByID( const char *id, const char* version ){
|
||||
unsigned int i;
|
||||
CModelWrapper *elem;
|
||||
for ( i = 0; i < m_ptrs->len; i++ )
|
||||
{
|
||||
elem = (CModelWrapper*)m_ptrs->pdata[i];
|
||||
if ( strcmp( elem->m_version.c_str(), version ) == 0
|
||||
&& strcmp( elem->m_id.c_str(), id ) == 0 ) {
|
||||
elem->refcount++;
|
||||
return &elem->m_model;
|
||||
}
|
||||
}
|
||||
|
||||
return &elem->m_model;
|
||||
}
|
||||
elem = new CModelWrapper( id, version );
|
||||
g_ptr_array_add( m_ptrs, elem );
|
||||
|
||||
virtual void RefreshAll(){
|
||||
for ( unsigned int i = 0; i < m_ptrs->len; ++i )
|
||||
( (CModelWrapper*)m_ptrs->pdata[i] )->Refresh();
|
||||
}
|
||||
private:
|
||||
GPtrArray *m_ptrs; // array of CModelWrapper*
|
||||
return &elem->m_model;
|
||||
}
|
||||
|
||||
virtual void RefreshAll(){
|
||||
for ( unsigned int i = 0; i < m_ptrs->len; ++i )
|
||||
( (CModelWrapper*)m_ptrs->pdata[i] )->Refresh();
|
||||
}
|
||||
private:
|
||||
GPtrArray *m_ptrs; // array of CModelWrapper*
|
||||
};
|
||||
|
||||
CModelManager g_model_cache;
|
||||
|
|
Loading…
Reference in a new issue