📄 serialexecutor.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) ¶meters, 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) ¶meters, 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 + -