add get_num_on_bits(), etc.
This commit is contained in:
parent
4ae6be208c
commit
a71cd2a689
|
|
@ -305,6 +305,90 @@ clear_range(int low_bit, int size) {
|
|||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_num_on_bits
|
||||
// Access: Published
|
||||
// Description: Returns the number of bits that are set to 1 in the
|
||||
// array. Returns -1 if there are an infinite number of
|
||||
// 1 bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int BitArray::
|
||||
get_num_on_bits() const {
|
||||
if (_highest_bits) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
result += (*ai).get_num_on_bits();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_num_off_bits
|
||||
// Access: Published
|
||||
// Description: Returns the number of bits that are set to 0 in the
|
||||
// array. Returns -1 if there are an infinite number of
|
||||
// 0 bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int BitArray::
|
||||
get_num_off_bits() const {
|
||||
if (!_highest_bits) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
result += (*ai).get_num_off_bits();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_next_higher_different_bit
|
||||
// Access: Published
|
||||
// Description: Returns the index of the next bit in the array, above
|
||||
// low_bit, whose value is different that the value of
|
||||
// low_bit. Returns low_bit again if all bits higher
|
||||
// than low_bit have the same value.
|
||||
//
|
||||
// This can be used to quickly iterate through all of
|
||||
// the bits in the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int BitArray::
|
||||
get_next_higher_different_bit(int low_bit) const {
|
||||
int w = low_bit / num_bits_per_word;
|
||||
int b = low_bit % num_bits_per_word;
|
||||
int num_words = get_num_words();
|
||||
if (w >= num_words) {
|
||||
return low_bit;
|
||||
}
|
||||
int b2 = _array[w].get_next_higher_different_bit(b);
|
||||
if (b2 != b) {
|
||||
// The next higher bit is within the same word.
|
||||
return w * num_bits_per_word + b2;
|
||||
}
|
||||
// Look for the next word with anything interesting.
|
||||
MaskType skip_next = (_array[w].get_bit(b)) ? MaskType::all_on() : MaskType::all_off();
|
||||
++w;
|
||||
while (w < num_words && _array[w] == skip_next) {
|
||||
++w;
|
||||
}
|
||||
if (w >= num_words) {
|
||||
return low_bit;
|
||||
}
|
||||
if (_array[w].get_bit(0) != _array[w].get_bit(b)) {
|
||||
// The first bit of word w is different.
|
||||
return w * num_bits_per_word;
|
||||
}
|
||||
|
||||
b2 = _array[w].get_next_higher_different_bit(0);
|
||||
return w * num_bits_per_word + b2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::invert_in_place
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ PUBLISHED:
|
|||
void clear_range(int low_bit, int size);
|
||||
INLINE void set_range_to(bool value, int low_bit, int size);
|
||||
|
||||
int get_num_on_bits() const;
|
||||
int get_num_off_bits() const;
|
||||
int get_next_higher_different_bit(int low_bit) const;
|
||||
|
||||
INLINE int get_num_words() const;
|
||||
INLINE MaskType get_word(int n) const;
|
||||
INLINE void set_word(int n, MaskType value);
|
||||
|
|
|
|||
|
|
@ -440,6 +440,73 @@ clear() {
|
|||
_word = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::get_num_on_bits
|
||||
// Access: Published
|
||||
// Description: Returns the number of bits that are set to 1 in the
|
||||
// mask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
get_num_on_bits() const {
|
||||
return count_bits_in_word(_word);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::get_num_off_bits
|
||||
// Access: Published
|
||||
// Description: Returns the number of bits that are set to 0 in the
|
||||
// mask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
get_num_off_bits() const {
|
||||
return count_bits_in_word(~_word);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::get_next_higher_different_bit
|
||||
// Access: Published
|
||||
// Description: Returns the index of the next bit in the mask, above
|
||||
// low_bit, whose value is different that the value of
|
||||
// low_bit. Returns low_bit again if all bits higher
|
||||
// than low_bit have the same value.
|
||||
//
|
||||
// This can be used to quickly iterate through all of
|
||||
// the bits in the mask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
get_next_higher_different_bit(int low_bit) const {
|
||||
nassertr(low_bit >= 0 && low_bit < num_bits, low_bit);
|
||||
|
||||
WordType w;
|
||||
if (_word & ((WordType)1 << low_bit)) {
|
||||
// low_bit is 1. Get the next higher 0 bit. To do this, invert
|
||||
// the word and the get the next higher 1 bit.
|
||||
w = ~_word;
|
||||
} else {
|
||||
// low_bit is 0. Get the next higher 1 bit.
|
||||
w = _word;
|
||||
}
|
||||
|
||||
// Shift out all of the low bits.
|
||||
w >>= (low_bit + 1);
|
||||
|
||||
if (w == 0) {
|
||||
// No more bits.
|
||||
return low_bit;
|
||||
|
||||
} else {
|
||||
// Now determine the lowest 1 bit in the remaining word. This
|
||||
// operation will clear out all bits except for the lowest 1 bit.
|
||||
w = (w & -w);
|
||||
|
||||
// And the answer is the number of bits in (w - 1).
|
||||
return count_bits_in_word(w - 1) + low_bit + 1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::output
|
||||
// Access: Published
|
||||
|
|
@ -734,3 +801,22 @@ init_type() {
|
|||
str << "BitMask" << num_bits;
|
||||
register_type(_type_handle, str.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: count_bits_in_word
|
||||
// Description: Returns the number of 1 bits in the indicated word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
count_bits_in_word(PN_uint32 x) {
|
||||
return (int)num_bits_on[x & 0xffff] + (int)num_bits_on[(x >> 16) & 0xffff];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: count_bits_in_word
|
||||
// Description: Returns the number of 1 bits in the indicated word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int
|
||||
count_bits_in_word(PN_uint64 x) {
|
||||
return count_bits_in_word((PN_uint32)x) + count_bits_in_word((PN_uint32)(x >> 32));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,3 +23,4 @@
|
|||
#pragma implementation
|
||||
#endif
|
||||
|
||||
unsigned char num_bits_on[65536];
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ PUBLISHED:
|
|||
INLINE WordType get_word() const;
|
||||
INLINE void set_word(WordType value);
|
||||
|
||||
INLINE int get_num_on_bits() const;
|
||||
INLINE int get_num_off_bits() const;
|
||||
INLINE int get_next_higher_different_bit(int low_bit) const;
|
||||
|
||||
INLINE void invert_in_place();
|
||||
INLINE bool has_bits_in_common(const BitMask<WType, nbits> &other) const;
|
||||
INLINE void clear();
|
||||
|
|
@ -132,6 +136,12 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE int count_bits_in_word(PN_uint32 x);
|
||||
INLINE int count_bits_in_word(PN_uint64 x);
|
||||
|
||||
// This table precomputes the number of on bits in each 16-bit word.
|
||||
extern EXPCL_PANDA unsigned char num_bits_on[65536];
|
||||
|
||||
#include "bitMask.I"
|
||||
|
||||
template<class WType, int nbits>
|
||||
|
|
|
|||
|
|
@ -85,47 +85,9 @@ ConfigVariableSearchPath sound_path
|
|||
PRC_DESC("The directories to search for sound and music files to be loaded."));
|
||||
|
||||
ConfigureFn(config_util) {
|
||||
AnimInterface::init_type();
|
||||
BamCacheIndex::init_type();
|
||||
BamCacheRecord::init_type();
|
||||
BamReaderParam::init_type();
|
||||
BitArray::init_type();
|
||||
BitMask32::init_type();
|
||||
BitMask64::init_type();
|
||||
ButtonHandle::init_type();
|
||||
CachedTypedWritableReferenceCount::init_type();
|
||||
ClockObject::init_type();
|
||||
Configurable::init_type();
|
||||
CopyOnWriteObject::init_type();
|
||||
Datagram::init_type();
|
||||
DoubleBitMaskNative::init_type();
|
||||
QuadBitMaskNative::init_type();
|
||||
FactoryParam::init_type();
|
||||
Namable::init_type();
|
||||
NodeCachedReferenceCount::init_type();
|
||||
ReferenceCount::init_type();
|
||||
SparseArray::init_type();
|
||||
TypedObject::init_type();
|
||||
TypedReferenceCount::init_type();
|
||||
TypedWritable::init_type();
|
||||
TypedWritableReferenceCount::init_type();
|
||||
WritableConfigurable::init_type();
|
||||
WritableParam::init_type();
|
||||
|
||||
KeyboardButton::init_keyboard_buttons();
|
||||
MouseButton::init_mouse_buttons();
|
||||
|
||||
DeferredDeletor::register_deletor();
|
||||
NonDeletor::register_deletor();
|
||||
SpamDeletor::register_deletor();
|
||||
|
||||
register_type(BamReader::_remove_flag, "remove");
|
||||
|
||||
BamCacheIndex::register_with_read_factory();
|
||||
BamCacheRecord::register_with_read_factory();
|
||||
init_libputil();
|
||||
}
|
||||
|
||||
|
||||
// Set this true to enable tracking of ReferenceCount pointer
|
||||
// allocation/deallcation via the MemoryUsage object. This is
|
||||
// primarily useful for detecting memory leaks. It has no effect when
|
||||
|
|
@ -170,3 +132,68 @@ ConfigVariableDouble sleep_precision
|
|||
|
||||
ConfigVariableDouble average_frame_rate_interval
|
||||
("average-frame-rate-interval", 1.0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libputil
|
||||
// Description: Initializes the library. This must be called at
|
||||
// least once before any of the functions or classes in
|
||||
// this library can be used. Normally it will be
|
||||
// called by the static initializers and need not be
|
||||
// called explicitly, but special cases exist.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
init_libputil() {
|
||||
static bool initialized = false;
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
AnimInterface::init_type();
|
||||
BamCacheIndex::init_type();
|
||||
BamCacheRecord::init_type();
|
||||
BamReaderParam::init_type();
|
||||
BitArray::init_type();
|
||||
BitMask32::init_type();
|
||||
BitMask64::init_type();
|
||||
ButtonHandle::init_type();
|
||||
CachedTypedWritableReferenceCount::init_type();
|
||||
ClockObject::init_type();
|
||||
Configurable::init_type();
|
||||
CopyOnWriteObject::init_type();
|
||||
Datagram::init_type();
|
||||
DoubleBitMaskNative::init_type();
|
||||
QuadBitMaskNative::init_type();
|
||||
FactoryParam::init_type();
|
||||
Namable::init_type();
|
||||
NodeCachedReferenceCount::init_type();
|
||||
ReferenceCount::init_type();
|
||||
SparseArray::init_type();
|
||||
TypedObject::init_type();
|
||||
TypedReferenceCount::init_type();
|
||||
TypedWritable::init_type();
|
||||
TypedWritableReferenceCount::init_type();
|
||||
WritableConfigurable::init_type();
|
||||
WritableParam::init_type();
|
||||
|
||||
KeyboardButton::init_keyboard_buttons();
|
||||
MouseButton::init_mouse_buttons();
|
||||
|
||||
DeferredDeletor::register_deletor();
|
||||
NonDeletor::register_deletor();
|
||||
SpamDeletor::register_deletor();
|
||||
|
||||
register_type(BamReader::_remove_flag, "remove");
|
||||
|
||||
BamCacheIndex::register_with_read_factory();
|
||||
BamCacheRecord::register_with_read_factory();
|
||||
|
||||
// Initialize the num_bits_on table, for BitMask::get_num_on_bits().
|
||||
for (int bit = 0; bit < 16; ++bit) {
|
||||
int w = (1 << bit);
|
||||
for (int i = 0; i < w; ++i) {
|
||||
num_bits_on[i + w] = num_bits_on[i] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,4 +61,6 @@ extern ConfigVariableDouble max_dt;
|
|||
extern ConfigVariableDouble sleep_precision;
|
||||
extern ConfigVariableDouble average_frame_rate_interval;
|
||||
|
||||
extern EXPCL_PANDA void init_libputil();
|
||||
|
||||
#endif /* __CONFIG_UTIL_H__ */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,86 @@ SparseArray(const BitArray &from) {
|
|||
nassertv(current_state == empty_bit);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SparseArray::get_num_on_bits
|
||||
// Access: Published
|
||||
// Description: Returns the number of bits that are set to 1 in the
|
||||
// array. Returns -1 if there are an infinite number of
|
||||
// 1 bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int SparseArray::
|
||||
get_num_on_bits() const {
|
||||
if (_inverse) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
Subranges::const_iterator si;
|
||||
for (si = _subranges.begin(); si != _subranges.end(); ++si) {
|
||||
result += (*si)._end - (*si)._begin;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SparseArray::get_num_off_bits
|
||||
// Access: Published
|
||||
// Description: Returns the number of bits that are set to 0 in the
|
||||
// array. Returns -1 if there are an infinite number of
|
||||
// 0 bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int SparseArray::
|
||||
get_num_off_bits() const {
|
||||
if (!_inverse) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
Subranges::const_iterator si;
|
||||
for (si = _subranges.begin(); si != _subranges.end(); ++si) {
|
||||
result += (*si)._end - (*si)._begin;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SparseArray::get_next_higher_different_bit
|
||||
// Access: Published
|
||||
// Description: Returns the index of the next bit in the array, above
|
||||
// low_bit, whose value is different that the value of
|
||||
// low_bit. Returns low_bit again if all bits higher
|
||||
// than low_bit have the same value.
|
||||
//
|
||||
// This can be used to quickly iterate through all of
|
||||
// the bits in the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int SparseArray::
|
||||
get_next_higher_different_bit(int low_bit) const {
|
||||
Subrange range(low_bit, low_bit + 1);
|
||||
Subranges::const_iterator si = _subranges.lower_bound(range);
|
||||
if (si == _subranges.end()) {
|
||||
// That was the end of the array.
|
||||
return low_bit;
|
||||
}
|
||||
|
||||
if (low_bit >= (*si)._begin) {
|
||||
return (*si)._end;
|
||||
}
|
||||
|
||||
int next = (*si)._begin;
|
||||
|
||||
if (si != _subranges.begin()) {
|
||||
--si;
|
||||
if (low_bit < (*si)._end) {
|
||||
return (*si)._end;
|
||||
}
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SparseArray::has_bits_in_common
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -83,6 +83,10 @@ PUBLISHED:
|
|||
INLINE void clear_range(int low_bit, int size);
|
||||
INLINE void set_range_to(bool value, int low_bit, int size);
|
||||
|
||||
int get_num_on_bits() const;
|
||||
int get_num_off_bits() const;
|
||||
int get_next_higher_different_bit(int low_bit) const;
|
||||
|
||||
INLINE void invert_in_place();
|
||||
bool has_bits_in_common(const SparseArray &other) const;
|
||||
INLINE void clear();
|
||||
|
|
|
|||
Loading…
Reference in New Issue