ExtendableProperty is a Property which has callbacks associated with it, to be notified when it is accessed or updated. More...
#include <Property.h>
Public Types | |
using | PropertyChangedEventHandler = function< PropertyCommon::PropertyChangedEventResultType(const PropertyChangedEvent &)> |
using | PropertyReadEventHandlerArgAndReturnValue_ = conditional_t< is_reference_v< base_value_type >, decayed_value_type *, base_value_type > |
using | PropertyReadEventHandler = function< PropertyReadEventHandlerArgAndReturnValue_(const PropertyReadEventHandlerArgAndReturnValue_ &)> |
![]() | |
using | base_value_type = T |
base_value_type is T the type declared, and decayed_value_type is similar, but with the references etc removed (so can be set/stored) | |
Public Attributes | |
ReadOnlyProperty< const std::forward_list< PropertyReadEventHandler > & > | propertyReadHandlers |
ReadOnlyProperty< const std::forward_list< PropertyChangedEventHandler > & > | propertyChangedHandlers |
Additional Inherited Members | |
![]() | |
Property ()=delete | |
![]() | |
ReadOnlyProperty ()=delete | |
nonvirtual T | Get () const |
nonvirtual | operator const T () const |
nonvirtual const T | operator() () const |
![]() | |
WriteOnlyProperty ()=delete | |
nonvirtual WriteOnlyProperty & | operator= (ArgByValueType< remove_cvref_t< T > > value) |
nonvirtual void | Set (ArgByValueType< remove_cvref_t< T > > value) |
nonvirtual void | operator() (ArgByValueType< remove_cvref_t< T > > value) |
ExtendableProperty is a Property which has callbacks associated with it, to be notified when it is accessed or updated.
These callbacks which you can attach to an ExtendableProperty effectively allow OVERRIDING the property because you can suppress update or handle it differently yourself.
Use Cases:
VIABLE APPROACHES:
The third approach sucks cuz waste of space, and inconsistent behavior if you access property through ptr to base class.
'Events' approach nice in that it is more generally useful (listeners could be largely unrelated - external - like vtable methods vs 'function' ptr objects). But its COSTLY when not used (must maintain a list of callbacks, or worse two). Can mitigate cost as mentioned above, by only having subclass of Property (PropertyWithEvents) that supports events.
REPLACING the GETTER/SETTER seems quite viable, except that it appears to really kill modularity. No way (I can think of) within c++ to capture any kind of public/private thing. Anybody would be replacing GETTERS or SETTERS (if anybody can) (cannot use protected cuz not subclassing, and forcing extra subclassing would be awkward).
Though its up to any object which uses properties, its generally presumed and recommended that of you copy objects O1 (of type O, with ExtendableProperty P) to object O2, then the event handlers watching properties P (from O1) will NOT be copied to object O2 (to its property P).
Definition at line 491 of file Property.h.
using Stroika::Foundation::Common::ExtendableProperty< T >::PropertyChangedEventHandler = function<PropertyCommon::PropertyChangedEventResultType (const PropertyChangedEvent&)> |
if return result is false, this silently cuts-off processing. EventHandlers can also throw also can be used to prevent further processing, but then calling code will see that as an error. So event handler ordering matters. If any event propertyChangedHandlers present, they are handled in-order, with the underlying SETTER being the final 'eventhandler'
TODO
This means you may find you need to do such comparisons yourself in callbacks before doing much to 'process' the change.
Definition at line 537 of file Property.h.
using Stroika::Foundation::Common::ExtendableProperty< T >::PropertyReadEventHandlerArgAndReturnValue_ = conditional_t<is_reference_v<base_value_type>, decayed_value_type*, base_value_type> |
Note - that assigning/coping reference values and using them with optional works poorly, so when T is a reference type, the PropertyReadEventHandler just takes and returns a pointer to T instead to avoid this unpleasantness.
#if 0 This must return optional<base_value_type> because base_value_type is what is returned by the Get() function. But C++ doesn't allow optional<reference type>. So - for reference types, PropertyReadEventHandler returns a pointer.
Definition at line 551 of file Property.h.
using Stroika::Foundation::Common::ExtendableProperty< T >::PropertyReadEventHandler = function<PropertyReadEventHandlerArgAndReturnValue_ (const PropertyReadEventHandlerArgAndReturnValue_&)> |
this gets handed the original base value (stored), but then each handler gets a crack at overriding the value.
Definition at line 558 of file Property.h.
ReadOnlyProperty<const std::forward_list<PropertyReadEventHandler>&> Stroika::Foundation::Common::ExtendableProperty< T >::propertyReadHandlers |
Use forward_list instead of Sequence<> to avoid a dependency on Stroika containers in a potentially low level component
Definition at line 564 of file Property.h.
ReadOnlyProperty<const std::forward_list<PropertyChangedEventHandler>&> Stroika::Foundation::Common::ExtendableProperty< T >::propertyChangedHandlers |
Use forward_list instead of Sequence<> to avoid a dependency on Stroika containers in a potentially low level component
Definition at line 571 of file Property.h.