wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
Simulation.h
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
7
8#pragma once
9
10#include <chrono>
11#include <memory>
12
13#include <QGraphicsItem>
14#include <QHash>
15#include <QObject>
16#include <QSet>
17#include <QTimer>
18
19class Clock;
20class GraphicElement;
22class InputPort;
23class OutputPort;
24class SimulationHost;
25
38class Simulation : public QObject
39{
40 Q_OBJECT
41
42 friend class TestDanglingPointer;
43 friend class TestSimulationUnit;
44
45public:
48 static constexpr int kMaxSettleIterations = 10;
49
50 // --- Lifecycle ---
51
58 explicit Simulation(SimulationHost *host, QObject *parent = nullptr);
59
61 ~Simulation() override = default; // LCOV_EXCL_LINE -- destructor-ABI-variant gcov gap (Itanium ABI's separate deleting/complete-object destructors), same class as other `= default` destructors across this sweep.
62
63 // --- Control ---
64
66 void start();
67
69 void stop();
70
72 void setUserMuted(bool muted);
73
75 bool isUserMuted() const;
76
83 void restart();
84
86 bool isRunning();
87
89 bool isInFeedbackLoop(const GraphicElement *element) const;
90
91 // --- Initialization ---
92
97 bool initialize();
98
99 // --- Step ---
100
102 void update();
103
107 void setVisualThrottleEnabled(bool enabled);
108
109 // --- Static graph building (used by IC::initializeSimulation too) ---
110
111 static void buildConnectionGraph(const QVector<GraphicElement *> &elements);
114 static void connectWirelessElements(const QVector<GraphicElement *> &elements);
115
117 static QHash<QString, GraphicElement *> buildTxMap(const QVector<GraphicElement *> &elements);
118
120 static QHash<GraphicElement *, QVector<GraphicElement *>> buildSuccessorGraph(
121 const QVector<GraphicElement *> &elements,
122 const QHash<QString, GraphicElement *> &txMap);
123
125 struct SortResult {
126 QVector<GraphicElement *> sorted;
127 QHash<GraphicElement *, int> priorities;
128 QSet<GraphicElement *> feedbackNodes;
129 };
130
132 static SortResult topologicalSort(const QVector<GraphicElement *> &elements,
133 const QHash<GraphicElement *, QVector<GraphicElement *>> &successors);
134
137 static bool iterativeSettle(const QVector<GraphicElement *> &elements, int maxIterations = kMaxSettleIterations);
138
139signals:
141 void simulationWarning(const QString &message);
142
143private:
144 Q_DISABLE_COPY(Simulation)
145
146 // --- Helpers ---
147
148 static void updatePort(InputPort *port);
149 static void updatePort(OutputPort *port);
151 bool updateWithIterativeSettling(const QVector<GraphicElement *> &elements);
152 void sortSimElements(const QVector<GraphicElement *> &elements);
153
155 void pushVisualStatuses(const QVector<GraphicElement *> &elements, const QVector<GraphicElement *> &outputs);
156
160 void collectSequentialElements(const QVector<GraphicElement *> &elements);
161
162 // --- Members: Timer & element lists ---
163
164 QTimer m_timer;
169 std::chrono::steady_clock::time_point m_pausedAt;
170 bool m_hasPausedAt = false;
171 QVector<Clock *> m_clocks;
172 QVector<GraphicElement *> m_outputs;
173 QVector<GraphicElementInput *> m_inputs;
174
175 // --- Members: Host & state ---
176
177 SimulationHost *m_host;
178
179 // --- Members: State flags ---
180
181 bool m_initialized = false;
182 bool m_convergenceWarned = false;
183 bool m_userMuted = false;
184
190 bool m_atFixedPoint = false;
191
194 bool m_visualsDirty = true;
195
196 // --- Members: Visual refresh throttle ---
197
198 int m_visualTickCount = 0;
199 int m_visualTickInterval = 16;
200 bool m_visualThrottleEnabled = true;
201
202 // --- Members: Direct simulation graph ---
203
204 QVector<GraphicElement *> m_sortedElements;
208 QVector<GraphicElement *> m_sequentialElements;
209 QHash<const GraphicElement *, int> m_simPriorities;
210 QSet<const GraphicElement *> m_simFeedbackNodes;
211 bool m_simHasFeedbackElements = false;
212};
Event-driven real-time clock input element.
Definition Clock.h:23
Abstract base for all interactive input elements (switches, buttons, clocks, etc.).
Abstract base class for all graphical circuit elements in wiRedPanda.
A port that receives a signal (the destination end of a wire).
Definition Port.h:234
A port that drives a signal (the source end of a wire).
Definition Port.h:266
Narrow interface letting Simulation reach its host scene without naming the concrete Scene class.
void update()
Executes one simulation step (used by tests to advance the simulation manually).
static SortResult topologicalSort(const QVector< GraphicElement * > &elements, const QHash< GraphicElement *, QVector< GraphicElement * > > &successors)
Topologically sorts elements using the successor graph, detects feedback loops.
void setVisualThrottleEnabled(bool enabled)
Simulation(SimulationHost *host, QObject *parent=nullptr)
Constructs a Simulation bound to host.
static bool iterativeSettle(const QVector< GraphicElement * > &elements, int maxIterations=kMaxSettleIterations)
static QHash< QString, GraphicElement * > buildTxMap(const QVector< GraphicElement * > &elements)
Builds a label→element map for wireless Tx nodes. First Tx per label wins.
void setUserMuted(bool muted)
Sets whether the user has explicitly muted audio; persists across stop/start cycles.
void simulationWarning(const QString &message)
Emitted (at most once per initialize()) when a feedback circuit fails to converge.
void restart()
friend class TestDanglingPointer
Definition Simulation.h:42
static void buildConnectionGraph(const QVector< GraphicElement * > &elements)
bool initialize()
Builds the simulation graph from the current scene elements.
static void connectWirelessElements(const QVector< GraphicElement * > &elements)
static QHash< GraphicElement *, QVector< GraphicElement * > > buildSuccessorGraph(const QVector< GraphicElement * > &elements, const QHash< QString, GraphicElement * > &txMap)
Builds a successor adjacency list from connection graph + wireless Tx→Rx edges.
static constexpr int kMaxSettleIterations
Definition Simulation.h:48
friend class TestSimulationUnit
Definition Simulation.h:43
void start()
Starts the 1 ms simulation timer.
bool isRunning()
Returns true if the simulation timer is currently running.
~Simulation() override=default
Destructor; stops the simulation timer.
bool isUserMuted() const
Returns true if the user has explicitly muted audio.
bool isInFeedbackLoop(const GraphicElement *element) const
Returns true if element is part of a combinational feedback loop.
void stop()
Stops the simulation timer.
Result of topological sort with feedback detection.
Definition Simulation.h:125
QSet< GraphicElement * > feedbackNodes
Elements in feedback loops.
Definition Simulation.h:128
QVector< GraphicElement * > sorted
Elements in priority order (highest first).
Definition Simulation.h:126
QHash< GraphicElement *, int > priorities
Priority per element.
Definition Simulation.h:127