mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:00:04 +00:00 
			
		
		
		
	Adding initial text event manager
This commit is contained in:
		
							parent
							
								
									3ae001c3b9
								
							
						
					
					
						commit
						cc82c5b102
					
				
					 3 changed files with 192 additions and 2 deletions
				
			
		|  | @ -58,11 +58,13 @@ set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp | |||
| set(HDR_MANAGER source/scwx/qt/manager/radar_product_manager.hpp | ||||
|                 source/scwx/qt/manager/radar_product_manager_notifier.hpp | ||||
|                 source/scwx/qt/manager/resource_manager.hpp | ||||
|                 source/scwx/qt/manager/settings_manager.hpp) | ||||
|                 source/scwx/qt/manager/settings_manager.hpp | ||||
|                 source/scwx/qt/manager/text_event_manager.hpp) | ||||
| set(SRC_MANAGER source/scwx/qt/manager/radar_product_manager.cpp | ||||
|                 source/scwx/qt/manager/radar_product_manager_notifier.cpp | ||||
|                 source/scwx/qt/manager/resource_manager.cpp | ||||
|                 source/scwx/qt/manager/settings_manager.cpp) | ||||
|                 source/scwx/qt/manager/settings_manager.cpp | ||||
|                 source/scwx/qt/manager/text_event_manager.cpp) | ||||
| set(HDR_MAP source/scwx/qt/map/color_table_layer.hpp | ||||
|             source/scwx/qt/map/draw_layer.hpp | ||||
|             source/scwx/qt/map/generic_layer.hpp | ||||
|  |  | |||
							
								
								
									
										154
									
								
								scwx-qt/source/scwx/qt/manager/text_event_manager.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								scwx-qt/source/scwx/qt/manager/text_event_manager.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,154 @@ | |||
| #include <scwx/qt/manager/text_event_manager.hpp> | ||||
| #include <scwx/awips/pvtec.hpp> | ||||
| #include <scwx/awips/text_product_file.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| #include <scwx/util/threads.hpp> | ||||
| 
 | ||||
| #include <shared_mutex> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| #include <boost/container_hash/hash.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace manager | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "scwx::qt::manager::text_event_manager"; | ||||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||
| 
 | ||||
| struct TextEventKey | ||||
| { | ||||
|    TextEventKey(const awips::PVtec& pvtec) : | ||||
|        officeId_ {pvtec.office_id()}, | ||||
|        phenomenon_ {pvtec.phenomenon()}, | ||||
|        significance_ {pvtec.significance()}, | ||||
|        etn_ {pvtec.event_tracking_number()} | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    bool operator==(const TextEventKey& o) const; | ||||
| 
 | ||||
|    std::string         officeId_; | ||||
|    awips::Phenomenon   phenomenon_; | ||||
|    awips::Significance significance_; | ||||
|    int16_t             etn_; | ||||
| }; | ||||
| 
 | ||||
| template<class Key> | ||||
| struct TextEventHash; | ||||
| 
 | ||||
| template<> | ||||
| struct TextEventHash<TextEventKey> | ||||
| { | ||||
|    size_t operator()(const TextEventKey& x) const | ||||
|    { | ||||
|       size_t seed = 0; | ||||
|       boost::hash_combine(seed, x.officeId_); | ||||
|       boost::hash_combine(seed, x.phenomenon_); | ||||
|       boost::hash_combine(seed, x.significance_); | ||||
|       boost::hash_combine(seed, x.etn_); | ||||
|       return seed; | ||||
|    } | ||||
| }; | ||||
| 
 | ||||
| class TextEventManager::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl() : textEventMap_ {}, textEventMutex_ {} {} | ||||
| 
 | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    void HandleMessage(std::shared_ptr<awips::TextProductMessage> message); | ||||
| 
 | ||||
|    std::unordered_map<TextEventKey, | ||||
|                       std::list<std::shared_ptr<awips::TextProductMessage>>, | ||||
|                       TextEventHash<TextEventKey>> | ||||
|                      textEventMap_; | ||||
|    std::shared_mutex textEventMutex_; | ||||
| }; | ||||
| 
 | ||||
