std::vector<const TFx *> calculateSortedFxs(TRasterFxP rootFx) { std::map<const TFx *, std::set<const TFx *>> E; /* 辺の情報 */ std::set<const TFx *> Sources; /* 入次数0のノード群 */ std::queue<const TFx *> Q; Q.push(rootFx.getPointer()); E[rootFx.getPointer()] = std::set<const TFx *>(); while (!Q.empty()) { const TFx *vptr = Q.front(); Q.pop(); if (!vptr) { continue; } /* 繋がっている入力ポートの先の Fx を訪問する 入力ポートが無ければ終了 */ int portCount = vptr->getInputPortCount(); if (portCount < 1) { Sources.insert(vptr); continue; } for (int i = 0; i < portCount; i++) { TFxPort *port = vptr->getInputPort(i); if (!port) { continue; } TFxP u = port->getFx(); const TFx *uptr = u.getPointer(); if (E.count(uptr) == 0) { E[uptr] = std::set<const TFx *>(); } if (E[uptr].count(vptr) == 0) { E[uptr].insert(vptr); } Q.push(uptr); } } /* トポロジカルソート */ std::set<const TFx *> visited; std::vector<const TFx *> L; std::function<void(const TFx *)> visit = [&visit, &visited, &E, &L](const TFx *fx) { if (visited.count(fx)) return; visited.insert(fx); auto edge = E[fx]; for (auto i = edge.cbegin(); i != edge.cend(); i++) { visit(*i); } L.insert(L.begin(), fx); }; for (auto i = E.cbegin(); i != E.cend(); i++) { visit(i->first); } return L; }
void SwatchViewer::computeContent() { if (suspendedRendering) return; if (!m_enabled) return; if (!m_raster) return; //Clear the swatch cache when the zoom scale has changed (cache results are not compatible //between different scale levels) if (m_aff.a11 != m_contentAff.a11) SwatchCacheManager::instance()->clearSwatchResults(); TRect rect(0, 0, width() - 1, height() - 1); TDimension size = rect.getSize(); assert(m_raster->getSize() == size); if (m_fx) { //TFxP fx = makeAffine(m_fx, m_aff); //TRasterFxP rasterFx = fx; TRasterFxP rasterFx = m_fx; if (rasterFx) { m_executor.cancelAll(); m_executor.addTask(new ContentRender(rasterFx.getPointer(), m_frame, size, this)); submittedTasks++; return; } else { m_content = TRaster32P(size); m_content->fill(TPixel32::Red); } } else { m_content = TRaster32P(size); m_content->fill(TPixel32::Transparent); } updateRaster(); }