Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pgraph/renderEffect.cxx

Go to the documentation of this file.
00001 // Filename: renderEffect.cxx
00002 // Created by:  drose (14Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "renderEffect.h"
00020 #include "bamReader.h"
00021 #include "indent.h"
00022 
00023 RenderEffect::Effects RenderEffect::_effects;
00024 TypeHandle RenderEffect::_type_handle;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: RenderEffect::Constructor
00028 //       Access: Protected
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 RenderEffect::
00032 RenderEffect() {
00033   _saved_entry = _effects.end();
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: RenderEffect::Copy Constructor
00038 //       Access: Private
00039 //  Description: RenderEffects are not meant to be copied.
00040 ////////////////////////////////////////////////////////////////////
00041 RenderEffect::
00042 RenderEffect(const RenderEffect &) {
00043   nassertv(false);
00044 }
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 //     Function: RenderEffect::Copy Assignment Operator
00048 //       Access: Private
00049 //  Description: RenderEffects are not meant to be copied.
00050 ////////////////////////////////////////////////////////////////////
00051 void RenderEffect::
00052 operator = (const RenderEffect &) {
00053   nassertv(false);
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: RenderEffect::Destructor
00058 //       Access: Public, Virtual
00059 //  Description: The destructor is responsible for removing the
00060 //               RenderEffect from the global set if it is there.
00061 ////////////////////////////////////////////////////////////////////
00062 RenderEffect::
00063 ~RenderEffect() {
00064   if (_saved_entry != _effects.end()) {
00065     // We cannot make this assertion, because the RenderEffect has
00066     // already partially destructed--this means we cannot look up the
00067     // object in the map.  In fact, the map is temporarily invalid
00068     // until we finish destructing, since we screwed up the ordering
00069     // when we changed the return value of get_type().
00070     //    nassertv(_effects.find(this) == _saved_entry);
00071 
00072     // Note: this isn't thread-safe, because once the derived class
00073     // destructor exits and before this destructor completes, the map
00074     // is invalid, and other threads may inadvertently attempt to read
00075     // the invalid map.  To make it thread-safe, we need to move this
00076     // functionality to a separate method, that is to be called from
00077     // *each* derived class's destructor (and then we can put the
00078     // above assert back in).
00079     _effects.erase(_saved_entry);
00080     _saved_entry = _effects.end();
00081   }
00082 }
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 //     Function: RenderEffect::safe_to_transform
00086 //       Access: Public, Virtual
00087 //  Description: Returns true if it is generally safe to transform
00088 //               this particular kind of RenderEffect by calling the
00089 //               xform() method, false otherwise.
00090 ////////////////////////////////////////////////////////////////////
00091 bool RenderEffect::
00092 safe_to_transform() const {
00093   return true;
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: RenderEffect::safe_to_combine
00098 //       Access: Public, Virtual
00099 //  Description: Returns true if this kind of effect can safely be
00100 //               combined with sibling nodes that share the exact same
00101 //               effect, or false if this is not a good idea.
00102 ////////////////////////////////////////////////////////////////////
00103 bool RenderEffect::
00104 safe_to_combine() const {
00105   return true;
00106 }
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 //     Function: RenderEffect::xform
00110 //       Access: Public, Virtual
00111 //  Description: Returns a new RenderEffect transformed by the
00112 //               indicated matrix.
00113 ////////////////////////////////////////////////////////////////////
00114 CPT(RenderEffect) RenderEffect::
00115 xform(const LMatrix4f &) const {
00116   return this;
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //     Function: RenderEffect::output
00121 //       Access: Published, Virtual
00122 //  Description: 
00123 ////////////////////////////////////////////////////////////////////
00124 void RenderEffect::
00125 output(ostream &out) const {
00126   out << get_type();
00127 }
00128 
00129 ////////////////////////////////////////////////////////////////////
00130 //     Function: RenderEffect::write
00131 //       Access: Published, Virtual
00132 //  Description: 
00133 ////////////////////////////////////////////////////////////////////
00134 void RenderEffect::
00135 write(ostream &out, int indent_level) const {
00136   indent(out, indent_level) << *this << "\n";
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //     Function: RenderEffect::return_new
00141 //       Access: Protected, Static
00142 //  Description: This function is used by derived RenderEffect types
00143 //               to share a common RenderEffect pointer for all
00144 //               equivalent RenderEffect objects.
00145 //
00146 //               The make() function of the derived type should create
00147 //               a new RenderEffect and pass it through return_new(),
00148 //               which will either save the pointer and return it
00149 //               unchanged (if this is the first similar such object)
00150 //               or delete it and return an equivalent pointer (if
00151 //               there was already a similar object saved).
00152 ////////////////////////////////////////////////////////////////////
00153 CPT(RenderEffect) RenderEffect::
00154 return_new(RenderEffect *effect) {
00155   nassertr(effect != (RenderEffect *)NULL, effect);
00156 
00157   // This should be a newly allocated pointer, not one that was used
00158   // for anything else.
00159   nassertr(effect->_saved_entry == _effects.end(), effect);
00160 
00161   // Save the effect in a local PointerTo so that it will be freed at
00162   // the end of this function if no one else uses it.
00163   CPT(RenderEffect) pt_effect = effect;
00164 
00165   pair<Effects::iterator, bool> result = _effects.insert(effect);
00166   if (result.second) {
00167     // The effect was inserted; save the iterator and return the
00168     // input effect.
00169     effect->_saved_entry = result.first;
00170     return pt_effect;
00171   }
00172 
00173   // The effect was not inserted; there must be an equivalent one
00174   // already in the set.  Return that one.
00175   return *(result.first);
00176 }
00177 
00178 ////////////////////////////////////////////////////////////////////
00179 //     Function: RenderEffect::compare_to_impl
00180 //       Access: Protected, Virtual
00181 //  Description: Intended to be overridden by derived RenderEffect
00182 //               types to return a unique number indicating whether
00183 //               this RenderEffect is equivalent to the other one.
00184 //
00185 //               This should return 0 if the two RenderEffect objects
00186 //               are equivalent, a number less than zero if this one
00187 //               should be sorted before the other one, and a number
00188 //               greater than zero otherwise.
00189 //
00190 //               This will only be called with two RenderEffect
00191 //               objects whose get_type() functions return the same.
00192 ////////////////////////////////////////////////////////////////////
00193 int RenderEffect::
00194 compare_to_impl(const RenderEffect *other) const {
00195   return 0;
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: RenderEffect::write_datagram
00200 //       Access: Public, Virtual
00201 //  Description: Writes the contents of this object to the datagram
00202 //               for shipping out to a Bam file.
00203 ////////////////////////////////////////////////////////////////////
00204 void RenderEffect::
00205 write_datagram(BamWriter *manager, Datagram &dg) {
00206   TypedWritable::write_datagram(manager, dg);
00207 }
00208 
00209 ////////////////////////////////////////////////////////////////////
00210 //     Function: RenderEffect::change_this
00211 //       Access: Public, Static
00212 //  Description: Called immediately after complete_pointers(), this
00213 //               gives the object a chance to adjust its own pointer
00214 //               if desired.  Most objects don't change pointers after
00215 //               completion, but some need to.
00216 //
00217 //               Once this function has been called, the old pointer
00218 //               will no longer be accessed.
00219 ////////////////////////////////////////////////////////////////////
00220 TypedWritable *RenderEffect::
00221 change_this(TypedWritable *old_ptr, BamReader *manager) {
00222   // First, uniquify the pointer.
00223   RenderEffect *effect = DCAST(RenderEffect, old_ptr);
00224   CPT(RenderEffect) pointer = return_new(effect);
00225 
00226   // But now we have a problem, since we have to hold the reference
00227   // count and there's no way to return a TypedWritable while still
00228   // holding the reference count!  We work around this by explicitly
00229   // upping the count, and also setting a finalize() callback to down
00230   // it later.
00231   if (pointer == effect) {
00232     pointer->ref();
00233     manager->register_finalize(effect);
00234   }
00235   
00236   // We have to cast the pointer back to non-const, because the bam
00237   // reader expects that.
00238   return (RenderEffect *)pointer.p();
00239 }
00240 
00241 ////////////////////////////////////////////////////////////////////
00242 //     Function: RenderEffect::finalize
00243 //       Access: Public, Virtual
00244 //  Description: Method to ensure that any necessary clean up tasks
00245 //               that have to be performed by this object are performed
00246 ////////////////////////////////////////////////////////////////////
00247 void RenderEffect::
00248 finalize() {
00249   // Unref the pointer that we explicitly reffed in make_from_bam().
00250   unref();
00251 
00252   // We should never get back to zero after unreffing our own count,
00253   // because we expect to have been stored in a pointer somewhere.  If
00254   // we do get to zero, it's a memory leak; the way to avoid this is
00255   // to call unref_delete() above instead of unref(), but this is
00256   // dangerous to do from within a virtual function.
00257   nassertv(get_ref_count() != 0);
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: RenderEffect::fillin
00262 //       Access: Protected
00263 //  Description: This internal function is called by make_from_bam to
00264 //               read in all of the relevant data from the BamFile for
00265 //               the new RenderEffect.
00266 ////////////////////////////////////////////////////////////////////
00267 void RenderEffect::
00268 fillin(DatagramIterator &scan, BamReader *manager) {
00269   TypedWritable::fillin(scan, manager);
00270 }

Generated on Fri May 2 00:42:14 2003 for Panda by doxygen1.3