panda3d/pandatool/src/palettizer/paletteGroups.cxx
2003-09-12 22:37:52 +00:00

365 lines
12 KiB
C++

// Filename: paletteGroups.cxx
// Created by: drose (30Nov00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "paletteGroups.h"
#include "paletteGroup.h"
#include "indent.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "indirectCompareNames.h"
#include "pvector.h"
TypeHandle PaletteGroups::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PaletteGroups::
PaletteGroups() {
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::insert
// Access: Public
// Description: Inserts a new group to the set, if it is not already
// there.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
insert(PaletteGroup *group) {
_groups.insert(group);
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::count
// Access: Public
// Description: Returns the number of times the given group appears
// in the set. This is either 1 if it appears at all,
// or 0 if it does not appear.
////////////////////////////////////////////////////////////////////
PaletteGroups::size_type PaletteGroups::
count(PaletteGroup *group) const {
return _groups.count(group);
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::make_complete
// Access: Public
// Description: Completes the set with the transitive closure of all
// dependencies: for each PaletteGroup already in the
// set a, all of the groups that it depends on are added
// to the set, and so on. The indicated set a may be
// the same as this set.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
make_complete(const PaletteGroups &a) {
Groups result;
Groups::const_iterator gi;
for (gi = a._groups.begin(); gi != a._groups.end(); ++gi) {
r_make_complete(result, *gi);
}
_groups.swap(result);
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::make_union
// Access: Public
// Description: Computes the union of PaletteGroups a and b, and
// stores the result in this object. The result may be
// the same object as either a or b.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
make_union(const PaletteGroups &a, const PaletteGroups &b) {
Groups u;
Groups::const_iterator ai, bi;
ai = a._groups.begin();
bi = b._groups.begin();
while (ai != a._groups.end() && bi != b._groups.end()) {
if ((*ai) < (*bi)) {
u.insert(u.end(), *ai);
++ai;
} else if ((*bi) < (*ai)) {
u.insert(u.end(), *bi);
++bi;
} else { // (*ai) == (*bi)
u.insert(u.end(), *ai);
++ai;
++bi;
}
}
while (ai != a._groups.end()) {
u.insert(u.end(), *ai);
++ai;
}
while (bi != b._groups.end()) {
u.insert(u.end(), *bi);
++bi;
}
_groups.swap(u);
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::make_intersection
// Access: Public
// Description: Computes the intersection of PaletteGroups a and b,
// and stores the result in this object. The result may
// be the same object as either a or b.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
make_intersection(const PaletteGroups &a, const PaletteGroups &b) {
Groups i;
Groups::const_iterator ai, bi;
ai = a._groups.begin();
bi = b._groups.begin();
while (ai != a._groups.end() && bi != b._groups.end()) {
if ((*ai) < (*bi)) {
++ai;
} else if ((*bi) < (*ai)) {
++bi;
} else { // (*ai) == (*bi)
i.insert(i.end(), *ai);
++ai;
++bi;
}
}
_groups.swap(i);
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::clear
// Access: Public
// Description: Empties the set.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
clear() {
_groups.clear();
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::empty
// Access: Public
// Description: Returns true if the set is empty, false otherwise.
////////////////////////////////////////////////////////////////////
bool PaletteGroups::
empty() const {
return _groups.empty();
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::size
// Access: Public
// Description: Returns the number of elements in the set.
////////////////////////////////////////////////////////////////////
PaletteGroups::size_type PaletteGroups::
size() const {
return _groups.size();
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::begin
// Access: Public
// Description: Returns an iterator suitable for traversing the set.
////////////////////////////////////////////////////////////////////
PaletteGroups::iterator PaletteGroups::
begin() const {
return _groups.begin();
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::end
// Access: Public
// Description: Returns an iterator suitable for traversing the set.
////////////////////////////////////////////////////////////////////
PaletteGroups::iterator PaletteGroups::
end() const {
return _groups.end();
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PaletteGroups::
output(ostream &out) const {
if (!_groups.empty()) {
// Sort the group names into order by name for output.
pvector<PaletteGroup *> group_vector;
group_vector.reserve(_groups.size());
Groups::const_iterator gi;
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
group_vector.push_back(*gi);
}
sort(group_vector.begin(), group_vector.end(),
IndirectCompareNames<PaletteGroup>());
pvector<PaletteGroup *>::const_iterator gvi = group_vector.begin();
out << (*gvi)->get_name();
++gvi;
while (gvi != group_vector.end()) {
out << " " << (*gvi)->get_name();
++gvi;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::write
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void PaletteGroups::
write(ostream &out, int indent_level) const {
// Sort the group names into order by name for output.
pvector<PaletteGroup *> group_vector;
group_vector.reserve(_groups.size());
Groups::const_iterator gi;
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
group_vector.push_back(*gi);
}
sort(group_vector.begin(), group_vector.end(),
IndirectCompareNames<PaletteGroup>());
pvector<PaletteGroup *>::const_iterator gvi;
for (gvi = group_vector.begin(); gvi != group_vector.end(); ++gvi) {
indent(out, indent_level) << (*gvi)->get_name() << "\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::r_make_complete
// Access: Private
// Description: The recursive implementation of make_complete(), this
// adds the indicated group and all of its dependencies
// to the set.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
r_make_complete(PaletteGroups::Groups &result, PaletteGroup *group) {
bool inserted = result.insert(group).second;
if (inserted) {
Groups::const_iterator gi;
for (gi = group->_dependent._groups.begin();
gi != group->_dependent._groups.end();
++gi) {
r_make_complete(result, *gi);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::register_with_read_factory
// Access: Public, Static
// Description: Registers the current object as something that can be
// read from a Bam file.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
register_with_read_factory() {
BamReader::get_factory()->
register_factory(get_class_type(), make_PaletteGroups);
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::write_datagram
// Access: Public, Virtual
// Description: Fills the indicated datagram up with a binary
// representation of the current object, in preparation
// for writing to a Bam file.
////////////////////////////////////////////////////////////////////
void PaletteGroups::
write_datagram(BamWriter *writer, Datagram &datagram) {
TypedWritable::write_datagram(writer, datagram);
datagram.add_uint32(_groups.size());
Groups::const_iterator gi;
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
writer->write_pointer(datagram, *gi);
}
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::complete_pointers
// Access: Public, Virtual
// Description: Called after the object is otherwise completely read
// from a Bam file, this function's job is to store the
// pointers that were retrieved from the Bam file for
// each pointer object written. The return value is the
// number of pointers processed from the list.
////////////////////////////////////////////////////////////////////
int PaletteGroups::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = TypedWritable::complete_pointers(p_list, manager);
for (int i = 0; i < _num_groups; i++) {
PaletteGroup *group;
DCAST_INTO_R(group, p_list[pi++], i);
_groups.insert(group);
}
return pi;
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::make_PaletteGroups
// Access: Protected
// Description: This method is called by the BamReader when an object
// of this type is encountered in a Bam file; it should
// allocate and return a new object with all the data
// read.
////////////////////////////////////////////////////////////////////
TypedWritable* PaletteGroups::
make_PaletteGroups(const FactoryParams &params) {
PaletteGroups *me = new PaletteGroups;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
me->fillin(scan, manager);
return me;
}
////////////////////////////////////////////////////////////////////
// Function: PaletteGroups::fillin
// Access: Protected
// Description: Reads the binary data from the given datagram
// iterator, which was written by a previous call to
// write_datagram().
////////////////////////////////////////////////////////////////////
void PaletteGroups::
fillin(DatagramIterator &scan, BamReader *manager) {
TypedWritable::fillin(scan, manager);
_num_groups = scan.get_int32();
manager->read_pointers(scan, _num_groups);
}