renderEffect.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Filename: renderEffect.cxx
  2. // Created by: drose (14Mar02)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "renderEffect.h"
  19. #include "bamReader.h"
  20. #include "indent.h"
  21. RenderEffect::Effects RenderEffect::_effects;
  22. TypeHandle RenderEffect::_type_handle;
  23. ////////////////////////////////////////////////////////////////////
  24. // Function: RenderEffect::Constructor
  25. // Access: Protected
  26. // Description:
  27. ////////////////////////////////////////////////////////////////////
  28. RenderEffect::
  29. RenderEffect() {
  30. _saved_entry = _effects.end();
  31. }
  32. ////////////////////////////////////////////////////////////////////
  33. // Function: RenderEffect::Copy Constructor
  34. // Access: Private
  35. // Description: RenderEffects are not meant to be copied.
  36. ////////////////////////////////////////////////////////////////////
  37. RenderEffect::
  38. RenderEffect(const RenderEffect &) {
  39. nassertv(false);
  40. }
  41. ////////////////////////////////////////////////////////////////////
  42. // Function: RenderEffect::Copy Assignment Operator
  43. // Access: Private
  44. // Description: RenderEffects are not meant to be copied.
  45. ////////////////////////////////////////////////////////////////////
  46. void RenderEffect::
  47. operator = (const RenderEffect &) {
  48. nassertv(false);
  49. }
  50. ////////////////////////////////////////////////////////////////////
  51. // Function: RenderEffect::Destructor
  52. // Access: Public, Virtual
  53. // Description: The destructor is responsible for removing the
  54. // RenderEffect from the global set if it is there.
  55. ////////////////////////////////////////////////////////////////////
  56. RenderEffect::
  57. ~RenderEffect() {
  58. if (_saved_entry != _effects.end()) {
  59. // We cannot make this assertion, because the RenderEffect has
  60. // already partially destructed--this means we cannot look up the
  61. // object in the map. In fact, the map is temporarily invalid
  62. // until we finish destructing, since we screwed up the ordering
  63. // when we changed the return value of get_type().
  64. // nassertv(_effects.find(this) == _saved_entry);
  65. // Note: this isn't thread-safe, because once the derived class
  66. // destructor exits and before this destructor completes, the map
  67. // is invalid, and other threads may inadvertently attempt to read
  68. // the invalid map. To make it thread-safe, we need to move this
  69. // functionality to a separate method, that is to be called from
  70. // *each* derived class's destructor (and then we can put the
  71. // above assert back in).
  72. _effects.erase(_saved_entry);
  73. _saved_entry = _effects.end();
  74. }
  75. }
  76. ////////////////////////////////////////////////////////////////////
  77. // Function: RenderEffect::safe_to_transform
  78. // Access: Public, Virtual
  79. // Description: Returns true if it is generally safe to transform
  80. // this particular kind of RenderEffect by calling the
  81. // xform() method, false otherwise.
  82. ////////////////////////////////////////////////////////////////////
  83. bool RenderEffect::
  84. safe_to_transform() const {
  85. return true;
  86. }
  87. ////////////////////////////////////////////////////////////////////
  88. // Function: RenderEffect::safe_to_combine
  89. // Access: Public, Virtual
  90. // Description: Returns true if this kind of effect can safely be
  91. // combined with sibling nodes that share the exact same
  92. // effect, or false if this is not a good idea.
  93. ////////////////////////////////////////////////////////////////////
  94. bool RenderEffect::
  95. safe_to_combine() const {
  96. return true;
  97. }
  98. ////////////////////////////////////////////////////////////////////
  99. // Function: RenderEffect::xform
  100. // Access: Public, Virtual
  101. // Description: Returns a new RenderEffect transformed by the
  102. // indicated matrix.
  103. ////////////////////////////////////////////////////////////////////
  104. CPT(RenderEffect) RenderEffect::
  105. xform(const LMatrix4f &) const {
  106. return this;
  107. }
  108. ////////////////////////////////////////////////////////////////////
  109. // Function: RenderEffect::output
  110. // Access: Published, Virtual
  111. // Description:
  112. ////////////////////////////////////////////////////////////////////
  113. void RenderEffect::
  114. output(ostream &out) const {
  115. out << get_type();
  116. }
  117. ////////////////////////////////////////////////////////////////////
  118. // Function: RenderEffect::write
  119. // Access: Published, Virtual
  120. // Description:
  121. ////////////////////////////////////////////////////////////////////
  122. void RenderEffect::
  123. write(ostream &out, int indent_level) const {
  124. indent(out, indent_level) << *this << "\n";
  125. }
  126. ////////////////////////////////////////////////////////////////////
  127. // Function: RenderEffect::return_new
  128. // Access: Protected, Static
  129. // Description: This function is used by derived RenderEffect types
  130. // to share a common RenderEffect pointer for all
  131. // equivalent RenderEffect objects.
  132. //
  133. // The make() function of the derived type should create
  134. // a new RenderEffect and pass it through return_new(),
  135. // which will either save the pointer and return it
  136. // unchanged (if this is the first similar such object)
  137. // or delete it and return an equivalent pointer (if
  138. // there was already a similar object saved).
  139. ////////////////////////////////////////////////////////////////////
  140. CPT(RenderEffect) RenderEffect::
  141. return_new(RenderEffect *effect) {
  142. nassertr(effect != (RenderEffect *)NULL, effect);
  143. // This should be a newly allocated pointer, not one that was used
  144. // for anything else.
  145. nassertr(effect->_saved_entry == _effects.end(), effect);
  146. // Save the effect in a local PointerTo so that it will be freed at
  147. // the end of this function if no one else uses it.
  148. CPT(RenderEffect) pt_effect = effect;
  149. pair<Effects::iterator, bool> result = _effects.insert(effect);
  150. if (result.second) {
  151. // The effect was inserted; save the iterator and return the
  152. // input effect.
  153. effect->_saved_entry = result.first;
  154. return pt_effect;
  155. }
  156. // The effect was not inserted; there must be an equivalent one
  157. // already in the set. Return that one.
  158. return *(result.first);
  159. }
  160. ////////////////////////////////////////////////////////////////////
  161. // Function: RenderEffect::compare_to_impl
  162. // Access: Protected, Virtual
  163. // Description: Intended to be overridden by derived RenderEffect
  164. // types to return a unique number indicating whether
  165. // this RenderEffect is equivalent to the other one.
  166. //
  167. // This should return 0 if the two RenderEffect objects
  168. // are equivalent, a number less than zero if this one
  169. // should be sorted before the other one, and a number
  170. // greater than zero otherwise.
  171. //
  172. // This will only be called with two RenderEffect
  173. // objects whose get_type() functions return the same.
  174. ////////////////////////////////////////////////////////////////////
  175. int RenderEffect::
  176. compare_to_impl(const RenderEffect *other) const {
  177. return 0;
  178. }
  179. ////////////////////////////////////////////////////////////////////
  180. // Function: RenderEffect::write_datagram
  181. // Access: Public, Virtual
  182. // Description: Writes the contents of this object to the datagram
  183. // for shipping out to a Bam file.
  184. ////////////////////////////////////////////////////////////////////
  185. void RenderEffect::
  186. write_datagram(BamWriter *manager, Datagram &dg) {
  187. TypedWritable::write_datagram(manager, dg);
  188. }
  189. ////////////////////////////////////////////////////////////////////
  190. // Function: RenderEffect::change_this
  191. // Access: Public, Static
  192. // Description: Called immediately after complete_pointers(), this
  193. // gives the object a chance to adjust its own pointer
  194. // if desired. Most objects don't change pointers after
  195. // completion, but some need to.
  196. //
  197. // Once this function has been called, the old pointer
  198. // will no longer be accessed.
  199. ////////////////////////////////////////////////////////////////////
  200. TypedWritable *RenderEffect::
  201. change_this(TypedWritable *old_ptr, BamReader *manager) {
  202. // First, uniquify the pointer.
  203. RenderEffect *effect = DCAST(RenderEffect, old_ptr);
  204. CPT(RenderEffect) pointer = return_new(effect);
  205. // But now we have a problem, since we have to hold the reference
  206. // count and there's no way to return a TypedWritable while still
  207. // holding the reference count! We work around this by explicitly
  208. // upping the count, and also setting a finalize() callback to down
  209. // it later.
  210. if (pointer == effect) {
  211. pointer->ref();
  212. manager->register_finalize(effect);
  213. }
  214. // We have to cast the pointer back to non-const, because the bam
  215. // reader expects that.
  216. return (RenderEffect *)pointer.p();
  217. }
  218. ////////////////////////////////////////////////////////////////////
  219. // Function: RenderEffect::finalize
  220. // Access: Public, Virtual
  221. // Description: Method to ensure that any necessary clean up tasks
  222. // that have to be performed by this object are performed
  223. ////////////////////////////////////////////////////////////////////
  224. void RenderEffect::
  225. finalize() {
  226. // Unref the pointer that we explicitly reffed in make_from_bam().
  227. unref();
  228. // We should never get back to zero after unreffing our own count,
  229. // because we expect to have been stored in a pointer somewhere. If
  230. // we do get to zero, it's a memory leak; the way to avoid this is
  231. // to call unref_delete() above instead of unref(), but this is
  232. // dangerous to do from within a virtual function.
  233. nassertv(get_ref_count() != 0);
  234. }
  235. ////////////////////////////////////////////////////////////////////
  236. // Function: RenderEffect::fillin
  237. // Access: Protected
  238. // Description: This internal function is called by make_from_bam to
  239. // read in all of the relevant data from the BamFile for
  240. // the new RenderEffect.
  241. ////////////////////////////////////////////////////////////////////
  242. void RenderEffect::
  243. fillin(DatagramIterator &scan, BamReader *manager) {
  244. TypedWritable::fillin(scan, manager);
  245. }