# GpgFrontend Project: src/core/thread/Task.h Source File

Task.h
#ifndef GPGFRONTEND_TASK_H
#define GPGFRONTEND_TASK_H
#include <functional>
#include <memory>
#include <stack>
#include <string>
#include <type_traits>
#include <utility>
#include "core/GpgFrontendCore.h"
namespace GpgFrontend::Thread {
class TaskRunner;
class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
Q_OBJECT
public:
class DataObject;
using DataObjectPtr = std::shared_ptr<DataObject>;
using TaskRunnable = std::function<int(DataObjectPtr)>;
using TaskCallback = std::function<void(int, DataObjectPtr)>;
static const std::string DEFAULT_TASK_NAME;
friend class TaskRunner;
class GPGFRONTEND_CORE_EXPORT DataObject {
public:
struct Destructor {
const void *p_obj;
void (*destroy)(const void *);
};
size_t GetObjectSize();
template <typename T>
void AppendObject(T &&obj) {
SPDLOG_TRACE("append object: {}", static_cast<void *>(this));
auto *obj_dstr = this->get_heap_ptr(sizeof(T));
new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj));
if (std::is_class_v<T>) {
auto destructor = [](const void *x) {
static_cast<const T *>(x)->~T();
};
obj_dstr->destroy = destructor;
} else {
obj_dstr->destroy = nullptr;
}
data_objects_.push(obj_dstr);
}
template <typename T>
void AppendObject(T *obj) {
SPDLOG_TRACE("called: {}", static_cast<void *>(this));
auto *obj_dstr = this->get_heap_ptr(sizeof(T));
auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj));
if (std::is_class_v<T>) {
SPDLOG_TRACE("is class");
auto destructor = [](const void *x) {
static_cast<const T *>(x)->~T();
};
obj_dstr->destroy = destructor;
} else {
obj_dstr->destroy = nullptr;
}
data_objects_.push(std::move(obj_dstr));
}
template <typename T>
T PopObject() {
SPDLOG_TRACE("pop object: {}", static_cast<void *>(this));
if (data_objects_.empty()) throw std::runtime_error("No object to pop");
auto *obj_dstr = data_objects_.top();
auto *heap_ptr = (T *)obj_dstr->p_obj;
auto obj = std::move(*(T *)(heap_ptr));
this->free_heap_ptr(obj_dstr);
data_objects_.pop();
return obj;
}
~DataObject();
private:
std::stack<Destructor *> data_objects_;
Destructor *get_heap_ptr(size_t bytes_size);
void free_heap_ptr(Destructor *);
};
Task(std::string name = DEFAULT_TASK_NAME);
explicit Task(TaskRunnable runnable, std::string name = DEFAULT_TASK_NAME,
DataObjectPtr data_object = nullptr, bool sequency = true);
explicit Task(
TaskRunnable runnable, std::string name, DataObjectPtr data,
TaskCallback callback = [](int, const std::shared_ptr<DataObject> &) {},
bool sequency = true);
virtual ~Task() override;
virtual void Run();
std::string GetUUID() const;
std::string GetFullID() const;
bool GetSequency() const;
public slots:
void SlotRun();
signals:
void SignalTaskRunnableEnd(int rtn);
void SignalTaskEnd();
protected:
void SetFinishAfterRun(bool finish_after_run);
void SetRTN(int rtn);
private:
const std::string uuid_;
const std::string name_;
const bool sequency_ = true;
TaskCallback callback_;
TaskRunnable runnable_;
bool run_callback_after_runnable_finished_ = true;
int rtn_ = 0;
QThread *callback_thread_ = nullptr;
DataObjectPtr data_object_ = nullptr;
void init();
virtual void run() override;
static std::string generate_uuid();
private slots:
void slot_task_run_callback(int rtn);
};
} // namespace GpgFrontend::Thread
#endif // GPGFRONTEND_TASK_H
GpgFrontend::Thread::TaskRunner
Definition: TaskRunner.h:40
GpgFrontend::Thread::Task::DataObject
DataObject to be passed to the callback function.
Definition: Task.h:61
GpgFrontend::Thread::Task::DataObject::AppendObject
void AppendObject(T &&obj)
Definition: Task.h:82
GpgFrontend::Thread::Task::DataObject::AppendObject
void AppendObject(T *obj)
Definition: Task.h:106
GpgFrontend::Thread::Task::DataObject::PopObject
T PopObject()
Definition: Task.h:129
GpgFrontend::Thread::Task
Definition: Task.h:45
GpgFrontend::Thread::Task::SignalTaskRunnableEnd
void SignalTaskRunnableEnd(int rtn)
announce runnable finished
GpgFrontend::Thread::Task::DEFAULT_TASK_NAME
static const std::string DEFAULT_TASK_NAME
Definition: Task.h:53
GpgFrontend::Thread::Task::SignalTaskEnd
void SignalTaskEnd()
runnable and callabck all finished
GpgFrontend::Thread
Definition: CtxCheckTask.h:33
GpgFrontend::Thread::Task::DataObject::Destructor
Definition: Task.h:63