Use multimap to speed up custom map marker code

sceneinput
scrawl 10 years ago
parent 91d71d0fcd
commit 41bed4c7d9

@ -92,31 +92,41 @@ namespace MWGui
void CustomMarkerCollection::addMarker(const ESM::CustomMarker &marker, bool triggerEvent) void CustomMarkerCollection::addMarker(const ESM::CustomMarker &marker, bool triggerEvent)
{ {
mMarkers.push_back(marker); mMarkers.insert(std::make_pair(marker.mCell, marker));
if (triggerEvent) if (triggerEvent)
eventMarkersChanged(); eventMarkersChanged();
} }
void CustomMarkerCollection::deleteMarker(const ESM::CustomMarker &marker) void CustomMarkerCollection::deleteMarker(const ESM::CustomMarker &marker)
{ {
std::vector<ESM::CustomMarker>::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker); std::pair<ContainerType::iterator, ContainerType::iterator> range = mMarkers.equal_range(marker.mCell);
if (it != mMarkers.end())
mMarkers.erase(it);
else
throw std::runtime_error("can't find marker to delete");
eventMarkersChanged(); for (ContainerType::iterator it = range.first; it != range.second; ++it)
{
if (it->second == marker)
{
mMarkers.erase(it);
eventMarkersChanged();
return;
}
}
throw std::runtime_error("can't find marker to delete");
} }
void CustomMarkerCollection::updateMarker(const ESM::CustomMarker &marker, const std::string &newNote) void CustomMarkerCollection::updateMarker(const ESM::CustomMarker &marker, const std::string &newNote)
{ {
std::vector<ESM::CustomMarker>::iterator it = std::find(mMarkers.begin(), mMarkers.end(), marker); std::pair<ContainerType::iterator, ContainerType::iterator> range = mMarkers.equal_range(marker.mCell);
if (it != mMarkers.end())
it->mNote = newNote;
else
throw std::runtime_error("can't find marker to update");
eventMarkersChanged(); for (ContainerType::iterator it = range.first; it != range.second; ++it)
{
if (it->second == marker)
{
it->second.mNote = newNote;
eventMarkersChanged();
return;
}
}
throw std::runtime_error("can't find marker to update");
} }
void CustomMarkerCollection::clear() void CustomMarkerCollection::clear()
@ -125,16 +135,21 @@ namespace MWGui
eventMarkersChanged(); eventMarkersChanged();
} }
std::vector<ESM::CustomMarker>::const_iterator CustomMarkerCollection::begin() const CustomMarkerCollection::ContainerType::const_iterator CustomMarkerCollection::begin() const
{ {
return mMarkers.begin(); return mMarkers.begin();
} }
std::vector<ESM::CustomMarker>::const_iterator CustomMarkerCollection::end() const CustomMarkerCollection::ContainerType::const_iterator CustomMarkerCollection::end() const
{ {
return mMarkers.end(); return mMarkers.end();
} }
CustomMarkerCollection::RangeType CustomMarkerCollection::getMarkers(const ESM::CellId &cellId) const
{
return mMarkers.equal_range(cellId);
}
size_t CustomMarkerCollection::size() const size_t CustomMarkerCollection::size() const
{ {
return mMarkers.size(); return mMarkers.size();
@ -299,44 +314,43 @@ namespace MWGui
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
mCustomMarkerWidgets.clear(); mCustomMarkerWidgets.clear();
for (std::vector<ESM::CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) for (int dX = -1; dX <= 1; ++dX)
{ {
const ESM::CustomMarker& marker = *it; for (int dY =-1; dY <= 1; ++dY)
if (marker.mCell.mPaged != !mInterior)
continue;
if (mInterior)
{
if (marker.mCell.mWorldspace != mPrefix)
continue;
}
else
{ {
if (std::abs(marker.mCell.mIndex.mX - mCurX) > 1) ESM::CellId cellId;
continue; cellId.mPaged = !mInterior;
if (std::abs(marker.mCell.mIndex.mY - mCurY) > 1) cellId.mWorldspace = (mInterior ? mPrefix : "sys::default");
continue; cellId.mIndex.mX = mCurX+dX;
cellId.mIndex.mY = mCurY+dY;
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellId);
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it)
{
const ESM::CustomMarker& marker = it->second;
MarkerUserData markerPos (mLocalMapRender);
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos);
MyGUI::IntCoord widgetCoord(widgetPos.left - 8,
widgetPos.top - 8,
16, 16);
MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>("CustomMarkerButton",
widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote));
markerWidget->setNormalColour(MyGUI::Colour(0.6f, 0.6f, 0.6f));
markerWidget->setHoverColour(MyGUI::Colour(1.0f, 1.0f, 1.0f));
markerWidget->setUserData(marker);
markerWidget->setNeedMouseFocus(true);
customMarkerCreated(markerWidget);
mCustomMarkerWidgets.push_back(markerWidget);
}
} }
MarkerUserData markerPos (mLocalMapRender);
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos);
MyGUI::IntCoord widgetCoord(widgetPos.left - 8,
widgetPos.top - 8,
16, 16);
MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>("CustomMarkerButton",
widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote));
markerWidget->setNormalColour(MyGUI::Colour(0.6f, 0.6f, 0.6f));
markerWidget->setHoverColour(MyGUI::Colour(1.0f, 1.0f, 1.0f));
markerWidget->setUserData(marker);
markerWidget->setNeedMouseFocus(true);
customMarkerCreated(markerWidget);
mCustomMarkerWidgets.push_back(markerWidget);
} }
redraw(); redraw();
} }
@ -411,11 +425,9 @@ namespace MWGui
MWBase::World::DoorMarker marker = *it; MWBase::World::DoorMarker marker = *it;
std::vector<std::string> destNotes; std::vector<std::string> destNotes;
for (std::vector<ESM::CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest);
{ for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it)
if (it->mCell == marker.dest) destNotes.push_back(it->second.mNote);
destNotes.push_back(it->mNote);
}
MarkerUserData data (mLocalMapRender); MarkerUserData data (mLocalMapRender);
data.notes = destNotes; data.notes = destNotes;

