Loading...
Searching...
No Matches
LoadPresetCommand.hpp
1#pragma once
2#include <State/Value.hpp>
3#include <State/ValueSerialization.hpp>
4
5#include <Process/Commands/LoadPresetCommandFactory.hpp>
6#include <Process/Dataflow/Port.hpp>
7#include <Process/Process.hpp>
8
9#include <Scenario/Commands/ScenarioCommandFactory.hpp>
10
11#include <Dataflow/Commands/CableHelpers.hpp>
12
13#include <score/model/path/PathSerialization.hpp>
14
15#include <score_plugin_scenario_export.h>
16
17namespace Scenario::Command
18{
19class LoadPreset final : public score::Command
20{
21 SCORE_COMMAND_DECL(
22 Scenario::Command::CommandFactoryName(), LoadPreset, "Load a preset")
23
24public:
26 : m_path{obj}
27 , m_old{obj.savePreset()}
28 , m_new{std::move(newval)}
29 {
30 }
31
32private:
33 void undo(const score::DocumentContext& ctx) const final override
34 {
35 m_path.find(ctx).loadPreset(m_old);
36 }
37
38 void redo(const score::DocumentContext& ctx) const final override
39 {
40 m_path.find(ctx).loadPreset(m_new);
41 }
42
43 void serializeImpl(DataStreamInput& stream) const final override
44 {
45 stream << m_path << m_old << m_new;
46 }
47 void deserializeImpl(DataStreamOutput& stream) final override
48 {
49 stream >> m_path >> m_old >> m_new;
50 }
51
53 Process::Preset m_old;
54 Process::Preset m_new;
55};
56
57// Note: see ScriptEditCommand.hpp which is very similar!
59{
60 SCORE_COMMAND_DECL(
61 Scenario::Command::CommandFactoryName(), LoadPresetWithCablesBackup,
62 "Load a preset")
63
64public:
66 const Process::ProcessModel& model, Process::Preset newval,
67 const score::DocumentContext& ctx)
68 : m_path{model}
69 , m_old{model.savePreset()}
70 , m_new{std::move(newval)}
71 {
72 m_oldCables
73 = Dataflow::saveCables({const_cast<Process::ProcessModel*>(&model)}, ctx);
74
75 for(auto& port : model.inlets())
76 m_oldInlets.emplace_back(
77 Dataflow::SavedPort{port->name(), port->type(), port->saveData()});
78 for(auto& port : model.outlets())
79 m_oldOutlets.emplace_back(
80 Dataflow::SavedPort{port->name(), port->type(), port->saveData()});
81 }
82
83private:
84 void undo(const score::DocumentContext& ctx) const final override
85 {
86 auto& cmt = m_path.find(ctx);
87 // Remove all the cables that could have been added during
88 // the creation
89 Dataflow::removeCables(m_oldCables, ctx);
90
91 // Set the old preset
92 cmt.loadPreset(m_old);
93
94 // We expect the inputs / outputs to revert back to the
95 // exact same state
96 SCORE_ASSERT(m_oldInlets.size() == cmt.inlets().size());
97 SCORE_ASSERT(m_oldOutlets.size() == cmt.outlets().size());
98
99 // So we can reload their data identically
100 for(std::size_t i = 0; i < m_oldInlets.size(); i++)
101 {
102 cmt.inlets()[i]->loadData(m_oldInlets[i].data);
103 }
104 for(std::size_t i = 0; i < m_oldOutlets.size(); i++)
105 {
106 cmt.outlets()[i]->loadData(m_oldOutlets[i].data);
107 }
108
109 // Recreate the old cables
110 Dataflow::restoreCables(m_oldCables, ctx);
111 cmt.inletsChanged();
112 cmt.outletsChanged();
113 }
114
115 void redo(const score::DocumentContext& ctx) const final override
116 {
117 Dataflow::removeCables(m_oldCables, ctx);
118
119 auto& cmt = m_path.find(ctx);
120 cmt.loadPreset(m_new);
121
122 Dataflow::reloadPortsInNewProcess(m_oldInlets, m_oldOutlets, m_oldCables, cmt, ctx);
123
124 cmt.inletsChanged();
125 cmt.outletsChanged();
126 // FIXME if we have it only here, then changing cables fails for the exec nodes
127 // as in the cable loading, in SetupContext::connectCable(Process::Cable& cable)
128 // auto it = outlets.find(port_src); fails because the new outlet hasn't yet been created by the component
129 // but if we have it only above, the JS GPU node fails
130 }
131
132 void serializeImpl(DataStreamInput& stream) const final override
133 {
134 stream << m_path << m_old << m_new << m_oldInlets << m_oldOutlets << m_oldCables;
135 }
136 void deserializeImpl(DataStreamOutput& stream) final override
137 {
138 stream >> m_path >> m_old >> m_new >> m_oldInlets >> m_oldOutlets >> m_oldCables;
139 }
140
142 Process::Preset m_old;
143 Process::Preset m_new;
144
145 std::vector<Dataflow::SavedPort> m_oldInlets, m_oldOutlets;
146
147 Dataflow::SerializedCables m_oldCables;
148};
149
151{
152 SCORE_CONCRETE("b04a9d8a-1374-4223-a258-0f90e8e0aef6")
153public:
154 bool matches(
156 const score::DocumentContext& ctx) const noexcept override
157 {
158 return true;
159 }
160 score::Command* make(
161 const Process::ProcessModel& obj, Process::Preset newval,
162 const score::DocumentContext& ctx) const override
163 {
165 return new LoadPresetWithCablesBackup{obj, std::move(newval), ctx};
166 else
167 return new LoadPreset{obj, std::move(newval)};
168 }
169};
170}
The Path class is a typesafe wrapper around ObjectPath.
Definition Path.hpp:52
Definition LoadPresetCommandFactory.hpp:16
The Process class.
Definition score-lib-process/Process/Process.hpp:61
Definition LoadPresetCommand.hpp:151
Definition LoadPresetCommand.hpp:20
Definition LoadPresetCommand.hpp:59
The Command class.
Definition Command.hpp:34
@ DynamicPorts
The process has a variable structure, e.g. its ports can change dynamically.
Definition ProcessFlags.hpp:59
Definition DataStreamHelpers.hpp:99
Definition DataStreamHelpers.hpp:103
Definition CableHelpers.hpp:69
Definition Preset.hpp:32
Definition ObjectMatches.hpp:6
Definition DocumentContext.hpp:18
Definition Unused.hpp:3