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
parent 045c7b2066
commit 3f226cf342
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);
m_in_transaction = true;
if (announce) {
send_local_notifications(DidChangeNotification);
if (announce && m_delegate) {
m_delegate->did_change();
}
}
@ -240,8 +240,10 @@ void Realm::commit_transaction()
LangBindHelper::commit_and_continue_as_read(*m_shared_group);
m_in_transaction = false;
send_external_notifications();
send_local_notifications(DidChangeNotification);
if (m_delegate) {
m_delegate->transaction_committed();
m_delegate->did_change();
}
}
void Realm::cancel_transaction()
@ -303,24 +305,17 @@ void Realm::notify()
if (m_group) {
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);
}
}
bool Realm::refresh()
{
verify_thread();
@ -344,7 +339,9 @@ bool Realm::refresh()
read_group();
}
send_local_notifications(DidChangeNotification);
if (m_delegate) {
m_delegate->did_change();
}
return true;
}

View File

@ -21,18 +21,18 @@
#include <map>
#include <memory>
#include <set>
#include <thread>
#include <vector>
#include "object_store.hpp"
namespace realm {
class RealmCache;
class ClientHistory;
class Realm;
class RealmCache;
class RealmDelegate;
typedef std::shared_ptr<Realm> SharedRealm;
typedef std::weak_ptr<Realm> WeakRealm;
class ClientHistory;
class Realm : public std::enable_shared_from_this<Realm>
{
@ -90,20 +90,12 @@ namespace realm {
bool auto_refresh() { return m_auto_refresh; }
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();
bool compact();
std::thread::id thread_id() const { return m_thread_id; }
void verify_thread();
const std::string RefreshRequiredNotification = "RefreshRequiredNotification";
const std::string DidChangeNotification = "DidChangeNotification";
private:
Realm(Config config);
@ -112,12 +104,6 @@ namespace realm {
bool m_in_transaction = false;
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<SharedGroup> m_shared_group;
std::unique_ptr<Group> m_read_only_group;
@ -125,7 +111,7 @@ namespace realm {
Group *m_group = nullptr;
public:
ExternalNotificationFunction m_external_notifier;
std::unique_ptr<RealmDelegate> m_delegate;
// FIXME private
Group *read_group();
@ -146,6 +132,23 @@ namespace realm {
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
{
public: