Panda3D
paletteGroups.cxx
1 // Filename: paletteGroups.cxx
2 // Created by: drose (30Nov00)
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 "paletteGroups.h"
16 #include "paletteGroup.h"
17 
18 #include "indent.h"
19 #include "datagram.h"
20 #include "datagramIterator.h"
21 #include "bamReader.h"
22 #include "bamWriter.h"
23 #include "indirectCompareNames.h"
24 #include "pvector.h"
25 
26 TypeHandle PaletteGroups::_type_handle;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: PaletteGroups::Constructor
30 // Access: Public
31 // Description:
32 ////////////////////////////////////////////////////////////////////
33 PaletteGroups::
34 PaletteGroups() {
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: PaletteGroups::Copy Constructor
39 // Access: Public
40 // Description:
41 ////////////////////////////////////////////////////////////////////
42 PaletteGroups::
43 PaletteGroups(const PaletteGroups &copy) :
44  _groups(copy._groups)
45 {
46 }
47 
48 ////////////////////////////////////////////////////////////////////
49 // Function: PaletteGroups::operator =
50 // Access: Public
51 // Description:
52 ////////////////////////////////////////////////////////////////////
53 void PaletteGroups::
54 operator = (const PaletteGroups &copy) {
55  _groups = copy._groups;
56 }
57 
58 ////////////////////////////////////////////////////////////////////
59 // Function: PaletteGroups::insert
60 // Access: Public
61 // Description: Inserts a new group to the set, if it is not already
62 // there.
63 ////////////////////////////////////////////////////////////////////
64 void PaletteGroups::
66  _groups.insert(group);
67 }
68 
69 ////////////////////////////////////////////////////////////////////
70 // Function: PaletteGroups::count
71 // Access: Public
72 // Description: Returns the number of times the given group appears
73 // in the set. This is either 1 if it appears at all,
74 // or 0 if it does not appear.
75 ////////////////////////////////////////////////////////////////////
76 PaletteGroups::size_type PaletteGroups::
77 count(PaletteGroup *group) const {
78  return _groups.count(group);
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: PaletteGroups::make_complete
83 // Access: Public
84 // Description: Completes the set with the transitive closure of all
85 // dependencies: for each PaletteGroup already in the
86 // set a, all of the groups that it depends on are added
87 // to the set, and so on. The indicated set a may be
88 // the same as this set.
89 ////////////////////////////////////////////////////////////////////
90 void PaletteGroups::
92  Groups result;
93 
94  Groups::const_iterator gi;
95  for (gi = a._groups.begin(); gi != a._groups.end(); ++gi) {
96  r_make_complete(result, *gi);
97  }
98 
99  _groups.swap(result);
100 }
101 
102 ////////////////////////////////////////////////////////////////////
103 // Function: PaletteGroups::make_union
104 // Access: Public
105 // Description: Computes the union of PaletteGroups a and b, and
106 // stores the result in this object. The result may be
107 // the same object as either a or b.
108 ////////////////////////////////////////////////////////////////////
109 void PaletteGroups::
111  Groups u;
112 
113  Groups::const_iterator ai, bi;
114  ai = a._groups.begin();
115  bi = b._groups.begin();
116 
117  while (ai != a._groups.end() && bi != b._groups.end()) {
118  if ((*ai) < (*bi)) {
119  u.insert(u.end(), *ai);
120  ++ai;
121 
122  } else if ((*bi) < (*ai)) {
123  u.insert(u.end(), *bi);
124  ++bi;
125 
126  } else { // (*ai) == (*bi)
127  u.insert(u.end(), *ai);
128  ++ai;
129  ++bi;
130  }
131  }
132 
133  while (ai != a._groups.end()) {
134  u.insert(u.end(), *ai);
135  ++ai;
136  }
137 
138  while (bi != b._groups.end()) {
139  u.insert(u.end(), *bi);
140  ++bi;
141  }
142 
143  _groups.swap(u);
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: PaletteGroups::make_intersection
148 // Access: Public
149 // Description: Computes the intersection of PaletteGroups a and b,
150 // and stores the result in this object. The result may
151 // be the same object as either a or b.
152 ////////////////////////////////////////////////////////////////////
153 void PaletteGroups::
155  Groups i;
156 
157  Groups::const_iterator ai, bi;
158  ai = a._groups.begin();
159  bi = b._groups.begin();
160 
161  while (ai != a._groups.end() && bi != b._groups.end()) {
162  if ((*ai) < (*bi)) {
163  ++ai;
164 
165  } else if ((*bi) < (*ai)) {
166  ++bi;
167 
168  } else { // (*ai) == (*bi)
169  i.insert(i.end(), *ai);
170  ++ai;
171  ++bi;
172  }
173  }
174 
175  _groups.swap(i);
176 }
177 
178 ////////////////////////////////////////////////////////////////////
179 // Function: PaletteGroups::remove_null
180 // Access: Public
181 // Description: Removes the special "null" group from the set. This
182 // is a special group that egg files may be assigned to,
183 // but which textures never are; it indicates that the
184 // egg file should not influence the palette assignment.
185 ////////////////////////////////////////////////////////////////////
186 void PaletteGroups::
188  Groups::iterator gi;
189  for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
190  if ((*gi)->get_name() == "null") {
191  _groups.erase(gi);
192  return;
193  }
194  }
195 }
196 
197 ////////////////////////////////////////////////////////////////////
198 // Function: PaletteGroups::clear
199 // Access: Public
200 // Description: Empties the set.
201 ////////////////////////////////////////////////////////////////////
202 void PaletteGroups::
203 clear() {
204  _groups.clear();
205 }
206 
207 ////////////////////////////////////////////////////////////////////
208 // Function: PaletteGroups::empty
209 // Access: Public
210 // Description: Returns true if the set is empty, false otherwise.
211 ////////////////////////////////////////////////////////////////////
212 bool PaletteGroups::
213 empty() const {
214  return _groups.empty();
215 }
216 
217 ////////////////////////////////////////////////////////////////////
218 // Function: PaletteGroups::size
219 // Access: Public
220 // Description: Returns the number of elements in the set.
221 ////////////////////////////////////////////////////////////////////
222 PaletteGroups::size_type PaletteGroups::
223 size() const {
224  return _groups.size();
225 }
226 
227 ////////////////////////////////////////////////////////////////////
228 // Function: PaletteGroups::begin
229 // Access: Public
230 // Description: Returns an iterator suitable for traversing the set.
231 ////////////////////////////////////////////////////////////////////
232 PaletteGroups::iterator PaletteGroups::
233 begin() const {
234  return _groups.begin();
235 }
236 
237 ////////////////////////////////////////////////////////////////////
238 // Function: PaletteGroups::end
239 // Access: Public
240 // Description: Returns an iterator suitable for traversing the set.
241 ////////////////////////////////////////////////////////////////////
242 PaletteGroups::iterator PaletteGroups::
243 end() const {
244  return _groups.end();
245 }
246 
247 ////////////////////////////////////////////////////////////////////
248 // Function: PaletteGroups::output
249 // Access: Public
250 // Description:
251 ////////////////////////////////////////////////////////////////////
252 void PaletteGroups::
253 output(ostream &out) const {
254  if (!_groups.empty()) {
255  // Sort the group names into order by name for output.
256  pvector<PaletteGroup *> group_vector;
257  group_vector.reserve(_groups.size());
258  Groups::const_iterator gi;
259  for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
260  group_vector.push_back(*gi);
261  }
262  sort(group_vector.begin(), group_vector.end(),
264 
265  pvector<PaletteGroup *>::const_iterator gvi = group_vector.begin();
266  out << (*gvi)->get_name();
267  ++gvi;
268  while (gvi != group_vector.end()) {
269  out << " " << (*gvi)->get_name();
270  ++gvi;
271  }
272  }
273 }
274 
275 ////////////////////////////////////////////////////////////////////
276 // Function: PaletteGroups::write
277 // Access: Public
278 // Description:
279 ////////////////////////////////////////////////////////////////////
280 void PaletteGroups::
281 write(ostream &out, int indent_level) const {
282  // Sort the group names into order by name for output.
283  pvector<PaletteGroup *> group_vector;
284  group_vector.reserve(_groups.size());
285  Groups::const_iterator gi;
286  for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
287  group_vector.push_back(*gi);
288  }
289  sort(group_vector.begin(), group_vector.end(),
291 
293  for (gvi = group_vector.begin(); gvi != group_vector.end(); ++gvi) {
294  indent(out, indent_level) << (*gvi)->get_name() << "\n";
295  }
296 }
297 
298 ////////////////////////////////////////////////////////////////////
299 // Function: PaletteGroups::r_make_complete
300 // Access: Private
301 // Description: The recursive implementation of make_complete(), this
302 // adds the indicated group and all of its dependencies
303 // to the set.
304 ////////////////////////////////////////////////////////////////////
305 void PaletteGroups::
306 r_make_complete(PaletteGroups::Groups &result, PaletteGroup *group) {
307  bool inserted = result.insert(group).second;
308 
309  if (inserted) {
310  Groups::const_iterator gi;
311  for (gi = group->_dependent._groups.begin();
312  gi != group->_dependent._groups.end();
313  ++gi) {
314  r_make_complete(result, *gi);
315  }
316  }
317 }
318 
319 ////////////////////////////////////////////////////////////////////
320 // Function: PaletteGroups::register_with_read_factory
321 // Access: Public, Static
322 // Description: Registers the current object as something that can be
323 // read from a Bam file.
324 ////////////////////////////////////////////////////////////////////
325 void PaletteGroups::
328  register_factory(get_class_type(), make_PaletteGroups);
329 }
330 
331 ////////////////////////////////////////////////////////////////////
332 // Function: PaletteGroups::write_datagram
333 // Access: Public, Virtual
334 // Description: Fills the indicated datagram up with a binary
335 // representation of the current object, in preparation
336 // for writing to a Bam file.
337 ////////////////////////////////////////////////////////////////////
338 void PaletteGroups::
339 write_datagram(BamWriter *writer, Datagram &datagram) {
340  TypedWritable::write_datagram(writer, datagram);
341  datagram.add_uint32(_groups.size());
342 
343  Groups::const_iterator gi;
344  for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
345  writer->write_pointer(datagram, *gi);
346  }
347 }
348 
349 ////////////////////////////////////////////////////////////////////
350 // Function: PaletteGroups::complete_pointers
351 // Access: Public, Virtual
352 // Description: Called after the object is otherwise completely read
353 // from a Bam file, this function's job is to store the
354 // pointers that were retrieved from the Bam file for
355 // each pointer object written. The return value is the
356 // number of pointers processed from the list.
357 ////////////////////////////////////////////////////////////////////
358 int PaletteGroups::
360  int pi = TypedWritable::complete_pointers(p_list, manager);
361  for (int i = 0; i < _num_groups; i++) {
362  PaletteGroup *group;
363  DCAST_INTO_R(group, p_list[pi++], i);
364  _groups.insert(group);
365  }
366  return pi;
367 }
368 
369 ////////////////////////////////////////////////////////////////////
370 // Function: PaletteGroups::make_PaletteGroups
371 // Access: Protected
372 // Description: This method is called by the BamReader when an object
373 // of this type is encountered in a Bam file; it should
374 // allocate and return a new object with all the data
375 // read.
376 ////////////////////////////////////////////////////////////////////
377 TypedWritable* PaletteGroups::
378 make_PaletteGroups(const FactoryParams &params) {
379  PaletteGroups *me = new PaletteGroups;
380  DatagramIterator scan;
381  BamReader *manager;
382 
383  parse_params(params, scan, manager);
384  me->fillin(scan, manager);
385  return me;
386 }
387 
388 ////////////////////////////////////////////////////////////////////
389 // Function: PaletteGroups::fillin
390 // Access: Protected
391 // Description: Reads the binary data from the given datagram
392 // iterator, which was written by a previous call to
393 // write_datagram().
394 ////////////////////////////////////////////////////////////////////
395 void PaletteGroups::
397  TypedWritable::fillin(scan, manager);
398  _num_groups = scan.get_int32();
399  manager->read_pointers(scan, _num_groups);
400 }
void make_intersection(const PaletteGroups &a, const PaletteGroups &b)
Computes the intersection of PaletteGroups a and b, and stores the result in this object...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function&#39;s job is to store...
iterator end() const
Returns an iterator suitable for traversing the set.
void remove_null()
Removes the special "null" group from the set.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object, in preparation for writing to a Bam file.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
iterator begin() const
Returns an iterator suitable for traversing the set.
size_type count(PaletteGroup *group) const
Returns the number of times the given group appears in the set.
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:47
size_type size() const
Returns the number of elements in the set.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
void clear()
Empties the set.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
PN_int32 get_int32()
Extracts a signed 32-bit integer.
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...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:700
An STL function object class, this is intended to be used on any ordered collection of pointers to cl...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
bool empty() const
Returns true if the set is empty, false otherwise.
void make_complete(const PaletteGroups &a)
Completes the set with the transitive closure of all dependencies: for each PaletteGroup already in t...
void make_union(const PaletteGroups &a, const PaletteGroups &b)
Computes the union of PaletteGroups a and b, and stores the result in this object.
void insert(PaletteGroup *group)
Inserts a new group to the set, if it is not already there.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:192
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
A set of PaletteGroups.
Definition: paletteGroups.h:31
This is our own Panda specialization on the default STL set.
Definition: pset.h:52
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
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279