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();
68 if (action ==
"start") {
70 }
else if (action ==
"stop") {
72 }
else if (action ==
"restart") {
74 }
else if (action ==
"update") {
81 },
"control simulation", requestId);
84QJsonObject SimulationHandler::handleCreateWaveform(
const QJsonObject ¶ms,
const QJsonValue &requestId)
91 int duration = params.value(
"duration").toInt(32);
92 QJsonObject inputPatterns = params.value(
"input_patterns").toObject();
99 if (m_persistentDolphin) {
100 m_persistentDolphin->deleteLater();
101 m_persistentDolphin =
nullptr;
104 BewavedDolphin *bewavedDolphin = m_persistentDolphin;
108 bewavedDolphin->
setLength(duration,
false);
110 if (!inputPatterns.isEmpty()) {
111 for (
auto it = inputPatterns.begin(); it != inputPatterns.end(); ++it) {
112 QString inputLabel = it.key();
113 QJsonArray pattern = it.value().toArray();
115 const int rowIndex = bewavedDolphin->
inputRow(inputLabel);
117 if (rowIndex == -1) {
118 return createErrorResponse(QString(
"Input element with label '%1' not found").arg(inputLabel),
122 if (pattern.size() != duration) {
123 return createErrorResponse(QString(
"Pattern length for '%1' (%2) doesn't match duration (%3)")
124 .arg(inputLabel).arg(pattern.size()).arg(duration),
128 for (
int col = 0; col < duration; ++col) {
129 int value = pattern[col].toInt();
130 if (value != 0 && value != 1) {
131 return createErrorResponse(QString(
"Invalid pattern value %1 for '%2' at step %3 (must be 0 or 1)")
132 .arg(value).arg(inputLabel).arg(col),
140 bewavedDolphin->
run();
142 QJsonObject waveformData;
143 QJsonArray inputData;
144 QJsonArray outputData;
146 const auto waveform = bewavedDolphin->
snapshot(duration);
148 for (
const auto &signal : waveform.inputs) {
149 QJsonObject inputSignal;
150 inputSignal[
"label"] = signal.label;
151 inputSignal[
"type"] =
"input";
154 for (
const int value : signal.values) {
155 values.append(value);
157 inputSignal[
"values"] = values;
158 inputData.append(inputSignal);
161 for (
const auto &signal : waveform.outputs) {
162 QJsonObject outputSignal;
163 outputSignal[
"label"] = signal.label;
164 outputSignal[
"type"] =
"output";
167 for (
const int value : signal.values) {
168 values.append(value);
170 outputSignal[
"values"] = values;
171 outputData.append(outputSignal);
174 waveformData[
"inputs"] = inputData;
175 waveformData[
"outputs"] = outputData;
176 waveformData[
"duration"] = duration;
179 result[
"actual_duration"] = duration;
180 result[
"requested_duration"] = duration;
181 result[
"waveform_data"] = waveformData;
182 result[
"message"] =
"Waveform created and analyzed successfully";
183 result[
"status"] =
"ready";
186 },
"create waveform", requestId);
189QJsonObject SimulationHandler::handleExportWaveform(
const QJsonObject ¶ms,
const QJsonValue &requestId)
195 QString filename = params.value(
"filename").toString();
196 QString format = params.value(
"format").toString().toLower();
198 if (format !=
"txt" && format !=
"png") {
199 return createErrorResponse(
"Only 'txt' and 'png' formats are supported for waveform export",
203 if (!m_persistentDolphin) {
210 result[
"filename"] = filename;
211 result[
"format"] = format;
213 if (format ==
"txt") {
214 QFile file(filename);
215 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
220 QTextStream stream(&file);
221 m_persistentDolphin->saveToTxt(stream);
223 if (stream.status() != QTextStream::Ok || file.error() != QFileDevice::NoError) {
224 return createErrorResponse(QString(
"Failed to write waveform text: %1").arg(file.errorString()),
228 }
else if (format ==
"png") {
229 if (!m_persistentDolphin->exportToPng(filename)) {
234 result[
"exported"] =
true;
236 },
"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.).