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