open_toontown_panda3d/direct/src/dcparser/dcNumericRange.I

331 lines
11 KiB
Plaintext

// Filename: dcNumericRange.I
// Created by: drose (21Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE DCNumericRange<NUM>::
DCNumericRange() {
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE DCNumericRange<NUM>::
DCNumericRange(Number min, Number max) {
add_range(min, max);
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE DCNumericRange<NUM>::
DCNumericRange(const DCNumericRange<NUM> &copy) :
_ranges(copy._ranges)
{
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
operator = (const DCNumericRange<NUM> &copy) {
_ranges = copy._ranges;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::is_in_range
// Access: Public
// Description: Returns true if the indicated number is within the
// specified range, false otherwise.
////////////////////////////////////////////////////////////////////
template <class NUM>
bool DCNumericRange<NUM>::
is_in_range(Number num) const {
if (_ranges.empty()) {
return true;
}
TYPENAME Ranges::const_iterator ri;
for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
if (num >= (*ri)._min && num <= (*ri)._max) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::validate
// Access: Public
// Description: Convenience function to validate the indicated
// number. If the number is within the specified range,
// does nothing; otherwise, if it is outside the range,
// sets range_error to true.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
validate(Number num, bool &range_error) const {
if (!is_in_range(num)) {
range_error = true;
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::has_one_value
// Access: Public
// Description: Returns true if the numeric range specifies exactly
// one legal value, false if multiple values are legal.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE bool DCNumericRange<NUM>::
has_one_value() const {
return _ranges.size() == 1 && _ranges[0]._min == _ranges[0]._max;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_one_value
// Access: Public
// Description: If has_one_value() returns true, this returns the one
// legal value accepted by the numeric range.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
get_one_value() const {
nassertr(has_one_value(), 0);
return _ranges[0]._min;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::generate_hash
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
void DCNumericRange<NUM>::
generate_hash(HashGenerator &hashgen) const {
if (!_ranges.empty()) {
hashgen.add_int(_ranges.size());
TYPENAME Ranges::const_iterator ri;
for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
// We don't account for the fractional part of floating-point
// ranges here. Shouldn't be a real issue.
hashgen.add_int((int)(*ri)._min);
hashgen.add_int((int)(*ri)._max);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
void DCNumericRange<NUM>::
output(ostream &out, Number divisor) const {
if (!_ranges.empty()) {
TYPENAME Ranges::const_iterator ri;
ri = _ranges.begin();
output_minmax(out, divisor, *ri);
++ri;
while (ri != _ranges.end()) {
out << ", ";
output_minmax(out, divisor, *ri);
++ri;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::output_char
// Access: Public
// Description: Outputs the range, formatting the numeric values as
// quoted ASCII characters.
////////////////////////////////////////////////////////////////////
template <class NUM>
void DCNumericRange<NUM>::
output_char(ostream &out, Number divisor) const {
if (divisor != 1) {
output(out, divisor);
} else {
if (!_ranges.empty()) {
TYPENAME Ranges::const_iterator ri;
ri = _ranges.begin();
output_minmax_char(out, *ri);
++ri;
while (ri != _ranges.end()) {
out << ", ";
output_minmax_char(out, *ri);
++ri;
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::clear
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
clear() {
_ranges.clear();
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::add_range
// Access: Public
// Description: Adds a new minmax to the list of ranges. This is
// normally called only during dc file parsing. Returns
// true if successful, or false if the new minmax
// overlaps an existing minmax.
////////////////////////////////////////////////////////////////////
template <class NUM>
bool DCNumericRange<NUM>::
add_range(Number min, Number max) {
// Check for an overlap. This is probably indicative of a typo and
// should be reported.
if (max < min) {
return false;
}
TYPENAME Ranges::const_iterator ri;
for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
if ((min >= (*ri)._min && min <= (*ri)._max) ||
(max >= (*ri)._min && max <= (*ri)._max) ||
(min < (*ri)._min && max > (*ri)._max)) {
return false;
}
}
MinMax minmax;
minmax._min = min;
minmax._max = max;
_ranges.push_back(minmax);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::is_empty
// Access: Private
// Description: Returns true if the range contains no elements (and
// thus allows all numbers), false if it contains at
// least one.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE bool DCNumericRange<NUM>::
is_empty() const {
return _ranges.empty();
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_num_ranges
// Access: Private
// Description: Returns the number of minmax components in the range
// description.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE int DCNumericRange<NUM>::
get_num_ranges() const {
return _ranges.size();
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_min
// Access: Private
// Description: Returns the minimum value defined by the nth component.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
get_min(int n) const {
nassertr(n >= 0 && n < (int)_ranges.size(), 0);
return _ranges[n]._min;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::get_max
// Access: Private
// Description: Returns the maximum value defined by the nth component.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
get_max(int n) const {
nassertr(n >= 0 && n < (int)_ranges.size(), 0);
return _ranges[n]._max;
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::output_minmax
// Access: Private
// Description: Outputs a single element of the range description.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
output_minmax(ostream &out, Number divisor, const MinMax &range) const {
if (divisor == 1) {
if (range._min == range._max) {
out << range._min;
} else {
out << range._min << "-" << range._max;
}
} else {
if (range._min == range._max) {
out << (double)range._min / (double)divisor;
} else {
out << (double)range._min / (double)divisor
<< "-"
<< (double)range._max / (double)divisor;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::output_minmax_char
// Access: Private
// Description: Outputs a single element of the range description.
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE void DCNumericRange<NUM>::
output_minmax_char(ostream &out, const MinMax &range) const {
if (range._min == range._max) {
DCPacker::enquote_string(out, '\'', string(1, range._min));
} else {
DCPacker::enquote_string(out, '\'', string(1, range._min));
out << "-";
DCPacker::enquote_string(out, '\'', string(1, range._max));
}
}