Generalize AISRecentEntries -> templated RecentEntries.

Also access Entry unique key via key().
This commit is contained in:
Jared Boone 2016-01-17 17:58:39 -08:00
parent 5a864d8d44
commit 3ee6fd3d87
2 changed files with 38 additions and 23 deletions

View File

@ -216,15 +216,15 @@ void AISRecentEntry::update(const ais::Packet& packet) {
} }
} }
const AISRecentEntry& AISRecentEntries::on_packet(const ais::Packet& packet) { template<class Packet, class Entry>
const auto source_id = packet.source_id(); const Entry& RecentEntries<Packet, Entry>::on_packet(const Key key, const Packet& packet) {
auto matching_recent = find(source_id); auto matching_recent = find(key);
if( matching_recent != std::end(entries) ) { if( matching_recent != std::end(entries) ) {
// Found within. Move to front of list, increment counter. // Found within. Move to front of list, increment counter.
entries.push_front(*matching_recent); entries.push_front(*matching_recent);
entries.erase(matching_recent); entries.erase(matching_recent);
} else { } else {
entries.emplace_front(source_id); entries.emplace_front(key);
truncate_entries(); truncate_entries();
} }
@ -234,21 +234,24 @@ const AISRecentEntry& AISRecentEntries::on_packet(const ais::Packet& packet) {
return entry; return entry;
} }
AISRecentEntries::ContainerType::const_iterator AISRecentEntries::find(const ais::MMSI key) const { template<class Packet, class Entry>
typename RecentEntries<Packet, Entry>::const_iterator RecentEntries<Packet, Entry>::find(const Key key) const {
return std::find_if( return std::find_if(
std::begin(entries), std::end(entries), 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<class Packet, class Entry>
void RecentEntries<Packet, Entry>::truncate_entries() {
while(entries.size() > entries_max) { while(entries.size() > entries_max) {
entries.pop_back(); entries.pop_back();
} }
} }
AISRecentEntries::RangeType AISRecentEntries::range_around( template<class Packet, class Entry>
ContainerType::const_iterator item, const size_t count typename RecentEntries<Packet, Entry>::RangeType RecentEntries<Packet, Entry>::range_around(
const_iterator item, const size_t count
) const { ) const {
auto start = item; auto start = item;
auto end = item; auto end = item;
@ -332,7 +335,7 @@ void AISRecentEntriesView::paint(Painter& painter) {
for(auto p = range.first; p != range.second; p++) { for(auto p = range.first; p != range.second; p++) {
const auto& entry = *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)); ais_list_item_draw(entry, target_rect, painter, s, (has_focus() && is_selected_key));
target_rect.pos.y += target_rect.height(); target_rect.pos.y += target_rect.height();
} }
@ -344,7 +347,7 @@ void AISRecentEntriesView::advance(const int32_t amount) {
if( recent.empty() ) { if( recent.empty() ) {
selected_key = invalid_key; selected_key = invalid_key;
} else { } else {
selected_key = recent.front().mmsi; selected_key = recent.front().key();
} }
} else { } else {
if( amount < 0 ) { if( amount < 0 ) {
@ -358,7 +361,7 @@ void AISRecentEntriesView::advance(const int32_t amount) {
return; return;
} }
} }
selected_key = selected->mmsi; selected_key = selected->key();
} }
set_dirty(); set_dirty();
@ -470,11 +473,11 @@ void AISAppView::set_parent_rect(const Rect new_parent_rect) {
void AISAppView::on_packet(const ais::Packet& packet) { void AISAppView::on_packet(const ais::Packet& packet) {
logger.on_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(); recent_entries_view.set_dirty();
// TODO: Crude hack, should be a more formal listener arrangement... // 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); recent_entry_detail_view.set_entry(updated_entry);
} }
} }

View File

@ -49,6 +49,8 @@ struct AISPosition {
}; };
struct AISRecentEntry { struct AISRecentEntry {
using Key = ais::MMSI;
ais::MMSI mmsi; ais::MMSI mmsi;
std::string name; std::string name;
std::string call_sign; std::string call_sign;
@ -71,27 +73,35 @@ struct AISRecentEntry {
{ {
} }
Key key() const {
return mmsi;
}
void update(const ais::Packet& packet); void update(const ais::Packet& packet);
}; };
class AISRecentEntries { template<class Packet, class Entry>
class RecentEntries {
public: public:
using ContainerType = std::list<AISRecentEntry>; using Key = typename Entry::Key;
using RangeType = std::pair<ContainerType::const_iterator, ContainerType::const_iterator>; using ContainerType = std::list<Entry>;
using const_reference = typename ContainerType::const_reference;
using const_iterator = typename ContainerType::const_iterator;
using RangeType = std::pair<const_iterator, const_iterator>;
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(); 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(); return entries.begin();
} }
ContainerType::const_iterator end() const { const_iterator end() const {
return entries.end(); return entries.end();
} }
@ -100,7 +110,7 @@ public:
} }
RangeType range_around( RangeType range_around(
ContainerType::const_iterator, const size_t count const_iterator, const size_t count
) const; ) const;
private: private:
@ -110,6 +120,8 @@ private:
void truncate_entries(); void truncate_entries();
}; };
using AISRecentEntries = RecentEntries<ais::Packet, AISRecentEntry>;
class AISLogger { class AISLogger {
public: public:
void on_packet(const ais::Packet& packet); void on_packet(const ais::Packet& packet);