mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -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);
|
||||
NotifyCategoryDef(uniqueIdAllocator, "");
|
||||
|
||||
const U32 UniqueIdAllocator::IndexEnd=(U32)-1;
|
||||
const U32 UniqueIdAllocator::IndexAllocated=(U32)-2;
|
||||
const PN_uint32 UniqueIdAllocator::IndexEnd = (PN_uint32)-1;
|
||||
const PN_uint32 UniqueIdAllocator::IndexAllocated = (PN_uint32)-2;
|
||||
|
||||
#ifndef NDEBUG //[
|
||||
// Non-release build:
|
||||
@ -51,20 +51,25 @@ const U32 UniqueIdAllocator::IndexAllocated=(U32)-2;
|
||||
#define audio_error(msg) \
|
||||
audio_cat->error() << msg << endl
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function:
|
||||
// Access:
|
||||
// Function: UniqueIdAllocator::Constructor
|
||||
// Access: Published
|
||||
// Description: Create a free id pool in the range [min:max].
|
||||
////////////////////////////////////////////////////////////////////
|
||||
UniqueIdAllocator::
|
||||
UniqueIdAllocator(U32 min, U32 max)
|
||||
UniqueIdAllocator(PN_uint32 min, PN_uint32 max)
|
||||
: _min(min), _max(max) {
|
||||
uniqueIdAllocator_debug("UniqueIdAllocator("<<min<<", "<<max<<")");
|
||||
|
||||
nassertv(_max > _min);
|
||||
_size = _max-_min+1; // +1 because min and max are inclusive.
|
||||
nassertv(_size); // size must be > 0.
|
||||
_table=new U32[_size];
|
||||
nassertv(_size != 0); // size must be > 0.
|
||||
|
||||
_table=new PN_uint32[_size];
|
||||
nassertv(_table); // This should be redundant if new throws an exception.
|
||||
for (U32 i=0; i<_size; ++i) {
|
||||
|
||||
for (PN_uint32 i = 0; i < _size; ++i) {
|
||||
_table[i] = i + 1;
|
||||
}
|
||||
_table[_size - 1] = IndexEnd;
|
||||
@ -74,8 +79,8 @@ UniqueIdAllocator(U32 min, U32 max)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function:
|
||||
// Access:
|
||||
// Function: UniqueIdAllocator::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
UniqueIdAllocator::
|
||||
@ -86,57 +91,113 @@ UniqueIdAllocator::
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function:
|
||||
// Access:
|
||||
// Description: Receive an id between _min and _max (that were passed
|
||||
// Function: UniqueIdAllocator::allocate
|
||||
// Access: Published
|
||||
// Description: Returns an id between _min and _max (that were passed
|
||||
// to the constructor).
|
||||
// IndexEnd is returned if no ids are available.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
U32 UniqueIdAllocator::
|
||||
PN_uint32 UniqueIdAllocator::
|
||||
allocate() {
|
||||
if (_next_free == IndexEnd) {
|
||||
// ...all ids allocated.
|
||||
uniqueIdAllocator_warning("allocate Error: no more free ids.");
|
||||
return IndexEnd;
|
||||
}
|
||||
U32 id=_min+_next_free;
|
||||
PN_uint32 index = _next_free;
|
||||
_next_free = _table[_next_free];
|
||||
|
||||
#ifndef NDEBUG //[
|
||||
_table[id-_min]=IndexAllocated;
|
||||
nassertr(_table[index] != IndexAllocated, IndexEnd);
|
||||
_table[index] = IndexAllocated;
|
||||
#endif //]
|
||||
|
||||
--_free;
|
||||
|
||||
PN_uint32 id = index + _min;
|
||||
uniqueIdAllocator_debug("allocate() returning " << 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
|
||||
// Access:
|
||||
// Function: UniqueIdAllocator::free
|
||||
// Access: Published
|
||||
// Description: Free an allocated index (index must be between _min
|
||||
// and _max that were passed to the constructor).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void UniqueIdAllocator::
|
||||
free(U32 index) {
|
||||
uniqueIdAllocator_debug("free("<<index<<")");
|
||||
nassertv(index>=_min); // Attempt to free out-of-range id.
|
||||
nassertv(index<=_max); // Attempt to free out-of-range id.
|
||||
index=index-_min; // Convert to _table index.
|
||||
free(PN_uint32 id) {
|
||||
uniqueIdAllocator_debug("free("<<id<<")");
|
||||
|
||||
nassertv(id >= _min && id <= _max); // Attempt to free out-of-range id.
|
||||
PN_uint32 index = id - _min; // Convert to _table index.
|
||||
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) {
|
||||
nassertv(_table[_last_free] == IndexEnd);
|
||||
_table[_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;
|
||||
}
|
||||
_last_free=index;
|
||||
|
||||
++_free;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: fraction_used
|
||||
// Access:
|
||||
// Function: UniqueIdAllocator::fraction_used
|
||||
// Access: Published
|
||||
// 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).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -145,27 +206,45 @@ fraction_used() const {
|
||||
return float(_size-_free)/_size;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: output
|
||||
// Access:
|
||||
// Function: UniqueIdAllocator::output
|
||||
// Access: Published
|
||||
// Description: ...intended for debugging only.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void UniqueIdAllocator::
|
||||
output(ostream& os, bool verbose) const {
|
||||
os <<"[_min: "<<_min<<"; _max: "<<_max
|
||||
<<";\n_next_free: "<<long(_next_free)
|
||||
<<"; _last_free: "<<long(_last_free)
|
||||
output(ostream &out) const {
|
||||
out << "UniqueIdAllocator(" << _min << ", " << _max << "), "
|
||||
<< _free << " id's remaining of " << _size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: UniqueIdAllocator::write
|
||||
// Access: Published
|
||||
// Description: ...intended for debugging only.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void UniqueIdAllocator::
|
||||
write(ostream &out) const {
|
||||
out << "_min: " << _min << "; _max: " << _max
|
||||
<< ";\n_next_free: " << PN_int32(_next_free)
|
||||
<< "; _last_free: " << PN_int32(_last_free)
|
||||
<< "; _size: " << _size
|
||||
<< "; _free: " << _free
|
||||
<< "; used: " << _size - _free
|
||||
<<"; fraction_used: "<<fraction_used();
|
||||
if (verbose) {
|
||||
os <<";\n ";
|
||||
for (U32 i=0; i<_size; ++i) {
|
||||
os<<long(_table[i])<<", ";
|
||||
<< "; 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];
|
||||
}
|
||||
os<<"]"<<endl;
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,7 @@
|
||||
#define _UNIQUEIDALLOCATOR_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
typedef unsigned long U32;
|
||||
|
||||
#include "numeric_types.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : UniqueIdAllocator
|
||||
@ -49,30 +47,54 @@ typedef unsigned long U32;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA UniqueIdAllocator {
|
||||
PUBLISHED:
|
||||
UniqueIdAllocator(U32 min=0, U32 max=20);
|
||||
UniqueIdAllocator(PN_uint32 min=0, PN_uint32 max=20);
|
||||
~UniqueIdAllocator();
|
||||
U32 allocate();
|
||||
void free(U32 index);
|
||||
|
||||
PN_uint32 allocate();
|
||||
void initial_reserve_id(PN_uint32 id);
|
||||
|
||||
void free(PN_uint32 index);
|
||||
float fraction_used() const;
|
||||
void output(ostream& os, bool verbose=false) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out) const;
|
||||
|
||||
public:
|
||||
// VC6 does not support declaring const values within the class
|
||||
// definition; we must therefore define the value for this in the
|
||||
// .cxx file. This does potentially change the way the code is
|
||||
// generated (since the compiler does not necessarily know the value
|
||||
// of this constant).
|
||||
static const U32 IndexEnd;
|
||||
static const PN_uint32 IndexEnd;
|
||||
static const PN_uint32 IndexAllocated;
|
||||
|
||||
protected:
|
||||
static const U32 IndexAllocated;
|
||||
U32* _table;
|
||||
U32 _min;
|
||||
U32 _max;
|
||||
U32 _next_free;
|
||||
U32 _last_free;
|
||||
U32 _size;
|
||||
U32 _free;
|
||||
// _table stores an array of _size words, corresponding to each
|
||||
// allocatable id.
|
||||
|
||||
// For each free id, the table entry at the corresponding index
|
||||
// contains the index number of the next free id, thus defining a
|
||||
// chain of free id's. The last element of the chain contains
|
||||
// IndexEnd.
|
||||
|
||||
// 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 //]
|
||||
|
Loading…
x
Reference in New Issue
Block a user