18 , m_persistentDolphin(nullptr)
26 delete m_persistentDolphin;
27 m_persistentDolphin =
nullptr;
32 if (command ==
"simulation_control") {
33 return handleSimulationControl(params, requestId);
34 }
else if (command ==
"create_waveform") {
35 return handleCreateWaveform(params, requestId);
36 }
else if (command ==
"export_waveform") {
37 return handleExportWaveform(params, requestId);
44QJsonObject SimulationHandler::handleSimulationControl(
const QJsonObject ¶ms,
const QJsonValue &requestId)
55 QString action = params.value(
"action").toString();
69 if (action ==
"start") {
71 }
else if (action ==
"stop") {
73 }
else if (action ==
"restart") {
75 }
else if (action ==
"update") {
82 },
"control simulation", requestId);
85QJsonObject SimulationHandler::handleCreateWaveform(
const QJsonObject ¶ms,
const QJsonValue &requestId)
92 int duration = params.value(
"duration").toInt(32);
93 QJsonObject inputPatterns = params.value(
"input_patterns").toObject();
100 if (m_persistentDolphin) {
101 m_persistentDolphin->deleteLater();
102 m_persistentDolphin =
nullptr;
105 BewavedDolphin *bewavedDolphin = m_persistentDolphin;
109 bewavedDolphin->
setLength(duration,
false);
111 if (!inputPatterns.isEmpty()) {
112 for (
auto it = inputPatterns.begin(); it != inputPatterns.end(); ++it) {
113 QString inputLabel = it.key();
114 QJsonArray pattern = it.value().toArray();
116 const int rowIndex = bewavedDolphin->
inputRow(inputLabel);
118 if (rowIndex == -1) {
119 return createErrorResponse(QString(
"Input element with label '%1' not found").arg(inputLabel),
123 if (pattern.size() != duration) {
124 return createErrorResponse(QString(
"Pattern length for '%1' (%2) doesn't match duration (%3)")
125 .arg(inputLabel).arg(pattern.size()).arg(duration),
129 for (
int col = 0; col < duration; ++col) {
130 int value = pattern[col].toInt();
131 if (value != 0 && value != 1) {
132 return createErrorResponse(QString(
"Invalid pattern value %1 for '%2' at step %3 (must be 0 or 1)")
133 .arg(value).arg(inputLabel).arg(col),
141 bewavedDolphin->
run();
143 QJsonObject waveformData;
144 QJsonArray inputData;
145 QJsonArray outputData;
147 const auto waveform = bewavedDolphin->
snapshot(duration);
149 for (
const auto &signal : waveform.inputs) {
150 QJsonObject inputSignal;
151 inputSignal[
"label"] = signal.label;
152 inputSignal[
"type"] =
"input";
155 for (
const int value : signal.values) {
156 values.append(value);
158 inputSignal[
"values"] = values;
159 inputData.append(inputSignal);
162 for (
const auto &signal : waveform.outputs) {
163 QJsonObject outputSignal;
164 outputSignal[
"label"] = signal.label;
165 outputSignal[
"type"] =
"output";
168 for (
const int value : signal.values) {
169 values.append(value);
171 outputSignal[
"values"] = values;
172 outputData.append(outputSignal);
175 waveformData[
"inputs"] = inputData;
176 waveformData[
"outputs"] = outputData;
177 waveformData[
"duration"] = duration;
180 result[
"actual_duration"] = duration;
181 result[
"requested_duration"] = duration;
182 result[
"waveform_data"] = waveformData;
183 result[
"message"] =
"Waveform created and analyzed successfully";
184 result[
"status"] =
"ready";
187 },
"create waveform", requestId);
190QJsonObject SimulationHandler::handleExportWaveform(
const QJsonObject ¶ms,
const QJsonValue &requestId)
196 QString filename = params.value(
"filename").toString();
197 QString format = params.value(
"format").toString().toLower();
199 if (format !=
"txt" && format !=
"png") {
200 return createErrorResponse(
"Only 'txt' and 'png' formats are supported for waveform export",
204 if (!m_persistentDolphin) {
211 result[
"filename"] = filename;
212 result[
"format"] = format;
214 if (format ==
"txt") {
215 QFile file(filename);
216 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
221 QTextStream stream(&file);
222 m_persistentDolphin->saveToTxt(stream);
224 if (stream.status() != QTextStream::Ok || file.error() != QFileDevice::NoError) {
225 return createErrorResponse(QString(
"Failed to write waveform text: %1").arg(file.errorString()),
229 }
else if (format ==
"png") {
230 if (!m_persistentDolphin->exportToPng(filename)) {
235 result[
"exported"] =
true;
237 },
"export waveform", requestId);
BewavedDolphin waveform editor: digital signal creation, display, and export.
Main application window providing menus, toolbars, and tab management.
Main circuit editing scene with undo/redo and user interaction.
SignalModel for the beWavedDolphin waveform table.
Synchronous cycle-based simulation engine with event-driven clock support.
QJsonObject createSuccessResponse(const QJsonObject &result={}, const QJsonValue &requestId=QJsonValue()) const
QJsonObject tryCommand(Fn &&fn, const QString &action, const QJsonValue &requestId=QJsonValue())
Wraps fn in a try/catch, returning an error response on exception.
BaseHandler(MainWindow *mainWindow, const MCPValidator *validator)
QJsonObject createErrorResponse(const QString &error, const QJsonValue &requestId=QJsonValue(), int code=JsonRpcError::InternalError) const
MainWindow * m_mainWindow
bool validateParameters(const QJsonObject ¶ms, const QStringList &required) const
bool validateNonEmptyString(const QJsonValue &value, const QString ¶mName, QString &errorMsg) const
int inputRow(const QString &label) const
Returns the input row index whose element label equals label, or -1 (MCP access).
void run()
Runs the simulation for all input combinations and fills output rows.
void setCellValue(const int row, const int col, const int value)
Sets a single cell value in the waveform table.
void prepare(const QString &fileName={})
Prepares the waveform from fileName (or blank if empty).
WaveformSnapshot snapshot(int duration) const
Returns the input/output signals over the first duration columns (MCP access).
void setLength(const int simLength, const bool runSimulation=false)
Sets the number of time-step columns.
JSON Schema validator for MCP commands and responses using native json-schema-validator.
The top-level application window hosting the tab bar, menus, element palette, and editor.
Simulation * simulation()
Returns the simulation engine associated with this scene.
static constexpr int kMaxColumns
QJsonObject handleCommand(const QString &command, const QJsonObject ¶ms, const QJsonValue &requestId) override
SimulationHandler(MainWindow *mainWindow, const MCPValidator *validator)
void update()
Executes one simulation step (used by tests to advance the simulation manually).
void start()
Starts the 1 ms simulation timer.
void stop()
Stops the simulation timer.
constexpr int SceneNotAvailable
No active circuit scene to operate on.
constexpr int SimulationError
Simulation control / waveform failure.
constexpr int MethodNotFound
The requested method does not exist or is unavailable.
constexpr int ElementNotFound
Referenced element id does not exist in the scene.
constexpr int FileError
File save/load/path error.
constexpr int ValidationError
Semantic validation failure (e.g. port index out of range, enum value not allowed).
constexpr int InvalidParams
Invalid method parameters (missing required, wrong type, etc.).