mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:20:06 +00:00
Add working poi manager implementation
This commit is contained in:
parent
ec4387112e
commit
f5d867cf1a
2 changed files with 191 additions and 13 deletions
|
|
@ -1,9 +1,14 @@
|
||||||
#include <scwx/qt/manager/poi_manager.hpp>
|
#include <scwx/qt/manager/poi_manager.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/qt/types/poi_types.hpp>
|
||||||
#include <scwx/qt/util/json.hpp>
|
#include <scwx/qt/util/json.hpp>
|
||||||
|
#include <scwx/qt/main/application.hpp>
|
||||||
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <boost/json.hpp>
|
#include <boost/json.hpp>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
|
|
@ -13,7 +18,7 @@ namespace qt
|
||||||
namespace manager
|
namespace manager
|
||||||
{
|
{
|
||||||
|
|
||||||
static const std::string logPrefix_ = "scwx::qt::manager::placefile_manager";
|
static const std::string logPrefix_ = "scwx::qt::manager::poi_manager";
|
||||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
static const std::string kNameName_ = "name";
|
static const std::string kNameName_ = "name";
|
||||||
|
|
@ -23,22 +28,27 @@ static const std::string kLongitudeName_ = "longitude";
|
||||||
class POIManager::Impl
|
class POIManager::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class PointOfInterest;
|
class POIRecord;
|
||||||
|
|
||||||
explicit Impl(POIManager* self) : self_ {self} {}
|
explicit Impl(POIManager* self) : self_ {self} {}
|
||||||
|
~Impl() {}
|
||||||
|
|
||||||
std::string poiSettingsPath_ {};
|
std::string poiSettingsPath_ {};
|
||||||
|
std::vector<std::shared_ptr<POIRecord>> poiRecords_ {};
|
||||||
|
|
||||||
POIManager* self_;
|
POIManager* self_;
|
||||||
|
|
||||||
|
void InitializePOISettings();
|
||||||
void ReadPOISettings();
|
void ReadPOISettings();
|
||||||
|
void WritePOISettings();
|
||||||
|
std::shared_ptr<POIRecord> GetPOIByName(const std::string& name);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class POIManager::Impl::PointOfInterest
|
class POIManager::Impl::POIRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PointOfInterest(std::string name, double latitude, double longitude) :
|
POIRecord(std::string name, double latitude, double longitude) :
|
||||||
name_ {name}, latitude_ {latitude}, longitude_ {longitude}
|
name_ {name}, latitude_ {latitude}, longitude_ {longitude}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -49,28 +59,45 @@ public:
|
||||||
|
|
||||||
friend void tag_invoke(boost::json::value_from_tag,
|
friend void tag_invoke(boost::json::value_from_tag,
|
||||||
boost::json::value& jv,
|
boost::json::value& jv,
|
||||||
const std::shared_ptr<PointOfInterest>& record)
|
const std::shared_ptr<POIRecord>& record)
|
||||||
{
|
{
|
||||||
jv = {{kNameName_, record->name_},
|
jv = {{kNameName_, record->name_},
|
||||||
{kLatitudeName_, record->latitude_},
|
{kLatitudeName_, record->latitude_},
|
||||||
{kLongitudeName_, record->longitude_}};
|
{kLongitudeName_, record->longitude_}};
|
||||||
}
|
}
|
||||||
|
|
||||||
friend PointOfInterest tag_invoke(boost::json::value_to_tag<PointOfInterest>,
|
friend POIRecord tag_invoke(boost::json::value_to_tag<POIRecord>,
|
||||||
const boost::json::value& jv)
|
const boost::json::value& jv)
|
||||||
{
|
{
|
||||||
return PointOfInterest(
|
return POIRecord(
|
||||||
boost::json::value_to<std::string>(jv.at(kNameName_)),
|
boost::json::value_to<std::string>(jv.at(kNameName_)),
|
||||||
boost::json::value_to<double>(jv.at(kLatitudeName_)),
|
boost::json::value_to<double>(jv.at(kLatitudeName_)),
|
||||||
boost::json::value_to<double>(jv.at(kLongitudeName_)));
|
boost::json::value_to<double>(jv.at(kLongitudeName_)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
POIManager::POIManager() : p(std::make_unique<Impl>(this)) {}
|
|
||||||
|
void POIManager::Impl::InitializePOISettings()
|
||||||
|
{
|
||||||
|
std::string appDataPath {
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
|
||||||
|
.toStdString()};
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(appDataPath))
|
||||||
|
{
|
||||||
|
if (!std::filesystem::create_directories(appDataPath))
|
||||||
|
{
|
||||||
|
logger_->error("Unable to create application data directory: \"{}\"",
|
||||||
|
appDataPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
poiSettingsPath_ = appDataPath + "/points_of_interest.json";
|
||||||
|
}
|
||||||
|
|
||||||
void POIManager::Impl::ReadPOISettings()
|
void POIManager::Impl::ReadPOISettings()
|
||||||
{
|
{
|
||||||
logger_->info("Reading point of intrest settings");
|
logger_->info("Reading point of interest settings");
|
||||||
|
|
||||||
boost::json::value poiJson = nullptr;
|
boost::json::value poiJson = nullptr;
|
||||||
|
|
||||||
|
|
@ -84,16 +111,18 @@ void POIManager::Impl::ReadPOISettings()
|
||||||
{
|
{
|
||||||
// For each poi entry
|
// For each poi entry
|
||||||
auto& poiArray = poiJson.as_array();
|
auto& poiArray = poiJson.as_array();
|
||||||
|
poiRecords_.reserve(poiArray.size());
|
||||||
for (auto& poiEntry : poiArray)
|
for (auto& poiEntry : poiArray)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PointOfInterest record =
|
POIRecord record =
|
||||||
boost::json::value_to<PointOfInterest>(poiEntry);
|
boost::json::value_to<POIRecord>(poiEntry);
|
||||||
|
|
||||||
if (!record.name_.empty())
|
if (!record.name_.empty())
|
||||||
{
|
{
|
||||||
// Add record
|
poiRecords_.emplace_back(std::make_shared<POIRecord>(
|
||||||
|
record.name_, record.latitude_, record.longitude_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
|
|
@ -101,9 +130,147 @@ void POIManager::Impl::ReadPOISettings()
|
||||||
logger_->warn("Invalid point of interest entry: {}", ex.what());
|
logger_->warn("Invalid point of interest entry: {}", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger_->debug("{} point of interest entries", poiRecords_.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void POIManager::Impl::WritePOISettings()
|
||||||
|
{
|
||||||
|
logger_->info("Saving point of interest settings");
|
||||||
|
|
||||||
|
auto poiJson = boost::json::value_from(poiRecords_);
|
||||||
|
util::json::WriteJsonFile(poiSettingsPath_, poiJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<POIManager::Impl::POIRecord>
|
||||||
|
POIManager::Impl::GetPOIByName(const std::string& name)
|
||||||
|
{
|
||||||
|
for (auto& poiRecord : poiRecords_)
|
||||||
|
{
|
||||||
|
if (poiRecord->name_ == name)
|
||||||
|
{
|
||||||
|
return poiRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
POIManager::POIManager() : p(std::make_unique<Impl>(this))
|
||||||
|
{
|
||||||
|
// TODO THREADING?
|
||||||
|
try
|
||||||
|
{
|
||||||
|
p->InitializePOISettings();
|
||||||
|
|
||||||
|
// Read POI settings on startup
|
||||||
|
//main::Application::WaitForInitialization();
|
||||||
|
p->ReadPOISettings();
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
logger_->error(ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
POIManager::~POIManager()
|
||||||
|
{
|
||||||
|
p->WritePOISettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t POIManager::poi_count()
|
||||||
|
{
|
||||||
|
return p->poiRecords_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO deal with out of range/not found
|
||||||
|
types::PointOfInterest POIManager::get_poi(size_t index)
|
||||||
|
{
|
||||||
|
std::shared_ptr<POIManager::Impl::POIRecord> poiRecord =
|
||||||
|
p->poiRecords_[index];
|
||||||
|
return types::PointOfInterest(
|
||||||
|
poiRecord->name_, poiRecord->latitude_, poiRecord->longitude_);
|
||||||
|
}
|
||||||
|
|
||||||
|
types::PointOfInterest POIManager::get_poi(const std::string& name)
|
||||||
|
{
|
||||||
|
std::shared_ptr<POIManager::Impl::POIRecord> poiRecord =
|
||||||
|
p->GetPOIByName(name);
|
||||||
|
return types::PointOfInterest(
|
||||||
|
poiRecord->name_, poiRecord->latitude_, poiRecord->longitude_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void POIManager::set_poi(size_t index, const types::PointOfInterest& poi)
|
||||||
|
{
|
||||||
|
std::shared_ptr<POIManager::Impl::POIRecord> poiRecord =
|
||||||
|
p->poiRecords_[index];
|
||||||
|
poiRecord->name_ = poi.name_;
|
||||||
|
poiRecord->latitude_ = poi.latitude_;
|
||||||
|
poiRecord->longitude_ = poi.longitude_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void POIManager::set_poi(const std::string& name,
|
||||||
|
const types::PointOfInterest& poi)
|
||||||
|
{
|
||||||
|
std::shared_ptr<POIManager::Impl::POIRecord> poiRecord =
|
||||||
|
p->GetPOIByName(name);
|
||||||
|
poiRecord->name_ = poi.name_;
|
||||||
|
poiRecord->latitude_ = poi.latitude_;
|
||||||
|
poiRecord->longitude_ = poi.longitude_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void POIManager::add_poi(const types::PointOfInterest& poi)
|
||||||
|
{
|
||||||
|
p->poiRecords_.emplace_back(std::make_shared<Impl::POIRecord>(
|
||||||
|
poi.name_, poi.latitude_, poi.longitude_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void POIManager::move_poi(size_t from, size_t to)
|
||||||
|
{
|
||||||
|
if (from >= p->poiRecords_.size() || to >= p->poiRecords_.size())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::shared_ptr<POIManager::Impl::POIRecord> poiRecord =
|
||||||
|
p->poiRecords_[from];
|
||||||
|
|
||||||
|
if (from == to)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (from < to)
|
||||||
|
{
|
||||||
|
for (size_t i = from; i < to; i++)
|
||||||
|
{
|
||||||
|
p->poiRecords_[i] = p->poiRecords_[i + 1];
|
||||||
|
}
|
||||||
|
p->poiRecords_[to] = poiRecord;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (size_t i = from; i > to; i--)
|
||||||
|
{
|
||||||
|
p->poiRecords_[i] = p->poiRecords_[i - 1];
|
||||||
|
}
|
||||||
|
p->poiRecords_[to] = poiRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<POIManager> POIManager::Instance()
|
||||||
|
{
|
||||||
|
static std::weak_ptr<POIManager> poiManagerReference_ {};
|
||||||
|
|
||||||
|
std::shared_ptr<POIManager> poiManager = poiManagerReference_.lock();
|
||||||
|
|
||||||
|
if (poiManager == nullptr)
|
||||||
|
{
|
||||||
|
poiManager = std::make_shared<POIManager>();
|
||||||
|
poiManagerReference_ = poiManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
return poiManager;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace manager
|
} // namespace manager
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <scwx/qt/types/poi_types.hpp>
|
#include <scwx/qt/types/poi_types.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
|
|
@ -19,6 +21,15 @@ public:
|
||||||
explicit POIManager();
|
explicit POIManager();
|
||||||
~POIManager();
|
~POIManager();
|
||||||
|
|
||||||
|
size_t poi_count();
|
||||||
|
types::PointOfInterest get_poi(size_t index);
|
||||||
|
types::PointOfInterest get_poi(const std::string& name);
|
||||||
|
void set_poi(size_t index, const types::PointOfInterest& poi);
|
||||||
|
void set_poi(const std::string& name, const types::PointOfInterest& poi);
|
||||||
|
void add_poi(const types::PointOfInterest& poi);
|
||||||
|
void move_poi(size_t from, size_t to);
|
||||||
|
|
||||||
|
static std::shared_ptr<POIManager> Instance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue