HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Data Fields | Static Public Attributes
tt::observable< T > Class Template Reference

#include <ttauri/observable.hpp>

Public Types

using value_type = T
 
using reference = detail::observable_proxy<value_type, false>
 
using const_reference = detail::observable_proxy<value_type, true>
 
using impl_type = detail::observable_impl<value_type>
 
using callback_ptr_type = std::shared_ptr<std::function<void()>>
 

Public Member Functions

 observable () noexcept
 Construct an observable.
 
 observable (observable const &other) noexcept
 Construct an observable and chain it to another.
 
observableoperator= (observable const &other) noexcept
 Chain with another observable.
 
const_reference cget () const noexcept
 Get a constant reference to the shared value.
 
const_reference get () const noexcept
 Get a constant reference to the shared value.
 
reference get () noexcept
 Get a writable reference to the shared-value.
 
 observable (std::convertible_to< value_type > auto &&value) noexcept
 Construct an observable with its value set.
 
template<typename Value = value_type>
requires (not std::is_same_v<std::remove_cvref_t<Value>, observable>)
observableoperator= (Value &&value) noexcept
 Assign a new value.
 
value_type operator* () const noexcept
 Get copy of the shared-value.
 
detail::observable_proxy< value_type, true > operator* () const noexcept
 
detail::observable_proxy< value_type, false > operator* () noexcept
 
detail::observable_proxy< value_type, true > operator-> () const noexcept
 
detail::observable_proxy< value_type, false > operator-> () noexcept
 
 operator bool () const noexcept
 
 X (==) X(-) X(-) template< typename Rhs > value_type operator+
 
void notify () const noexcept
 

Data Fields

std::vector< std::weak_ptr< std::function< void()> > > _callbacks
 
friend impl_type
 

Static Public Attributes

static constexpr bool is_atomic = impl_type::is_atomic
 

Detailed Description

template<typename T>
class tt::observable< T >

A value which can be observed for modifications.

An observable is used to share a value between different objects, and for those objects to be notified when this shared-value is modified.

Typically objects will own an instance of an observable and subscribe() one of its methods to the observable. By assigning the observables of each object to each other they will share the same value. Now if one object changes the shared value, the other objects will get notified.

When assigning observables to each other, the subscriptions to the observable remain unmodified. However which value is shared is shown in the example below:

auto a = observable<int>{1};
auto b = observable<int>{5};
auto c = observable<int>{42};
auto d = observable<int>{9};
a = b; // both 'a' and 'b' share the value 5.
b = c; // 'a', 'b' and 'c' all share the value 42.
b = d; // 'a', 'b', 'c' and 'd' all share the value 9.
A value which can be observed for modifications.
Definition observable.hpp:464

A subscription to a observable is maintained using a std::weak_ptr to a callback function. This means that the object that subscribed to the observable needs to own the std::shared_ptr that is returned by the subscribe() method.

A proxy object is returned when dereferencing an observable. The callbacks are called when both the value has changed and the lifetime of all non-scalar proxy objects in the system has ended.

A proxy of a non-scalar observable holds a mutex. It may be useful to extend the lifetime of a proxy to handle multiple steps atomically. However due to the mutex held, it may be possible to dead-lock when the lifetime of multiple proxy objects are extended in different orders.

Constant proxies are more efficient than non-constant proxies. You can get a non-constant proxy using the cget() function. Many of the operations available directly on the observable uses constant proxies internally for this reason.

Template Parameters
TThe type of the value to be observed.

Constructor & Destructor Documentation

◆ observable() [1/3]

template<typename T >
tt::observable< T >::observable ( )
inlinenoexcept

Construct an observable.

The observer is created with a value that is default constructed.

◆ observable() [2/3]

template<typename T >
tt::observable< T >::observable ( observable< T > const & other)
inlinenoexcept

Construct an observable and chain it to another.

The new observable will share a value with the other observable.

Parameters
otherThe other observable to share the value with.

◆ observable() [3/3]

template<typename T >
tt::observable< T >::observable ( std::convertible_to< value_type > auto && value)
inlinenoexcept

Construct an observable with its value set.

Parameters
valueThe value to assign to the shared-value.

Member Function Documentation

◆ cget()

template<typename T >
const_reference tt::observable< T >::cget ( ) const
inlinenoexcept

Get a constant reference to the shared value.

In reality the reference is a proxy object which makes available operations to be used with the shared value. This proxy object will make sure any state is done atomically.

Returns
A reference to the shared value.

◆ get() [1/2]

template<typename T >
const_reference tt::observable< T >::get ( ) const
inlinenoexcept

Get a constant reference to the shared value.

In reality the reference is a proxy object which makes available operations to be used with the shared value. This proxy object will make sure any state is done atomically.

Returns
A reference to the shared value.

◆ get() [2/2]

template<typename T >
reference tt::observable< T >::get ( )
inlinenoexcept

Get a writable reference to the shared-value.

In reality the reference is a proxy object which makes available operations to be used with the shared-value. This proxy object will make sure any state is done atomically and that subscribers are notified when the proxy's lifetime has ended.

Postcondition
subscribers are notified after reference's lifetime has ended.
Returns
A reference to the shared value.

◆ operator*()

template<typename T >
value_type tt::observable< T >::operator* ( ) const
inlinenoexcept

Get copy of the shared-value.

Returns
a copy of the shared-value.

◆ operator=() [1/2]

template<typename T >
observable & tt::observable< T >::operator= ( observable< T > const & other)
inlinenoexcept

Chain with another observable.

Replace the current shared value, with the value of the other observer. This means the other observers that share the current value will also be reseated with the new value.

Postcondition
observers sharing the same value will be modified to share the new value.
subscribers are notified
Parameters
otherThe other observable to share the value with.

◆ operator=() [2/2]

template<typename T >
template<typename Value = value_type>
requires (not std::is_same_v<std::remove_cvref_t<Value>, observable>)
observable & tt::observable< T >::operator= ( Value && value)
inlinenoexcept

Assign a new value.

Postcondition
subscribers are notified.
Parameters
valueThe value to assign to the shared-value.

The documentation for this class was generated from the following file: