Optimize change_light search
Use std::equal_range to find the upper and lower bounds in a single binary search, rather than relying on a linear search to find the first sought element.
This commit is contained in:
parent
3594e7093f
commit
092d947830
|
@ -279,6 +279,14 @@ struct dl_index {
|
|||
uint8_t sidenum;
|
||||
uint8_t count;
|
||||
uint16_t index;
|
||||
bool operator<(const dl_index &rhs) const
|
||||
{
|
||||
if (segnum < rhs.segnum)
|
||||
return true;
|
||||
if (segnum > rhs.segnum)
|
||||
return false;
|
||||
return sidenum < rhs.sidenum;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -993,14 +993,7 @@ static int load_game_data(PHYSFS_File *LoadFile)
|
|||
const auto &&lr = partial_range(Dl_indices, Num_static_lights);
|
||||
range_for (auto &i, lr)
|
||||
dl_index_read(&i, LoadFile);
|
||||
const auto predicate = [](const dl_index &a, const dl_index &b) {
|
||||
if (a.segnum < b.segnum)
|
||||
return true;
|
||||
if (a.segnum > b.segnum)
|
||||
return false;
|
||||
return a.sidenum < b.sidenum;
|
||||
};
|
||||
std::sort(lr.begin(), lr.end(), predicate);
|
||||
std::sort(lr.begin(), lr.end());
|
||||
}
|
||||
|
||||
// Indicate that no light has been subtracted from any vertices.
|
||||
|
|
|
@ -1686,18 +1686,15 @@ static void change_segment_light(const vsegptridx_t segp,int sidenum,int dir)
|
|||
// dir = -1 -> subtract light
|
||||
// dir = 17 -> add 17x light
|
||||
// dir = 0 -> you are dumb
|
||||
static void change_light(const vsegptridx_t segnum, int sidenum, int dir)
|
||||
static void change_light(const vsegptridx_t segnum, const uint8_t sidenum, const int dir)
|
||||
{
|
||||
const fix ds = dir * DL_SCALE;
|
||||
range_for (auto &i, partial_const_range(Dl_indices, Num_static_lights))
|
||||
const auto &&pr = partial_const_range(Dl_indices, Num_static_lights);
|
||||
const auto &&er = std::equal_range(pr.begin(), pr.end(), dl_index{segnum, sidenum, 0, 0});
|
||||
range_for (auto &i, partial_range_t<const dl_index *>(er.first, er.second))
|
||||
{
|
||||
if (i.segnum == segnum)
|
||||
{
|
||||
if (i.sidenum > sidenum)
|
||||
break;
|
||||
if (i.sidenum < sidenum)
|
||||
continue;
|
||||
range_for (auto &j, partial_const_range(Delta_lights, static_cast<uint_fast32_t>(i.index), static_cast<uint_fast32_t>(i.count)))
|
||||
const uint_fast32_t idx = i.index;
|
||||
range_for (auto &j, partial_const_range(Delta_lights, idx, idx + i.count))
|
||||
{
|
||||
assert(j.sidenum < MAX_SIDES_PER_SEGMENT);
|
||||
const auto &&segp = vsegptr(j.segnum);
|
||||
|
@ -1710,9 +1707,6 @@ static void change_light(const vsegptridx_t segnum, int sidenum, int dir)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (i.segnum > segnum)
|
||||
break;
|
||||
}
|
||||
|
||||
//recompute static light for segment
|
||||
change_segment_light(segnum,sidenum,dir);
|
||||
|
|
Loading…
Reference in a new issue