[eye] unordered_map is replaced by kdtree

This commit is contained in:
Arsentiy Milchakov 2018-11-02 17:10:58 +03:00 committed by Tatiana Yan
parent 285c155cb2
commit 2bf229b09a
8 changed files with 292 additions and 179 deletions

View file

@ -33,9 +33,9 @@ Queue MakeDefaultQueueForTesting()
notification.m_type = Notification::Type::UgcReview;
notification.m_mapObject = std::make_unique<eye::MapObject>();
notification.m_mapObject->m_bestType = "cafe";
notification.m_mapObject->m_pos = {15.686299, 73.704084};
notification.m_mapObject->m_readableName = "Baba";
notification.m_mapObject->SetBestType("cafe");
notification.m_mapObject->SetPos({15.686299, 73.704084});
notification.m_mapObject->SetReadableName("Baba");
queue.m_candidates.emplace_back(std::move(notification));
}
@ -45,9 +45,9 @@ Queue MakeDefaultQueueForTesting()
notification.m_type = Notification::Type::UgcReview;
notification.m_mapObject = std::make_unique<eye::MapObject>();
notification.m_mapObject->m_bestType = "shop";
notification.m_mapObject->m_pos = {12.923975, 100.776627};
notification.m_mapObject->m_readableName = "7eleven";
notification.m_mapObject->SetBestType("shop");
notification.m_mapObject->SetPos({12.923975, 100.776627});
notification.m_mapObject->SetReadableName("7eleven");
queue.m_candidates.emplace_back(std::move(notification));
}
@ -57,9 +57,9 @@ Queue MakeDefaultQueueForTesting()
notification.m_type = Notification::Type::UgcReview;
notification.m_mapObject = std::make_unique<eye::MapObject>();
notification.m_mapObject->m_bestType = "viewpoint";
notification.m_mapObject->m_pos = {-45.943995, 167.619933};
notification.m_mapObject->m_readableName = "Waiau";
notification.m_mapObject->SetBestType("viewpoint");
notification.m_mapObject->SetPos({-45.943995, 167.619933});
notification.m_mapObject->SetReadableName("Waiau");
queue.m_candidates.emplace_back(std::move(notification));
}
@ -79,9 +79,9 @@ void CompareWithDefaultQueue(Queue const & lhs)
auto const & rhsItem = rhs.m_candidates[i];
TEST_EQUAL(lhsItem.m_type, rhsItem.m_type, ());
TEST(lhsItem.m_mapObject, ());
TEST_EQUAL(lhsItem.m_mapObject->m_bestType, rhsItem.m_mapObject->m_bestType, ());
TEST_EQUAL(lhsItem.m_mapObject->m_readableName, rhsItem.m_mapObject->m_readableName, ());
TEST_EQUAL(lhsItem.m_mapObject->m_pos, lhsItem.m_mapObject->m_pos, ());
TEST_EQUAL(lhsItem.m_mapObject->GetBestType(), rhsItem.m_mapObject->GetBestType(), ());
TEST_EQUAL(lhsItem.m_mapObject->GetReadableName(), rhsItem.m_mapObject->GetReadableName(), ());
TEST_EQUAL(lhsItem.m_mapObject->GetPos(), lhsItem.m_mapObject->GetPos(), ());
}
}

View file

@ -37,8 +37,7 @@ boost::optional<Notification> NotificationManager::GetNotification() const
return {};
}
void NotificationManager::OnMapObjectEvent(eye::MapObject const & poi,
eye::MapObject::Events const & events)
void NotificationManager::OnMapObjectEvent(eye::MapObject const & poi)
{
// Is not implemented yet. Coming soon.
}

View file

@ -18,7 +18,7 @@ public:
boost::optional<Notification> GetNotification() const;
// eye::Subscriber overrides:
void OnMapObjectEvent(eye::MapObject const & poi, eye::MapObject::Events const & events) override;
void OnMapObjectEvent(eye::MapObject const & poi) override;
private:
bool Save();

View file

