예제 #1
0
bool TMacroFx::analyze(const vector<TFxP> &fxs,
					   TFxP &root,
					   vector<TFxP> &roots,
					   vector<TFxP> &leafs)
{
	if (fxs.size() == 1)
		return false;
	else {
		leafs.clear();
		roots.clear();
		std::vector<TFxP>::const_iterator it = fxs.begin();
		for (; it != fxs.end(); ++it) {
			TFxP fx = *it;
			int inputInternalConnection = 0;
			int inputExternalConnection = 0;
			int outputInternalConnection = 0;
			int outputExternalConnection = 0;

			int i;

			// calcola se ci sono connessioni in input dall'esterno
			// verso l'interno e/o internamente a orderedFxs
			int inputPortCount = fx->getInputPortCount();
			for (i = 0; i < inputPortCount; ++i) {
				TFxPort *inputPort = fx->getInputPort(i);
				TFx *inputPortFx = inputPort->getFx();
				if (inputPortFx) {
					if (std::find_if(fxs.begin(), fxs.end(), MatchesFx(inputPortFx)) != fxs.end())
						++inputInternalConnection;
					else
						++inputExternalConnection;
				}
			}

			// calcola se ci sono connessioni in output dall'interno
			// verso l'esterno e/o internamente a orderedFxs
			int outputPortCount = fx->getOutputConnectionCount();
			for (i = 0; i < outputPortCount; ++i) {
				TFxPort *outputPort = fx->getOutputConnection(i);
				TFx *outputFx = outputPort->getOwnerFx();
				if (outputFx) {
					if (std::find_if(fxs.begin(), fxs.end(), MatchesFx(outputFx)) != fxs.end())
						++outputInternalConnection;
					else
						++outputExternalConnection;
				}
			}

			// se fx e' una radice
			if ((outputExternalConnection > 0) ||
				(outputExternalConnection == 0 && outputInternalConnection == 0)) {
				root = fx;
				roots.push_back(fx);
			}

			// se fx e' una foglia
			if (inputExternalConnection > 0 || fx->getInputPortCount() == 0 ||
				(inputExternalConnection == 0 && inputInternalConnection < fx->getInputPortCount())) {
				leafs.push_back(fx);
			}
		}

		if (roots.size() != 1)
			return false;
		else {
			if (leafs.size() == 0)
				return false;
		}

		return true;
	}
}
예제 #2
0
TMacroFx *TMacroFx::create(const vector<TFxP> &fxs)
{
	std::vector<TFxP> leafs;
	std::vector<TFxP> roots;
	TFxP root = 0;

	vector<TFxP> orederedFxs = sortFxs(fxs);

	// verifica che gli effetti selezionati siano idonei ad essere raccolti
	// in una macro. Ci deve essere un solo nodo terminale
	// (roots.size()==1, roots[0] == root) e uno o piu' nodi di ingresso
	// (assert leafs.size()>0)
	if (!analyze(orederedFxs, root, roots, leafs))
		return 0;

	// -----------------------------

	TMacroFx *macroFx = new TMacroFx;

	// tutti i nodi vengono spostati (e non copiati) nella macro stessa
	std::vector<TFxP>::const_iterator it = orederedFxs.begin();
	for (; it != orederedFxs.end(); ++it)
		macroFx->m_fxs.push_back(*it);

	// i nodi di ingresso vengono messi in collegamento con le
	// porte di ingresso della macro
	for (int i = 0; i < (int)leafs.size(); i++) {
		TFxP fx = leafs[i];
		int k = 0;
		int count = fx->getInputPortCount();
		for (; k < count; k++) {
			TFxPort *port = fx->getInputPort(k);
			string portName = fx->getInputPortName(k);
			string fxId = toString(fx->getFxId());
			portName += "_" + toString(macroFx->getInputPortCount()) + "_" + fxId;
			TFx *portFx = port->getFx();
			if (portFx) {
				// se la porta k-esima del nodo di ingresso i-esimo e' collegata
				// ad un effetto, la porta viene inserita solo se l'effetto non fa
				// gia' parte della macro
				if (std::find_if(orederedFxs.begin(), orederedFxs.end(), MatchesFx(portFx)) == orederedFxs.end())
					macroFx->addInputPort(portName, *port);
			} else
				macroFx->addInputPort(portName, *port);
		}
	}

	// le porte di uscita di root diventano le porte di uscita della macro
	int count = root->getOutputConnectionCount();
	int k = count - 1;
	for (; k >= 0; --k) {
		TFxPort *port = root->getOutputConnection(k);
		port->setFx(macroFx);
	}

	macroFx->setRoot(root.getPointer());

	// tutti i parametri delle funzioni figlie diventano parametri della macro
	collectParams(macroFx);
	return macroFx;
}