template class EE::ObservableValue

Overview

Owns a value and notifies scoped observers after the value changes. More…

#include <observablevalue.hpp>

template <typename T>
class ObservableValue {
public:
    // typedefs

    typedef T ValueType;
    typedef std::function<void(const T&)> Callback;

    // structs

    struct State;

    // classes

    class Connection;
    class WeakHandle;

    // construction

    ObservableValue();
    ObservableValue(T value);
    ObservableValue(const ObservableValue&);
    ObservableValue(ObservableValue&&);

    // methods

    ObservableValue& operator=(const ObservableValue&);
    ObservableValue& operator=(ObservableValue&&);
    const T& get() const;
    void set(const T& value);
    void set(T&& value);
    ObservableValue& operator=(const T& value);
    ObservableValue& operator=(T&& value);
    const T& operator*() const;
    const T* operator->() const;
    operator const T &() const;
    Connection observe(Callback callback);
    WeakHandle weakHandle() const;
    std::size_t observerCount() const;
    bool isNotifying() const;
};

Detailed Documentation

Owns a value and notifies scoped observers after the value changes.

ObservableValue is a deliberately small synchronous primitive. Assignment and set() notify observers immediately on the calling thread. Observer callbacks use snapshot semantics: changes to the observer list during a notification take effect on the next notification.

The class is non-copyable. Moving it transfers the value and its existing observers, allowing handles and UI bindings to keep observing the moved-to instance. ObservableValue and all of its connections must be used from a single owning thread.

Use ObservableValue for model or application state whose observers are not known by the model. A configuration object, for example, can publish changes without depending on UIWidget; a live UI may attach with UIValueBinding and disappear safely later.

struct ApplicationConfig {
    ObservableValue<bool> showLineNumbers{ true };
};
ApplicationConfig config;
auto connection = config.showLineNumbers.observe(
    []( bool enabled ) { updateEditorPolicy( enabled ); } );
config.showLineNumbers = false;

Construction

ObservableValue()

Creates an observable containing a default-constructed value.

ObservableValue(T value)

Creates an observable containing value. No notification is emitted.

Methods

const T& get() const

Returns:

A reference to the current value.

void set(const T& value)

Replaces the value and synchronously notifies observers when it changed.

void set(T&& value)

Move-replaces the value and synchronously notifies observers when it changed.

Connection observe(Callback callback)

Observes subsequent value changes.

Registration does not invoke callback with the current value. Reentrant set() calls are queued and delivered after the current observer snapshot completes.

Returns:

A scoped connection; destroying it disconnects the callback.

WeakHandle weakHandle() const

Returns:

A non-owning handle that expires safely with this observable.

std::size_t observerCount() const

Returns:

The number of currently connected observers.

bool isNotifying() const

Returns:

Whether observer callbacks are currently being delivered.