mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
add initial_reserve_id(), bring up to Panda coding standards
This commit is contained in:
parent
1fdb425b88
commit
7022d6ab9e
@ -26,8 +26,8 @@
|
|||||||
NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA, EXPTP_PANDA);
|
NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA, EXPTP_PANDA);
|
||||||
NotifyCategoryDef(uniqueIdAllocator, "");
|
NotifyCategoryDef(uniqueIdAllocator, "");
|
||||||
|
|
||||||
const U32 UniqueIdAllocator::IndexEnd=(U32)-1;
|
const PN_uint32 UniqueIdAllocator::IndexEnd = (PN_uint32)-1;
|
||||||
const U32 UniqueIdAllocator::IndexAllocated=(U32)-2;
|
const PN_uint32 UniqueIdAllocator::IndexAllocated = (PN_uint32)-2;
|
||||||
|
|
||||||
#ifndef NDEBUG //[
|
#ifndef NDEBUG //[
|
||||||
// Non-release build:
|
// Non-release build:
|
||||||
@ -51,31 +51,36 @@ const U32 UniqueIdAllocator::IndexAllocated=(U32)-2;
|
|||||||
#define audio_error(msg) \
|
#define audio_error(msg) \
|
||||||
audio_cat->error() << msg << endl
|
audio_cat->error() << msg << endl
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function:
|
// Function: UniqueIdAllocator::Constructor
|
||||||
// Access:
|
// Access: Published
|
||||||
// Description: Create a free id pool in the range [min:max].
|
// Description: Create a free id pool in the range [min:max].
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
UniqueIdAllocator::
|
UniqueIdAllocator::
|
||||||
UniqueIdAllocator(U32 min, U32 max)
|
UniqueIdAllocator(PN_uint32 min, PN_uint32 max)
|
||||||
: _min(min), _max(max) {
|
: _min(min), _max(max) {
|
||||||
uniqueIdAllocator_debug("UniqueIdAllocator("<<min<<", "<<max<<")");
|
uniqueIdAllocator_debug("UniqueIdAllocator("<<min<<", "<<max<<")");
|
||||||
_size=_max-_min+1; // +1 because min and max are inclusive.
|
|
||||||
nassertv(_size); // size must be > 0.
|
nassertv(_max > _min);
|
||||||
_table=new U32[_size];
|
_size = _max-_min+1; // +1 because min and max are inclusive.
|
||||||
|
nassertv(_size != 0); // size must be > 0.
|
||||||
|
|
||||||
|
_table=new PN_uint32[_size];
|
||||||
nassertv(_table); // This should be redundant if new throws an exception.
|
nassertv(_table); // This should be redundant if new throws an exception.
|
||||||
for (U32 i=0; i<_size; ++i) {
|
|
||||||
_table[i]=i+1;
|
for (PN_uint32 i = 0; i < _size; ++i) {
|
||||||
|
_table[i] = i + 1;
|
||||||
}
|
}
|
||||||
_table[_size-1]=IndexEnd;
|
_table[_size - 1] = IndexEnd;
|
||||||
_next_free=0;
|
_next_free = 0;
|
||||||
_last_free=_size-1;
|
_last_free = _size - 1;
|
||||||
_free=_size;
|
_free=_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function:
|
// Function: UniqueIdAllocator::Destructor
|
||||||
// Access:
|
// Access: Published
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
UniqueIdAllocator::
|
UniqueIdAllocator::
|
||||||
@ -86,57 +91,113 @@ UniqueIdAllocator::
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function:
|
// Function: UniqueIdAllocator::allocate
|
||||||
// Access:
|
// Access: Published
|
||||||
// Description: Receive an id between _min and _max (that were passed
|
// Description: Returns an id between _min and _max (that were passed
|
||||||
// to the constructor).
|
// to the constructor).
|
||||||
// IndexEnd is returned if no ids are available.
|
// IndexEnd is returned if no ids are available.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
U32 UniqueIdAllocator::
|
PN_uint32 UniqueIdAllocator::
|
||||||
allocate() {
|
allocate() {
|
||||||
if (_next_free==IndexEnd) {
|
if (_next_free == IndexEnd) {
|
||||||
// ...all ids allocated.
|
// ...all ids allocated.
|
||||||
uniqueIdAllocator_warning("allocate Error: no more free ids.");
|
uniqueIdAllocator_warning("allocate Error: no more free ids.");
|
||||||
return IndexEnd;
|
return IndexEnd;
|
||||||
}
|
}
|
||||||
U32 id=_min+_next_free;
|
PN_uint32 index = _next_free;
|
||||||
_next_free=_table[_next_free];
|
_next_free = _table[_next_free];
|
||||||
|
|
||||||
#ifndef NDEBUG //[
|
#ifndef NDEBUG //[
|
||||||
_table[id-_min]=IndexAllocated;
|
nassertr(_table[index] != IndexAllocated, IndexEnd);
|
||||||
|
_table[index] = IndexAllocated;
|
||||||
#endif //]
|
#endif //]
|
||||||
|
|
||||||
--_free;
|
--_free;
|
||||||
uniqueIdAllocator_debug("allocate() returning "<<id);
|
|
||||||
|
PN_uint32 id = index + _min;
|
||||||
|
uniqueIdAllocator_debug("allocate() returning " << id);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: UniqueIdAllocator::initial_reserve_id
|
||||||
|
// Access: Published
|
||||||
|
// Description: This may be called to mark a particular id as having
|
||||||
|
// already been allocated (for instance, by a prior
|
||||||
|
// pass). The specified id is removed from the
|
||||||
|
// available pool.
|
||||||
|
//
|
||||||
|
// Because of the limitations of this algorithm, this
|
||||||
|
// may only be called before the first call to
|
||||||
|
// allocate(); and all the calls to initial_reserve_id()
|
||||||
|
// must be made in descending order by id.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void UniqueIdAllocator::
|
||||||
|
initial_reserve_id(PN_uint32 id) {
|
||||||
|
nassertv(_next_free == 0); // Must call before any call to allocate().
|
||||||
|
nassertv(id >= _min && id <= _max); // Attempt to reserve out-of-range id.
|
||||||
|
PN_uint32 index = id - _min; // Convert to _table index.
|
||||||
|
|
||||||
|
nassertv(_table[index] != IndexAllocated);
|
||||||
|
|
||||||
|
// Because we insist that this call be made before any calls to
|
||||||
|
// allocate(), and in descending order, it follows that the _table
|
||||||
|
// is still set up such that _table[i] = i+1, at least for all slots
|
||||||
|
// <= index. Thus, the free link to slot [index] is guaranteed to
|
||||||
|
// be the slot right before it.
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
_next_free = _table[index];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nassertv(_table[index - 1] == index);
|
||||||
|
_table[index - 1] = _table[index];
|
||||||
|
|
||||||
|
if (index == _last_free) {
|
||||||
|
_last_free = index - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG //[
|
||||||
|
_table[index] = IndexAllocated;
|
||||||
|
#endif //]
|
||||||
|
|
||||||
|
--_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: free
|
// Function: UniqueIdAllocator::free
|
||||||
// Access:
|
// Access: Published
|
||||||
// Description: Free an allocated index (index must be between _min
|
// Description: Free an allocated index (index must be between _min
|
||||||
// and _max that were passed to the constructor).
|
// and _max that were passed to the constructor).
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void UniqueIdAllocator::
|
void UniqueIdAllocator::
|
||||||
free(U32 index) {
|
free(PN_uint32 id) {
|
||||||
uniqueIdAllocator_debug("free("<<index<<")");
|
uniqueIdAllocator_debug("free("<<id<<")");
|
||||||
nassertv(index>=_min); // Attempt to free out-of-range id.
|
|
||||||
nassertv(index<=_max); // Attempt to free out-of-range id.
|
nassertv(id >= _min && id <= _max); // Attempt to free out-of-range id.
|
||||||
index=index-_min; // Convert to _table index.
|
PN_uint32 index = id - _min; // Convert to _table index.
|
||||||
nassertv(_table[index]==IndexAllocated); // Attempt to free non-allocated id.
|
nassertv(_table[index] == IndexAllocated); // Attempt to free non-allocated id.
|
||||||
_table[index]=IndexEnd; // Mark this element as the end of the list.
|
if (_next_free != IndexEnd) {
|
||||||
_table[_last_free]=index;
|
nassertv(_table[_last_free] == IndexEnd);
|
||||||
if (_next_free==IndexEnd) {
|
_table[_last_free] = index;
|
||||||
// ...the free list was empty.
|
|
||||||
_next_free=index;
|
|
||||||
}
|
}
|
||||||
_last_free=index;
|
_table[index] = IndexEnd; // Mark this element as the end of the list.
|
||||||
|
_last_free = index;
|
||||||
|
|
||||||
|
if (_next_free == IndexEnd) {
|
||||||
|
// ...the free list was empty.
|
||||||
|
_next_free = index;
|
||||||
|
}
|
||||||
|
|
||||||
++_free;
|
++_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: fraction_used
|
// Function: UniqueIdAllocator::fraction_used
|
||||||
// Access:
|
// Access: Published
|
||||||
// Description: return the decimal fraction of the pool that is used.
|
// Description: return the decimal fraction of the pool that is used.
|
||||||
// The range is 0 to 1.0 (e.g. 75% would be 0.75).
|
// The range is 0 to 1.0 (e.g. 75% would be 0.75).
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -145,27 +206,45 @@ fraction_used() const {
|
|||||||
return float(_size-_free)/_size;
|
return float(_size-_free)/_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: output
|
// Function: UniqueIdAllocator::output
|
||||||
// Access:
|
// Access: Published
|
||||||
// Description: ...intended for debugging only.
|
// Description: ...intended for debugging only.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void UniqueIdAllocator::
|
void UniqueIdAllocator::
|
||||||
output(ostream& os, bool verbose) const {
|
output(ostream &out) const {
|
||||||
os <<"[_min: "<<_min<<"; _max: "<<_max
|
out << "UniqueIdAllocator(" << _min << ", " << _max << "), "
|
||||||
<<";\n_next_free: "<<long(_next_free)
|
<< _free << " id's remaining of " << _size;
|
||||||
<<"; _last_free: "<<long(_last_free)
|
}
|
||||||
<<"; _size: "<<_size
|
|
||||||
<<"; _free: "<<_free
|
////////////////////////////////////////////////////////////////////
|
||||||
<<"; used: "<<_size-_free
|
// Function: UniqueIdAllocator::write
|
||||||
<<"; fraction_used: "<<fraction_used();
|
// Access: Published
|
||||||
if (verbose) {
|
// Description: ...intended for debugging only.
|
||||||
os <<";\n ";
|
////////////////////////////////////////////////////////////////////
|
||||||
for (U32 i=0; i<_size; ++i) {
|
void UniqueIdAllocator::
|
||||||
os<<long(_table[i])<<", ";
|
write(ostream &out) const {
|
||||||
}
|
out << "_min: " << _min << "; _max: " << _max
|
||||||
}
|
<< ";\n_next_free: " << PN_int32(_next_free)
|
||||||
os<<"]"<<endl;
|
<< "; _last_free: " << PN_int32(_last_free)
|
||||||
|
<< "; _size: " << _size
|
||||||
|
<< "; _free: " << _free
|
||||||
|
<< "; used: " << _size - _free
|
||||||
|
<< "; fraction_used: " << fraction_used()
|
||||||
|
<< ";\n";
|
||||||
|
|
||||||
|
out << "Table:";
|
||||||
|
for (PN_uint32 i = 0; i < _size; ++i) {
|
||||||
|
out << " " << PN_int32(_table[i]);
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
|
|
||||||
|
out << "Free chain:";
|
||||||
|
PN_uint32 index = _next_free;
|
||||||
|
while (index != IndexEnd) {
|
||||||
|
out << " " << index + _min;
|
||||||
|
index = _table[index];
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,7 @@
|
|||||||
#define _UNIQUEIDALLOCATOR_H
|
#define _UNIQUEIDALLOCATOR_H
|
||||||
|
|
||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
#include "numeric_types.h"
|
||||||
typedef unsigned long U32;
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : UniqueIdAllocator
|
// Class : UniqueIdAllocator
|
||||||
@ -49,30 +47,54 @@ typedef unsigned long U32;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDA UniqueIdAllocator {
|
class EXPCL_PANDA UniqueIdAllocator {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
UniqueIdAllocator(U32 min=0, U32 max=20);
|
UniqueIdAllocator(PN_uint32 min=0, PN_uint32 max=20);
|
||||||
~UniqueIdAllocator();
|
~UniqueIdAllocator();
|
||||||
U32 allocate();
|
|
||||||
void free(U32 index);
|
|
||||||
float fraction_used() const;
|
|
||||||
void output(ostream& os, bool verbose=false) const;
|
|
||||||
|
|
||||||
public:
|
PN_uint32 allocate();
|
||||||
// VC6 does not support declaring const values within the class
|
void initial_reserve_id(PN_uint32 id);
|
||||||
// definition; we must therefore define the value for this in the
|
|
||||||
// .cxx file. This does potentially change the way the code is
|
void free(PN_uint32 index);
|
||||||
// generated (since the compiler does not necessarily know the value
|
float fraction_used() const;
|
||||||
// of this constant).
|
|
||||||
static const U32 IndexEnd;
|
void output(ostream &out) const;
|
||||||
|
void write(ostream &out) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const PN_uint32 IndexEnd;
|
||||||
|
static const PN_uint32 IndexAllocated;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const U32 IndexAllocated;
|
// _table stores an array of _size words, corresponding to each
|
||||||
U32* _table;
|
// allocatable id.
|
||||||
U32 _min;
|
|
||||||
U32 _max;
|
// For each free id, the table entry at the corresponding index
|
||||||
U32 _next_free;
|
// contains the index number of the next free id, thus defining a
|
||||||
U32 _last_free;
|
// chain of free id's. The last element of the chain contains
|
||||||
U32 _size;
|
// IndexEnd.
|
||||||
U32 _free;
|
|
||||||
|
// For an allocated id, the table entry at the corresponding index
|
||||||
|
// is undefined (but in debug mode, it contains IndexAllocated).
|
||||||
|
PN_uint32 *_table;
|
||||||
|
|
||||||
|
// The minimum and maximum as passed to the constructor.
|
||||||
|
PN_uint32 _min;
|
||||||
|
PN_uint32 _max;
|
||||||
|
|
||||||
|
// This is the head of the free chain: as elements are allocated,
|
||||||
|
// they are taken from _table[_next_free]. If the free chain is
|
||||||
|
// empty, _next_free == IndexEnd.
|
||||||
|
PN_uint32 _next_free;
|
||||||
|
|
||||||
|
// This is the tail of the free chain: as elements are freed, they
|
||||||
|
// are stored in _table[_last_free]. Normally, _table[_last_free]
|
||||||
|
// is the end of the free chain, unless the free chain is empty.
|
||||||
|
PN_uint32 _last_free;
|
||||||
|
|
||||||
|
// The total number of elements in _table.
|
||||||
|
PN_uint32 _size;
|
||||||
|
|
||||||
|
// The number of free elements in _table.
|
||||||
|
PN_uint32 _free;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //]
|
#endif //]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user