@ -63,10 +63,12 @@ bool SaveMapObjects(MapObjects const & mapObjects)
return Storage::SaveMapObjects(fileData);
}
bool SaveMapObjectEvent(MapObject const & mapObject, MapObject::Event const & event)
bool SaveLastMapObjectEvent(MapObject const & mapObject)
{
ASSERT(!mapObject.GetEvents().empty(), ());
std::vector<int8_t> eventData;
Serdes::SerializeMapObjectEvent(mapObject, event, eventData);
Serdes::SerializeMapObjectEvent(mapObject, mapObject.GetEvents().back(), eventData);
return Storage::AppendMapObjectEvent(eventData);
}
@ -126,9 +128,11 @@ void Eye::TrimExpiredMapObjectEvents()
auto editableInfo = std::make_shared<Info>(*info);
auto changed = false;
for (auto it = editableInfo->m_mapObjects.begin(); it != editableInfo->m_mapObjects.end();)
std::vector<MapObject> removeQueue;
editableInfo->m_mapObjects.ForEach([&removeQueue, &changed](MapObject const & item)
{
auto & events = it->second;
auto & events = item.GetEditableEvents();
events.erase(std::remove_if(events.begin(), events.end(), [&changed](auto const & item)
{
if (Clock::now() - item.m_eventTime >= kMapObjectEventsExpirePeriod)
@ -142,9 +146,12 @@ void Eye::TrimExpiredMapObjectEvents()
}), events.end());
if (events.empty())
it = editableInfo->m_mapObjects.erase(it);
else
++it;
removeQueue.push_back(item);
});
for (auto const & toRemove : removeQueue)
{
editableInfo->m_mapObjects.Erase(toRemove);
}
if (changed && SaveMapObjects(editableInfo->m_mapObjects))
@ -316,33 +323,40 @@ void Eye::RegisterMapObjectEvent(MapObject const & mapObject, MapObject::Event::
auto editableInfo = std::make_shared<Info>(*info);
auto & mapObjects = editableInfo->m_mapObjects;
MapObject result = mapObject;
MapObject::Event event;
event.m_type = type;
event.m_userPos = userPos;
event.m_eventTime = Clock::now();
MapObject::Events events;
auto it = mapObjects.find(mapObject);
if (it == mapObjects.end())
bool found = false;
mapObjects.ForEachInRect(result.GetLimitRect(), [&found, &event, &result](MapObject const & item)
{
events = {event};
mapObjects.emplace(mapObject, std::move(events));
}
else
if (item != result)
return;
if (!found)
found = true;
item.GetEditableEvents().emplace_back(std::move(event));
result = item;
});
if (!found)
{
it->second.push_back(event);
events = it->second;
result.GetEditableEvents() = {std::move(event)};
mapObjects.Add(result);
}
if (!SaveMapObjectEvent(mapObject, event))
if (!SaveLastMapObjectEvent(result))
return;
m_info.Set(editableInfo);
GetPlatform().RunTask(Platform::Thread::Gui, [this, mapObject, events]
GetPlatform().RunTask(Platform::Thread::Gui, [this, result]
{
for (auto subscriber : m_subscribers)
{
subscriber->OnMapObjectEvent(mapObject, events);
subscriber->OnMapObjectEvent(result);
}
});
}
@ -404,54 +418,54 @@ void Eye::Event::LayerShown(Layer::Type type)
// static
void Eye::Event::PlacePageOpened(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos)
std::string const & readableName, m2::PointD const & userPos)
{
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, userPos]
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, readableName, userPos]
{
Instance().RegisterMapObjectEvent({bestType, pos}, MapObject::Event::Type::Open, userPos);
Instance().RegisterMapObjectEvent({bestType, pos, readableName}, MapObject::Event::Type::Open, userPos);
});
}
// static
void Eye::Event::UgcEditorOpened(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos)
std::string const & readableName, m2::PointD const & userPos)
{
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, userPos]
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, readableName, userPos]
{
Instance().RegisterMapObjectEvent({bestType, pos}, MapObject::Event::Type::UgcEditorOpened,
Instance().RegisterMapObjectEvent({bestType, pos, readableName}, MapObject::Event::Type::UgcEditorOpened,
userPos);
});
}
// static
void Eye::Event::UgcSaved(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos)
std::string const & readableName, m2::PointD const & userPos)
{
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, userPos]
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, readableName, userPos]
{
Instance().RegisterMapObjectEvent({bestType, pos}, MapObject::Event::Type::UgcSaved,
Instance().RegisterMapObjectEvent({bestType, pos, readableName}, MapObject::Event::Type::UgcSaved,
userPos);
});
}
// static
void Eye::Event::AddToBookmarkClicked(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos)
std::string const & readableName, m2::PointD const & userPos)
{
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, userPos]
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, readableName, userPos]
{
Instance().RegisterMapObjectEvent({bestType, pos}, MapObject::Event::Type::AddToBookmark,
Instance().RegisterMapObjectEvent({bestType, pos, readableName}, MapObject::Event::Type::AddToBookmark,
userPos);
});
}
// static
void Eye::Event::RouteCreatedToObject(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos)
std::string const & readableName, m2::PointD const & userPos)
{
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, userPos]
GetPlatform().RunTask(Platform::Thread::File, [bestType, pos, readableName, userPos]
{
Instance().RegisterMapObjectEvent({bestType, pos}, MapObject::Event::Type::RouteToCreated,
Instance().RegisterMapObjectEvent({bestType, pos, readableName}, MapObject::Event::Type::RouteToCreated,
userPos);
});
}

