Warning, file /frameworks/bluez-qt/src/job.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * BluezQt - Asynchronous BlueZ wrapper library
0003  *
0004  * SPDX-FileCopyrightText: 2014 Alejandro Fiestas Olivares <afiestas@kde.org>
0005  * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com>
0006  *
0007  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0008  */
0009 
0010 #ifndef BLUEZQT_JOB_H
0011 #define BLUEZQT_JOB_H
0012 
0013 #include <QObject>
0014 
0015 #include "bluezqt_export.h"
0016 
0017 #include <memory>
0018 
0019 namespace BluezQt
0020 {
0021 class JobPrivate;
0022 
0023 /**
0024  * @class BluezQt::Job job.h <BluezQt/Job>
0025  *
0026  * This class represents an asynchronous job performed by BluezQt,
0027  * it is usually not used directly but instead it is inherit by some
0028  * other class.
0029  *
0030  * There are two ways of using this class, one is via exec() which will block
0031  * the thread until a result is fetched, the other is via connecting to the
0032  * signal result()
0033  *
0034  * Please, think twice before using exec(), it should be used only in either
0035  * unittest or cli apps.
0036  *
0037  * @note Job and its subclasses are meant to be used in a fire-and-forget way.
0038  * Jobs will delete themselves when they finish using deleteLater().
0039  *
0040  * @note Even given their asynchronous nature, Jobs are still executed in the
0041  * main thread, so any blocking code executed in it will block the app calling it.
0042  *
0043  * @see InitManagerJob
0044  * @see InitObexManagerJob
0045  */
0046 class BLUEZQT_EXPORT Job : public QObject
0047 {
0048     Q_OBJECT
0049     Q_PROPERTY(int error READ error)
0050     Q_PROPERTY(QString errorText READ errorText)
0051     Q_PROPERTY(bool running READ isRunning)
0052     Q_PROPERTY(bool finished READ isFinished)
0053 
0054 public:
0055     /**
0056      * Creates a new Job object.
0057      *
0058      * @param parent
0059      */
0060     explicit Job(QObject *parent = nullptr);
0061 
0062     /**
0063      * Destroys a Job object.
0064      */
0065     ~Job() override;
0066 
0067     /**
0068      * Error type
0069      *
0070      * @see error() const
0071      */
0072     enum Error {
0073         /** Indicates there is no error */
0074         NoError = 0,
0075         /** Subclasses should define error codes starting at this value */
0076         UserDefinedError = 100
0077     };
0078     Q_ENUM(Error)
0079 
0080     /**
0081      * Executes the job synchronously.
0082      *
0083      * This will start a nested QEventLoop internally. Nested event loop can be dangerous and
0084      * can have unintended side effects, you should avoid calling exec() whenever you can and use the
0085      * asynchronous interface of Job instead.
0086      *
0087      * Should you indeed call this method, you need to make sure that all callers are reentrant,
0088      * so that events delivered by the inner event loop don't cause non-reentrant functions to be
0089      * called, which usually wreaks havoc.
0090      *
0091      * Note that the event loop started by this method does not process user input events, which means
0092      * your user interface will effectively be blocked. Other events like paint or network events are
0093      * still being processed. The advantage of not processing user input events is that the chance of
0094      * accidental reentrancy is greatly reduced. Still you should avoid calling this function.
0095      *
0096      * @warning This method blocks until the job finishes!
0097      *
0098      * @return true if the job has been executed without error, false otherwise
0099      */
0100     bool exec();
0101 
0102     /**
0103      * Returns the error code, if there has been an error.
0104      *
0105      * Make sure to call this once result() has been emitted
0106      *
0107      * @return the error code for this job, 0 if no error.
0108      */
0109     int error() const;
0110 
0111     /**
0112      * Returns the error text if there has been an error.
0113      *
0114      * Only call if error is not 0.
0115      *
0116      * This is usually some extra data associated with the error,
0117      * such as a URL.  Use errorString() to get a human-readable,
0118      * translated message.
0119      *
0120      * @return a string to help understand the error
0121      */
0122     QString errorText() const;
0123 
0124     /**
0125      * Returns whether the job is currently running
0126      *
0127      * @return true if the job is running
0128      */
0129     bool isRunning() const;
0130 
0131     /**
0132      * Returns whether the job have already finished
0133      *
0134      * @return true if the job already finished
0135      */
0136     bool isFinished() const;
0137 
0138 public Q_SLOTS:
0139     /**
0140      * Starts the job asynchronously.
0141      *
0142      * This method will schedule doStart() to be executed in the next
0143      * loop. This is done so this method returns as soon as possible.
0144      *
0145      * When the job is finished, result() is emitted.
0146      */
0147     void start();
0148 
0149     /**
0150      * Kills the job.
0151      *
0152      * This method will kill the job and then call deleteLater().
0153      * Only jobs started with start() can be killed.
0154      *
0155      * It will not emit result signal.
0156      */
0157     void kill();
0158 
0159 protected Q_SLOTS:
0160     /**
0161      * Implementation for start() that will be executed in next loop
0162      *
0163      * This slot is always called in the next loop, triggered by start().
0164      *
0165      * When implementing this method is important to remember that jobs
0166      * are not executed on a different thread (unless done that way), so any
0167      * blocking task has to be done in a different thread or process.
0168      */
0169     virtual void doStart() = 0;
0170 
0171 protected:
0172     /**
0173      * Sets the error code.
0174      *
0175      * It should be called when an error
0176      * is encountered in the job, just before calling emitResult().
0177      *
0178      * You should define an enum of error codes,
0179      * with values starting at Job::UserDefinedError, and use
0180      * those. For example:
0181      * @code
0182      * enum ExampleErrors{
0183      *   InvalidFoo = UserDefinedError,
0184      *   BarNotFound
0185      * };
0186      * @endcode
0187      *
0188      * @param errorCode the error code
0189      * @see emitResult()
0190      */
0191     void setError(int errorCode);
0192 
0193     /**
0194      * Sets the error text.
0195      *
0196      * It should be called when an error
0197      * is encountered in the job, just before calling emitResult().
0198      *
0199      * Provides extra information about the error that cannot be
0200      * determined directly from the error code.  For example, a
0201      * URL or filename.  This string is not normally translatable.
0202      *
0203      * @param errorText the error text
0204      * @see emitResult(), setError()
0205      */
0206     void setErrorText(const QString &errorText);
0207 
0208     /**
0209      * Utility function to emit the result signal, and remove this job.
0210      *
0211      * @note Deletes this job using deleteLater().
0212      * @see result() const
0213      */
0214     void emitResult();
0215 
0216     /**
0217      * Implementation for emitting the result signal
0218      *
0219      * This function is needed to be able to emit result() signal
0220      * with the job pointer's type being subclass
0221      */
0222     virtual void doEmitResult() = 0;
0223 
0224 private:
0225     std::unique_ptr<JobPrivate> const d_ptr;
0226 
0227     Q_DECLARE_PRIVATE(Job)
0228 };
0229 
0230 } // namespace BluezQt
0231 
0232 #endif // BLUEZQT_JOB_H