sneedmc/logic/resources/ResourceObserver.h
2015-09-05 19:23:46 +02:00

74 lines
1.8 KiB
C++

#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>());
}
};