View file

@ -22,7 +22,7 @@ public:
virtual void OnDiscoveryShown(Time const & time) {}
virtual void OnDiscoveryItemClicked(Discovery::Event event) {}
virtual void OnLayerShown(Layer const & layer) {}
virtual void OnMapObjectEvent(MapObject const & poi, MapObject::Events const & events) {}
virtual void OnMapObjectEvent(MapObject const & poi) {}
};
// Note This class IS thread-safe.
@ -45,15 +45,15 @@ public:
static void DiscoveryItemClicked(Discovery::Event event);
static void LayerShown(Layer::Type type);
static void PlacePageOpened(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos);
std::string const & readableName, m2::PointD const & userPos);
static void UgcEditorOpened(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos);
std::string const & readableName, m2::PointD const & userPos);
static void UgcSaved(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos);
std::string const & readableName, m2::PointD const & userPos);
static void AddToBookmarkClicked(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos);
std::string const & readableName, m2::PointD const & userPos);
static void RouteCreatedToObject(std::string const & bestType, m2::PointD const & pos,
m2::PointD const & userPos);
std::string const & readableName, m2::PointD const & userPos);
};
static Eye & Instance();

View file

@ -4,6 +4,8 @@
#include "geometry/point2d.hpp"
#include "geometry/tree4d.hpp"
#include "base/visitor.hpp"
#include <array>
@ -12,7 +14,6 @@
#include <deque>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>
namespace eye
@ -160,8 +161,9 @@ struct Tip
using Tips = std::vector<Tip>;
struct MapObject
class MapObject
{
public:
struct Event
{
enum class Type : uint8_t
@ -183,29 +185,57 @@ struct MapObject
using Events = std::deque<Event>;
struct Hash
MapObject() = default;
MapObject(std::string const & bestType, m2::PointD const & pos, std::string const & readableName)
: m_bestType(bestType)
, m_pos(pos)
, m_readableName(readableName)
, m_limitRect(pos.x - 1e-7, pos.y - 1e-7, pos.x + 1e-7, pos.y + 1e-7)
{
size_t operator()(MapObject const & p) const
{
return base::Hash(base::Hash(p.m_pos.x, p.m_pos.y),
base::Hash(p.m_bestType, p.m_bestType));
}
};
}
bool operator==(MapObject const & rhs) const
{
return m_pos == rhs.m_pos && m_bestType == rhs.m_bestType;
return m_pos.EqualDxDy(rhs.GetPos(), 1e-7) && GetBestType() == rhs.GetBestType();
}
DECLARE_VISITOR(visitor(m_bestType, "type"), visitor(m_pos, "pos"),
visitor(m_readableName, "name"));
bool operator!=(MapObject const & rhs) const { return !((*this) == rhs); }
std::string const & GetBestType() const { return m_bestType; }
void SetBestType(std::string const & bestType) { m_bestType = bestType; }
m2::PointD const & GetPos() const { return m_pos; }
void SetPos(m2::PointD const & pos)
{
m_pos = pos;
m_limitRect = {m_pos.x - 1e-7, m_pos.y - 1e-7, m_pos.x + 1e-7, m_pos.y + 1e-7};
}
std::string const & GetReadableName() const { return m_readableName; }
void SetReadableName(std::string const & readableName) { m_readableName = readableName; }
MapObject::Events & GetEditableEvents() const { return m_events; }
MapObject::Events const & GetEvents() const { return m_events; }
m2::RectD GetLimitRect() const { return m_limitRect; }
DECLARE_VISITOR(visitor(m_bestType, "type"), visitor(m_pos, "pos"),
visitor(m_readableName, "name"), visitor(m_events, "events"));
private:
std::string m_bestType;
m2::PointD m_pos;
std::string m_readableName;
mutable MapObject::Events m_events;
m2::RectD m_limitRect;
};
using MapObjects = std::unordered_map<MapObject, MapObject::Events, MapObject::Hash>;
using MapObjects = m4::Tree<MapObject>;
struct InfoV0
{

View file

@ -79,21 +79,21 @@ void Serdes::SerializeMapObjects(MapObjects const & mapObjects, std::vector<int8
std::string const nextLine = "\n";
MapObjectEvent event;
for (auto const & poi : mapObjects)
mapObjects.ForEach([&writer, &event, &nextLine](MapObject const & item)
{
for (auto const & poiEvent : poi.second)
for (auto const & poiEvent : item.GetEvents())
{
// Additional scope is added because of the coding::SerializerJson dumps result at destruction.
{
coding::SerializerJson<Sink> ser(writer);
event.m_bestPoiType = poi.first.m_bestType;
event.m_poiPos = poi.first.m_pos;
event.m_bestPoiType = item.GetBestType();
event.m_poiPos = item.GetPos();
event.m_event = poiEvent;
ser(event);
}
writer.Write(nextLine.data(), nextLine.size());
}
}
});
}
// static
@ -118,18 +118,25 @@ void Serdes::DeserializeMapObjects(std::vector<int8_t> const & bytes, MapObjects
coding::DeserializerJson des(eventString);
des(event);
poi.m_bestType = event.m_bestPoiType;
poi.m_pos = event.m_poiPos;
poi.SetBestType(event.m_bestPoiType);
poi.SetPos(event.m_poiPos);
auto it = result.find(poi);
if (it == result.end())
bool found = false;
result.ForEachInRect(poi.GetLimitRect(), [&found, &poi, &event](MapObject const & item)
{
MapObject::Events events = {event.m_event};
result.emplace(poi, std::move(events));
}
else
if (item != poi)
return;
if (!found)
found = true;
item.GetEditableEvents().push_back(event.m_event);
});
if (!found)
{
it->second.emplace_back(event.m_event);
poi.GetEditableEvents().push_back(event.m_event);
result.Add(poi);
}
}
}
@ -153,8 +160,8 @@ void Serdes::SerializeMapObjectEvent(MapObject const & poi, MapObject::Event con
std::string const nextLine = "\n";
MapObjectEvent event;
event.m_bestPoiType = poi.m_bestType;
event.m_poiPos = poi.m_pos;
event.m_bestPoiType = poi.GetBestType();
event.m_poiPos = poi.GetPos();
event.m_event = poiEvent;
ser(event);
writer.Write(nextLine.data(), nextLine.size());

View file

@ -41,19 +41,18 @@ Info MakeDefaultInfoForTesting()
info.m_discovery.m_lastClickedTime = Time(std::chrono::hours(30005));
MapObject poi;
poi.m_bestType = "shop";
poi.m_pos = {53.652007, 108.143443};
poi.SetBestType("shop");
poi.SetPos({53.652007, 108.143443});
MapObject::Event eventInfo;
MapObject::Events events;
eventInfo.m_eventTime = Time(std::chrono::hours(90000));
eventInfo.m_userPos = {72.045507, 81.408095};
eventInfo.m_type = MapObject::Event::Type::AddToBookmark;
events.emplace_back(eventInfo);
poi.GetEditableEvents().push_back(eventInfo);
eventInfo.m_eventTime = Time(std::chrono::hours(80000));
eventInfo.m_userPos = {53.016347, 158.683327};
eventInfo.m_type = MapObject::Event::Type::Open;
events.emplace_back(eventInfo);
info.m_mapObjects.emplace(poi, events);
poi.GetEditableEvents().push_back(eventInfo);
info.m_mapObjects.Add(poi);
return info;
}
@ -78,19 +77,23 @@ void CompareWithDefaultInfo(Info const & lhs)
TEST_EQUAL(lhs.m_discovery.m_lastClickedTime, rhs.m_discovery.m_lastClickedTime, ());
TEST_EQUAL(lhs.m_discovery.m_eventCounters.Get(Discovery::Event::MoreAttractionsClicked),
rhs.m_discovery.m_eventCounters.Get(Discovery::Event::MoreAttractionsClicked), ());
TEST_EQUAL(lhs.m_mapObjects.size(), rhs.m_mapObjects.size(), ());
TEST_EQUAL(lhs.m_mapObjects.GetSize(), rhs.m_mapObjects.GetSize(), ());
auto const & lPoi = *(lhs.m_mapObjects.begin());
auto const & rPoi = *(rhs.m_mapObjects.begin());
TEST(lPoi.first.m_pos.EqualDxDy(rPoi.first.m_pos, 1e-6), ());
TEST_EQUAL(lPoi.first.m_bestType, rPoi.first.m_bestType, ());
TEST_EQUAL(lPoi.second.size(), rPoi.second.size(), ());
TEST(lPoi.second[0].m_userPos.EqualDxDy(rPoi.second[0].m_userPos, 1e-6), ());
TEST_EQUAL(lPoi.second[0].m_eventTime, rPoi.second[0].m_eventTime, ());
TEST_EQUAL(lPoi.second[0].m_type, rPoi.second[0].m_type, ());
TEST(lPoi.second[1].m_userPos.EqualDxDy(rPoi.second[1].m_userPos, 1e-6), ());
TEST_EQUAL(lPoi.second[1].m_eventTime, rPoi.second[1].m_eventTime, ());
TEST_EQUAL(lPoi.second[1].m_type, rPoi.second[1].m_type, ());
lhs.m_mapObjects.ForEach([&rhs](MapObject const & lhsObj)
{
rhs.m_mapObjects.ForEach([&lhsObj](MapObject const & rhsObj)
{
TEST(lhsObj.GetPos().EqualDxDy(rhsObj.GetPos(), 1e-6), ());
TEST_EQUAL(lhsObj.GetBestType(), rhsObj.GetBestType(), ());
TEST_EQUAL(lhsObj.GetEvents().size(), rhsObj.GetEvents().size(), ());
TEST(lhsObj.GetEvents()[0].m_userPos.EqualDxDy(rhsObj.GetEvents()[0].m_userPos, 1e-6), ());
TEST_EQUAL(lhsObj.GetEvents()[0].m_eventTime, rhsObj.GetEvents()[0].m_eventTime, ());
TEST_EQUAL(lhsObj.GetEvents()[0].m_type, rhsObj.GetEvents()[0].m_type, ());
TEST(lhsObj.GetEvents()[1].m_userPos.EqualDxDy(rhsObj.GetEvents()[1].m_userPos, 1e-6), ());
TEST_EQUAL(lhsObj.GetEvents()[1].m_eventTime, rhsObj.GetEvents()[1].m_eventTime, ());
TEST_EQUAL(lhsObj.GetEvents()[1].m_type, rhsObj.GetEvents()[1].m_type, ());
});
});
}
Time GetLastShownTipTime(Tips const & tips)
@ -392,53 +395,51 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, TrimExpiredMapObjectEvents)
Info info;
{
MapObject poi;
poi.m_bestType = "shop";
poi.m_pos = {53.652007, 108.143443};
poi.SetBestType("shop");
poi.SetPos({53.652007, 108.143443});
MapObject::Event eventInfo;
MapObject::Events events;
eventInfo.m_eventTime = Clock::now() - std::chrono::hours((24 * 30 * 3) + 1);
eventInfo.m_userPos = {72.045507, 81.408095};
eventInfo.m_type = MapObject::Event::Type::Open;
events.emplace_back(eventInfo);
poi.GetEditableEvents().emplace_back(eventInfo);
eventInfo.m_eventTime =
Clock::now() - (std::chrono::hours(24 * 30 * 3) + std::chrono::seconds(1));
eventInfo.m_userPos = {72.045400, 81.408200};
eventInfo.m_type = MapObject::Event::Type::AddToBookmark;
events.emplace_back(eventInfo);
poi.GetEditableEvents().emplace_back(eventInfo);
eventInfo.m_eventTime = Clock::now() - std::chrono::hours(24 * 30 * 3);
eventInfo.m_userPos = {72.045450, 81.408201};
eventInfo.m_type = MapObject::Event::Type::RouteToCreated;
events.emplace_back(eventInfo);
poi.GetEditableEvents().emplace_back(eventInfo);
info.m_mapObjects.emplace(poi, events);
info.m_mapObjects.Add(poi);
}
{
MapObject poi;
poi.m_bestType = "cafe";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("cafe");
poi.SetPos({53.652005, 108.143448});
MapObject::Event eventInfo;
MapObject::Events events;
eventInfo.m_eventTime = Clock::now() - std::chrono::hours(24 * 30 * 3);
eventInfo.m_userPos = {53.016347, 158.683327};
eventInfo.m_type = MapObject::Event::Type::Open;
events.emplace_back(eventInfo);
poi.GetEditableEvents().emplace_back(eventInfo);
eventInfo.m_eventTime = Clock::now() - std::chrono::seconds(30);
eventInfo.m_userPos = {53.016347, 158.683327};
eventInfo.m_type = MapObject::Event::Type::UgcEditorOpened;
events.emplace_back(eventInfo);
poi.GetEditableEvents().emplace_back(eventInfo);
eventInfo.m_eventTime = Clock::now();
eventInfo.m_userPos = {53.116347, 158.783327};
eventInfo.m_type = MapObject::Event::Type::UgcSaved;
events.emplace_back(eventInfo);
poi.GetEditableEvents().emplace_back(eventInfo);
info.m_mapObjects.emplace(poi, events);
info.m_mapObjects.Add(poi);
}
EyeForTesting::SetInfo(info);
@ -446,34 +447,52 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, TrimExpiredMapObjectEvents)
{
auto const resultInfo = Eye::Instance().GetInfo();
auto const & mapObjects = resultInfo->m_mapObjects;
TEST_EQUAL(mapObjects.size(), 2, ());
TEST_EQUAL(mapObjects.GetSize(), 2, ());
{
MapObject poi;
poi.m_bestType = "shop";
poi.m_pos = {53.652007, 108.143443};
poi.SetBestType("shop");
poi.SetPos({53.652007, 108.143443});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it != mapObjects.end(), ());
TEST_EQUAL(it->second.size(), 3, ());
TEST_EQUAL(it->second[0].m_type, MapObject::Event::Type::Open, ());
TEST_EQUAL(it->second[1].m_userPos, m2::PointD(72.045400, 81.408200), ());
TEST_EQUAL(it->second[2].m_userPos, m2::PointD(72.045450, 81.408201), ());
if (!found)
found = true;
TEST_EQUAL(item.GetEvents().size(), 3, ());
TEST_EQUAL(item.GetEvents()[0].m_type, MapObject::Event::Type::Open, ());
TEST_EQUAL(item.GetEvents()[1].m_userPos, m2::PointD(72.045400, 81.408200), ());
TEST_EQUAL(item.GetEvents()[2].m_userPos, m2::PointD(72.045450, 81.408201), ());
});
TEST(found, ());
}
{
MapObject poi;
poi.m_bestType = "cafe";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("cafe");
poi.SetPos({53.652005, 108.143448});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it != mapObjects.end(), ());
TEST_EQUAL(it->second.size(), 3, ());
TEST_EQUAL(it->second[0].m_type, MapObject::Event::Type::Open, ());
TEST_EQUAL(it->second[1].m_userPos, m2::PointD(53.016347, 158.683327), ());
TEST_EQUAL(it->second[2].m_userPos, m2::PointD(53.116347, 158.783327), ());
if (!found)
found = true;
TEST_EQUAL(item.GetEvents().size(), 3, ());
TEST_EQUAL(item.GetEvents()[0].m_type, MapObject::Event::Type::Open, ());
TEST_EQUAL(item.GetEvents()[1].m_userPos, m2::PointD(53.016347, 158.683327), ());
TEST_EQUAL(item.GetEvents()[2].m_userPos, m2::PointD(53.116347, 158.783327), ());
});
TEST(found, ());
}
}
@ -482,32 +501,49 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, TrimExpiredMapObjectEvents)
{
auto const resultInfo = Eye::Instance().GetInfo();
auto const & mapObjects = resultInfo->m_mapObjects;
TEST_EQUAL(mapObjects.size(), 1, ());
TEST_EQUAL(mapObjects.GetSize(), 1, ());
{
MapObject poi;
poi.m_bestType = "shop";
poi.m_pos = {53.652007, 108.143443};
poi.SetBestType("shop");
poi.SetPos({53.652007, 108.143443});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it == mapObjects.end(), ());
if (!found)
found = true;
});
TEST(!found, ());
}
{
MapObject poi;
poi.m_bestType = "cafe";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("cafe");
poi.SetPos({53.652005, 108.143448});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it != mapObjects.end(), ());
TEST_EQUAL(it->second.size(), 2, ());
TEST_EQUAL(it->second[0].m_userPos, m2::PointD(53.016347, 158.683327), ());
TEST_EQUAL(it->second[0].m_type, MapObject::Event::Type::UgcEditorOpened, ());
if (!found)
found = true;
TEST_EQUAL(it->second[1].m_userPos, m2::PointD(53.116347, 158.783327), ());
TEST_EQUAL(it->second[1].m_type, MapObject::Event::Type::UgcSaved, ());
TEST_EQUAL(item.GetEvents().size(), 2, ());
TEST_EQUAL(item.GetEvents()[0].m_userPos, m2::PointD(53.016347, 158.683327), ());
TEST_EQUAL(item.GetEvents()[0].m_type, MapObject::Event::Type::UgcEditorOpened, ());
TEST_EQUAL(item.GetEvents()[1].m_userPos, m2::PointD(53.116347, 158.783327), ());
TEST_EQUAL(item.GetEvents()[1].m_type, MapObject::Event::Type::UgcSaved, ());
});
TEST(found, ());
}
}
}
@ -516,8 +552,8 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, RegisterMapObjectEvent)
{
{
MapObject poi;
poi.m_bestType = "cafe";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("cafe");
poi.SetPos({53.652005, 108.143448});
m2::PointD userPos = {53.016347, 158.683327};
EyeForTesting::RegisterMapObjectEvent(poi, MapObject::Event::Type::Open, userPos);
@ -528,8 +564,8 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, RegisterMapObjectEvent)
}
{
MapObject poi;
poi.m_bestType = "shop";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("shop");
poi.SetPos({53.652005, 108.143448});
m2::PointD userPos = {0.0, 0.0};
EyeForTesting::RegisterMapObjectEvent(poi, MapObject::Event::Type::RouteToCreated, userPos);
@ -541,8 +577,8 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, RegisterMapObjectEvent)
{
MapObject poi;
poi.m_bestType = "amenity-bench";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("amenity-bench");
poi.SetPos({53.652005, 108.143448});
m2::PointD userPos = {0.0, 0.0};
EyeForTesting::RegisterMapObjectEvent(poi, MapObject::Event::Type::Open, userPos);
@ -551,51 +587,78 @@ UNIT_CLASS_TEST(ScopedEyeForTesting, RegisterMapObjectEvent)
{
auto const resultInfo = Eye::Instance().GetInfo();
auto const & mapObjects = resultInfo->m_mapObjects;
TEST_EQUAL(mapObjects.size(), 3, ());
TEST_EQUAL(mapObjects.GetSize(), 3, ());
{
MapObject poi;
poi.m_bestType = "cafe";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("cafe");
poi.SetPos({53.652005, 108.143448});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it != mapObjects.end(), ());
TEST_EQUAL(it->second.size(), 2, ());
TEST_EQUAL(it->second[0].m_userPos, m2::PointD(53.016347, 158.683327), ());
TEST_EQUAL(it->second[0].m_type, MapObject::Event::Type::Open, ());
if (!found)
found = true;
TEST_EQUAL(it->second[1].m_userPos, m2::PointD(53.016345, 158.683329), ());
TEST_EQUAL(it->second[1].m_type, MapObject::Event::Type::RouteToCreated, ());
TEST_EQUAL(item.GetEvents().size(), 2, ());
TEST_EQUAL(item.GetEvents()[0].m_userPos, m2::PointD(53.016347, 158.683327), ());
TEST_EQUAL(item.GetEvents()[0].m_type, MapObject::Event::Type::Open, ());
TEST_EQUAL(item.GetEvents()[1].m_userPos, m2::PointD(53.016345, 158.683329), ());
TEST_EQUAL(item.GetEvents()[1].m_type, MapObject::Event::Type::RouteToCreated, ());
});
TEST(found, ());
}
{
MapObject poi;
poi.m_bestType = "shop";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("shop");
poi.SetPos({53.652005, 108.143448});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it != mapObjects.end(), ());
TEST_EQUAL(it->second.size(), 2, ());
TEST_EQUAL(it->second[0].m_userPos, m2::PointD(0.0, 0.0), ());
TEST_EQUAL(it->second[0].m_type, MapObject::Event::Type::RouteToCreated, ());
if (!found)
found = true;
TEST_EQUAL(it->second[1].m_userPos, m2::PointD(158.016345, 53.683329), ());
TEST_EQUAL(it->second[1].m_type, MapObject::Event::Type::AddToBookmark, ());
TEST_EQUAL(item.GetEvents().size(), 2, ());
TEST_EQUAL(item.GetEvents()[0].m_userPos, m2::PointD(0.0, 0.0), ());
TEST_EQUAL(item.GetEvents()[0].m_type, MapObject::Event::Type::RouteToCreated, ());
TEST_EQUAL(item.GetEvents()[1].m_userPos, m2::PointD(158.016345, 53.683329), ());
TEST_EQUAL(item.GetEvents()[1].m_type, MapObject::Event::Type::AddToBookmark, ());
});
TEST(found, ());
}
{
MapObject poi;
poi.m_bestType = "amenity-bench";
poi.m_pos = {53.652005, 108.143448};
poi.SetBestType("amenity-bench");
poi.SetPos({53.652005, 108.143448});
auto const it = mapObjects.find(poi);
bool found = false;
mapObjects.ForEachInRect(poi.GetLimitRect(), [&poi, &found](MapObject const & item)
{
if (poi != item)
return;
TEST(it != mapObjects.end(), ());
TEST_EQUAL(it->second.size(), 1, ());
TEST_EQUAL(it->second[0].m_userPos, m2::PointD(0.0, 0.0), ());
TEST_EQUAL(it->second[0].m_type, MapObject::Event::Type::Open, ());
if (!found)
found = true;
TEST_EQUAL(item.GetEvents().size(), 1, ());
TEST_EQUAL(item.GetEvents()[0].m_userPos, m2::PointD(0.0, 0.0), ());
TEST_EQUAL(item.GetEvents()[0].m_type, MapObject::Event::Type::Open, ());
});
TEST(found, ());
}
}
}