133 lines
5.9 KiB
C++
Executable File
133 lines
5.9 KiB
C++
Executable File
#pragma once
|
|
|
|
/*
|
|
This is free and unencumbered software released into the public domain.
|
|
|
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
distribute this software, either in source code form or as a compiled
|
|
binary, for any purpose, commercial or non-commercial, and by any
|
|
means.
|
|
|
|
In jurisdictions that recognize copyright laws, the author or authors
|
|
of this software dedicate any and all copyright interest in the
|
|
software to the public domain. We make this dedication for the benefit
|
|
of the public at large and to the detriment of our heirs and
|
|
successors. We intend this dedication to be an overt act of
|
|
relinquishment in perpetuity of all present and future rights to this
|
|
software under copyright law.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
For more information, please refer to <http://unlicense.org/>
|
|
*/
|
|
|
|
#include <LtsUtilsCore/ltsutilscore_export.h>
|
|
|
|
#include <QObject>
|
|
#include <QVariant>
|
|
|
|
#include <functional>
|
|
|
|
|
|
class QTimer;
|
|
|
|
|
|
namespace LtsUtils
|
|
{
|
|
typedef std::function<void(const QVariant &value)> RawResultFunction;
|
|
typedef const RawResultFunction &ResultFunction;
|
|
|
|
|
|
/**
|
|
* @brief The Promise class is the (sort of) non-retarded brother of QFuture and a clone of Javascript's
|
|
* famous Promise. Its purpose is to have a function be executed asynchronously after Qt's event loop was
|
|
* entered, and having a positive (resolve) or negative (reject) result after execution.
|
|
* Otherwise a new class for every promise-like situation has to be created, maintained, and tested.
|
|
* See examples on how to use a Promise here: LtsUtilsCore/promise_examples.h
|
|
* Note that C(++) is a static typed language, this makes this C++ version of Promises need a little more
|
|
* boilerplate code than the original Javascript implementation. Excuse: But TypeScript causes this, too.
|
|
*/
|
|
class LTSUTILSCORE_EXPORT Promise : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
/**
|
|
* @brief Promise creates a promise with the given function - the function is called after Qt entered the event loop
|
|
* so that a task can execute asyncronous. The code inside function has to call either resolve(..) or reject(..) (but never both)
|
|
* if its execution is done. Calling resolve(..) or reject(..) will call the function given beforehand with resolved(..)
|
|
* and / or with reject(..). Failing to call either resolve(..) or reject(..) will result in a promise that
|
|
* will never return and will never remove itself from heap. Don't forget to call either one!
|
|
* This class can be created without setting a function. But then a function has to be set with with setFunction. Otherwise
|
|
* the promise is not executed. The promise is queued for execution if either a function was set in the constructor or
|
|
* it was set with setFunction.
|
|
* @param function
|
|
*/
|
|
Promise(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function, QObject *parent = nullptr);
|
|
|
|
/**
|
|
* @brief setFunction sets the function and queues it for execution into the Qt event loop. Do not use if a
|
|
* function was alread specified in the constructor, because the constructor already calls setFunction if a
|
|
* function was given to the constructor.
|
|
* Calling this method more than once, or a function was already specified in the constructor, does nothing.
|
|
* @param function
|
|
*/
|
|
void setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function);
|
|
|
|
/**
|
|
* @brief resolve must only be called from the function given to the promise's constructor
|
|
* @param value the value to give as a parameter to resolveFn (resolveFn is set by calling resolved(..) after the promise was created)
|
|
*/
|
|
void resolve(const QVariant &value = QVariant());
|
|
|
|
/**
|
|
* @brief reject must only be called from the function given to the promise's constructor
|
|
* @param value the value to give as a parameter to rejectFn (rejectFn is set by calling rejected(..) after the promise was created)
|
|
*/
|
|
void reject(const QVariant &value = QVariant());
|
|
|
|
/**
|
|
* @brief setTimeout starts a timer that when interval is reached, the reject function is called with the value "timeout".
|
|
* Useful if you depend on the promise to always deliver, even though the asynchronous functionality behind the function
|
|
* is not returning. The timer behind the timeout is started right before the function is executed and is stopped right
|
|
* before the function resolves or rejects. Timeout is default off.
|
|
* @param interval milliseconds after the function was executed. Or 0 if timeout should be deactivated again.
|
|
*/
|
|
void setTimeout(int interval);
|
|
|
|
/**
|
|
* @brief resolved sets resolveFn - resolveFn is called if the function given to the promise's constructor calls resolve(..)
|
|
* @param resolveFn the function that is called if resolve(..) was called
|
|
* @return this promise, so that another ResultFunctin can be set directly, without having to call the promise again
|
|
*/
|
|
Promise &resolved(ResultFunction resolveFn);
|
|
|
|
/**
|
|
* @brief rejected sets rejectFn - rejectFn is called if the function given to the promise's constructor calls reject(..)
|
|
* @param rejectFn the function that is called if reject(..) was called
|
|
* @return this promise, so that another ResultFunctin can be set directly, without having to call the promise again
|
|
*/
|
|
Promise &rejected(ResultFunction rejectFn);
|
|
|
|
|
|
private:
|
|
RawResultFunction m_resolveFn;
|
|
RawResultFunction m_rejectFn;
|
|
bool m_functionAlreadySet;
|
|
QTimer *m_timeout;
|
|
bool m_resultSet;
|
|
bool m_timeoutSet;
|
|
|
|
|
|
private slots:
|
|
void slotTimeout();
|
|
};
|
|
|
|
} // namespace LtsUtils
|