⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialexecutor.cpp

📁 粗糙集应用软件
💻 CPP
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Revisions.....:
//===================================================================

#include <stdafx.h> // Precompiled headers.
#include <copyright.h>

#include <kernel/algorithms/serialexecutor.h>
#include <kernel/algorithms/keyword.h>

#include <kernel/structures/project.h>
#include <kernel/structures/projectmanager.h>

#include <kernel/utilities/creator.h>

#include <kernel/basic/message.h>

#include <common/objectmanager.h>

//-------------------------------------------------------------------
// Static methods (file scope).
//===================================================================

//-------------------------------------------------------------------
// Method........: StaticCleanUp
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Cleans up temporary project stuff set in the
//                 ExecuteCommands method.
// Comments......:
// Revisions.....:
//===================================================================

static void
StaticCleanUp(Handle<Project> project, Handle<Structure> first, Structure &structure, bool remove) {

	// Remove project from project pool.
	ProjectManager::RemoveProject(project.GetPointer());

	// Don't remove the child?
	if (!remove)
		return;

	if (first == NULL)
		return;

	// Find child index.
	int index = structure.FindChild(first.GetPointer());

	// Remove child.
	if (index != Undefined::Integer())
		structure.RemoveChild(index);

}

static void
StaticCleanUp(Handle<Project> project, Handle<Structure> first, Structure &structure, Handle<Structure> output, bool remove) {

	// Remove project from project pool.
	ProjectManager::RemoveProject(project.GetPointer());

	if (output == &structure && !remove)
		return;

	if (first == NULL)
		return;

	// Find child index.
	int index = structure.FindChild(first.GetPointer());

	// Remove child.
	if (index != Undefined::Integer())
		structure.RemoveChild(index);

}

//-------------------------------------------------------------------
// Methods for class SerialExecutor.
//===================================================================

//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================

SerialExecutor::SerialExecutor() {
}

SerialExecutor::~SerialExecutor() {
}

//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================

IMPLEMENTIDMETHODS(SerialExecutor, SERIALEXECUTOR, Executor)

//-------------------------------------------------------------------
// Methods inherited from Algorithm.
//===================================================================

//-------------------------------------------------------------------
// Method........: GetParameters
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================

String
SerialExecutor::GetParameters() const {
	return Executor::GetParameters();
}

//-------------------------------------------------------------------
// Method........: SetParameter
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================

bool
SerialExecutor::SetParameter(const String &keyword, const String &value) {
	return Executor::SetParameter(keyword, value);
}

//-------------------------------------------------------------------
// Methods inherited from Executor.
//===================================================================

//-------------------------------------------------------------------
// Method........: ExecuteCommands
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Adds a fixed Boolean argument and passes the
//                 command on.
// Comments......:
// Revisions.....:
//===================================================================

Structure *
SerialExecutor::ExecuteCommands(Structure &structure, const Algorithm::Handles &algorithms, const Vector(String) &parameters, ofstream &stream) const {
	return ExecuteCommands(structure, algorithms, parameters, stream, true);
}

//-------------------------------------------------------------------
// New virtual methods.
//===================================================================

//-------------------------------------------------------------------
// Method........: SetSpecialParameters
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Can be used if an algorithm needs to have some
//                 parameters set that cannot be represented as a
//                 text string.
//
//                 Default implementation does nothing. Can be
//                 overloaded by special-purpose subclasses.
// Comments......:
// Revisions.....:
//===================================================================

bool
SerialExecutor::SetSpecialParameters(Algorithm &/*algorithm*/, const String &/*parameters*/) const {
	return true;
}

//-------------------------------------------------------------------
// Method........: ExecuteCommands
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Starting with the input structure, all algorithms in
//                 the pipeline are applied in sequence, with the output
//                 of one being the input to the next. The last produced
//                 structure of a specified type is returned. If the
//                 specified type is Undefined::Id(), the input structure
//                 itself is returned unless an error occurs.
//
//                 A Boolean flag is passed to indicate how the clean-up
//                 is performed. Ordinarily, children of the input structure
//                 are to be removed. However, if the input structure is
//                 equal to the output structure, this may not always be
//                 desirable.
//
// Comments......: A temporary project is set up so that the
//                 FindParent method will function properly in case
//                 any of the algorithms need this.
// Revisions.....:
//===================================================================

Structure *
SerialExecutor::ExecuteCommands(Structure &structure, const Algorithm::Handles &algorithms, const Vector(String) &parameters, ofstream &stream, bool remove) const {

	// Set up a temporary project.
	Handle<Project> project = Creator::Project();

	if (!ProjectManager::InsertProject(project.GetPointer()))
		return NULL;

	if (!project->AppendChild(&structure)) {
		ProjectManager::RemoveProject(project.GetPointer());
		return NULL;
	}

	Handle<Structure> current; // Current structure in pipeline.
	Handle<Structure> first;   // Structure generated from method input.
	Handle<Structure> output;  // Output to return.

	current = &structure;

	int i;

	// Execute pipeline.
	for (i = 0; i < algorithms.size(); i++) {

		// Get algorithm.
		Handle<Algorithm> algorithm = algorithms[i];

		// Set parameters.
		algorithm->SetParameters(parameters[i]);

		if (!SetSpecialParameters(*algorithm, parameters[i])) {
			Message::Error("Failed to set special parameters for " + IdHolder::GetClassname(algorithm->GetId()) + ".");
			StaticCleanUp(project, first, structure, true);
			return NULL;
		}

		// Check applicability.
		if (!algorithm->IsApplicable(*current)) {
			Message::Error(IdHolder::GetClassname(algorithm->GetId()) + " is not applicable to a " + IdHolder::GetClassname(current->GetId()) + ".");
			StaticCleanUp(project, first, structure, true);
			return NULL;
		}

		// Save algorithm status to log.
		if (!SaveLogEntry(stream, *algorithm)) {
			StaticCleanUp(project, first, structure, true);
			return NULL;
		}

		Message message;

		message.Notify("Executing " + IdHolder::GetClassname(algorithm->GetId()) + "...");

		// Apply.
		Handle<Structure> result = current->Apply(*algorithm);

		if (result == NULL) {
			Message::Error("Application of " + IdHolder::GetClassname(algorithm->GetId()) + " failed.");
			StaticCleanUp(project, first, structure, true);
			return NULL;
		}

		// Save result structure status to log.
		if (!SaveLogEntry(stream, *result)) {
			StaticCleanUp(project, first, structure, true);
			return NULL;
		}

		// Possibly append as child (for dictionary purposes, mostly).
		if (result != current)
			current->AppendChild(result.GetPointer());

		if (first == NULL)
			first = result;

		// Remember the last produced structure of the desired type.
		if (result->IsA(GetOutputType()))
			output = result;

		current = result;

	}

	// Was an output produced? If not, does the input match the desired type?
	if (output == NULL) {
		if (GetOutputType() == Undefined::Id() || structure.IsA(GetOutputType()))
			output = &structure;
	}

	if (output == NULL)
		Message::Error("Unable to return a structure of type " + IdHolder::GetClassname(GetOutputType()) + ".");

	// Clean up.
	if (remove)
		StaticCleanUp(project, first, structure, true);
	else
		StaticCleanUp(project, first, structure, output != &structure);

	// So that handles do not inadvertently delete output structure on method exit.
	current = NULL;
	first   = NULL;

	return output.Release();

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -