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

panda/src/pgraph/renderAttrib.cxx

Go to the documentation of this file.
00001 // Filename: renderAttrib.cxx
00002 // Created by:  drose (21Feb02)
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 "renderAttrib.h"
00020 #include "bamReader.h"
00021 #include "indent.h"
00022 
00023 RenderAttrib::Attribs *RenderAttrib::_attribs = NULL;
00024 TypeHandle RenderAttrib::_type_handle;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: RenderAttrib::Constructor
00028 //       Access: Protected
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 RenderAttrib::
00032 RenderAttrib() {
00033   if (_attribs == (Attribs *)NULL) {
00034     // Make sure the global _attribs map is allocated.  This only has
00035     // to be done once.  We could make this map static, but then we
00036     // run into problems if anyone creates a RenderState object at
00037     // static init time; it also seems to cause problems when the
00038     // Panda shared library is unloaded at application exit time.
00039     _attribs = new Attribs;
00040   }
00041   _saved_entry = _attribs->end();
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: RenderAttrib::Copy Constructor
00046 //       Access: Private
00047 //  Description: RenderAttribs are not meant to be copied.
00048 ////////////////////////////////////////////////////////////////////
00049 RenderAttrib::
00050 RenderAttrib(const RenderAttrib &) {
00051   nassertv(false);
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: RenderAttrib::Copy Assignment Operator
00056 //       Access: Private
00057 //  Description: RenderAttribs are not meant to be copied.
00058 ////////////////////////////////////////////////////////////////////
00059 void RenderAttrib::
00060 operator = (const RenderAttrib &) {
00061   nassertv(false);
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: RenderAttrib::Destructor
00066 //       Access: Public, Virtual
00067 //  Description: The destructor is responsible for removing the
00068 //               RenderAttrib from the global set if it is there.
00069 ////////////////////////////////////////////////////////////////////
00070 RenderAttrib::
00071 ~RenderAttrib() {
00072   if (_saved_entry != _attribs->end()) {
00073     // We cannot make this assertion, because the RenderAttrib has
00074     // already partially destructed--this means we cannot look up the
00075     // object in the map.  In fact, the map is temporarily invalid
00076     // until we finish destructing, since we screwed up the ordering
00077     // when we changed the return value of get_type().
00078     //    nassertv(_attribs->find(this) == _saved_entry);
00079 
00080     // Note: this isn't thread-safe, because once the derived class
00081     // destructor exits and before this destructor completes, the map
00082     // is invalid, and other threads may inadvertently attempt to read
00083     // the invalid map.  To make it thread-safe, we need to move this
00084     // functionality to a separate method, that is to be called from
00085     // *each* derived class's destructor (and then we can put the
00086     // above assert back in).
00087     _attribs->erase(_saved_entry);
00088     _saved_entry = _attribs->end();
00089   }
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: RenderAttrib::issue
00094 //       Access: Public, Virtual
00095 //  Description: Calls the appropriate method on the indicated GSG
00096 //               to issue the graphics commands appropriate to the
00097 //               given attribute.  This is normally called
00098 //               (indirectly) only from
00099 //               GraphicsStateGuardian::set_state() or modify_state().
00100 ////////////////////////////////////////////////////////////////////
00101 void RenderAttrib::
00102 issue(GraphicsStateGuardianBase *) const {
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: RenderAttrib::output
00107 //       Access: Published, Virtual
00108 //  Description: 
00109 ////////////////////////////////////////////////////////////////////
00110 void RenderAttrib::
00111 output(ostream &out) const {
00112   out << get_type();
00113 }
00114 
00115 void RenderAttrib::
00116 output_comparefunc(ostream &out,PandaCompareFunc fn) const {
00117    static char *FuncStrs[M_always+1] = {"none","never","less","equal", "less or equal","greater","not equal","greater or equal","always"};
00118    out << FuncStrs[fn];
00119 }
00120 
00121 ////////////////////////////////////////////////////////////////////
00122 //     Function: RenderAttrib::write
00123 //       Access: Published, Virtual
00124 //  Description: 
00125 ////////////////////////////////////////////////////////////////////
00126 void RenderAttrib::
00127 write(ostream &out, int indent_level) const {
00128   indent(out, indent_level) << *this << "\n";
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: RenderAttrib::return_new
00133 //       Access: Protected, Static
00134 //  Description: This function is used by derived RenderAttrib types
00135 //               to share a common RenderAttrib pointer for all
00136 //               equivalent RenderAttrib objects.
00137 //
00138 //               The make() function of the derived type should create
00139 //               a new RenderAttrib and pass it through return_new(),
00140 //               which will either save the pointer and return it
00141 //               unchanged (if this is the first similar such object)
00142 //               or delete it and return an equivalent pointer (if
00143 //               there was already a similar object saved).
00144 ////////////////////////////////////////////////////////////////////
00145 CPT(RenderAttrib) RenderAttrib::
00146 return_new(RenderAttrib *attrib) {
00147   nassertr(attrib != (RenderAttrib *)NULL, attrib);
00148 
00149   // This should be a newly allocated pointer, not one that was used
00150   // for anything else.
00151   nassertr(attrib->_saved_entry == _attribs->end(), attrib);
00152 
00153   // Save the attrib in a local PointerTo so that it will be freed at
00154   // the end of this function if no one else uses it.
00155   CPT(RenderAttrib) pt_attrib = attrib;
00156 
00157   pair<Attribs::iterator, bool> result = _attribs->insert(attrib);
00158   if (result.second) {
00159     // The attribute was inserted; save the iterator and return the
00160     // input attribute.
00161     attrib->_saved_entry = result.first;
00162     return pt_attrib;
00163   }
00164 
00165   // The attribute was not inserted; there must be an equivalent one
00166   // already in the set.  Return that one.
00167   return *(result.first);
00168 }
00169 
00170 ////////////////////////////////////////////////////////////////////
00171 //     Function: RenderAttrib::compare_to_impl
00172 //       Access: Protected, Virtual
00173 //  Description: Intended to be overridden by derived RenderAttrib
00174 //               types to return a unique number indicating whether
00175 //               this RenderAttrib is equivalent to the other one.
00176 //
00177 //               This should return 0 if the two RenderAttrib objects
00178 //               are equivalent, a number less than zero if this one
00179 //               should be sorted before the other one, and a number
00180 //               greater than zero otherwise.
00181 //
00182 //               This will only be called with two RenderAttrib
00183 //               objects whose get_type() functions return the same.
00184 ////////////////////////////////////////////////////////////////////
00185 int RenderAttrib::
00186 compare_to_impl(const RenderAttrib *other) const {
00187   return 0;
00188 }
00189 
00190 ////////////////////////////////////////////////////////////////////
00191 //     Function: RenderAttrib::compose_impl
00192 //       Access: Protected, Virtual
00193 //  Description: Intended to be overridden by derived RenderAttrib
00194 //               types to specify how two consecutive RenderAttrib
00195 //               objects of the same type interact.
00196 //
00197 //               This should return the result of applying the other
00198 //               RenderAttrib to a node in the scene graph below this
00199 //               RenderAttrib, which was already applied.  In most
00200 //               cases, the result is the same as the other
00201 //               RenderAttrib (that is, a subsequent RenderAttrib
00202 //               completely replaces the preceding one).  On the other
00203 //               hand, some kinds of RenderAttrib (for instance,
00204 //               ColorTransformAttrib) might combine in meaningful
00205 //               ways.
00206 ////////////////////////////////////////////////////////////////////
00207 CPT(RenderAttrib) RenderAttrib::
00208 compose_impl(const RenderAttrib *other) const {
00209   return other;
00210 }
00211 
00212 ////////////////////////////////////////////////////////////////////
00213 //     Function: RenderAttrib::invert_compose_impl
00214 //       Access: Protected, Virtual
00215 //  Description: Intended to be overridden by derived RenderAttrib
00216 //               types to specify how two consecutive RenderAttrib
00217 //               objects of the same type interact.
00218 //
00219 //               See invert_compose() and compose_impl().
00220 ////////////////////////////////////////////////////////////////////
00221 CPT(RenderAttrib) RenderAttrib::
00222 invert_compose_impl(const RenderAttrib *other) const {
00223   return other;
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: RenderAttrib::make_default_impl
00228 //       Access: Protected, Virtual
00229 //  Description: Intended to be overridden by derived RenderAttrib
00230 //               types to specify what the default property for a
00231 //               RenderAttrib of this type should be.
00232 //
00233 //               This should return a newly-allocated RenderAttrib of
00234 //               the same type that corresponds to whatever the
00235 //               standard default for this kind of RenderAttrib is.
00236 ////////////////////////////////////////////////////////////////////
00237 RenderAttrib *RenderAttrib::
00238 make_default_impl() const {
00239   return (RenderAttrib *)NULL;
00240 }
00241 
00242 ////////////////////////////////////////////////////////////////////
00243 //     Function: RenderAttrib::write_datagram
00244 //       Access: Public, Virtual
00245 //  Description: Writes the contents of this object to the datagram
00246 //               for shipping out to a Bam file.
00247 ////////////////////////////////////////////////////////////////////
00248 void RenderAttrib::
00249 write_datagram(BamWriter *manager, Datagram &dg) {
00250   TypedWritable::write_datagram(manager, dg);
00251 }
00252 
00253 ////////////////////////////////////////////////////////////////////
00254 //     Function: RenderAttrib::change_this
00255 //       Access: Public, Static
00256 //  Description: Called immediately after complete_pointers(), this
00257 //               gives the object a chance to adjust its own pointer
00258 //               if desired.  Most objects don't change pointers after
00259 //               completion, but some need to.
00260 //
00261 //               Once this function has been called, the old pointer
00262 //               will no longer be accessed.
00263 ////////////////////////////////////////////////////////////////////
00264 TypedWritable *RenderAttrib::
00265 change_this(TypedWritable *old_ptr, BamReader *manager) {
00266   // First, uniquify the pointer.
00267   RenderAttrib *attrib = DCAST(RenderAttrib, old_ptr);
00268   CPT(RenderAttrib) pointer = return_new(attrib);
00269 
00270   // But now we have a problem, since we have to hold the reference
00271   // count and there's no way to return a TypedWritable while still
00272   // holding the reference count!  We work around this by explicitly
00273   // upping the count, and also setting a finalize() callback to down
00274   // it later.
00275   if (pointer == attrib) {
00276     pointer->ref();
00277     manager->register_finalize(attrib);
00278   }
00279   
00280   // We have to cast the pointer back to non-const, because the bam
00281   // reader expects that.
00282   return (RenderAttrib *)pointer.p();
00283 }
00284 
00285 ////////////////////////////////////////////////////////////////////
00286 //     Function: RenderAttrib::finalize
00287 //       Access: Public, Virtual
00288 //  Description: Method to ensure that any necessary clean up tasks
00289 //               that have to be performed by this object are performed
00290 ////////////////////////////////////////////////////////////////////
00291 void RenderAttrib::
00292 finalize() {
00293   // Unref the pointer that we explicitly reffed in make_from_bam().
00294   unref();
00295 
00296   // We should never get back to zero after unreffing our own count,
00297   // because we expect to have been stored in a pointer somewhere.  If
00298   // we do get to zero, it's a memory leak; the way to avoid this is
00299   // to call unref_delete() above instead of unref(), but this is
00300   // dangerous to do from within a virtual function.
00301   nassertv(get_ref_count() != 0);
00302 }
00303 
00304 ////////////////////////////////////////////////////////////////////
00305 //     Function: RenderAttrib::fillin
00306 //       Access: Protected
00307 //  Description: This internal function is called by make_from_bam to
00308 //               read in all of the relevant data from the BamFile for
00309 //               the new RenderAttrib.
00310 ////////////////////////////////////////////////////////////////////
00311 void RenderAttrib::
00312 fillin(DatagramIterator &scan, BamReader *manager) {
00313   TypedWritable::fillin(scan, manager);
00314   manager->register_change_this(change_this, this);
00315 }

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