diff --git a/openVulkanoCpp/Base/Observable.hpp b/openVulkanoCpp/Base/Observable.hpp index 6df40ad..2569e8d 100644 --- a/openVulkanoCpp/Base/Observable.hpp +++ b/openVulkanoCpp/Base/Observable.hpp @@ -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 + class Observable final + { + T object; + + void Notify() { OnChange(object); } + + public: + template>> + 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>> + 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>> + auto& operator = (const T& val) { object = val; Notify(); return *this; } + + template>> + auto& operator = (T&& val) { object = std::forward(val); Notify(); return *this; } + + template>> + 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 accessFunction) { if (accessFunction(object)) Notify(); } + + Event OnChange; + }; +}