예제 #1
0
파일: repository.cpp 프로젝트: qreal/qreal
void Repository::stackBefore(const qReal::Id &id, const qReal::Id &child, const qReal::Id &sibling) {
	if(!mObjects.contains(id)) {
		throw Exception("Repository: Moving child " + child.toString() + " of nonexistent object " + id.toString());
	}

	if(!mObjects.contains(child)) {
		throw Exception("Repository: Moving nonexistent child " + child.toString());
	}

	if(!mObjects.contains(sibling)) {
		throw Exception("Repository: Stacking before nonexistent child " + sibling.toString());
	}

	mObjects[id]->stackBefore(child, sibling);
}
예제 #2
0
void PioneerStateMachineGenerator::visitFinal(const qReal::Id &id, const QList<LinkInfo> &links)
{
	generatorBase::GotoControlFlowGenerator::visitFinal(id, links);

	trace("Visiting final node: " + id.toString());
	if (mErrorsOccured) {
		return;
	}

	// Here we are going to add finishing end-of-handler node in case it is missing (for example, diagrams like
	// "Initial Node" -> "Final Node" will not generate it automatically).
	// It is a kind of hack because asynchronous handler shall be a first-class entity and a zone node.

	auto nodes = mSemanticTreeManager->nodes(id);
	for (auto node : nodes) {
		if (!node) {
			continue;
		}

		SimpleNode * const thisNode = static_cast<SimpleNode *>(node);

		// Getting top level parent node for this node.
		NonZoneNode *parent = mSemanticTreeManager->topLevelParent(thisNode);

		// Searching for end-of-handler node.
		SemanticNode * endOfHandler = findEndOfHandler(parent);

		if (!endOfHandler) {
			// If not found, create and add one.
			endOfHandler = produceEndOfHandlerNode();
			mSemanticTreeManager->addAfter(thisNode, endOfHandler);
		}
	}
}
예제 #3
0
void PioneerStateMachineGenerator::visitConditional(const qReal::Id &id, const QList<LinkInfo> &links)
{
	Q_UNUSED(links)

	trace("Visiting conditional node: " + id.toString());
	if (mErrorsOccured) {
		return;
	}

	if (not mVisitedNodes.contains(id)) {
		++mConditionals;
	}

	const QPair<LinkInfo, LinkInfo> branches(ifBranchesFor(id));
	const LinkInfo thenLink = branches.first;
	const LinkInfo elseLink = branches.second;

	const auto nodes = mSemanticTreeManager->nodes(id);

	for (const auto node : nodes) {
		IfNode * const thisNode = static_cast<IfNode *>(node);

		mSemanticTreeManager->addToZone(thisNode->thenZone(), thenLink.target);
		mSemanticTreeManager->addToZone(thisNode->elseZone(), elseLink.target);
		mConditionZonesQueue.enqueue(std::make_tuple(thisNode, false, thisNode->thenZone(), thisNode->elseZone()));
		mBranchAsyncMarkers[thisNode->thenZone()] = false;
		mBranchAsyncMarkers[thisNode->elseZone()] = false;

		if (!mSemanticTreeManager->isTopLevelNode(thisNode)) {
			reportError(tr("Nested If's constructions is not allowed."));
			return;
		}
	}
}
예제 #4
0
void PioneerStateMachineGenerator::visitRegular(const qReal::Id &id, const QList<LinkInfo> &links)
{
	// Base class method checks for subprogram calls, which is irrelevant for now, but does not hurt and hopefully
	// will be needed later.
	ControlFlowGeneratorBase::visitRegular(id, links);

	if (mErrorsOccured) {
		return;
	}

	if (id.element() == "InitialNode") {
		mLabeledNodes << links.first().target;
	}

	if (not mVisitedNodes.contains(id) && id.element() == "FiBlock") {
		++mConditionalEnds;
	}

	trace("Visiting " + id.toString());

	const qReal::Id target = links[0].target;
	QList<NonZoneNode *> nodesWithThisId = mSemanticTreeManager->nodes(id);
	for (auto thisNode : nodesWithThisId) {
		if (thisNode) {
			processNode(thisNode, target);
		} else {
			mErrorsOccured = true;
			return;
		}
	}

	if (mErrorsOccured) {
		return;
	}

	// Generation of a node may lead to sudden appearance of new copies of a node (for example, if this node was in a
	// branch of If statement that get copied when generating node, quite common in if-loop programs). So we need to
	// process new clones as well.
	auto updatedNodes = mSemanticTreeManager->nodes(id);
	while (updatedNodes.size() != nodesWithThisId.size()) {
		for (auto node : updatedNodes) {
			if (!nodesWithThisId.contains(node)) {
				processNode(node, target);
				nodesWithThisId.append(node);
			}
		}

		updatedNodes = mSemanticTreeManager->nodes(id);
	}

	doDeferredGotoGeneration(id, target);
}