diff --git a/panda/src/express/Sources.pp b/panda/src/express/Sources.pp index c978576a36..a49c355848 100644 --- a/panda/src/express/Sources.pp +++ b/panda/src/express/Sources.pp @@ -62,6 +62,7 @@ virtualFileMountMultifile.I virtualFileMountSystem.h \ virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \ virtualFileSystem.h virtualFileSystem.I \ + weakPointerCallback.I weakPointerCallback.h \ weakPointerTo.I weakPointerTo.h \ weakPointerToBase.I weakPointerToBase.h \ weakPointerToVoid.I weakPointerToVoid.h \ @@ -112,6 +113,7 @@ virtualFileMount.cxx \ virtualFileMountMultifile.cxx virtualFileMountSystem.cxx \ virtualFileSimple.cxx virtualFileSystem.cxx \ + weakPointerCallback.cxx \ weakPointerTo.cxx \ weakPointerToBase.cxx \ weakPointerToVoid.cxx \ @@ -173,6 +175,7 @@ virtualFileMountMultifile.I virtualFileMountSystem.h \ virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \ virtualFileSystem.h virtualFileSystem.I \ + weakPointerCallback.I weakPointerCallback.h \ weakPointerTo.I weakPointerTo.h \ weakPointerToBase.I weakPointerToBase.h \ weakPointerToVoid.I weakPointerToVoid.h \ diff --git a/panda/src/express/express_composite2.cxx b/panda/src/express/express_composite2.cxx index a7a7ae531e..c05f881961 100644 --- a/panda/src/express/express_composite2.cxx +++ b/panda/src/express/express_composite2.cxx @@ -22,6 +22,7 @@ #include "virtualFileMountSystem.cxx" #include "virtualFileSimple.cxx" #include "virtualFileSystem.cxx" +#include "weakPointerCallback.cxx" #include "weakPointerTo.cxx" #include "weakPointerToBase.cxx" #include "weakPointerToVoid.cxx" diff --git a/panda/src/express/weakPointerCallback.I b/panda/src/express/weakPointerCallback.I new file mode 100644 index 0000000000..3cd80d5de7 --- /dev/null +++ b/panda/src/express/weakPointerCallback.I @@ -0,0 +1,18 @@ +// Filename: weakPointerCallback.I +// Created by: drose (06Oct06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + diff --git a/panda/src/express/weakPointerCallback.cxx b/panda/src/express/weakPointerCallback.cxx new file mode 100644 index 0000000000..279bc961bc --- /dev/null +++ b/panda/src/express/weakPointerCallback.cxx @@ -0,0 +1,19 @@ +// Filename: weakPointerCallback.cxx +// Created by: drose (06Oct06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "weakPointerCallback.h" diff --git a/panda/src/express/weakPointerCallback.h b/panda/src/express/weakPointerCallback.h new file mode 100644 index 0000000000..fd0b6e881a --- /dev/null +++ b/panda/src/express/weakPointerCallback.h @@ -0,0 +1,38 @@ +// Filename: weakPointerCallback.h +// Created by: drose (06Oct06) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef WEAKPOINTERCALLBACK_H +#define WEAKPOINTERCALLBACK_H + +#include "pandabase.h" + +//////////////////////////////////////////////////////////////////// +// Class : WeakPointerCallback +// Description : Derive from this class and override the callback() +// method if you want to get an immediate callback from +// a WeakPointerTo object when its referenced pointer is +// deleted. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAEXPRESS WeakPointerCallback { +public: + virtual void wp_callback(void *pointer)=0; +}; + +#include "weakPointerCallback.I" + +#endif diff --git a/panda/src/express/weakPointerToVoid.I b/panda/src/express/weakPointerToVoid.I index 6325843de7..3bcb3d0f7f 100644 --- a/panda/src/express/weakPointerToVoid.I +++ b/panda/src/express/weakPointerToVoid.I @@ -25,6 +25,7 @@ INLINE WeakPointerToVoid:: WeakPointerToVoid() { _ptr_was_deleted = false; + _callback = NULL; } //////////////////////////////////////////////////////////////////// @@ -48,6 +49,39 @@ INLINE void WeakPointerToVoid:: mark_deleted() { nassertv(!_ptr_was_deleted); _ptr_was_deleted = true; + if (_callback != (WeakPointerCallback *)NULL) { + _callback->wp_callback(_void_ptr); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WeakPointerToVoid::set_callback +// Access: Public +// Description: Sets a callback that will be made when the pointer is +// deleted. If a previous callback has already been +// set, it will be replaced. +// +// If the pointer has already been deleted, the callback +// will be made immediately. +//////////////////////////////////////////////////////////////////// +INLINE void WeakPointerToVoid:: +set_callback(WeakPointerCallback *callback) { + _callback = callback; + if (_ptr_was_deleted && _callback != (WeakPointerCallback *)NULL) { + _callback->wp_callback(_void_ptr); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WeakPointerToVoid::get_callback +// Access: Public +// Description: Returns the callback that will be made when the +// pointer is deleted, or NULL if no callback has been +// set. +//////////////////////////////////////////////////////////////////// +INLINE WeakPointerCallback *WeakPointerToVoid:: +get_callback() const { + return _callback; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/express/weakPointerToVoid.h b/panda/src/express/weakPointerToVoid.h index c0691dd425..60ed137eb3 100644 --- a/panda/src/express/weakPointerToVoid.h +++ b/panda/src/express/weakPointerToVoid.h @@ -21,6 +21,7 @@ #include "pandabase.h" #include "pointerToVoid.h" +#include "weakPointerCallback.h" //////////////////////////////////////////////////////////////////// // Class : WeakPointerToVoid @@ -36,12 +37,16 @@ protected: public: INLINE void mark_deleted(); + INLINE void set_callback(WeakPointerCallback *callback); + INLINE WeakPointerCallback *get_callback() const; + PUBLISHED: INLINE bool was_deleted() const; INLINE bool is_valid_pointer() const; protected: bool _ptr_was_deleted; + WeakPointerCallback *_callback; }; #include "weakPointerToVoid.I" diff --git a/panda/src/glstuff/glGeomMunger_src.I b/panda/src/glstuff/glGeomMunger_src.I index 5c55e04c1f..42f22e5dc0 100644 --- a/panda/src/glstuff/glGeomMunger_src.I +++ b/panda/src/glstuff/glGeomMunger_src.I @@ -28,4 +28,8 @@ CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) : _texture(state->get_texture()), _tex_gen(state->get_tex_gen()) { + // Set a callback to unregister ourselves when either the Texture or + // the TexGen object gets deleted. + _texture.set_callback(this); + _tex_gen.set_callback(this); } diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index db7b8e2b04..e84e5febfb 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -37,6 +37,19 @@ CLP(GeomMunger):: _geom_contexts.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: CLP(GeomMunger)::wp_callback +// Access: Public, Virtual +// Description: This callback is set to be made whenever the +// associated _texture or _tex_gen attributes are +// destructed, in which case the GeomMunger is invalid +// and should no longer be used. +//////////////////////////////////////////////////////////////////// +void CLP(GeomMunger):: +wp_callback(void *) { + unregister_myself(); +} + //////////////////////////////////////////////////////////////////// // Function: CLP(GeomMunger)::munge_format_impl // Access: Protected, Virtual diff --git a/panda/src/glstuff/glGeomMunger_src.h b/panda/src/glstuff/glGeomMunger_src.h index 88598b4abe..5834f24038 100644 --- a/panda/src/glstuff/glGeomMunger_src.h +++ b/panda/src/glstuff/glGeomMunger_src.h @@ -22,6 +22,8 @@ #include "textureAttrib.h" #include "texGenAttrib.h" #include "renderState.h" +#include "weakPointerTo.h" +#include "weakPointerCallback.h" class CLP(GeomContext); @@ -31,12 +33,14 @@ class CLP(GeomContext); // for OpenGL rendering. In particular, it makes sure // colors aren't stored in DirectX's packed_argb format. //////////////////////////////////////////////////////////////////// -class EXPCL_GL CLP(GeomMunger) : public StandardMunger { +class EXPCL_GL CLP(GeomMunger) : public StandardMunger, public WeakPointerCallback { public: INLINE CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state); virtual ~CLP(GeomMunger)(); ALLOC_DELETED_CHAIN(CLP(GeomMunger)); + virtual void wp_callback(void *); + protected: virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig, const GeomVertexAnimationSpec &animation); @@ -44,8 +48,8 @@ protected: virtual int geom_compare_to_impl(const GeomMunger *other) const; private: - CPT(TextureAttrib) _texture; - CPT(TexGenAttrib) _tex_gen; + WCPT(TextureAttrib) _texture; + WCPT(TexGenAttrib) _tex_gen; typedef pset GeomContexts; GeomContexts _geom_contexts; diff --git a/panda/src/gobj/geomMunger.I b/panda/src/gobj/geomMunger.I index d922e37e71..74c0347734 100644 --- a/panda/src/gobj/geomMunger.I +++ b/panda/src/gobj/geomMunger.I @@ -50,6 +50,40 @@ register_munger(GeomMunger *munger, Thread *current_thread) { return get_registry()->register_munger(munger, current_thread); } +//////////////////////////////////////////////////////////////////// +// Function: GeomMunger::munge_format +// Access: Public +// Description: Given a source GeomVertexFormat, converts it if +// necessary to the appropriate format for rendering. +// +// If the GeomVertexAnimationSpec so indicates, then the +// format will be chosen to convert CPU-based animation +// tables to HW-based animation tables, reserving space +// for the specified number of transforms per vertex. +//////////////////////////////////////////////////////////////////// +INLINE CPT(GeomVertexFormat) GeomMunger:: +munge_format(const GeomVertexFormat *format, + const GeomVertexAnimationSpec &animation) const { + // We cast away the const pointer, because do_munge_format() needs + // to update caches and stuff, but we trust it not to change any + // user-definable parameters. + return ((GeomMunger *)this)->do_munge_format(format, animation); +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomMunger::munge_data +// Access: Public +// Description: Given a source GeomVertexData, converts it if +// necessary to the appropriate data for rendering. +//////////////////////////////////////////////////////////////////// +INLINE CPT(GeomVertexData) GeomMunger:: +munge_data(const GeomVertexData *data) const { + // We cast away the const pointer, because do_munge_data() needs to + // update caches and stuff, but we trust it not to change any + // user-definable parameters. + return ((GeomMunger *)this)->munge_data_impl(data); +} + //////////////////////////////////////////////////////////////////// // Function: GeomMunger::compare_to // Access: Public @@ -96,37 +130,22 @@ geom_compare_to(const GeomMunger &other) const { } //////////////////////////////////////////////////////////////////// -// Function: GeomMunger::munge_format -// Access: Public -// Description: Given a source GeomVertexFormat, converts it if -// necessary to the appropriate format for rendering. +// Function: GeomMunger::unregister_myself +// Access: Protected +// Description: Unregisters the GeomMunger, for instance when it is +// being destructed, or whenever it has become invalid +// for some reason. This removes it from the registry +// so that it will no longer be available to be returned +// by register_munger(). // -// If the GeomVertexAnimationSpec so indicates, then the -// format will be chosen to convert CPU-based animation -// tables to HW-based animation tables, reserving space -// for the specified number of transforms per vertex. +// It is not an error to call this if the munger has +// already been unregistered. //////////////////////////////////////////////////////////////////// -INLINE CPT(GeomVertexFormat) GeomMunger:: -munge_format(const GeomVertexFormat *format, - const GeomVertexAnimationSpec &animation) const { - // We cast away the const pointer, because do_munge_format() needs - // to update caches and stuff, but we trust it not to change any - // user-definable parameters. - return ((GeomMunger *)this)->do_munge_format(format, animation); -} - -//////////////////////////////////////////////////////////////////// -// Function: GeomMunger::munge_data -// Access: Public -// Description: Given a source GeomVertexData, converts it if -// necessary to the appropriate data for rendering. -//////////////////////////////////////////////////////////////////// -INLINE CPT(GeomVertexData) GeomMunger:: -munge_data(const GeomVertexData *data) const { - // We cast away the const pointer, because do_munge_data() needs to - // update caches and stuff, but we trust it not to change any - // user-definable parameters. - return ((GeomMunger *)this)->munge_data_impl(data); +INLINE void GeomMunger:: +unregister_myself() { + if (is_registered()) { + get_registry()->unregister_munger(this); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomMunger.cxx b/panda/src/gobj/geomMunger.cxx index 1a7148d80d..15363471e2 100644 --- a/panda/src/gobj/geomMunger.cxx +++ b/panda/src/gobj/geomMunger.cxx @@ -76,9 +76,7 @@ operator = (const GeomMunger ©) { //////////////////////////////////////////////////////////////////// GeomMunger:: ~GeomMunger() { - if (is_registered()) { - get_registry()->unregister_munger(this); - } + unregister_myself(); nassertv(_formats_by_animation.empty()); } diff --git a/panda/src/gobj/geomMunger.h b/panda/src/gobj/geomMunger.h index 6c2cc6e498..5f81f0a1fa 100644 --- a/panda/src/gobj/geomMunger.h +++ b/panda/src/gobj/geomMunger.h @@ -81,6 +81,8 @@ public: INLINE int geom_compare_to(const GeomMunger &other) const; protected: + INLINE void unregister_myself(); + CPT(GeomVertexFormat) do_munge_format(const GeomVertexFormat *format, const GeomVertexAnimationSpec &animation);