@ -42,14 +42,20 @@ namespace MWGui
size_t size() const; size_t size() const;
std::vector<ESM::CustomMarker>::const_iterator begin() const; typedef std::multimap<ESM::CellId, ESM::CustomMarker> ContainerType;
std::vector<ESM::CustomMarker>::const_iterator end() const;
typedef std::pair<ContainerType::const_iterator, ContainerType::const_iterator> RangeType;
ContainerType::const_iterator begin() const;
ContainerType::const_iterator end() const;
RangeType getMarkers(const ESM::CellId& cellId) const;
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
EventHandle_Void eventMarkersChanged; EventHandle_Void eventMarkersChanged;
private: private:
std::vector<ESM::CustomMarker> mMarkers; ContainerType mMarkers;
}; };
class LocalMapBase class LocalMapBase

@ -1672,10 +1672,10 @@ namespace MWGui
writer.endRecord(ESM::REC_ASPL); writer.endRecord(ESM::REC_ASPL);
} }
for (std::vector<ESM::CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) for (CustomMarkerCollection::ContainerType::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it)
{ {
writer.startRecord(ESM::REC_MARK); writer.startRecord(ESM::REC_MARK);
(*it).save(writer); it->second.save(writer);
writer.endRecord(ESM::REC_MARK); writer.endRecord(ESM::REC_MARK);
} }
} }

@ -35,3 +35,26 @@ bool ESM::operator!= (const CellId& left, const CellId& right)
{ {
return !(left==right); return !(left==right);
} }
bool ESM::operator < (const CellId& left, const CellId& right)
{
if (left.mPaged < right.mPaged)
return true;
if (left.mPaged > right.mPaged)
return false;
if (left.mPaged)
{
if (left.mIndex.mX < right.mIndex.mX)
return true;
if (left.mIndex.mX > right.mIndex.mX)
return false;
if (left.mIndex.mY < right.mIndex.mY)
return true;
if (left.mIndex.mY > right.mIndex.mY)
return false;
}
return left.mWorldspace < right.mWorldspace;
}

@ -26,6 +26,7 @@ namespace ESM
bool operator== (const CellId& left, const CellId& right); bool operator== (const CellId& left, const CellId& right);
bool operator!= (const CellId& left, const CellId& right); bool operator!= (const CellId& left, const CellId& right);
bool operator< (const CellId& left, const CellId& right);
} }
#endif #endif

Loading…
Cancel
Save