StageObjectsData *StageObjectsData::clone() const { StageObjectsData *data = new StageObjectsData(); // Clone each element (the new data gets ownership) int i, elementsCount = m_elements.size(); for (i = 0; i < elementsCount; ++i) data->m_elements.append(m_elements[i]->clone()); // Clone each spline (the new data gets ownership) for (i = 0; i < m_splines.size(); ++i) data->m_splines.append(m_splines[i]->clone()); // Same for internal fxs std::map<TFx *, TFx *> fxTable; // And trace the pairings with the originals std::set<TFx *>::const_iterator it; for (it = m_fxs.begin(); it != m_fxs.end(); ++it) { TFx *fxOrig = *it; assert(fxOrig); assert(fxTable.count(fxOrig) == 0); TFx *fx = fxOrig->clone(false); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; fx->setName(fxOrig->getName()); fx->setFxId(fxOrig->getFxId()); fxTable[fxOrig] = fx; fx->addRef(); data->m_fxs.insert(fx); } // Same with terminals for (it = m_terminalFxs.begin(); it != m_terminalFxs.end(); ++it) { TFx *fxOrig = *it; assert(fxOrig); // If the fx was not already cloned above, do it now TFx *fx = searchFx(fxTable, fxOrig); if (!fx) { fx = fxOrig->clone(false); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; fx->setName(fxOrig->getName()); fx->setFxId(fxOrig->getFxId()); fxTable[fxOrig] = fx; } fx->addRef(); data->m_terminalFxs.insert(fx); } if (!fxTable.empty()) updateFxLinks(fxTable); // Applies the traced map pairings to every fx descendant // of each fx stored in the map. // WARNING: m_fxsTable is NOT COPIED / CLONED !! return data; }
void StageObjectsData::storeFxs(const std::set<TFx *> &fxs, TXsheet *xsh, int fxFlags) { bool doClone = (fxFlags & eDoClone); bool resetFxDagPositions = (fxFlags & eResetFxDagPositions); TFxSet *terminalFxs = xsh->getFxDag()->getTerminalFxs(); // Traverse specified fxs std::set<TFx *>::const_iterator it; for (it = fxs.begin(); it != fxs.end(); ++it) { TFx *fxOrig = *it, *fx = fxOrig; if (doClone) { // If required, clone them fx = fxOrig->clone(false); fx->setName(fxOrig->getName()); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; if (resetFxDagPositions) fx->getAttributes()->setDagNodePos(TConst::nowhere); } // Store them (and the original/clone pairing even if not cloning) m_fxTable[fxOrig] = fx; fx->addRef(); m_fxs.insert(fx); // Find out if the fx is a terminal one in the selection. If so, store it there too. bool isTerminal = true; if (!terminalFxs->containsFx(fxOrig)) // If it's terminal in the xsheet, no doubt { // Otherwise, check terminality with respect to the selection int i, outputConnectionsCount = fxOrig->getOutputConnectionCount(); for (i = 0; i < outputConnectionsCount; ++i) { TFx *outputFx = fxOrig->getOutputConnection(i)->getOwnerFx(); if (outputFx && fxs.count(outputFx) > 0) { isTerminal = false; break; } } } // Well, excluding true TOutputFxs... TOutputFx *outFx = dynamic_cast<TOutputFx *>(fx); if (isTerminal && !outFx) { fx->addRef(); m_terminalFxs.insert(fx); } } // Updating terminality of the column fxs too! // WARNING: This requires that storeObjects() is invoked BEFORE this ! for (it = m_originalColumnFxs.begin(); it != m_originalColumnFxs.end(); ++it) { TFx *fxOrig = *it; bool isTerminal = true; if (!terminalFxs->containsFx(fxOrig)) { int i, outputConnectionsCount = fxOrig->getOutputConnectionCount(); for (i = 0; i < outputConnectionsCount; ++i) { TFx *outputFx = fxOrig->getOutputConnection(i)->getOwnerFx(); if (outputFx && fxs.count(outputFx) > 0) { isTerminal = false; break; } } } if (isTerminal) { TFx *fx = m_fxTable[fxOrig]; fx->addRef(); m_terminalFxs.insert(fx); } } if (!m_fxTable.empty() && doClone) updateFxLinks(m_fxTable); // Apply original/clone pairings // to fx relatives }
void StageObjectsData::storeObjects(const std::vector<TStageObjectId> &ids, TXsheet *xsh, int fxFlags) { assert(m_fxTable.empty()); // Should be enforced OUTSIDE. Track implicit uses. m_fxTable.clear(); // TO BE REMOVED int i, objCount = ids.size(); // Discriminate sensible stage object types (ie cameras and columns from the rest). // Store them in a map, ordered by object index. std::map<int, TStageObjectId> cameraIds, columnIds, pegbarIds; for (i = 0; i < objCount; ++i) { TStageObjectId id = ids[i]; if (id.isColumn()) columnIds[id.getIndex()] = id; else if (id.isPegbar()) pegbarIds[id.getIndex()] = id; else if (id.isCamera()) cameraIds[id.getIndex()] = id; } // Store a suitable object for each std::map<int, TStageObjectId>::iterator it; for (it = cameraIds.begin(); it != cameraIds.end(); ++it) { // Cameras TCameraDataElement *cameraElement = new TCameraDataElement(); cameraElement->storeCamera(it->second, xsh); m_elements.append(cameraElement); } for (it = pegbarIds.begin(); it != pegbarIds.end(); ++it) { // Pegbars (includes curves) TStageObjectDataElement *objElement = new TStageObjectDataElement(); objElement->storeObject(it->second, xsh); m_elements.append(objElement); } for (it = columnIds.begin(); it != columnIds.end(); ++it) { // Columns int colIndex = it->second.getIndex(); TXshColumn *column = xsh->getColumn(colIndex); if (!column) continue; TColumnDataElement *columnElement = new TColumnDataElement(); columnElement->storeColumn(xsh, colIndex, fxFlags); m_elements.append(columnElement); TXshColumn *copiedColumn = columnElement->m_column.getPointer(); if (column->getFx() && copiedColumn->getFx()) { // Store column fx pairings (even if the originals are not cloned) m_fxTable[column->getFx()] = copiedColumn->getFx(); m_originalColumnFxs.insert(column->getFx()); } } // Insert terminal fxs set<TFx *>::iterator jt; for (jt = m_originalColumnFxs.begin(); jt != m_originalColumnFxs.end(); ++jt) { if (isColumnSelectionTerminalFx( *jt, xsh->getFxDag()->getTerminalFxs(), m_originalColumnFxs)) { TFx *fx = m_fxTable[*jt]; fx->addRef(); m_terminalFxs.insert(fx); } } }