#include "RHI/RHICommondList.h"

#include "RHI/RHICommond.h"
#include "RHI/RHI.h"
#include "Core/Thread/ThreadChecker.h"

RHICommonList::RHICommonList() noexcept {
    INFOLOG("actor self:{}", spdlog::fmt_lib::ptr(this));
}

RHICommonList::~RHICommonList() {
    INFOLOG("dctor self:{}", spdlog::fmt_lib::ptr(this));
}

RHICommonList::Ptr RHICommonList::Create() {
    RHICommonList::Ptr Self(new RHICommonList());
    return Self;
}

bool RHICommonList::Start() {
    isRunning_ = true;
    thread_ = std::make_unique<std::thread>([this]() {
        SetThreadName("renderThread");

        DriverSettings& driverSetting = RHI::Get()->GetDriverSettings();
        if (nullptr == driverSetting.renderMakeCurrentContext) {
            return;
        }
        driverSetting.renderMakeCurrentContext();
        RHI::Get()->InitRenderEnv();
        while (isRunning_) {
            {
                std::unique_lock<std::mutex> lock(queueMutex_);
                queueCondVar_.wait(lock, [this, driverSetting]() { return !queue_.empty() || !isRunning_; });
                if (!isRunning_) {
                    break;
                }

                while (!queue_.empty()) {
                    SharedPtr<RHICommond> commond = queue_.front();
                    queue_.pop();
                    if (!isRunning_) {
                        break;
                    }

                    commond->Execute();
                }
            }
        }
    });
    return true;
}

void RHICommonList::Stop() {
    isRunning_ = false;
    queueCondVar_.notify_one();
    if (thread_ && thread_->joinable()) {
        thread_->join();
        thread_.reset();
    }
}

void RHICommonList::Push(RHICommond* commond) {
    {
        std::lock_guard<std::mutex> lock(queueMutex_);
        queue_.emplace(commond);
    }
    queueCondVar_.notify_one();
}
