64    std::function<void(
void *)> m_handle;
 
   65    std::function<void(
void *)> m_handleProxy;
 
   67    std::function<void(
void)> m_handleV;
 
   68    std::function<void(
void)> m_handleVProxy;
 
   70    bool m_dasyncDestroyed = 
false;
 
   74    void setDAsyncDestroyed() { m_dasyncDestroyed = 
true; }
 
   75    bool dasyncDestroyed() { 
return m_dasyncDestroyed; }
 
   82        Q_ASSERT(qApp->instance() && qApp->instance()->thread());
 
   83        moveToThread(qApp->instance()->thread());
 
   85        bool isStartInMain = D_THREAD_IN_MAIN();
 
   87        QObject::connect(
this,
 
   88                         &MainWorker::sigRunInMain,
 
   90                         &MainWorker::slotRunInMain,
 
   91                         isStartInMain ? Qt::AutoConnection : Qt::BlockingQueuedConnection);
 
   93        QObject::connect(
this,
 
   94                         &MainWorker::sigRunInMainVoid,
 
   96                         &MainWorker::slotRunInMainVoid,
 
   97                         isStartInMain ? Qt::AutoConnection : Qt::BlockingQueuedConnection);
 
  101    template <
typename FUNC, 
typename ArgType>
 
  102    typename std::enable_if<!std::is_void<ArgType>::value>::type setHandle(FUNC &&func)
 
  104        m_handle = [&](
void *arg) {
 
  106            while (q && q->size()) {
 
  112        m_handleProxy = [
this](
void *arg) {
 
  120    template <
typename FUNC, 
typename ArgType>
 
  121    typename std::enable_if<std::is_void<ArgType>::value>::type setHandle(FUNC &&func)
 
  123        m_handleV = [&](void) {
 
  128        m_handleVProxy = [
this](void) {
 
  135    void sigRunInMain(
void *arg);
 
  136    void sigRunInMainVoid();
 
  138    void slotRunInMain(
void *arg)
 
  140        Q_ASSERT(D_THREAD_IN_MAIN());
 
  141        if (m_handleProxy && !m_dasyncDestroyed) {
 
  145    void slotRunInMainVoid(
void)
 
  147        Q_ASSERT(D_THREAD_IN_MAIN());
 
  148        if (m_handleVProxy && !m_dasyncDestroyed) {
 
 
  178class D_DECL_DEPRECATED 
DAsync : 
public QObject
 
  183    std::condition_variable m_cvIn;
 
  185    std::mutex m_mtxForWaitTask;
 
  186    std::condition_variable m_cvForWaitTask;
 
  193        bool m_dasDestructed = 
false;
 
  196        bool destructed() { 
return m_dasDestructed; }
 
  197        void setDestructed() { m_dasDestructed = 
true; }
 
  200        explicit Guard(
DAsync *as) noexcept
 
  203            m_as->m_status.setFlag(DAsyncState::Ready);
 
  204            m_as->m_status.setFlag(DAsyncState::Finished, 
false);  
 
  211            m_as->m_threadGuard = 
nullptr;
 
  212            m_as->m_status.setFlag(DAsyncState::Finished);
 
  213            m_as->m_status.setFlag(DAsyncState::Ready, 
false);  
 
  214            if (m_as->m_status.testFlag(DAsyncState::WaitFinished)) {
 
  215                m_as->m_cvForWaitTask.notify_one();
 
  219        void setPending(
bool isPending)
 
  222                m_as->m_status.setFlag(DAsyncState::Pending, isPending);
 
  226    Guard *m_threadGuard = 
nullptr;
 
  234    template <
typename T, 
typename Enable = 
void>
 
  240    struct DataQueueType<T, typename std::enable_if<std::is_void<T>::value>::type>
 
  243    using DataInQueue = DataQueueType<DataTypeIn>;
 
  244    using DataOutQueue = DataQueueType<DataTypeOut>;
 
  246    DataInQueue m_QueueIn;
 
  247    DataOutQueue m_QueueOut;
 
  250    template <
typename T1, 
typename T2, 
typename Enable1 = 
void, 
typename Enable2 = 
void>
 
  254    template <
typename T1, 
typename T2>
 
  257                    typename std::enable_if<std::is_void<T1>::value>::type,
 
  258                    typename std::enable_if<std::is_void<T2>::value>::type>
 
  260        std::function<void(
void)> cbp;
 
  262    template <
typename T1, 
typename T2>
 
  265                    typename std::enable_if<!std::is_void<T1>::value>::type,
 
  266                    typename std::enable_if<!std::is_void<T2>::value>::type>
 
  268        std::function<T2(T1)> cbp;
 
  270    template <
typename T1, 
typename T2>
 
  273                    typename std::enable_if<std::is_void<T1>::value>::type,
 
  274                    typename std::enable_if<!std::is_void<T2>::value>::type>
 
  276        std::function<T2(
void)> cbp;
 
  278    template <
typename T1, 
typename T2>
 
  281                    typename std::enable_if<!std::is_void<T1>::value>::type,
 
  282                    typename std::enable_if<std::is_void<T2>::value>::type>
 
  284        std::function<void(T1)> cbp;
 
  287    std::mutex m_mtxFunc;
 
  288    FuncType<DataTypeIn, DataTypeOut> m_func GUARDED_BY(m_mtxFunc);
 
  289    DAsyncState::AsyncTaskStatus m_status;
 
  292    explicit DAsync(QObject *parent = 
nullptr) noexcept
 
  295        , m_status(DAsyncState::NotReady)
 
  298        m_helper = 
new Helper(
this, 
this);
 
  303            m_threadGuard->setDestructed();
 
  305        m_status.setFlag(DAsyncState::Cancel);
 
  306        if (m_status.testFlag(DAsyncState::Pending)) {
 
  310            m_mainWorker->setDAsyncDestroyed();
 
  311            m_mainWorker->deleteLater();
 
  312            m_mainWorker = 
nullptr;
 
  318    template <
typename PostInType, 
typename EmitInType>
 
  319    typename std::enable_if<std::is_void<PostInType>::value && std::is_void<EmitInType>::value>::type emitHelper()
 
  322        Q_EMIT m_mainWorker->sigRunInMainVoid();
 
  325    template <
typename PostInType, 
typename EmitInType>
 
  326    typename std::enable_if<!std::is_void<PostInType>::value && !std::is_void<EmitInType>::value>::type emitHelper()
 
  328        m_QueueOut.m_queue.enqueue(m_func.cbp(m_QueueIn.m_queue.dequeue()));
 
  329        Q_EMIT m_mainWorker->sigRunInMain(
static_cast<void *
>(&(m_QueueOut.m_queue)));
 
  332    template <
typename PostInType, 
typename EmitInType>
 
  333    typename std::enable_if<!std::is_void<PostInType>::value && std::is_void<EmitInType>::value>::type emitHelper()
 
  335        m_func.cbp(m_QueueIn.m_queue.dequeue());
 
  336        Q_EMIT m_mainWorker->sigRunInMainVoid();
 
  339    template <
typename PostInType, 
typename EmitInType>
 
  340    typename std::enable_if<std::is_void<PostInType>::value && !std::is_void<EmitInType>::value>::type emitHelper()
 
  342        m_QueueOut.m_queue.enqueue(m_func.cbp());
 
  343        Q_EMIT m_mainWorker->sigRunInMain(
static_cast<void *
>(&(m_QueueOut.m_queue)));
 
  349        if (m_status.testFlag(DAsyncState::Cancel)) {
 
  356        m_status.setFlag(DAsyncState::Cancel);
 
  357        if (m_status.testFlag(DAsyncState::Pending)) {
 
  361    bool isFinished() { 
return m_status.testFlag(DAsyncState::Finished); }
 
  373    void waitForFinished(
bool cancelAllWorks = 
true)
 
  375        Q_ASSERT(!D_THREAD_IN_MAIN());
 
  376        if (cancelAllWorks) {
 
  379        if (!m_status.testFlag(DAsyncState::Finished)) {
 
  380            if (m_status.testFlag(DAsyncState::Pending)) {
 
  383            m_status.setFlag(DAsyncState::WaitFinished);
 
  384            std::unique_lock<std::mutex> lck(m_mtxForWaitTask);
 
  385            m_cvForWaitTask.wait(lck);
 
  389    template <
typename FUNC, 
typename InputType = DataTypeIn>
 
  390    typename std::enable_if<!std::is_void<InputType>::value, Helper *>::type post(FUNC &&func)
 
  392        m_func.cbp = std::forward<FUNC>(func);
 
  396        m_postProxy = [
this]() {
 
  397            std::thread thread([
this] {
 
  398                if (m_status.testFlag(DAsyncState::Cancel)) {
 
  402                m_threadGuard = &guard;
 
  404                std::unique_lock<std::mutex> lck(m_mtxIn);
 
  406                    while (!m_status.testFlag(DAsyncState::Ready) || !m_QueueIn.m_queue.size()) {
 
  407                        guard.setPending(
true);
 
  409                        m_cvIn.wait_for(lck, std::chrono::milliseconds(200));
 
  410                        if (guard.destructed() || m_status.testFlag(DAsyncState::Cancel)) {
 
  414                    guard.setPending(
false);
 
  416                    while (m_func.cbp && m_QueueIn.m_queue.size()) {
 
  417                        emitHelper<DataTypeIn, DataTypeOut>();
 
  427    template <
typename FUNC, 
typename InputType = DataTypeIn>
 
  428    typename std::enable_if<std::is_void<InputType>::value, Helper *>::type post(FUNC &&func)
 
  431            std::lock_guard<std::mutex> lckFunc(m_mtxFunc);
 
  432            m_func.cbp = std::forward<FUNC>(func);
 
  437        m_postProxy = [
this]() {
 
  438            std::thread thread([
this] {
 
  439                if (m_status.testFlag(DAsyncState::Cancel)) {
 
  443                m_threadGuard = &guard;
 
  445                std::unique_lock<std::mutex> lck(m_mtxIn);
 
  447                    if (!m_status.testFlag(DAsyncState::Ready)) {
 
  448                        guard.setPending(
true);
 
  450                        m_cvIn.wait_for(lck, std::chrono::milliseconds(200));
 
  451                        if (guard.destructed() || m_status.testFlag(DAsyncState::Cancel)) {
 
  455                    guard.setPending(
false);
 
  458                        std::lock_guard<std::mutex> lckFunc(m_mtxFunc);
 
  459                        emitHelper<DataTypeIn, DataTypeOut>();
 
  460                        m_func.cbp = 
nullptr;  
 
  471    template <
typename InputType = DataTypeIn>
 
  472    typename std::enable_if<!std::is_void<InputType>::value>::type postData(
const InputType &data)
 
  474        if (Q_UNLIKELY(!m_status.testFlag(DAsyncState::Cancel))) {
 
  475            m_QueueIn.m_queue.enqueue(data);
 
  476            if (m_status.testFlag(DAsyncState::Pending)) {
 
  483    std::function<void()> m_postProxy;
 
  484    class Helper : 
public QObject
 
  489        explicit Helper(
DAsync *async, QObject *parent = 
nullptr) noexcept
 
  495        template <
typename FUNC>
 
  496        Helper *then(FUNC &&func)
 
  498            m_async->m_mainWorker->template setHandle<FUNC, DataTypeOut>(std::forward<FUNC>(func));
 
  502        void start(
bool immediately = 
true)
 
  504            if (m_async->m_postProxy) {
 
  505                m_async->m_postProxy();
 
  508                m_async->m_status.setFlag(DAsyncState::Ready, 
false);
 
  510                m_async->m_status.setFlag(DAsyncState::Ready);
 
  511                if (m_async->m_status.testFlag(DAsyncState::Pending)) {
 
  512                    m_async->m_cvIn.notify_one();
 
  518    Helper *m_helper = 
nullptr;