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 <memory>
11
12#include <QGraphicsItem>
13#include <QHash>
14#include <QObject>
15#include <QSet>
16#include <QTimer>
17
18class Clock;
19class GraphicElement;
21class InputPort;
22class OutputPort;
23class SimulationHost;
24
37class Simulation : public QObject
38{
39 Q_OBJECT
40
41 friend class TestDanglingPointer;
42
43public:
46 static constexpr int kMaxSettleIterations = 10;
47
48 // --- Lifecycle ---
49
56 explicit Simulation(SimulationHost *host, QObject *parent = nullptr);
57
59 ~Simulation() override = default;
60
61 // --- Control ---
62
64 void start();
65
67 void stop();
68
70 void setUserMuted(bool muted);
71
73 bool isUserMuted() const;
74
81 void restart();
82
84 bool isRunning();
85
87 bool isInFeedbackLoop(const GraphicElement *element) const;
88
89 // --- Initialization ---
90
95 bool initialize();
96
97 // --- Step ---
98
100 void update();
101
105 void setVisualThrottleEnabled(bool enabled);
106
107 // --- Static graph building (used by IC::initializeSimulation too) ---
108
109 static void buildConnectionGraph(const QVector<GraphicElement *> &elements);
112 static void connectWirelessElements(const QVector<GraphicElement *> &elements);
113
115 static QHash<QString, GraphicElement *> buildTxMap(const QVector<GraphicElement *> &elements);
116
118 static QHash<GraphicElement *, QVector<GraphicElement *>> buildSuccessorGraph(
119 const QVector<GraphicElement *> &elements,
120 const QHash<QString, GraphicElement *> &txMap);
121
123 struct SortResult {
124 QVector<GraphicElement *> sorted;
125 QHash<GraphicElement *, int> priorities;
126 QSet<GraphicElement *> feedbackNodes;
127 };
128
130 static SortResult topologicalSort(const QVector<GraphicElement *> &elements,
131 const QHash<GraphicElement *, QVector<GraphicElement *>> &successors);
132
135 static bool iterativeSettle(const QVector<GraphicElement *> &elements, int maxIterations = kMaxSettleIterations);
136
137signals:
139 void simulationWarning(const QString &message);
140
141private:
142 Q_DISABLE_COPY(Simulation)
143
144 // --- Helpers ---
145
146 static void updatePort(InputPort *port);
147 static void updatePort(OutputPort *port);
149 bool updateWithIterativeSettling(const QVector<GraphicElement *> &elements);
150 void sortSimElements(const QVector<GraphicElement *> &elements);
151
153 void pushVisualStatuses(const QVector<GraphicElement *> &elements, const QVector<GraphicElement *> &outputs);
154
158 void collectSequentialElements(const QVector<GraphicElement *> &elements);
159
160 // --- Members: Timer & element lists ---
161
162 QTimer m_timer;
163 QVector<Clock *> m_clocks;
164 QVector<GraphicElement *> m_outputs;
165 QVector<GraphicElementInput *> m_inputs;
166
167 // --- Members: Host & state ---
168
169 SimulationHost *m_host;
170
171 // --- Members: State flags ---
172
173 bool m_initialized = false;
174 bool m_convergenceWarned = false;
175 bool m_userMuted = false;
176
182 bool m_atFixedPoint = false;
183
186 bool m_visualsDirty = true;
187
188 // --- Members: Visual refresh throttle ---
189
190 int m_visualTickCount = 0;
191 int m_visualTickInterval = 16;
192 bool m_visualThrottleEnabled = true;
193
194 // --- Members: Direct simulation graph ---
195
196 QVector<GraphicElement *> m_sortedElements;
200 QVector<GraphicElement *> m_sequentialElements;
201 QHash<const GraphicElement *, int> m_simPriorities;
202 QSet<const GraphicElement *> m_simFeedbackNodes;
203 bool m_simHasFeedbackElements = false;
204};
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:229
A port that drives a signal (the source end of a wire).
Definition Port.h:261
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:41
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:46
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:123
QSet< GraphicElement * > feedbackNodes
Elements in feedback loops.
Definition Simulation.h:126
QVector< GraphicElement * > sorted
Elements in priority order (highest first).
Definition Simulation.h:124
QHash< GraphicElement *, int > priorities
Priority per element.
Definition Simulation.h:125