summaryrefslogtreecommitdiffstats
path: root/libraries/logic/resources/ResourceObserver.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/logic/resources/ResourceObserver.h')
-rw-r--r--libraries/logic/resources/ResourceObserver.h73
1 files changed, 73 insertions, 0 deletions
diff --git a/libraries/logic/resources/ResourceObserver.h b/libraries/logic/resources/ResourceObserver.h
new file mode 100644
index 00000000..c42e41ba
--- /dev/null
+++ b/libraries/logic/resources/ResourceObserver.h
@@ -0,0 +1,73 @@
+#pragma once
+
+#include <memory>
+#include <functional>
+
+#include <QObject>
+#include <QMetaProperty>
+#include "multimc_logic_export.h"
+
+class QVariant;
+class Resource;
+
+/// Base class for things that can use a resource
+class MULTIMC_LOGIC_EXPORT ResourceObserver
+{
+public:
+ virtual ~ResourceObserver();
+
+protected: // these methods are called by the Resource when something changes
+ virtual void resourceUpdated() = 0;
+ virtual void setFailure(const QString &) {}
+ virtual void setProgress(const int) {}
+
+private:
+ friend class Resource;
+ void setSource(std::shared_ptr<Resource> resource) { m_resource = resource; }
+
+protected:
+ template<typename T>
+ T get() const { return getInternal(qMetaTypeId<T>()).template value<T>(); }
+ QVariant getInternal(const int typeId) const;
+
+private:
+ std::shared_ptr<Resource> m_resource;
+};
+
+/** Observer for QObject properties
+ *
+ * Give it a target and the name of a property, and that property will be set when the resource changes.
+ *
+ * If no name is given an attempt to find a default property for some common classes is done.
+ */
+class MULTIMC_LOGIC_EXPORT QObjectResourceObserver : public QObject, public ResourceObserver
+{
+public:
+ explicit QObjectResourceObserver(QObject *target, const char *property = nullptr);
+
+ void resourceUpdated() override;
+
+private:
+ QObject *m_target;
+ QMetaProperty m_property;
+};
+
+/** Observer for functions, lambdas etc.
+ * Template arguments:
+ * * We need Ret and Arg in order to create the std::function
+ * * We need Func in order to std::forward the function
+ */
+template <typename Ret, typename Arg, typename Func>
+class FunctionResourceObserver : public ResourceObserver
+{
+ std::function<Ret(Arg)> m_function;
+public:
+ template <typename T>
+ explicit FunctionResourceObserver(T &&func)
+ : m_function(std::forward<Func>(func)) {}
+
+ void resourceUpdated() override
+ {
+ m_function(get<Arg>());
+ }
+};