1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-09 07:13:54 +02:00

Tiny optimizations to avoid copies

This commit is contained in:
Tomasz Zieliński 2023-12-13 22:20:23 +01:00
parent d31789e745
commit 99870be24c
3 changed files with 68 additions and 42 deletions

View File

@ -238,6 +238,7 @@ bool Area::contains(const Area & area) const
bool Area::overlap(const std::vector<int3> & tiles) const
{
// Important: Make sure that tiles.size < area.size
for(const auto & t : tiles)
{
if(contains(t))
@ -296,15 +297,14 @@ int3 Area::nearest(const Area & area) const
Area Area::getSubarea(const std::function<bool(const int3 &)> & filter) const
{
Area subset;
for(const auto & t : getTilesVector())
if(filter(t))
subset.add(t);
vstd::copy_if(getTilesVector(), vstd::set_inserter(subset.dTiles), filter);
return subset;
}
void Area::clear()
{
dTiles.clear();
dTilesVectorCache.clear();
dTotalShiftCache = int3();
invalidate();
}
@ -329,11 +329,10 @@ void Area::erase(const int3 & tile)
void Area::unite(const Area & area)
{
invalidate();
for(const auto & t : area.getTilesVector())
{
dTiles.insert(t);
}
auto & vec = area.getTilesVector();
dTiles.insert(vec.begin(), vec.end());
}
void Area::intersect(const Area & area)
{
invalidate();
@ -359,7 +358,7 @@ void Area::translate(const int3 & shift)
{
dBorderCache.clear();
dBorderOutsideCache.clear();
if(dTilesVectorCache.empty())
{
getTiles();
@ -373,7 +372,6 @@ void Area::translate(const int3 & shift)
{
t += shift;
}
//toAbsolute(dTiles, shift);
}
void Area::erase_if(std::function<bool(const int3&)> predicate)

View File

@ -199,20 +199,24 @@ Object::Object(const Object & object):
setPosition(object.getPosition());
}
std::list<Object::Instance*> Object::instances()
std::list<Object::Instance*> & Object::instances()
{
std::list<Object::Instance*> result;
for(auto & i : dInstances)
result.push_back(&i);
return result;
if (cachedInstanceList.empty())
{
for(auto & i : dInstances)
cachedInstanceList.push_back(&i);
}
return cachedInstanceList;
}
std::list<const Object::Instance*> Object::instances() const
std::list<const Object::Instance*> & Object::instances() const
{
std::list<const Object::Instance*> result;
for(const auto & i : dInstances)
result.push_back(&i);
return result;
if (cachedInstanceConstList.empty())
{
for(const auto & i : dInstances)
cachedInstanceConstList.push_back(&i);
}
return cachedInstanceConstList;
}
void Object::addInstance(Instance & object)
@ -220,16 +224,22 @@ void Object::addInstance(Instance & object)
//assert(object.dParent == *this);
setGuardedIfMonster(object);
dInstances.push_back(object);
cachedInstanceList.push_back(&object);
cachedInstanceConstList.push_back(&object);
clearCachedArea();
visibleTopOffset.reset();
}
Object::Instance & Object::addInstance(CGObjectInstance & object)
{
dInstances.emplace_back(*this, object);
setGuardedIfMonster(dInstances.back());
cachedInstanceList.push_back(&dInstances.back());
cachedInstanceConstList.push_back(&dInstances.back());
clearCachedArea();
visibleTopOffset.reset();
return dInstances.back();
}
@ -237,8 +247,11 @@ Object::Instance & Object::addInstance(CGObjectInstance & object, const int3 & p
{
dInstances.emplace_back(*this, object, position);
setGuardedIfMonster(dInstances.back());
cachedInstanceList.push_back(&dInstances.back());
cachedInstanceConstList.push_back(&dInstances.back());
clearCachedArea();
visibleTopOffset.reset();
return dInstances.back();
}
@ -266,6 +279,7 @@ const rmg::Area & Object::getAccessibleArea(bool exceptLast) const
if(!exceptLast && !dAccessibleAreaFullCache.empty())
return dAccessibleAreaFullCache;
// FIXME: This clears tiles for every consecutive object
for(auto i = dInstances.begin(); i != std::prev(dInstances.end()); ++i)
dAccessibleAreaCache.unite(i->getAccessibleArea());
@ -282,28 +296,27 @@ const rmg::Area & Object::getAccessibleArea(bool exceptLast) const
const rmg::Area & Object::getBlockVisitableArea() const
{
if(dInstances.empty())
return dBlockVisitableCache;
for(const auto & i : dInstances)
if(dBlockVisitableCache.empty())
{
// FIXME: Account for blockvis objects with multiple visitable tiles
if (i.isBlockedVisitable())
dBlockVisitableCache.add(i.getVisitablePosition());
for(const auto & i : dInstances)
{
// FIXME: Account for blockvis objects with multiple visitable tiles
if (i.isBlockedVisitable())
dBlockVisitableCache.add(i.getVisitablePosition());
}
}
return dBlockVisitableCache;
}
const rmg::Area & Object::getRemovableArea() const
{
if(dInstances.empty())
return dRemovableAreaCache;
for(const auto & i : dInstances)
{
if (i.isRemovable())
dRemovableAreaCache.unite(i.getBlockedArea());
for(const auto & i : dInstances)
{
if (i.isRemovable())
dRemovableAreaCache.unite(i.getBlockedArea());
}
}
return dRemovableAreaCache;
@ -341,6 +354,8 @@ void Object::setTemplate(const TerrainId & terrain, CRandomGenerator & rng)
{
for(auto& i : dInstances)
i.setTemplate(terrain, rng);
visibleTopOffset.reset();
}
const Area & Object::getArea() const
@ -358,15 +373,23 @@ const Area & Object::getArea() const
const int3 Object::getVisibleTop() const
{
int3 topTile(-1, 10000, -1); //Start at the bottom
for (const auto& i : dInstances)
if (visibleTopOffset)
{
if (i.getTopTile().y < topTile.y)
{
topTile = i.getTopTile();
}
return dPosition + visibleTopOffset.value();
}
else
{
int3 topTile(-1, 10000, -1); //Start at the bottom
for (const auto& i : dInstances)
{
if (i.getTopTile().y < topTile.y)
{
topTile = i.getTopTile();
}
}
visibleTopOffset = topTile - dPosition;
return topTile;
}
return topTile;
}
bool rmg::Object::isGuarded() const
@ -444,6 +467,9 @@ void Object::clear()
for(auto & instance : dInstances)
instance.clear();
dInstances.clear();
cachedInstanceList.clear();
cachedInstanceConstList.clear();
visibleTopOffset.reset();
clearCachedArea();
}

View File

@ -68,8 +68,8 @@ public:
Instance & addInstance(CGObjectInstance & object);
Instance & addInstance(CGObjectInstance & object, const int3 & position);
std::list<Instance*> instances();
std::list<const Instance*> instances() const;
std::list<Instance*> & instances();
std::list<const Instance*> & instances() const;
int3 getVisitablePosition() const;
const Area & getAccessibleArea(bool exceptLast = false) const;
@ -98,7 +98,9 @@ private:
mutable Area dBlockVisitableCache;
mutable Area dRemovableAreaCache;
int3 dPosition;
ui32 dStrength;
mutable std::optional<int3> visibleTopOffset;
mutable std::list<Object::Instance*> cachedInstanceList;
mutable std::list<const Object::Instance*> cachedInstanceConstList;
bool guarded;
};
}