Refactored DbChangeObserver class to parametrized singletone. 84/59084/3
authorSergei Kobec <s.kobec@samsung.com>
Thu, 11 Feb 2016 07:49:47 +0000 (09:49 +0200)
committerSergei Kobec <s.kobec@samsung.com>
Thu, 11 Feb 2016 07:49:47 +0000 (09:49 +0200)
Now it can be only one instance of this class for every possible DB table.

Change-Id: Ida9d0376fc9d26c1acc7dde06c26b18631914869
Signed-off-by: Sergei Kobec <s.kobec@samsung.com>
lib-contact/inc/Contacts/List/Model/DbChangeObserver.h
lib-contact/src/Contacts/List/Model/DbChangeObserver.cpp

index 94d9b16..011872d 100644 (file)
@@ -40,7 +40,9 @@ namespace Contacts
                                 */
                                enum Table
                                {
-                                       Contact
+                                       TableFirst,
+                                       TableContact = TableFirst,
+                                       TableMax
                                };
 
                                /**
@@ -61,10 +63,12 @@ namespace Contacts
                                typedef RecordCbs::const_iterator CallbackHandle;
 
                                /**
-                                * @brief Create new observer object
-                                * @param[in]   viewUri     Uri to DB table view
+                                * @brief Get observer instance
+                                * @param[in]   table     DB table view
+                                * @return observer object on success or nullptr if wrong parameter passed
                                 */
-                               DbChangeObserver(Table table = Contact);
+                               static DbChangeObserver *getInstance(Table table = TableContact);
+
                                ~DbChangeObserver();
 
                                DbChangeObserver(const DbChangeObserver &that) = delete;
@@ -102,15 +106,26 @@ namespace Contacts
                                typedef RecordCbs                          Callbacks;
                                typedef std::unordered_map<int, RecordCbs> ChangeCallbacks;
 
+                               DbChangeObserver(Table table);
+                               DbChangeObserver(DbChangeObserver &&that) = default;
+
+                               void subscribe();
+                               void unsubscribe();
+
+                               CallbackHandle addCallback(RecordCbs &recordCbs, Callback callback);
+
                                void onChanged(const char *viewUri);
                                void notifyContactChanges();
                                void notify(int id, contacts_changed_e changeType);
 
+                               static DbChangeObserver m_Observers[TableMax];
+
                                Callbacks m_Callbacks;
                                ChangeCallbacks m_ChangeCallbacks;
 
                                Table m_Table;
                                int m_DbVersion;
+                               bool m_IsSubscribed;
                        };
                }
        }
index 35f9623..fe868ba 100644 (file)
@@ -18,6 +18,7 @@
 #include "Contacts/List/Model/DbChangeObserver.h"
 #include "Contacts/Utils.h"
 #include "Utils/Callback.h"
+#include "Utils/Range.h"
 
 using namespace Contacts::List::Model;
 
@@ -28,35 +29,37 @@ namespace
        };
 }
 
-DbChangeObserver::DbChangeObserver(Table table)
-       : m_Table(table)
+DbChangeObserver *DbChangeObserver::getInstance(Table table)
 {
-       contacts_db_get_current_version(&m_DbVersion);
-       contacts_db_add_changed_cb(uris[m_Table],
-                       makeCallbackWithLastParam(&DbChangeObserver::onChanged), this);
+       if (table < 0 || table >= Utils::count(m_Observers)) {
+               return nullptr;
+       }
+
+       return &m_Observers[table];
 }
 
 DbChangeObserver::~DbChangeObserver()
 {
-       contacts_db_remove_changed_cb(uris[m_Table],
-                       makeCallbackWithLastParam(&DbChangeObserver::onChanged), this);
+       unsubscribe();
 }
 
 DbChangeObserver::CallbackHandle DbChangeObserver::addCallback(Callback callback)
 {
-       m_Callbacks.push_back(std::move(callback));
-       return --m_Callbacks.cend();
+       return addCallback(m_Callbacks, std::move(callback));
 }
 
 void DbChangeObserver::removeCallback(CallbackHandle handle)
 {
        m_Callbacks.erase(handle);
+
+       if (m_Callbacks.empty() && m_ChangeCallbacks.empty()) {
+               unsubscribe();
+       }
 }
 
 DbChangeObserver::CallbackHandle DbChangeObserver::addCallback(int id, Callback callback)
 {
-       m_ChangeCallbacks[id].push_back(std::move(callback));
-       return --m_ChangeCallbacks[id].cend();
+       return addCallback(m_ChangeCallbacks[id], std::move(callback));
 }
 
 void DbChangeObserver::removeCallback(int id, CallbackHandle handle)
@@ -65,12 +68,55 @@ void DbChangeObserver::removeCallback(int id, CallbackHandle handle)
        if (it != m_ChangeCallbacks.end()) {
                it->second.erase(handle);
        }
+
+       if (it->second.empty()) {
+               m_ChangeCallbacks.erase(it);
+       }
+
+       if (m_Callbacks.empty() && m_ChangeCallbacks.empty()) {
+               unsubscribe();
+       }
+}
+
+DbChangeObserver::DbChangeObserver(Table table)
+       : m_Table(table), m_DbVersion(0), m_IsSubscribed(false)
+{
+}
+
+void DbChangeObserver::subscribe()
+{
+       contacts_db_get_current_version(&m_DbVersion);
+       contacts_db_add_changed_cb(uris[m_Table],
+                       makeCallbackWithLastParam(&DbChangeObserver::onChanged), this);
+
+       m_IsSubscribed = true;
+}
+
+void DbChangeObserver::unsubscribe()
+{
+       m_DbVersion = 0;
+       contacts_db_remove_changed_cb(uris[m_Table],
+                       makeCallbackWithLastParam(&DbChangeObserver::onChanged), this);
+
+       m_IsSubscribed = false;
+}
+
+DbChangeObserver::CallbackHandle DbChangeObserver::addCallback(RecordCbs &recordCbs,
+               Callback callback)
+{
+       if (!m_IsSubscribed) {
+               subscribe();
+       }
+
+       recordCbs.push_back(std::move(callback));
+       return --recordCbs.cend();
 }
 
 void DbChangeObserver::onChanged(const char *viewUri)
 {
        switch (m_Table) {
-               case Contact: notifyContactChanges(); break;
+               case TableContact: notifyContactChanges(); break;
+               default: break;
        }
 }
 
@@ -109,3 +155,7 @@ void DbChangeObserver::notify(int id, contacts_changed_e changeType)
        }
        notifyAll(m_Callbacks);
 }
+
+DbChangeObserver DbChangeObserver::m_Observers[DbChangeObserver::TableMax] = {
+       /* TableContact = */ { TableContact }
+};