Rework change notifications

Switch to an abstract class rather than std::function in preparation for having
more kinds of notifications with different arguments for KVO.
This commit is contained in:
Thomas Goyne 2015-08-26 16:11:45 -07:00 committed by Ari Lazier
parent 7fda90c3b2
commit 219ef48bf4
2 changed files with 35 additions and 35 deletions

View File

@ -223,8 +223,8 @@ void Realm::begin_transaction()
LangBindHelper::promote_to_write(*m_shared_group, *m_history); LangBindHelper::promote_to_write(*m_shared_group, *m_history);
m_in_transaction = true; m_in_transaction = true;
if (announce) { if (announce && m_delegate) {
send_local_notifications(DidChangeNotification); m_delegate->did_change();
} }
} }
@ -240,8 +240,10 @@ void Realm::commit_transaction()
LangBindHelper::commit_and_continue_as_read(*m_shared_group); LangBindHelper::commit_and_continue_as_read(*m_shared_group);
m_in_transaction = false; m_in_transaction = false;
send_external_notifications(); if (m_delegate) {
send_local_notifications(DidChangeNotification); m_delegate->transaction_committed();
m_delegate->did_change();
}
} }
void Realm::cancel_transaction() void Realm::cancel_transaction()
@ -303,20 +305,13 @@ void Realm::notify()
if (m_group) { if (m_group) {
LangBindHelper::advance_read(*m_shared_group, *m_history); LangBindHelper::advance_read(*m_shared_group, *m_history);
} }
send_local_notifications(DidChangeNotification); if (m_delegate) {
} m_delegate->did_change();
else {
send_local_notifications(RefreshRequiredNotification);
} }
} }
} else if (m_delegate) {
m_delegate->changes_available();
}
void Realm::send_local_notifications(const std::string &type)
{
verify_thread();
for (NotificationFunction const& notification : m_notifications) {
(*notification)(type);
} }
} }
@ -344,7 +339,9 @@ bool Realm::refresh()
read_group(); read_group();
} }
send_local_notifications(DidChangeNotification); if (m_delegate) {
m_delegate->did_change();
}
return true; return true;
} }

View File

@ -21,18 +21,18 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <set>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "object_store.hpp" #include "object_store.hpp"
namespace realm { namespace realm {
class RealmCache; class ClientHistory;
class Realm; class Realm;
class RealmCache;
class RealmDelegate;
typedef std::shared_ptr<Realm> SharedRealm; typedef std::shared_ptr<Realm> SharedRealm;
typedef std::weak_ptr<Realm> WeakRealm; typedef std::weak_ptr<Realm> WeakRealm;
class ClientHistory;
class Realm : public std::enable_shared_from_this<Realm> class Realm : public std::enable_shared_from_this<Realm>
{ {
@ -90,20 +90,12 @@ namespace realm {
bool auto_refresh() { return m_auto_refresh; } bool auto_refresh() { return m_auto_refresh; }
void notify(); void notify();
typedef std::shared_ptr<std::function<void(const std::string)>> NotificationFunction;
void add_notification(NotificationFunction &notification) { m_notifications.insert(notification); }
void remove_notification(NotificationFunction notification) { m_notifications.erase(notification); }
void remove_all_notifications() { m_notifications.clear(); }
void invalidate(); void invalidate();
bool compact(); bool compact();
std::thread::id thread_id() const { return m_thread_id; } std::thread::id thread_id() const { return m_thread_id; }
void verify_thread(); void verify_thread();
const std::string RefreshRequiredNotification = "RefreshRequiredNotification";
const std::string DidChangeNotification = "DidChangeNotification";
private: private:
Realm(Config config); Realm(Config config);
@ -112,12 +104,6 @@ namespace realm {
bool m_in_transaction = false; bool m_in_transaction = false;
bool m_auto_refresh = true; bool m_auto_refresh = true;
std::set<NotificationFunction> m_notifications;
void send_local_notifications(const std::string &notification);
typedef std::unique_ptr<std::function<void()>> ExternalNotificationFunction;
void send_external_notifications() { if (m_external_notifier) (*m_external_notifier)(); }
std::unique_ptr<ClientHistory> m_history; std::unique_ptr<ClientHistory> m_history;
std::unique_ptr<SharedGroup> m_shared_group; std::unique_ptr<SharedGroup> m_shared_group;
std::unique_ptr<Group> m_read_only_group; std::unique_ptr<Group> m_read_only_group;
@ -125,7 +111,7 @@ namespace realm {
Group *m_group = nullptr; Group *m_group = nullptr;
public: public:
ExternalNotificationFunction m_external_notifier; std::unique_ptr<RealmDelegate> m_delegate;
// FIXME private // FIXME private
Group *read_group(); Group *read_group();
@ -146,6 +132,23 @@ namespace realm {
std::mutex m_mutex; std::mutex m_mutex;
}; };
class RealmDelegate
{
public:
virtual ~RealmDelegate() = default;
// The Realm has committed a write transaction, and other Realms at the
// same path should be notified
virtual void transaction_committed() = 0;
// There are now new versions available for the Realm, but it has not
// had its read version advanced
virtual void changes_available() = 0;
// The Realm's read version has advanced
virtual void did_change() = 0;
};
class RealmFileException : public std::runtime_error class RealmFileException : public std::runtime_error
{ {
public: public: