#include "RenderAble.h" #include "base/Plot.h" #include "Axis/AbsAxis.h" #include "plottable/HoverInfo.h" namespace YSG { QDebug operator<<(QDebug debug, const Range& range) { QDebugStateSaver saver(debug); // 保存当前的 qDebug 状态 debug.nospace() << "Range(" << range.lower << ", " << range.upper << ")"; return debug; } void SpinLock::lock() { while (flag.test_and_set(std::memory_order_acquire)) {} } bool SpinLock::tryLock() { return !flag.test_and_set(std::memory_order_acquire); } bool SpinLock::tryLock(int durationMillis) { if (durationMillis == 0) { return tryLock(); } auto duration = std::chrono::milliseconds(durationMillis); auto start = std::chrono::steady_clock::now(); while (std::chrono::steady_clock::now() - start < duration) { if (tryLock()) { return true; } } return false; } void SpinLock::unlock() { flag.clear(std::memory_order_release); } SpinLockGuard::~SpinLockGuard() { if (mLock) mLock->unlock(); } SpinLockGuard::SpinLockGuard(SpinLock *lock) : mLock(lock) { if (mLock) mLock->lock(); } void RenderAble::init(Plot* plot, QString layerName) { if(layerName.isEmpty()) { layerName = plot->mDefaultLayerName; } plot->mLayerMap[layerName]->mRenderAbles.append(this); mPlot = plot; dPtr = createRenderData(); dPtr->mRenderState = createRenderState(); dPtr->mRenderStateCache = createRenderState(); dPtr->mTempData = createTempData(); dPtr->mTempDataCache = createTempData(); dPtr->mRenderState->dPtr = dPtr; dPtr->mRenderStateCache->dPtr = dPtr; dPtr->qPtr = this; } bool RenderAble::ok() const { return dPtr->mRenderStart && mPlot && !mPlot->mFirstResize && !mPlot->mFirstPrepareData; } RenderAble::~RenderAble(){ } bool RenderAble::dectCycleRely() { QQueue queue; queue.enqueue(this); while (!queue.isEmpty()) { RenderAble* current = queue.dequeue(); QSet visited; QSet recursionStack; QVector path; bool has = hasCycleRely(current, visited, recursionStack, path); if(has){ return true; } } qDebug() << this << " 检测成功!"; return false; } bool RenderAble::hasCycleRely(RenderAble* node, QSet& visited, QSet& recursionStack, QVector& currentPath) { if (!node) return false; if (recursionStack.contains(node)) { // 节点已经在当前递归路径中,检测到循环 qDebug() << "Cycle detected in path:"; // 打印循环依赖链 for (RenderAble* n : currentPath) { qDebug() << n->mObjectName << "(" << n << ")->"; } qDebug() << node; // 打印形成循环的节点 return true; } if (visited.contains(node)) { // 节点已经被处理过,无需再次处理 return false; } // 标记当前节点为已访问 visited.insert(node); // 将当前节点标记为递归路径中的节点 recursionStack.insert(node); // 记录当前节点在路径中 currentPath.append(node); // 递归检查所有子节点 for (RenderAble* child : node->mBeRelyList) { if (hasCycleRely(child, visited, recursionStack, currentPath)) { return true; } } // 从递归路径中移除当前节点 recursionStack.remove(node); // 从路径中移除当前节点 currentPath.removeLast(); return false; } QVector getTurboColorGradient() { QVector colors; QFile file(":/turbo.colorMap"); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "getTurboColorGradient2: Failed to open file"; return colors; // 返回一个空的 std::vector } QByteArray fileData = file.readAll(); file.close(); // 检查文件内容 if (fileData.size() != 768) { qDebug() << "getTurboColorGradient2: File size is not as expected (768 bytes), got" << fileData.size(); return colors; // 返回一个空的 std::vector } // 确保每个颜色有 3 个字节 (RGB),总共有 256 个颜色 colors.reserve(256); for (int i = 0; i < 256; ++i) { uchar r = fileData[i * 3]; uchar g = fileData[i * 3 + 1]; uchar b = fileData[i * 3 + 2]; colors.push_back(qRgb(r, g, b)); } return colors; } SRC RenderState::src() { return dPtr->mRenderState == this ? SRC::Render : SRC::Cache; } }