Panda3D
renderAttrib.cxx
1 // Filename: renderAttrib.cxx
2 // Created by: drose (21Feb02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "renderAttrib.h"
16 #include "bamReader.h"
17 #include "indent.h"
18 #include "config_pgraph.h"
19 #include "lightReMutexHolder.h"
20 #include "pStatTimer.h"
21 
22 LightReMutex *RenderAttrib::_attribs_lock = NULL;
23 RenderAttrib::Attribs *RenderAttrib::_attribs = NULL;
24 TypeHandle RenderAttrib::_type_handle;
25 
26 int RenderAttrib::_garbage_index = 0;
27 
28 PStatCollector RenderAttrib::_garbage_collect_pcollector("*:State Cache:Garbage Collect");
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: RenderAttrib::Constructor
32 // Access: Protected
33 // Description:
34 ////////////////////////////////////////////////////////////////////
35 RenderAttrib::
36 RenderAttrib() {
37  if (_attribs == (Attribs *)NULL) {
38  init_attribs();
39  }
40  _saved_entry = -1;
41 
42  _always_reissue = false;
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: RenderAttrib::Copy Constructor
47 // Access: Private
48 // Description: RenderAttribs are not meant to be copied.
49 ////////////////////////////////////////////////////////////////////
50 RenderAttrib::
51 RenderAttrib(const RenderAttrib &) {
52  nassertv(false);
53 }
54 
55 ////////////////////////////////////////////////////////////////////
56 // Function: RenderAttrib::Copy Assignment Operator
57 // Access: Private
58 // Description: RenderAttribs are not meant to be copied.
59 ////////////////////////////////////////////////////////////////////
60 void RenderAttrib::
61 operator = (const RenderAttrib &) {
62  nassertv(false);
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: RenderAttrib::Destructor
67 // Access: Public, Virtual
68 // Description: The destructor is responsible for removing the
69 // RenderAttrib from the global set if it is there.
70 ////////////////////////////////////////////////////////////////////
73  LightReMutexHolder holder(*_attribs_lock);
74 
75  // unref() should have cleared this.
76  nassertv(_saved_entry == -1);
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: RenderAttrib::lower_attrib_can_override
81 // Access: Public, Virtual
82 // Description: Intended to be overridden by derived RenderAttrib
83 // types to specify how two consecutive RenderAttrib
84 // objects of the same type interact.
85 //
86 // This should return false if a RenderAttrib on a
87 // higher node will compose into a RenderAttrib on a
88 // lower node that has a higher override value, or true
89 // if the lower RenderAttrib will completely replace the
90 // state.
91 //
92 // The default behavior is false: normally, a
93 // RenderAttrib in the graph cannot completely override
94 // a RenderAttrib above it, regardless of its override
95 // value--instead, the two attribs are composed. But
96 // for some kinds of RenderAttribs, it is useful to
97 // allow this kind of override.
98 //
99 // This method only handles the one special case of a
100 // lower RenderAttrib with a higher override value. If
101 // the higher RenderAttrib has a higher override value,
102 // it always completely overrides. And if both
103 // RenderAttribs have the same override value, they are
104 // always composed.
105 ////////////////////////////////////////////////////////////////////
106 bool RenderAttrib::
108  return false;
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: RenderAttrib::has_cull_callback
113 // Access: Public, Virtual
114 // Description: Should be overridden by derived classes to return
115 // true if cull_callback() has been defined. Otherwise,
116 // returns false to indicate cull_callback() does not
117 // need to be called for this node during the cull
118 // traversal.
119 ////////////////////////////////////////////////////////////////////
120 bool RenderAttrib::
122  return false;
123 }
124 
125 ////////////////////////////////////////////////////////////////////
126 // Function: RenderAttrib::cull_callback
127 // Access: Public, Virtual
128 // Description: If has_cull_callback() returns true, this function
129 // will be called during the cull traversal to perform
130 // any additional operations that should be performed at
131 // cull time.
132 //
133 // This is called each time the RenderAttrib is
134 // discovered applied to a Geom in the traversal. It
135 // should return true if the Geom is visible, false if
136 // it should be omitted.
137 ////////////////////////////////////////////////////////////////////
138 bool RenderAttrib::
140  return true;
141 }
142 
143 ////////////////////////////////////////////////////////////////////
144 // Function: RenderAttrib::get_auto_shader_attrib_impl
145 // Access: Protected, Virtual
146 // Description:
147 ////////////////////////////////////////////////////////////////////
148 CPT(RenderAttrib) RenderAttrib::
149 get_auto_shader_attrib_impl(const RenderState *state) const {
150  return NULL;
151 }
152 
153 ////////////////////////////////////////////////////////////////////
154 // Function: RenderAttrib::unref
155 // Access: Published, Virtual, Final
156 // Description: This method overrides ReferenceCount::unref() to
157 // clear the pointer from the global object pool when
158 // its reference count goes to zero.
159 ////////////////////////////////////////////////////////////////////
160 bool RenderAttrib::
161 unref() const {
162  if (!state_cache || garbage_collect_states) {
163  // If we're not using the cache at all, or if we're relying on
164  // garbage collection, just allow the pointer to unref normally.
165  return ReferenceCount::unref();
166  }
167 
168  // Here is the normal refcounting case, with a normal cache, and
169  // without garbage collection in effect. In this case we will pull
170  // the object out of the cache when its reference count goes to 0.
171 
172  // We always have to grab the lock, since we will definitely need to
173  // be holding it if we happen to drop the reference count to 0.
174  // Having to grab the lock at every call to unref() is a big
175  // limiting factor on parallelization.
176  LightReMutexHolder holder(*_attribs_lock);
177 
178  if (ReferenceCount::unref()) {
179  // The reference count is still nonzero.
180  return true;
181  }
182 
183  // The reference count has just reached zero. Make sure the object
184  // is removed from the global object pool, before anyone else finds
185  // it and tries to ref it.
186  ((RenderAttrib *)this)->release_new();
187 
188  return false;
189 }
190 
191 ////////////////////////////////////////////////////////////////////
192 // Function: RenderAttrib::output
193 // Access: Published, Virtual
194 // Description:
195 ////////////////////////////////////////////////////////////////////
196 void RenderAttrib::
197 output(ostream &out) const {
198  out << get_type();
199 }
200 
201 ////////////////////////////////////////////////////////////////////
202 // Function: RenderAttrib::write
203 // Access: Published, Virtual
204 // Description:
205 ////////////////////////////////////////////////////////////////////
206 void RenderAttrib::
207 write(ostream &out, int indent_level) const {
208  indent(out, indent_level) << *this << "\n";
209 }
210 
211 ////////////////////////////////////////////////////////////////////
212 // Function: RenderAttrib::get_num_attribs
213 // Access: Published, Static
214 // Description: Returns the total number of unique RenderAttrib
215 // objects allocated in the world. This will go up and
216 // down during normal operations.
217 ////////////////////////////////////////////////////////////////////
218 int RenderAttrib::
219 get_num_attribs() {
220  LightReMutexHolder holder(*_attribs_lock);
221 
222  if (_attribs == (Attribs *)NULL) {
223  return 0;
224  }
225  return _attribs->get_num_entries();
226 }
227 
228 ////////////////////////////////////////////////////////////////////
229 // Function: RenderAttrib::list_attribs
230 // Access: Published, Static
231 // Description: Lists all of the RenderAttribs in the cache to the
232 // output stream, one per line. This can be quite a lot
233 // of output if the cache is large, so be prepared.
234 ////////////////////////////////////////////////////////////////////
235 void RenderAttrib::
236 list_attribs(ostream &out) {
237  LightReMutexHolder holder(*_attribs_lock);
238 
239  out << _attribs->get_num_entries() << " attribs:\n";
240  int size = _attribs->get_size();
241  for (int si = 0; si < size; ++si) {
242  if (!_attribs->has_element(si)) {
243  continue;
244  }
245  const RenderAttrib *attrib = _attribs->get_key(si);
246  attrib->write(out, 2);
247  }
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: RenderAttrib::garbage_collect
252 // Access: Published, Static
253 // Description: Performs a garbage-collection cycle. This is called
254 // automatically from RenderState::garbage_collect();
255 // see that method for more information.
256 ////////////////////////////////////////////////////////////////////
257 int RenderAttrib::
259  if (_attribs == (Attribs *)NULL || !garbage_collect_states) {
260  return 0;
261  }
262  LightReMutexHolder holder(*_attribs_lock);
263 
264  PStatTimer timer(_garbage_collect_pcollector);
265  int orig_size = _attribs->get_num_entries();
266 
267  nassertr(_attribs->validate(), 0);
268 
269  // How many elements to process this pass?
270  int size = _attribs->get_size();
271  int num_this_pass = int(size * garbage_collect_states_rate);
272  if (num_this_pass <= 0) {
273  return 0;
274  }
275  num_this_pass = min(num_this_pass, size);
276  int stop_at_element = (_garbage_index + num_this_pass) % size;
277 
278  int num_elements = 0;
279  int si = _garbage_index;
280  do {
281  if (_attribs->has_element(si)) {
282  ++num_elements;
283  RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si);
284  if (attrib->get_ref_count() == 1) {
285  // This attrib has recently been unreffed to 1 (the one we
286  // added when we stored it in the cache). Now it's time to
287  // delete it. This is safe, because we're holding the
288  // _attribs_lock, so it's not possible for some other thread to
289  // find the attrib in the cache and ref it while we're doing
290  // this.
291  attrib->release_new();
292  unref_delete(attrib);
293  }
294  }
295 
296  si = (si + 1) % size;
297  } while (si != stop_at_element);
298  _garbage_index = si;
299  nassertr(_attribs->validate(), 0);
300 
301  int new_size = _attribs->get_num_entries();
302  return orig_size - new_size;
303 }
304 
305 ////////////////////////////////////////////////////////////////////
306 // Function: RenderAttrib::validate_attribs
307 // Access: Published, Static
308 // Description: Ensures that the cache is still stored in sorted
309 // order. Returns true if so, false if there is a
310 // problem (which implies someone has modified one of
311 // the supposedly-const RenderAttrib objects).
312 ////////////////////////////////////////////////////////////////////
313 bool RenderAttrib::
315  LightReMutexHolder holder(*_attribs_lock);
316  if (_attribs->is_empty()) {
317  return true;
318  }
319 
320  if (!_attribs->validate()) {
321  pgraph_cat.error()
322  << "RenderAttrib::_attribs cache is invalid!\n";
323 
324  int size = _attribs->get_size();
325  for (int si = 0; si < size; ++si) {
326  if (!_attribs->has_element(si)) {
327  continue;
328  }
329  const RenderAttrib *attrib = _attribs->get_key(si);
330  cerr << si << ": " << attrib << "\n";
331  attrib->write(cerr, 2);
332  }
333 
334  return false;
335  }
336 
337  int size = _attribs->get_size();
338  int si = 0;
339  while (si < size && !_attribs->has_element(si)) {
340  ++si;
341  }
342  nassertr(si < size, false);
343  nassertr(_attribs->get_key(si)->get_ref_count() >= 0, false);
344  int snext = si;
345  ++snext;
346  while (snext < size && !_attribs->has_element(snext)) {
347  ++snext;
348  }
349  while (snext < size) {
350  nassertr(_attribs->get_key(snext)->get_ref_count() >= 0, false);
351  const RenderAttrib *ssi = _attribs->get_key(si);
352  const RenderAttrib *ssnext = _attribs->get_key(snext);
353  int c = ssi->compare_to(*ssnext);
354  int ci = ssnext->compare_to(*ssi);
355  if ((ci < 0) != (c > 0) ||
356  (ci > 0) != (c < 0) ||
357  (ci == 0) != (c == 0)) {
358  pgraph_cat.error()
359  << "RenderAttrib::compare_to() not defined properly!\n";
360  pgraph_cat.error(false)
361  << "(a, b): " << c << "\n";
362  pgraph_cat.error(false)
363  << "(b, a): " << ci << "\n";
364  ssi->write(pgraph_cat.error(false), 2);
365  ssnext->write(pgraph_cat.error(false), 2);
366  return false;
367  }
368  si = snext;
369  ++snext;
370  while (snext < size && !_attribs->has_element(snext)) {
371  ++snext;
372  }
373  }
374 
375  return true;
376 }
377 
378 ////////////////////////////////////////////////////////////////////
379 // Function: RenderAttrib::return_new
380 // Access: Protected, Static
381 // Description: This function is used by derived RenderAttrib types
382 // to share a common RenderAttrib pointer for all
383 // equivalent RenderAttrib objects.
384 //
385 // This is different from return_unique() in that it
386 // does not actually guarantee a unique pointer, unless
387 // uniquify-attribs is set.
388 ////////////////////////////////////////////////////////////////////
389 CPT(RenderAttrib) RenderAttrib::
390 return_new(RenderAttrib *attrib) {
391  nassertr(attrib != (RenderAttrib *)NULL, attrib);
392  if (!uniquify_attribs) {
393  attrib->calc_hash();
394  return attrib;
395  }
396 
397  return return_unique(attrib);
398 }
399 
400 ////////////////////////////////////////////////////////////////////
401 // Function: RenderAttrib::return_unique
402 // Access: Protected, Static
403 // Description: This function is used by derived RenderAttrib types
404 // to share a common RenderAttrib pointer for all
405 // equivalent RenderAttrib objects.
406 //
407 // The make() function of the derived type should create
408 // a new RenderAttrib and pass it through return_new(),
409 // which will either save the pointer and return it
410 // unchanged (if this is the first similar such object)
411 // or delete it and return an equivalent pointer (if
412 // there was already a similar object saved).
413 ////////////////////////////////////////////////////////////////////
414 CPT(RenderAttrib) RenderAttrib::
415 return_unique(RenderAttrib *attrib) {
416  nassertr(attrib != (RenderAttrib *)NULL, attrib);
417 
418  attrib->calc_hash();
419 
420  if (!state_cache) {
421  return attrib;
422  }
423 
424 #ifndef NDEBUG
425  if (paranoid_const) {
426  nassertr(validate_attribs(), attrib);
427  }
428 #endif
429 
430  LightReMutexHolder holder(*_attribs_lock);
431 
432  if (attrib->_saved_entry != -1) {
433  // This attrib is already in the cache.
434  //nassertr(_attribs->find(attrib) == attrib->_saved_entry, attrib);
435  return attrib;
436  }
437 
438  // Save the attrib in a local PointerTo so that it will be freed at
439  // the end of this function if no one else uses it.
440  CPT(RenderAttrib) pt_attrib = attrib;
441 
442  int si = _attribs->find(attrib);
443  if (si != -1) {
444  // There's an equivalent attrib already in the set. Return it.
445  return _attribs->get_key(si);
446  }
447 
448  // Not already in the set; add it.
449  if (garbage_collect_states) {
450  // If we'll be garbage collecting attribs explicitly, we'll
451  // increment the reference count when we store it in the cache, so
452  // that it won't be deleted while it's in it.
453  attrib->ref();
454  }
455  si = _attribs->store(attrib, Empty());
456 
457  // Save the index and return the input attrib.
458  attrib->_saved_entry = si;
459  return pt_attrib;
460 }
461 
462 ////////////////////////////////////////////////////////////////////
463 // Function: RenderAttrib::compare_to_impl
464 // Access: Protected, Virtual
465 // Description: Intended to be overridden by derived RenderAttrib
466 // types to return a unique number indicating whether
467 // this RenderAttrib is equivalent to the other one.
468 //
469 // This should return 0 if the two RenderAttrib objects
470 // are equivalent, a number less than zero if this one
471 // should be sorted before the other one, and a number
472 // greater than zero otherwise.
473 //
474 // This will only be called with two RenderAttrib
475 // objects whose get_type() functions return the same.
476 ////////////////////////////////////////////////////////////////////
477 int RenderAttrib::
478 compare_to_impl(const RenderAttrib *other) const {
479  return 0;
480 }
481 
482 ////////////////////////////////////////////////////////////////////
483 // Function: RenderAttrib::get_hash_impl
484 // Access: Protected, Virtual
485 // Description: Intended to be overridden by derived RenderAttrib
486 // types to return a unique hash for these particular
487 // properties. RenderAttribs that compare the same with
488 // compare_to_impl(), above, should return the same
489 // hash; RenderAttribs that compare differently should
490 // return a different hash.
491 ////////////////////////////////////////////////////////////////////
492 size_t RenderAttrib::
493 get_hash_impl() const {
494  return 0;
495 }
496 
497 ////////////////////////////////////////////////////////////////////
498 // Function: RenderAttrib::compose_impl
499 // Access: Protected, Virtual
500 // Description: Intended to be overridden by derived RenderAttrib
501 // types to specify how two consecutive RenderAttrib
502 // objects of the same type interact.
503 //
504 // This should return the result of applying the other
505 // RenderAttrib to a node in the scene graph below this
506 // RenderAttrib, which was already applied. In most
507 // cases, the result is the same as the other
508 // RenderAttrib (that is, a subsequent RenderAttrib
509 // completely replaces the preceding one). On the other
510 // hand, some kinds of RenderAttrib (for instance,
511 // ColorTransformAttrib) might combine in meaningful
512 // ways.
513 ////////////////////////////////////////////////////////////////////
514 CPT(RenderAttrib) RenderAttrib::
515 compose_impl(const RenderAttrib *other) const {
516  return other;
517 }
518 
519 ////////////////////////////////////////////////////////////////////
520 // Function: RenderAttrib::invert_compose_impl
521 // Access: Protected, Virtual
522 // Description: Intended to be overridden by derived RenderAttrib
523 // types to specify how two consecutive RenderAttrib
524 // objects of the same type interact.
525 //
526 // See invert_compose() and compose_impl().
527 ////////////////////////////////////////////////////////////////////
528 CPT(RenderAttrib) RenderAttrib::
529 invert_compose_impl(const RenderAttrib *other) const {
530  return other;
531 }
532 
533 ////////////////////////////////////////////////////////////////////
534 // Function: RenderAttrib::output_comparefunc
535 // Access: Protected
536 // Description: Outputs a string representation of the given
537 // PandaCompareFunc object.
538 ////////////////////////////////////////////////////////////////////
539 void RenderAttrib::
540 output_comparefunc(ostream &out, PandaCompareFunc fn) const {
541  switch (fn) {
542  case M_none:
543  out << "none";
544  break;
545 
546  case M_never:
547  out << "never";
548  break;
549 
550  case M_less:
551  out << "less";
552  break;
553 
554  case M_equal:
555  out << "equal";
556  break;
557 
558  case M_less_equal:
559  out << "less_equal";
560  break;
561 
562  case M_greater:
563  out << "greater";
564  break;
565 
566  case M_not_equal:
567  out << "not_equal";
568  break;
569 
570  case M_greater_equal:
571  out << "greater_equal";
572  break;
573 
574  case M_always:
575  out << "always";
576  break;
577  }
578 }
579 
580 ////////////////////////////////////////////////////////////////////
581 // Function: RenderAttrib::release_new
582 // Access: Private
583 // Description: This inverse of return_new, this releases this object
584 // from the global RenderAttrib table.
585 //
586 // You must already be holding _attribs_lock before you
587 // call this method.
588 ////////////////////////////////////////////////////////////////////
589 void RenderAttrib::
590 release_new() {
591  nassertv(_attribs_lock->debug_is_locked());
592 
593  if (_saved_entry != -1) {
594  //nassertv(_attribs->find(this) == _saved_entry);
595  _saved_entry = _attribs->find(this);
596  _attribs->remove_element(_saved_entry);
597  _saved_entry = -1;
598  }
599 }
600 
601 ////////////////////////////////////////////////////////////////////
602 // Function: RenderAttrib::init_attribs
603 // Access: Public, Static
604 // Description: Make sure the global _attribs map is allocated. This
605 // only has to be done once. We could make this map
606 // static, but then we run into problems if anyone
607 // creates a RenderAttrib object at static init time;
608 // it also seems to cause problems when the Panda shared
609 // library is unloaded at application exit time.
610 ////////////////////////////////////////////////////////////////////
611 void RenderAttrib::
613  _attribs = new Attribs;
614 
615  // TODO: we should have a global Panda mutex to allow us to safely
616  // create _attribs_lock without a startup race condition. For the
617  // meantime, this is OK because we guarantee that this method is
618  // called at static init time, presumably when there is still only
619  // one thread in the world.
620  _attribs_lock = new LightReMutex("RenderAttrib::_attribs_lock");
622 }
623 
624 ////////////////////////////////////////////////////////////////////
625 // Function: RenderAttrib::write_datagram
626 // Access: Public, Virtual
627 // Description: Writes the contents of this object to the datagram
628 // for shipping out to a Bam file.
629 ////////////////////////////////////////////////////////////////////
630 void RenderAttrib::
632  TypedWritable::write_datagram(manager, dg);
633 }
634 
635 ////////////////////////////////////////////////////////////////////
636 // Function: RenderAttrib::change_this
637 // Access: Public, Static
638 // Description: Called immediately after complete_pointers(), this
639 // gives the object a chance to adjust its own pointer
640 // if desired. Most objects don't change pointers after
641 // completion, but some need to.
642 //
643 // Once this function has been called, the old pointer
644 // will no longer be accessed.
645 ////////////////////////////////////////////////////////////////////
647 change_this(TypedWritable *old_ptr, BamReader *manager) {
648  // First, uniquify the pointer.
649  RenderAttrib *attrib = DCAST(RenderAttrib, old_ptr);
650  CPT(RenderAttrib) pointer = return_unique(attrib);
651 
652  // But now we have a problem, since we have to hold the reference
653  // count and there's no way to return a TypedWritable while still
654  // holding the reference count! We work around this by explicitly
655  // upping the count, and also setting a finalize() callback to down
656  // it later.
657  if (pointer == attrib) {
658  pointer->ref();
659  manager->register_finalize(attrib);
660  }
661 
662  // We have to cast the pointer back to non-const, because the bam
663  // reader expects that.
664  return (RenderAttrib *)pointer.p();
665 }
666 
667 ////////////////////////////////////////////////////////////////////
668 // Function: RenderAttrib::finalize
669 // Access: Public, Virtual
670 // Description: Called by the BamReader to perform any final actions
671 // needed for setting up the object after all objects
672 // have been read and all pointers have been completed.
673 ////////////////////////////////////////////////////////////////////
674 void RenderAttrib::
676  // Unref the pointer that we explicitly reffed in change_this().
677  unref();
678 
679  // We should never get back to zero after unreffing our own count,
680  // because we expect to have been stored in a pointer somewhere. If
681  // we do get to zero, it's a memory leak; the way to avoid this is
682  // to call unref_delete() above instead of unref(), but this is
683  // dangerous to do from within a virtual function.
684  nassertv(get_ref_count() != 0);
685 }
686 
687 ////////////////////////////////////////////////////////////////////
688 // Function: RenderAttrib::fillin
689 // Access: Protected
690 // Description: This internal function is called by make_from_bam to
691 // read in all of the relevant data from the BamFile for
692 // the new RenderAttrib.
693 ////////////////////////////////////////////////////////////////////
694 void RenderAttrib::
695 fillin(DatagramIterator &scan, BamReader *manager) {
696  TypedWritable::fillin(scan, manager);
697  manager->register_change_this(change_this, this);
698 }
static void list_attribs(ostream &out)
Lists all of the RenderAttribs in the cache to the output stream, one per line.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
virtual bool unref() const FINAL
Explicitly decrements the reference count.
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined...
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
bool debug_is_locked() const
Returns true if the current thread has locked the LightReMutex, false otherwise.
A lightweight reentrant mutex.
Definition: lightReMutex.h:34
This collects together the pieces of data that are accumulated for each node while walking the scene ...
int store(const Key &key, const Value &data)
Records the indicated key/data pair in the map.
static void init_attribs()
Make sure the global _attribs map is allocated.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Definition: pStatTimer.h:34
This template class implements an unordered map of keys to data, implemented as a hashtable...
Definition: simpleHashMap.h:33
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
const Key & get_key(int n) const
Returns the key in the nth slot of the table.
static int garbage_collect()
Performs a garbage-collection cycle.
int get_num_entries() const
Returns the number of active entries in the table.
virtual ~RenderAttrib()
The destructor is responsible for removing the RenderAttrib from the global set if it is there...
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class&#39;s make_from_bam() method to read in all...
void register_change_this(ChangeThisFunc func, TypedWritable *whom)
Called by an object reading itself from the bam file to indicate that the object pointer that will be...
Definition: bamReader.cxx:917
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static Thread * get_main_thread()
Returns a pointer to the "main" Thread object–this is the Thread that started the whole process...
Definition: thread.I:107
A lightweight class that represents a single element that may be timed and/or counted via stats...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool has_element(int n) const
Returns true if there is an element stored in the nth slot, false otherwise.
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
Definition: bamReader.cxx:886
bool validate() const
Returns true if the internal table appears to be consistent, false if there are some internal errors...
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const
If has_cull_callback() returns true, this function will be called during the cull traversal to perfor...
Similar to MutexHolder, but for a light reentrant mutex.
void ref() const
Explicitly increments the reference count.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
int get_ref_count() const
Returns the current reference count.
static TypedWritable * change_this(TypedWritable *old_ptr, BamReader *manager)
Called immediately after complete_pointers(), this gives the object a chance to adjust its own pointe...
static bool validate_attribs()
Ensures that the cache is still stored in sorted order.
bool is_empty() const
Returns true if the table is empty; i.e.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
virtual bool lower_attrib_can_override() const
Intended to be overridden by derived RenderAttrib types to specify how two consecutive RenderAttrib o...
void remove_element(int n)
Removes the nth slot from the table.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
int get_size() const
Returns the total number of slots in the table.
virtual bool unref() const
Explicitly decrements the reference count.
int find(const Key &key) const
Searches for the indicated key in the table.
Definition: simpleHashMap.I:78