Add Observable class
This commit is contained in:
@@ -1,8 +1,74 @@
|
||||
//
|
||||
// Created by georg on 2024-04-24.
|
||||
//
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef MADVOXEL_SCANAPP_OBSERVABLE_HPP
|
||||
#define MADVOXEL_SCANAPP_OBSERVABLE_HPP
|
||||
#include "Event.hpp"
|
||||
|
||||
#endif //MADVOXEL_SCANAPP_OBSERVABLE_HPP
|
||||
namespace OpenVulkano
|
||||
{
|
||||
template<typename T>
|
||||
class Observable final
|
||||
{
|
||||
T object;
|
||||
|
||||
void Notify() { OnChange(object); }
|
||||
|
||||
public:
|
||||
template<typename = std::enable_if_t<std::is_default_constructible_v<T>>>
|
||||
Observable() {}
|
||||
|
||||
Observable(const T& initValue) : object(initValue) {}
|
||||
|
||||
Observable(T&& initValue) : object(std::forward(initValue)) {}
|
||||
|
||||
//TODO make this somehow only work for none string types to prevent issues?
|
||||
/*template<typename = std::enable_if_t<std::is_default_constructible_v<T>>>
|
||||
explicit Observable(const std::string& observableName) : OnChange(observableName) {}*/
|
||||
|
||||
Observable(const T& initValue, const std::string& observableName)
|
||||
: object(initValue), OnChange(observableName)
|
||||
{}
|
||||
|
||||
Observable(T&& initValue, const std::string& observableName)
|
||||
: object(std::forward(initValue)), OnChange(observableName)
|
||||
{}
|
||||
|
||||
template<typename = std::enable_if_t<std::is_copy_assignable_v<T>>>
|
||||
auto& operator = (const T& val) { object = val; Notify(); return *this; }
|
||||
|
||||
template<typename = std::enable_if_t<std::is_move_assignable_v<T>>>
|
||||
auto& operator = (T&& val) { object = std::forward(val); Notify(); return *this; }
|
||||
|
||||
template<typename = std::enable_if_t<std::is_copy_assignable_v<T>>>
|
||||
operator T() const { return object; }
|
||||
|
||||
operator const T&() const { return object; }
|
||||
|
||||
bool operator ==(const T& other) const { return object == other; }
|
||||
bool operator !=(const T& other) const { return object != other; }
|
||||
bool operator <(const T& other) const { return object < other; }
|
||||
bool operator <=(const T& other) const { return object <= other; }
|
||||
bool operator >(const T& other) const { return object > other; }
|
||||
bool operator >=(const T& other) const { return object >= other; }
|
||||
bool operator !() const { return !object; }
|
||||
|
||||
operator bool() const { return object.operator bool(); }
|
||||
auto& operator ++() { ++object; Notify(); return *this; }
|
||||
auto& operator --() { --object; Notify(); return *this; }
|
||||
auto& operator ++(int) { object++; Notify(); return *this; }
|
||||
auto& operator --(int) { object--; Notify(); return *this; }
|
||||
|
||||
auto& operator +=(const T& other) { object += other; Notify(); return *this; }
|
||||
auto& operator -=(const T& other) { object -= other; Notify(); return *this; }
|
||||
auto& operator *=(const T& other) { object *= other; Notify(); return *this; }
|
||||
auto& operator /=(const T& other) { object /= other; Notify(); return *this; }
|
||||
|
||||
const T* operator ->() const { return &object; }
|
||||
|
||||
void MutatingAccess(const std::function<bool(T&)> accessFunction) { if (accessFunction(object)) Notify(); }
|
||||
|
||||
Event<const T&> OnChange;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user