Add a bit of documentation for RealmDelegate

This commit is contained in:
Thomas Goyne 2015-09-10 13:47:06 -07:00
parent 95c80c98e6
commit 21d32bf581
1 changed files with 92 additions and 30 deletions

View File

@ -25,24 +25,106 @@
#include <vector> #include <vector>
namespace realm { namespace realm {
// RealmDelegate is the extension point for adding binding-specific behavior to
// a SharedRealm. It can be used to store additonal data associated with the
// Realm which is needed by the binding, and there are several methods which
// can be overridden to receive notifications of state changes within the Realm.
//
// A simple delegate implementation which lets the user register functions to be
// called on refresh could look like the following:
//
// class DelegateImplementation : public RealmDelegate {
// public:
// // A token returned from add_notification that can be used to remove the
// // notification later
// struct token : private std::list<std::function<void ()>>::iterator {
// token(std::list<std::function<void ()>>::iterator it) : std::list<std::function<void ()>>::iterator(it) { }
// friend class DelegateImplementation;
// };
//
// token add_notification(std::function<void ()> func)
// {
// m_registered_notifications.push_back(std::move(func));
// return token(std::prev(m_registered_notifications.end()));
// }
//
// void remove_notification(token entry)
// {
// m_registered_notifications.erase(entry);
// }
//
// // Override the did_change method to call each registered notification
// void did_change(std::vector<ObserverState> const&, std::vector<void*> const&) override
// {
// // Loop oddly so that unregistering a notification from within the
// // registered function works
// for (auto it = m_registered_notifications.begin(); it != m_registered_notifications.end(); ) {
// (*it++)();
// }
// }
//
// private:
// std::list<std::function<void ()>> m_registered_notifications;
// };
class RealmDelegate { class RealmDelegate {
public: public:
virtual ~RealmDelegate() = default; virtual ~RealmDelegate() = default;
// Called by the Realm when a write transaction is committed to the file by
// a different Realm instance (possibly in a different process)
virtual void changes_available() { }
struct ObserverState;
// Override this function if you want to recieve detailed information about
// external changes to a specific set of objects.
// This is called before each operation which may advance the read
// transaction to include
// ObserverStates for each row for which detailed change information is
// desired.
virtual std::vector<ObserverState> get_observed_rows() { return {}; }
// Called immediately before the read transaction is advanced if detailed
// change information was requested (by returning a non-empty array from
// get_observed_rows()).
// The observers vector is the vector returned by get_observed_row(),
// updated with change information. The invalidated vector is a list of the
// `info` fields of observed rows which will be deleted.
virtual void will_change(std::vector<ObserverState> const& observers,
std::vector<void*> const& invalidated);
// Called immediately after the read transaction version is advanced. Unlike
// will_change(), this is called even if detailed change information was not
// requested or if the Realm is not actually in a read transactuib, although
// both vectors will be empty in that case.
virtual void did_change(std::vector<ObserverState> const& observers,
std::vector<void*> const& invalidated);
// Change information for a single field of a row // Change information for a single field of a row
struct ColumnInfo { struct ColumnInfo {
// Did this column change?
bool changed = false; bool changed = false;
// For LinkList columns, what kind of change occurred?
// Always None for other column types
enum class Kind { enum class Kind {
None, None, // No change
Set, Set, // The entries at `indices` were assigned to
Insert, Insert, // New values were inserted at each of the indices given
Remove, Remove, // Values were removed at each of the indices given
SetAll SetAll // The entire LinkList has been replaced with a new set of values
} kind = Kind::None; } kind = Kind::None;
// The indices where things happened for Set, Insert and Remove
// Not used for None and SetAll
IndexSet indices; IndexSet indices;
}; };
// Information about an observed row in a table // Information about an observed row in a table
//
// Each object which needs detailed change information should have an
// ObserverState entry in the vector returned from get_observed_rows(), with
// the initial table and row indexes set (and optionally the info field).
// The Realm parses the transaction log, and populates the `changes` vector
// in each ObserverState with information about what changes were made.
struct ObserverState { struct ObserverState {
// Initial table and row which is observed // Initial table and row which is observed
// May be updated by row insertions and removals // May be updated by row insertions and removals
@ -58,35 +140,15 @@ public:
std::vector<ColumnInfo> changes; std::vector<ColumnInfo> changes;
// Simple lexographic ordering // Simple lexographic ordering
friend bool operator<(ObserverState const& lft, ObserverState const& rgt) { friend bool operator<(ObserverState const& lft, ObserverState const& rgt)
{
return std::tie(lft.table_ndx, lft.row_ndx) < std::tie(rgt.table_ndx, rgt.row_ndx); return std::tie(lft.table_ndx, lft.row_ndx) < std::tie(rgt.table_ndx, rgt.row_ndx);
} }
}; };
// There are now new versions available for the Realm, but it has not
// had its read version advanced
virtual void changes_available() = 0;
// Called before changing the read transaction. Should return a list of
// ObserverStates for each row for which detailed change information is
// desired.
virtual std::vector<ObserverState> get_observed_rows() = 0;
// The Realm's read version will change
// Only called if get_observed_row() returned a non-empty array.
// observers is the vector returned from get_observed_rows()
// invalidated is the `info` pointers for each observed object which was deleted
virtual void will_change(std::vector<ObserverState> const& observers,
std::vector<void*> const& invalidated) = 0;
// The Realm's read version has changed
// observers is the vector returned from get_observed_rows()
// invalidated is the `info` pointers for each observed object which was deleted
// Is called with empty change information following a local commit or if
// the Realm isn't in a read transaction yet
virtual void did_change(std::vector<ObserverState> const& observers,
std::vector<void*> const& invalidated) = 0;
}; };
inline void RealmDelegate::will_change(std::vector<ObserverState> const&, std::vector<void*> const&) { }
inline void RealmDelegate::did_change(std::vector<ObserverState> const&, std::vector<void*> const&) { }
} // namespace realm } // namespace realm
#endif /* REALM_DELEGATE_HPP */ #endif /* REALM_DELEGATE_HPP */