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 }