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:
parent
d31789e745
commit
99870be24c
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user