diff --git a/activity.hpp b/activity.hpp index 6849c39a48e01e2b3bcef1a81e0d70ca78a6d29f..9382a2d5caaa5c20854b066c7d190ee9ab399df5 100644 --- a/activity.hpp +++ b/activity.hpp @@ -15,6 +15,8 @@ #include <rlib/require/cxx14> #include <rlib/scope_guard.hpp> +#include "dirty-plugins.hpp" + namespace CIS { using std::string; using namespace rlib::literals; @@ -142,7 +144,7 @@ namespace CIS { Flow(const Flow &another) : queuedOnRight(another.queuedOnRight), xamlCode(another.xamlCode), prevOperationIsSequential(another.prevOperationIsSequential) {} // Actually modify xamlCode on "OperationChange". - // for example, A >> B >> C >> D | E. ABCD should be merged into one sequential operation. + // for example, A >> B >> C >> (D | E). ABCD should be merged into one sequential operation. Flow operator>>(const Flow &seqNext) const { return binaryOperation(seqNext, true); } @@ -230,7 +232,7 @@ namespace CIS { inline auto Flow::generateXaml(Metadata metadata) const { Flow finalized(*this); finalized.reduceQueuedIfNecessary(!finalized.prevOperationIsSequential); // Always necessary if queue is not empty. - return metadata.generateXamlHead() + finalized.xamlCode + metadata.generateXamlTail(); + return metadata.generateXamlHead() + dirty_plugins::patchGS(finalized.xamlCode) + metadata.generateXamlTail(); } inline auto Flow::generateXaml(std::string className) const { Metadata defaultMetadata(className); diff --git a/dirty-plugins.hpp b/dirty-plugins.hpp new file mode 100644 index 0000000000000000000000000000000000000000..eadac209415db03ac6d694634ad6f4e01ab9232c --- /dev/null +++ b/dirty-plugins.hpp @@ -0,0 +1,24 @@ +#ifndef CIS_WORKFLOW_GEN_DIRTY_PLUGIN_HPP +#define CIS_WORKFLOW_GEN_DIRTY_PLUGIN_HPP + +#include <rlib/string.hpp> +#include "xaml-template.hpp" + +namespace CIS::dirty_plugins { + rlib::string patchGS(const rlib::string &input) { + rlib::string output (input); + auto pos_seq = output.find("ControlledSequence"); + auto pos_par = output.find("ControlledParallel"); + rlib::string plugin_text = CIS::templates::PLUGIN_GlobalSettingsVariable_SEQ; + if(pos_seq == rlib::string::npos && pos_par == rlib::string::npos) + return output; + else if(pos_seq == rlib::string::npos || pos_par < pos_seq) + plugin_text.replace("ControlledSequence", "ControlledParallel"); + // else OutMost is sequence, nothing to do. + + return output.replace_once(">\n", ">\n" + plugin_text); + } +} + +#endif + diff --git a/xaml-template.hpp b/xaml-template.hpp index 07b77168c4bcc547b1fc436f2e6c59635abec40b..2f821a05f076e03652c0ba9bc0364ca45fae5f28 100644 --- a/xaml-template.hpp +++ b/xaml-template.hpp @@ -110,6 +110,13 @@ constexpr auto NOOP_XAML = R"XAML( <mwcwa:NoOpsActivity DisplayName="__TEMPLATE_ARG_DisplayName" __TEMPLATE_ARG_EntityDefPlaceholder/> )XAML"; +// The top-level Sequence or Parallel, need to add this "plugin" to make it happy. +constexpr auto PLUGIN_GlobalSettingsVariable_SEQ = +R"XAML( <mwcwa:ControlledSequence.Variables> + <Variable x:TypeArguments="mwcwcs:GlobalSettings" Name="GlobalSettings" /> + </mwcwa:ControlledSequence.Variables> +)XAML"; + } }