wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
DolphinModelBuilder.cpp
Go to the documentation of this file.
1// Copyright 2015 - 2026, GIBIS-UNIFESP and the wiRedPanda contributors
2// SPDX-License-Identifier: GPL-3.0-or-later
3
5
6#include <algorithm>
7
8#include <QCoreApplication>
9
10#include "App/Core/Common.h"
14#include "App/Scene/Scene.h"
15
17
18namespace {
19
22template <typename Elements, typename PortCount>
23QStringList buildLabels(const Elements &elements, const PortCount &portCount)
24{
25 QStringList labels;
26
27 for (auto *elm : elements) {
28 QString label = elm->label();
29
30 // Fall back to the element type name when the user hasn't given it a label
31 if (label.isEmpty()) {
32 label = ElementFactory::translatedName(elm->elementType());
33 }
34
35 const int ports = portCount(elm);
36 for (int port = 0; port < ports; ++port) {
37 // Multi-port elements (e.g. bus inputs, multi-bit displays) get indexed labels
38 if (ports > 1) {
39 labels.append(label + "[" + QString::number(port) + "]");
40 } else {
41 labels.append(label);
42 }
43 }
44 }
45
46 return labels;
47}
48
49} // namespace
50
52{
53 Signals result;
54
55 const auto elements = scene->elements();
56
57 if (elements.isEmpty()) {
58 throw PANDACEPTION_WITH_CONTEXT("BewavedDolphin", "The circuit is empty. Add input and output elements to generate a waveform.");
59 }
60
61 for (auto *elm : elements) {
62 if (!elm || (elm->type() != GraphicElement::Type)) {
63 continue;
64 }
65
66 if (elm->elementGroup() == ElementGroup::Input) {
67 result.inputs.append(qobject_cast<GraphicElementInput *>(elm));
68 // Multi-bit inputs (e.g. rotary encoder) contribute multiple port rows
69 result.inputPorts += elm->outputSize();
70 }
71
72 if (elm->elementGroup() == ElementGroup::Output) {
73 result.outputs.append(elm);
74 }
75 }
76
77 // Stable sort by label so the waveform table ordering is deterministic and
78 // matches what the user expects from the label names they assigned
79 std::stable_sort(result.inputs.begin(), result.inputs.end(), [](const auto &elm1, const auto &elm2) {
80 return QString::compare(elm1->label(), elm2->label(), Qt::CaseInsensitive) < 0;
81 });
82
83 std::stable_sort(result.outputs.begin(), result.outputs.end(), [](const auto &elm1, const auto &elm2) {
84 return QString::compare(elm1->label(), elm2->label(), Qt::CaseInsensitive) < 0;
85 });
86
87 if (result.inputs.isEmpty() && result.outputs.isEmpty()) {
88 throw PANDACEPTION_WITH_CONTEXT("BewavedDolphin", "The circuit has no input or output elements. Add at least one input (e.g. Switch) and one output (e.g. LED) to generate a waveform.");
89 }
90
91 if (result.inputs.isEmpty()) {
92 throw PANDACEPTION_WITH_CONTEXT("BewavedDolphin", "The circuit has no input elements. Add at least one input (e.g. Switch, Button, or Clock) to generate a waveform.");
93 }
94
95 if (result.outputs.isEmpty()) {
96 throw PANDACEPTION_WITH_CONTEXT("BewavedDolphin", "The circuit has no output elements. Add at least one output (e.g. LED or Display) to generate a waveform.");
97 }
98
99 result.inputLabels = buildLabels(result.inputs, [](const GraphicElementInput *e) { return e->outputSize(); });
100 result.outputLabels = buildLabels(result.outputs, [](const GraphicElement *e) { return e->inputSize(); });
101
102 return result;
103}
104
105} // namespace DolphinModelBuilder
Common logging utilities, the Pandaception error type, and helper macros.
#define PANDACEPTION_WITH_CONTEXT(context, msg,...)
Definition Common.h:102
DolphinModelBuilder: maps a circuit scene's I/O elements to waveform signal rows.
Singleton factory for all circuit element types.
Abstract base class for user-controllable input elements.
Abstract base class for all graphical circuit elements.
Main circuit editing scene with undo/redo and user interaction.
static QString translatedName(const ElementType type)
Returns the translated human-readable name for type.
Abstract base for all interactive input elements (switches, buttons, clocks, etc.).
Abstract base class for all graphical circuit elements in wiRedPanda.
Main circuit editing scene.
Definition Scene.h:56
const QVector< GraphicElement * > elements() const
Returns all graphic elements in the scene.
Definition Scene.cpp:336
Collects and orders the input/output elements of a circuit scene and derives the waveform table's row...
Signals collect(Scene *scene)
The input/output elements (label-sorted) and the row labels for a waveform table.
QVector< GraphicElement * > outputs
Output elements, sorted by label.
QStringList inputLabels
Row label per input port (indexed for multi-port).
QVector< GraphicElementInput * > inputs
Input elements, sorted by label.
QStringList outputLabels
Row label per output port (indexed for multi-port).
int inputPorts
Total input rows (sum of input output-port counts).