From 3ee6fd3d876fc66d1efda2a472f7bb5cfcbf6c55 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 17 Jan 2016 17:58:39 -0800 Subject: [PATCH] Generalize AISRecentEntries -> templated RecentEntries. Also access Entry unique key via key(). --- firmware/application/ais_app.cpp | 31 +++++++++++++++++-------------- firmware/application/ais_app.hpp | 30 +++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/firmware/application/ais_app.cpp b/firmware/application/ais_app.cpp index 54b5550d..04c482a4 100644 --- a/firmware/application/ais_app.cpp +++ b/firmware/application/ais_app.cpp @@ -216,15 +216,15 @@ void AISRecentEntry::update(const ais::Packet& packet) { } } -const AISRecentEntry& AISRecentEntries::on_packet(const ais::Packet& packet) { - const auto source_id = packet.source_id(); - auto matching_recent = find(source_id); +template +const Entry& RecentEntries::on_packet(const Key key, const Packet& packet) { + auto matching_recent = find(key); if( matching_recent != std::end(entries) ) { // Found within. Move to front of list, increment counter. entries.push_front(*matching_recent); entries.erase(matching_recent); } else { - entries.emplace_front(source_id); + entries.emplace_front(key); truncate_entries(); } @@ -234,21 +234,24 @@ const AISRecentEntry& AISRecentEntries::on_packet(const ais::Packet& packet) { return entry; } -AISRecentEntries::ContainerType::const_iterator AISRecentEntries::find(const ais::MMSI key) const { +template +typename RecentEntries::const_iterator RecentEntries::find(const Key key) const { return std::find_if( std::begin(entries), std::end(entries), - [key](const AISRecentEntry& e) { return e.mmsi == key; } + [key](const Entry& e) { return e.key() == key; } ); } -void AISRecentEntries::truncate_entries() { +template +void RecentEntries::truncate_entries() { while(entries.size() > entries_max) { entries.pop_back(); } } -AISRecentEntries::RangeType AISRecentEntries::range_around( - ContainerType::const_iterator item, const size_t count +template +typename RecentEntries::RangeType RecentEntries::range_around( + const_iterator item, const size_t count ) const { auto start = item; auto end = item; @@ -332,7 +335,7 @@ void AISRecentEntriesView::paint(Painter& painter) { for(auto p = range.first; p != range.second; p++) { const auto& entry = *p; - const auto is_selected_key = (selected_key == entry.mmsi); + const auto is_selected_key = (selected_key == entry.key()); ais_list_item_draw(entry, target_rect, painter, s, (has_focus() && is_selected_key)); target_rect.pos.y += target_rect.height(); } @@ -344,7 +347,7 @@ void AISRecentEntriesView::advance(const int32_t amount) { if( recent.empty() ) { selected_key = invalid_key; } else { - selected_key = recent.front().mmsi; + selected_key = recent.front().key(); } } else { if( amount < 0 ) { @@ -358,7 +361,7 @@ void AISRecentEntriesView::advance(const int32_t amount) { return; } } - selected_key = selected->mmsi; + selected_key = selected->key(); } set_dirty(); @@ -470,11 +473,11 @@ void AISAppView::set_parent_rect(const Rect new_parent_rect) { void AISAppView::on_packet(const ais::Packet& packet) { logger.on_packet(packet); - const auto updated_entry = recent.on_packet(packet); + const auto updated_entry = recent.on_packet(packet.source_id(), packet); recent_entries_view.set_dirty(); // TODO: Crude hack, should be a more formal listener arrangement... - if( updated_entry.mmsi == recent_entry_detail_view.entry().mmsi ) { + if( updated_entry.key() == recent_entry_detail_view.entry().key() ) { recent_entry_detail_view.set_entry(updated_entry); } } diff --git a/firmware/application/ais_app.hpp b/firmware/application/ais_app.hpp index b704d7ba..c3973c0e 100644 --- a/firmware/application/ais_app.hpp +++ b/firmware/application/ais_app.hpp @@ -49,6 +49,8 @@ struct AISPosition { }; struct AISRecentEntry { + using Key = ais::MMSI; + ais::MMSI mmsi; std::string name; std::string call_sign; @@ -71,27 +73,35 @@ struct AISRecentEntry { { } + Key key() const { + return mmsi; + } + void update(const ais::Packet& packet); }; -class AISRecentEntries { +template +class RecentEntries { public: - using ContainerType = std::list; - using RangeType = std::pair; + using Key = typename Entry::Key; + using ContainerType = std::list; + using const_reference = typename ContainerType::const_reference; + using const_iterator = typename ContainerType::const_iterator; + using RangeType = std::pair; - const AISRecentEntry& on_packet(const ais::Packet& packet); + const Entry& on_packet(const Key key, const Packet& packet); - ContainerType::const_reference front() const { + const_reference front() const { return entries.front(); } - ContainerType::const_iterator find(const ais::MMSI key) const; + const_iterator find(const Key key) const; - ContainerType::const_iterator begin() const { + const_iterator begin() const { return entries.begin(); } - ContainerType::const_iterator end() const { + const_iterator end() const { return entries.end(); } @@ -100,7 +110,7 @@ public: } RangeType range_around( - ContainerType::const_iterator, const size_t count + const_iterator, const size_t count ) const; private: @@ -110,6 +120,8 @@ private: void truncate_entries(); }; +using AISRecentEntries = RecentEntries; + class AISLogger { public: void on_packet(const ais::Packet& packet);