| TextEventManager::TextEventManager() : p(std::make_unique<Impl>()) {} | ||||
| TextEventManager::~TextEventManager() = default; | ||||
| 
 | ||||
| void TextEventManager::LoadFile(const std::string& filename) | ||||
| { | ||||
|    logger_->debug("LoadFile: {}", filename); | ||||
| 
 | ||||
|    util::async( | ||||
|       [=]() | ||||
|       { | ||||
|          awips::TextProductFile file; | ||||
| 
 | ||||
|          // Load file
 | ||||
|          bool fileLoaded = file.LoadFile(filename); | ||||
|          if (!fileLoaded) | ||||
|          { | ||||
|             return; | ||||
|          } | ||||
| 
 | ||||
|          // Process messages
 | ||||
|          auto messages = file.messages(); | ||||
|          for (auto& message : messages) | ||||
|          { | ||||
|             p->HandleMessage(message); | ||||
|          } | ||||
|       }); | ||||
| } | ||||
| 
 | ||||
| void TextEventManager::Impl::HandleMessage( | ||||
|    std::shared_ptr<awips::TextProductMessage> message) | ||||
| { | ||||
|    auto segments = message->segments(); | ||||
| 
 | ||||
|    // If there are no segments, if the first segment has no header, or if there
 | ||||
|    // is no VTEC string, skip this message
 | ||||
|    if (segments.empty() || !segments[0]->header_.has_value() || | ||||
|        segments[0]->header_->vtecString_.empty()) | ||||
|    { | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    std::unique_lock lock(textEventMutex_); | ||||
| 
 | ||||
|    // Find a matching event in the event map
 | ||||
|    auto&        vtecString = segments[0]->header_->vtecString_; | ||||
|    TextEventKey key {vtecString[0].pVtec_}; | ||||
|    auto         it = textEventMap_.find(key); | ||||
| 
 | ||||
|    if (it == textEventMap_.cend()) | ||||
|    { | ||||
|       // If there was no matching event, add the message to a new event
 | ||||
|       textEventMap_.emplace(key, std::list {message}); | ||||
|    } | ||||
|    else if (std::find_if(it->second.cbegin(), | ||||
|                          it->second.cend(), | ||||
|                          [=](auto& storedMessage) { | ||||
|                             return message->wmo_header() == | ||||
|                                    storedMessage->wmo_header(); | ||||
|                          }) == it->second.cend()) | ||||
|    { | ||||
|       // If there was a matching event, and this message has not been stored
 | ||||
|       // (WMO header equivalence check), add the updated message to the existing
 | ||||
|       // event
 | ||||
|       it->second.push_back(message); | ||||
|    }; | ||||
| } | ||||
| 
 | ||||
| TextEventManager& TextEventManager::Instance() | ||||
| { | ||||
|    static TextEventManager textEventManager_ {}; | ||||
|    return textEventManager_; | ||||
| } | ||||
| 
 | ||||
| bool TextEventKey::operator==(const TextEventKey& o) const | ||||
| { | ||||
|    return (officeId_ == o.officeId_ && phenomenon_ == o.phenomenon_ && | ||||
|            significance_ == o.significance_ && etn_ == o.etn_); | ||||
| } | ||||
| 
 | ||||
| } // namespace manager
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										34
									
								
								scwx-qt/source/scwx/qt/manager/text_event_manager.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								scwx-qt/source/scwx/qt/manager/text_event_manager.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <string> | ||||
| 
 | ||||
| #include <QObject> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace manager | ||||
| { | ||||
| 
 | ||||
| class TextEventManager : public QObject | ||||
| { | ||||
|    Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|    explicit TextEventManager(); | ||||
|    ~TextEventManager(); | ||||
| 
 | ||||
|    void LoadFile(const std::string& filename); | ||||
| 
 | ||||
|    static TextEventManager& Instance(); | ||||
| 
 | ||||
| private: | ||||
|    class Impl; | ||||
|    std::unique_ptr<Impl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace manager
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat