| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- // Filename: renderEffect.cxx
- // Created by: drose (14Mar02)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // PANDA 3D SOFTWARE
- // Copyright (c) 2001, 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://www.panda3d.org/license.txt .
- //
- // To contact the maintainers of this program write to
- // [email protected] .
- //
- ////////////////////////////////////////////////////////////////////
- #include "renderEffect.h"
- #include "bamReader.h"
- #include "indent.h"
- RenderEffect::Effects RenderEffect::_effects;
- TypeHandle RenderEffect::_type_handle;
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::Constructor
- // Access: Protected
- // Description:
- ////////////////////////////////////////////////////////////////////
- RenderEffect::
- RenderEffect() {
- _saved_entry = _effects.end();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::Copy Constructor
- // Access: Private
- // Description: RenderEffects are not meant to be copied.
- ////////////////////////////////////////////////////////////////////
- RenderEffect::
- RenderEffect(const RenderEffect &) {
- nassertv(false);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::Copy Assignment Operator
- // Access: Private
- // Description: RenderEffects are not meant to be copied.
- ////////////////////////////////////////////////////////////////////
- void RenderEffect::
- operator = (const RenderEffect &) {
- nassertv(false);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::Destructor
- // Access: Public, Virtual
- // Description: The destructor is responsible for removing the
- // RenderEffect from the global set if it is there.
- ////////////////////////////////////////////////////////////////////
- RenderEffect::
- ~RenderEffect() {
- if (_saved_entry != _effects.end()) {
- // We cannot make this assertion, because the RenderEffect has
- // already partially destructed--this means we cannot look up the
- // object in the map. In fact, the map is temporarily invalid
- // until we finish destructing, since we screwed up the ordering
- // when we changed the return value of get_type().
- // nassertv(_effects.find(this) == _saved_entry);
- // Note: this isn't thread-safe, because once the derived class
- // destructor exits and before this destructor completes, the map
- // is invalid, and other threads may inadvertently attempt to read
- // the invalid map. To make it thread-safe, we need to move this
- // functionality to a separate method, that is to be called from
- // *each* derived class's destructor (and then we can put the
- // above assert back in).
- _effects.erase(_saved_entry);
- _saved_entry = _effects.end();
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::safe_to_transform
- // Access: Public, Virtual
- // Description: Returns true if it is generally safe to transform
- // this particular kind of RenderEffect by calling the
- // xform() method, false otherwise.
- ////////////////////////////////////////////////////////////////////
- bool RenderEffect::
- safe_to_transform() const {
- return true;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::safe_to_combine
- // Access: Public, Virtual
- // Description: Returns true if this kind of effect can safely be
- // combined with sibling nodes that share the exact same
- // effect, or false if this is not a good idea.
- ////////////////////////////////////////////////////////////////////
- bool RenderEffect::
- safe_to_combine() const {
- return true;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::xform
- // Access: Public, Virtual
- // Description: Returns a new RenderEffect transformed by the
- // indicated matrix.
- ////////////////////////////////////////////////////////////////////
- CPT(RenderEffect) RenderEffect::
- xform(const LMatrix4f &) const {
- return this;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::output
- // Access: Published, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void RenderEffect::
- output(ostream &out) const {
- out << get_type();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::write
- // Access: Published, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- void RenderEffect::
- write(ostream &out, int indent_level) const {
- indent(out, indent_level) << *this << "\n";
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::return_new
- // Access: Protected, Static
- // Description: This function is used by derived RenderEffect types
- // to share a common RenderEffect pointer for all
- // equivalent RenderEffect objects.
- //
- // The make() function of the derived type should create
- // a new RenderEffect and pass it through return_new(),
- // which will either save the pointer and return it
- // unchanged (if this is the first similar such object)
- // or delete it and return an equivalent pointer (if
- // there was already a similar object saved).
- ////////////////////////////////////////////////////////////////////
- CPT(RenderEffect) RenderEffect::
- return_new(RenderEffect *effect) {
- nassertr(effect != (RenderEffect *)NULL, effect);
- // This should be a newly allocated pointer, not one that was used
- // for anything else.
- nassertr(effect->_saved_entry == _effects.end(), effect);
- // Save the effect in a local PointerTo so that it will be freed at
- // the end of this function if no one else uses it.
- CPT(RenderEffect) pt_effect = effect;
- pair<Effects::iterator, bool> result = _effects.insert(effect);
- if (result.second) {
- // The effect was inserted; save the iterator and return the
- // input effect.
- effect->_saved_entry = result.first;
- return pt_effect;
- }
- // The effect was not inserted; there must be an equivalent one
- // already in the set. Return that one.
- return *(result.first);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::compare_to_impl
- // Access: Protected, Virtual
- // Description: Intended to be overridden by derived RenderEffect
- // types to return a unique number indicating whether
- // this RenderEffect is equivalent to the other one.
- //
- // This should return 0 if the two RenderEffect objects
- // are equivalent, a number less than zero if this one
- // should be sorted before the other one, and a number
- // greater than zero otherwise.
- //
- // This will only be called with two RenderEffect
- // objects whose get_type() functions return the same.
- ////////////////////////////////////////////////////////////////////
- int RenderEffect::
- compare_to_impl(const RenderEffect *other) const {
- return 0;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::write_datagram
- // Access: Public, Virtual
- // Description: Writes the contents of this object to the datagram
- // for shipping out to a Bam file.
- ////////////////////////////////////////////////////////////////////
- void RenderEffect::
- write_datagram(BamWriter *manager, Datagram &dg) {
- TypedWritable::write_datagram(manager, dg);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::change_this
- // Access: Public, Static
- // Description: Called immediately after complete_pointers(), this
- // gives the object a chance to adjust its own pointer
- // if desired. Most objects don't change pointers after
- // completion, but some need to.
- //
- // Once this function has been called, the old pointer
- // will no longer be accessed.
- ////////////////////////////////////////////////////////////////////
- TypedWritable *RenderEffect::
- change_this(TypedWritable *old_ptr, BamReader *manager) {
- // First, uniquify the pointer.
- RenderEffect *effect = DCAST(RenderEffect, old_ptr);
- CPT(RenderEffect) pointer = return_new(effect);
- // But now we have a problem, since we have to hold the reference
- // count and there's no way to return a TypedWritable while still
- // holding the reference count! We work around this by explicitly
- // upping the count, and also setting a finalize() callback to down
- // it later.
- if (pointer == effect) {
- pointer->ref();
- manager->register_finalize(effect);
- }
-
- // We have to cast the pointer back to non-const, because the bam
- // reader expects that.
- return (RenderEffect *)pointer.p();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::finalize
- // Access: Public, Virtual
- // Description: Method to ensure that any necessary clean up tasks
- // that have to be performed by this object are performed
- ////////////////////////////////////////////////////////////////////
- void RenderEffect::
- finalize() {
- // Unref the pointer that we explicitly reffed in make_from_bam().
- unref();
- // We should never get back to zero after unreffing our own count,
- // because we expect to have been stored in a pointer somewhere. If
- // we do get to zero, it's a memory leak; the way to avoid this is
- // to call unref_delete() above instead of unref(), but this is
- // dangerous to do from within a virtual function.
- nassertv(get_ref_count() != 0);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: RenderEffect::fillin
- // Access: Protected
- // Description: This internal function is called by make_from_bam to
- // read in all of the relevant data from the BamFile for
- // the new RenderEffect.
- ////////////////////////////////////////////////////////////////////
- void RenderEffect::
- fillin(DatagramIterator &scan, BamReader *manager) {
- TypedWritable::fillin(scan, manager);
- }
|