annotate base/ById.h @ 1731:601851995f4b by-id

Introduce Model to ById
author Chris Cannam
date Fri, 21 Jun 2019 13:37:00 +0100
parents abd8b9673028
children bffccc8de3c1 d91ff235e69d
rev   line source
Chris@1729 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1729 2
Chris@1729 3 /*
Chris@1729 4 Sonic Visualiser
Chris@1729 5 An audio file viewer and annotation editor.
Chris@1729 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1729 7
Chris@1729 8 This program is free software; you can redistribute it and/or
Chris@1729 9 modify it under the terms of the GNU General Public License as
Chris@1729 10 published by the Free Software Foundation; either version 2 of the
Chris@1729 11 License, or (at your option) any later version. See the file
Chris@1729 12 COPYING included with this distribution for more information.
Chris@1729 13 */
Chris@1729 14
Chris@1729 15 #ifndef SV_BY_ID_H
Chris@1729 16 #define SV_BY_ID_H
Chris@1729 17
Chris@1729 18 #include <memory>
Chris@1729 19 #include <map>
Chris@1731 20 #include <typeinfo>
Chris@1731 21 #include <iostream>
Chris@1731 22 #include <climits>
Chris@1729 23
Chris@1729 24 #include <QMutex>
Chris@1731 25 #include <QString>
Chris@1729 26
Chris@1731 27 template <typename T>
Chris@1731 28 struct SvId {
Chris@1731 29 int id;
Chris@1729 30
Chris@1731 31 bool operator<(const SvId &other) const { return id < other.id; }
Chris@1731 32
Chris@1731 33 QString toString() const {
Chris@1731 34 return QString("%1").arg(id);
Chris@1731 35 }
Chris@1731 36 };
Chris@1731 37
Chris@1731 38 template <typename T>
Chris@1729 39 class WithId
Chris@1729 40 {
Chris@1729 41 public:
Chris@1731 42 typedef SvId<T> Id;
Chris@1731 43
Chris@1729 44 WithId() :
Chris@1729 45 m_id(getNextId()) {
Chris@1729 46 }
Chris@1729 47
Chris@1731 48 /**
Chris@1731 49 * Return an id for this object. The id is a unique identifier for
Chris@1731 50 * this object among all objects that implement WithId within this
Chris@1731 51 * single run of the application.
Chris@1731 52 */
Chris@1729 53 Id getId() const {
Chris@1731 54 Id id;
Chris@1731 55 id.id = m_id;
Chris@1731 56 return id;
Chris@1729 57 }
Chris@1729 58
Chris@1729 59 private:
Chris@1731 60 int m_id;
Chris@1731 61
Chris@1731 62 static int getNextId() {
Chris@1731 63 static int nextId = 0;
Chris@1731 64 static QMutex mutex;
Chris@1731 65 QMutexLocker locker(&mutex);
Chris@1731 66 int i = nextId;
Chris@1731 67 if (nextId == INT_MAX) {
Chris@1731 68 nextId = INT_MIN;
Chris@1731 69 }
Chris@1731 70 ++nextId;
Chris@1731 71 return i;
Chris@1731 72 }
Chris@1729 73 };
Chris@1729 74
Chris@1731 75 template <typename Item, typename Id>
Chris@1729 76 class ById
Chris@1729 77 {
Chris@1729 78 public:
Chris@1731 79 ~ById() {
Chris@1731 80 QMutexLocker locker(&m_mutex);
Chris@1731 81 for (const auto &p: m_items) {
Chris@1731 82 if (p.second && p.second.use_count() > 0) {
Chris@1731 83 std::cerr << "WARNING: ById map destroyed with use count of "
Chris@1731 84 << p.second.use_count() << " for item with type "
Chris@1731 85 << typeid(*p.second.get()).name()
Chris@1731 86 << " and id " << p.first.id << std::endl;
Chris@1731 87 }
Chris@1731 88 }
Chris@1731 89 }
Chris@1731 90
Chris@1729 91 void add(std::shared_ptr<Item> item) {
Chris@1729 92 QMutexLocker locker(&m_mutex);
Chris@1729 93 m_items[item->getId()] = item;
Chris@1729 94 }
Chris@1729 95
Chris@1729 96 void
Chris@1729 97 release(Id id) {
Chris@1729 98 QMutexLocker locker(&m_mutex);
Chris@1729 99 m_items.erase(id);
Chris@1729 100 }
Chris@1729 101
Chris@1729 102 std::shared_ptr<Item> get(Id id) const {
Chris@1729 103 QMutexLocker locker(&m_mutex);
Chris@1729 104 const auto &itr = m_items.find(id);
Chris@1729 105 if (itr != m_items.end()) {
Chris@1729 106 return itr->second;
Chris@1729 107 } else {
Chris@1729 108 return std::shared_ptr<Item>();
Chris@1729 109 }
Chris@1729 110 }
Chris@1729 111
Chris@1729 112 template <typename Derived>
Chris@1729 113 std::shared_ptr<Derived> getAs(Id id) const {
Chris@1729 114 return std::dynamic_pointer_cast<Derived>(get(id));
Chris@1729 115 }
Chris@1729 116
Chris@1729 117 private:
Chris@1729 118 mutable QMutex m_mutex;
Chris@1729 119 std::map<Id, std::shared_ptr<Item>> m_items;
Chris@1729 120 };
Chris@1729 121
Chris@1731 122 template <typename Item, typename Id>
Chris@1731 123 class StaticById
Chris@1729 124 {
Chris@1729 125 public:
Chris@1731 126 static void add(std::shared_ptr<Item> imagined) {
Chris@1731 127 byId().add(imagined);
Chris@1729 128 }
Chris@1729 129
Chris@1729 130 static void release(Id id) {
Chris@1731 131 byId().release(id);
Chris@1729 132 }
Chris@1729 133
Chris@1731 134 static std::shared_ptr<Item> get(Id id) {
Chris@1731 135 return byId().get(id);
Chris@1729 136 }
Chris@1729 137
Chris@1729 138 template <typename Derived>
Chris@1729 139 static
Chris@1729 140 std::shared_ptr<Derived> getAs(Id id) {
Chris@1731 141 return std::dynamic_pointer_cast<Derived>(get(id));
Chris@1729 142 }
Chris@1729 143
Chris@1729 144 private:
Chris@1731 145 static
Chris@1731 146 ById<Item, Id> &byId() {
Chris@1731 147 static ById<Item, Id> b;
Chris@1731 148 return b;
Chris@1731 149 }
Chris@1729 150 };
Chris@1731 151
Chris@1729 152 #endif
Chris@1729 153