mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 13:10:04 +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
	
	 AdenKoperczak
						AdenKoperczak