Panda3D
 All Classes Functions Variables Enumerations
materialPool.cxx
1 // Filename: materialPool.cxx
2 // Created by: drose (30Apr01)
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 "materialPool.h"
16 #include "config_gobj.h"
17 #include "lightMutexHolder.h"
18 
19 MaterialPool *MaterialPool::_global_ptr = (MaterialPool *)NULL;
20 
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: MaterialPool::write
24 // Access: Published, Static
25 // Description: Lists the contents of the material pool to the
26 // indicated output stream.
27 ////////////////////////////////////////////////////////////////////
28 void MaterialPool::
29 write(ostream &out) {
30  get_global_ptr()->ns_list_contents(out);
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: MaterialPool::ns_get_material
35 // Access: Public
36 // Description: The nonstatic implementation of get_material().
37 ////////////////////////////////////////////////////////////////////
38 Material *MaterialPool::
39 ns_get_material(Material *temp) {
40  LightMutexHolder holder(_lock);
41 
42  CPT(Material) cpttemp = temp;
43  Materials::iterator mi = _materials.find(cpttemp);
44  if (mi == _materials.end()) {
45  mi = _materials.insert(Materials::value_type(new Material(*temp), temp)).first;
46  } else {
47  if (*(*mi).first != *(*mi).second) {
48  // The pointer no longer matches its original value. Save a new
49  // one.
50  (*mi).second = temp;
51  }
52  }
53  return (*mi).second;
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: MaterialPool::ns_release_material
58 // Access: Private
59 // Description: The nonstatic implementation of release_material().
60 ////////////////////////////////////////////////////////////////////
61 void MaterialPool::
62 ns_release_material(Material *temp) {
63  LightMutexHolder holder(_lock);
64 
65  CPT(Material) cpttemp = temp;
66  _materials.erase(cpttemp);
67 }
68 
69 ////////////////////////////////////////////////////////////////////
70 // Function: MaterialPool::ns_release_all_materials
71 // Access: Private
72 // Description: The nonstatic implementation of release_all_materials().
73 ////////////////////////////////////////////////////////////////////
74 void MaterialPool::
75 ns_release_all_materials() {
76  LightMutexHolder holder(_lock);
77 
78  _materials.clear();
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: MaterialPool::ns_garbage_collect
83 // Access: Private
84 // Description: The nonstatic implementation of garbage_collect().
85 ////////////////////////////////////////////////////////////////////
86 int MaterialPool::
87 ns_garbage_collect() {
88  LightMutexHolder holder(_lock);
89 
90  int num_released = 0;
91  Materials new_set;
92 
93  Materials::iterator mi;
94  for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
95  const Material *mat1 = (*mi).first;
96  Material *mat2 = (*mi).second;
97  if ((*mat1) != (*mat2) || mat2->get_ref_count() == 1) {
98  if (gobj_cat.is_debug()) {
99  gobj_cat.debug()
100  << "Releasing " << *mat1 << "\n";
101  }
102  ++num_released;
103  } else {
104  new_set.insert(new_set.end(), *mi);
105  }
106  }
107 
108  _materials.swap(new_set);
109  return num_released;
110 }
111 
112 ////////////////////////////////////////////////////////////////////
113 // Function: MaterialPool::ns_list_contents
114 // Access: Private
115 // Description: The nonstatic implementation of list_contents().
116 ////////////////////////////////////////////////////////////////////
117 void MaterialPool::
118 ns_list_contents(ostream &out) const {
119  LightMutexHolder holder(_lock);
120 
121  out << _materials.size() << " materials:\n";
122  Materials::const_iterator mi;
123  for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
124  const Material *mat1 = (*mi).first;
125  Material *mat2 = (*mi).second;
126  out << " " << *mat1
127  << " (count = " << mat2->get_ref_count() << ")\n";
128  }
129 }
130 
131 ////////////////////////////////////////////////////////////////////
132 // Function: MaterialPool::get_global_ptr
133 // Access: Private, Static
134 // Description: Initializes and/or returns the global pointer to the
135 // one MaterialPool object in the system.
136 ////////////////////////////////////////////////////////////////////
137 MaterialPool *MaterialPool::
138 get_global_ptr() {
139  if (_global_ptr == (MaterialPool *)NULL) {
140  _global_ptr = new MaterialPool;
141  }
142  return _global_ptr;
143 }
The MaterialPool (there is only one in the universe) serves to unify different pointers to the same M...
Definition: materialPool.h:42
Similar to MutexHolder, but for a light mutex.
Defines the way an object appears in the presence of lighting.
Definition: material.h:34
static void write(ostream &out)
Lists the contents of the material pool to the indicated output stream.
int get_ref_count() const
Returns the current reference count.