Switch expandRegions to using a rcTempVector of structs rather than a blob of ints.
Also updates rcVector::clear() to not require the contained type to be default-constructible.
This commit is contained in:
parent
689cf00bd9
commit
bec073c947
@ -123,10 +123,12 @@ class rcVectorBase {
|
|||||||
|
|
||||||
void resize(rcSizeType size) { resize_impl(size, NULL); }
|
void resize(rcSizeType size) { resize_impl(size, NULL); }
|
||||||
void resize(rcSizeType size, const T& value) { resize_impl(size, &value); }
|
void resize(rcSizeType size, const T& value) { resize_impl(size, &value); }
|
||||||
|
// Not implemented as resize(0) because resize requires T to be default-constructible.
|
||||||
|
void clear() { destroy_range(0, m_size); m_size = 0; }
|
||||||
|
|
||||||
void push_back(const T& value);
|
void push_back(const T& value);
|
||||||
void pop_back() { rcAssert(m_size > 0); back().~T(); m_size--; }
|
void pop_back() { rcAssert(m_size > 0); back().~T(); m_size--; }
|
||||||
void clear() { resize(0); }
|
|
||||||
rcSizeType size() const { return m_size; }
|
rcSizeType size() const { return m_size; }
|
||||||
rcSizeType capacity() const { return m_cap; }
|
rcSizeType capacity() const { return m_cap; }
|
||||||
bool empty() const { return size() == 0; }
|
bool empty() const { return size() == 0; }
|
||||||
|
@ -343,6 +343,14 @@ static bool floodRegion(int x, int y, int i,
|
|||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Struct to keep track of entries in the region table that have been changed.
|
||||||
|
struct DirtyEntry {
|
||||||
|
DirtyEntry(int index_, unsigned short region_, unsigned short distance2_)
|
||||||
|
: index(index_), region(region_), distance2(distance2_) {}
|
||||||
|
int index;
|
||||||
|
unsigned short region;
|
||||||
|
unsigned short distance2;
|
||||||
|
};
|
||||||
static void expandRegions(int maxIter, unsigned short level,
|
static void expandRegions(int maxIter, unsigned short level,
|
||||||
rcCompactHeightfield& chf,
|
rcCompactHeightfield& chf,
|
||||||
unsigned short* srcReg, unsigned short* srcDist,
|
unsigned short* srcReg, unsigned short* srcDist,
|
||||||
@ -384,12 +392,12 @@ static void expandRegions(int maxIter, unsigned short level,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rcIntArray dirtyEntries;
|
rcTempVector<DirtyEntry> dirtyEntries;
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
while (stack.size() > 0)
|
while (stack.size() > 0)
|
||||||
{
|
{
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
dirtyEntries.resize(0);
|
dirtyEntries.clear();
|
||||||
|
|
||||||
for (int j = 0; j < stack.size(); j += 3)
|
for (int j = 0; j < stack.size(); j += 3)
|
||||||
{
|
{
|
||||||
@ -425,9 +433,7 @@ static void expandRegions(int maxIter, unsigned short level,
|
|||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
stack[j+2] = -1; // mark as used
|
stack[j+2] = -1; // mark as used
|
||||||
dirtyEntries.push(i);
|
dirtyEntries.push_back(DirtyEntry(i, r, d2));
|
||||||
dirtyEntries.push(r);
|
|
||||||
dirtyEntries.push(d2);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -436,10 +442,10 @@ static void expandRegions(int maxIter, unsigned short level,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy entries that differ between src and dst to keep them in sync.
|
// Copy entries that differ between src and dst to keep them in sync.
|
||||||
for (int i = 0; i < dirtyEntries.size(); i+=3) {
|
for (int i = 0; i < dirtyEntries.size(); i++) {
|
||||||
int idx = dirtyEntries[i];
|
int idx = dirtyEntries[i].index;
|
||||||
srcReg[idx] = (unsigned short)dirtyEntries[i+1];
|
srcReg[idx] = dirtyEntries[i].region;
|
||||||
srcDist[idx] = (unsigned short)dirtyEntries[i+2];
|
srcDist[idx] = dirtyEntries[i].distance2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed*3 == stack.size())
|
if (failed*3 == stack.size())
|
||||||
|
@ -892,6 +892,10 @@ struct Copier {
|
|||||||
const int Copier::kAlive = 0x1f;
|
const int Copier::kAlive = 0x1f;
|
||||||
const int Copier::kDead = 0xde;
|
const int Copier::kDead = 0xde;
|
||||||
|
|
||||||
|
struct NotDefaultConstructible {
|
||||||
|
NotDefaultConstructible(int) {}
|
||||||
|
};
|
||||||
|
|
||||||
TEST_CASE("rcVector")
|
TEST_CASE("rcVector")
|
||||||
{
|
{
|
||||||
SECTION("Vector basics.")
|
SECTION("Vector basics.")
|
||||||
@ -1068,6 +1072,17 @@ TEST_CASE("rcVector")
|
|||||||
REQUIRE(Incrementor::destructions == 0);
|
REQUIRE(Incrementor::destructions == 0);
|
||||||
REQUIRE(Incrementor::copies == 10);
|
REQUIRE(Incrementor::copies == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Type Requirements")
|
||||||
|
{
|
||||||
|
// This section verifies that we don't enforce unnecessary
|
||||||
|
// requirements on the types we hold.
|
||||||
|
|
||||||
|
// Implementing clear as resize(0) will cause this to fail
|
||||||
|
// as resize(0) requires T to be default constructible.
|
||||||
|
rcTempVector<NotDefaultConstructible> v;
|
||||||
|
v.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement benchmarking for platforms other than posix.
|
// TODO: Implement benchmarking for platforms other than posix.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user