Skip to content

Commit 0235bd1

Browse files
committed
2 parents 0490065 + b03b723 commit 0235bd1

File tree

4 files changed

+56
-34
lines changed

4 files changed

+56
-34
lines changed

src/backend/evaluator/evaluator.cpp

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,12 @@ void Evaluator::edit_removeConnection(
246246
Position inputBlockPosition,
247247
Position inputPosition
248248
) {
249-
std::optional<EvalConnectionPoint> outputPoint = getConnectionPoint(evalCircuitId, blockContainer, outputPosition, Direction::OUT);
249+
std::optional<EvalConnectionPoint> outputPoint = getConnectionPoint(evalCircuitId, outputPosition, Direction::OUT);
250250
if (!outputPoint.has_value()) {
251251
// logError("Output connection point not found for position {}", "Evaluator::edit_removeConnection", outputPosition.toString());
252252
return;
253253
}
254-
std::optional<EvalConnectionPoint> inputPoint = getConnectionPoint(evalCircuitId, blockContainer, inputPosition, Direction::IN);
254+
std::optional<EvalConnectionPoint> inputPoint = getConnectionPoint(evalCircuitId, inputPosition, Direction::IN);
255255
if (!inputPoint.has_value()) {
256256
// logError("Input connection point not found for position {}", "Evaluator::edit_removeConnection", inputPosition.toString());
257257
return;
@@ -276,14 +276,15 @@ void Evaluator::edit_createConnection(
276276
) {
277277
std::set<CircuitPortDependency> circuitPortDependencies;
278278
std::set<CircuitNode> circuitNodeDependencies;
279+
std::set<EvalPosition> visitedEvalPositions;
279280

280281
std::optional<EvalConnectionPoint> outputPoint =
281-
getConnectionPoint(evalCircuitId, outputPosition, Direction::OUT, circuitPortDependencies, circuitNodeDependencies, false);
282+
getConnectionPoint(evalCircuitId, outputPosition, Direction::OUT, circuitPortDependencies, circuitNodeDependencies, visitedEvalPositions, false);
282283
if (!outputPoint.has_value()) {
283284
return;
284285
}
285286
std::optional<EvalConnectionPoint> inputPoint =
286-
getConnectionPoint(evalCircuitId, inputPosition, Direction::IN, circuitPortDependencies, circuitNodeDependencies, false);
287+
getConnectionPoint(evalCircuitId, inputPosition, Direction::IN, circuitPortDependencies, circuitNodeDependencies, visitedEvalPositions, false);
287288
if (!inputPoint.has_value()) {
288289
return;
289290
}
@@ -296,6 +297,9 @@ void Evaluator::edit_createConnection(
296297
if (!circuitPortDependencies.empty() || !circuitNodeDependencies.empty()) {
297298
interCircuitConnections.push_back({ connection, circuitPortDependencies, circuitNodeDependencies });
298299
}
300+
for (const EvalPosition& evalPosition : visitedEvalPositions) {
301+
dirtyNodes.insert(evalPosition);
302+
}
299303
evalSimulator->makeConnection(pauseGuard, connection);
300304
}
301305

@@ -451,26 +455,22 @@ std::optional<connection_end_id_t> Evaluator::getPortId(
451455
}
452456
}
453457

454-
std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(const eval_circuit_id_t evalCircuitId, const Position portPosition, Direction direction) const {
458+
std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
459+
const eval_circuit_id_t evalCircuitId,
460+
const Position portPosition,
461+
Direction direction
462+
) const {
455463
EvalCircuit* evalCircuit = evalCircuitContainer.getCircuit(evalCircuitId);
456464
if (!evalCircuit) [[unlikely]] {
457465
return std::nullopt;
458466
}
467+
459468
circuit_id_t circuitId = evalCircuit->getCircuitId();
460469
SharedCircuit circuit = circuitManager.getCircuit(circuitId);
461470
if (!circuit) [[unlikely]] {
462471
return std::nullopt;
463472
}
464473
const BlockContainer* blockContainer = circuit->getBlockContainer();
465-
return getConnectionPoint(evalCircuitId, blockContainer, portPosition, direction);
466-
}
467-
468-
std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
469-
const eval_circuit_id_t evalCircuitId,
470-
const BlockContainer* blockContainer,
471-
const Position portPosition,
472-
Direction direction
473-
) const {
474474
// Get the block first - this is the most likely failure point
475475
const Block* block = blockContainer->getBlock(portPosition);
476476
if (!block) [[unlikely]] {
@@ -480,11 +480,6 @@ std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
480480
const BlockType blockType = block->type();
481481
const Position blockPosition = block->getPosition();
482482

483-
EvalCircuit* evalCircuit = evalCircuitContainer.getCircuit(evalCircuitId);
484-
if (!evalCircuit) [[unlikely]] {
485-
return std::nullopt;
486-
}
487-
488483
std::optional<CircuitNode> node = evalCircuit->getNode(blockPosition);
489484
if (!node.has_value()) [[unlikely]] {
490485
return std::nullopt;
@@ -527,8 +522,8 @@ std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
527522
return EvalConnectionPoint(node->getMiddleId(), portId.value());
528523
}
529524

530-
const circuit_id_t circuitId = circuitBlockDataManager.getCircuitId(blockType);
531-
CircuitBlockData* circuitBlockData = circuitBlockDataManager.getCircuitBlockData(circuitId);
525+
const circuit_id_t innerCircuitId = circuitBlockDataManager.getCircuitId(blockType);
526+
CircuitBlockData* circuitBlockData = circuitBlockDataManager.getCircuitBlockData(innerCircuitId);
532527
if (!circuitBlockData) [[unlikely]] {
533528
logError("CircuitBlockData for type {} not found", "Evaluator::getConnectionPoint", blockType);
534529
return std::nullopt;
@@ -549,6 +544,7 @@ std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
549544
Direction direction,
550545
std::set<CircuitPortDependency>& circuitPortDependencies,
551546
std::set<CircuitNode>& circuitNodeDependencies,
547+
std::set<EvalPosition>& visitedEvalPositions,
552548
bool isInterCircuit
553549
) const {
554550
EvalCircuit* evalCircuit = evalCircuitContainer.getCircuit(evalCircuitId);
@@ -566,6 +562,8 @@ std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
566562
return std::nullopt;
567563
}
568564

565+
visitedEvalPositions.insert({ portPosition, evalCircuitId });
566+
569567
const BlockType blockType = block->type();
570568
const Position blockPosition = block->getPosition();
571569

@@ -627,7 +625,7 @@ std::optional<EvalConnectionPoint> Evaluator::getConnectionPoint(
627625
}
628626

629627
circuitPortDependencies.insert({ circuitId, portId.value() });
630-
return getConnectionPoint(node->getEvalCircuitId(), *internalPosition, direction, circuitPortDependencies, circuitNodeDependencies, true);
628+
return getConnectionPoint(node->getEvalCircuitId(), *internalPosition, direction, circuitPortDependencies, circuitNodeDependencies, visitedEvalPositions, true);
631629
}
632630

633631
void Evaluator::edit_moveBlock(
@@ -749,7 +747,7 @@ logic_state_t Evaluator::getState(const Address& address) {
749747
}
750748
const BlockContainer* blockContainer = circuit->getBlockContainer();
751749

752-
std::optional<EvalConnectionPoint> connectionPointOpt = getConnectionPoint(evalCircuitId, blockContainer, address.getPosition(address.size() - 1), Direction::OUT);
750+
std::optional<EvalConnectionPoint> connectionPointOpt = getConnectionPoint(evalCircuitId, address.getPosition(address.size() - 1), Direction::OUT);
753751
if (!connectionPointOpt.has_value()) {
754752
logError("Connection point not found for address {}", "Evaluator::getState", address.toString());
755753
return logic_state_t::UNDEFINED;
@@ -780,12 +778,12 @@ void Evaluator::setState(const Address& address, logic_state_t state) {
780778
}
781779
const BlockContainer* blockContainer = circuit->getBlockContainer();
782780

783-
std::optional<EvalConnectionPoint> connectionPointOpt = getConnectionPoint(evalCircuitId, blockContainer, address.getPosition(address.size() - 1), Direction::OUT);
781+
std::optional<EvalConnectionPoint> connectionPointOpt = getConnectionPoint(evalCircuitId, address.getPosition(address.size() - 1), Direction::OUT);
784782
if (connectionPointOpt.has_value()) {
785783
evalSimulator->setState(connectionPointOpt.value(), state);
786784
return;
787785
}
788-
std::optional<EvalConnectionPoint> connectionPointOptIn = getConnectionPoint(evalCircuitId, blockContainer, address.getPosition(address.size() - 1), Direction::IN);
786+
std::optional<EvalConnectionPoint> connectionPointOptIn = getConnectionPoint(evalCircuitId, address.getPosition(address.size() - 1), Direction::IN);
789787
if (connectionPointOptIn.has_value()) {
790788
evalSimulator->setState(connectionPointOptIn.value(), state);
791789
return;
@@ -889,15 +887,19 @@ void Evaluator::checkToCreateExternalConnections(SimPauseGuard& pauseGuard, eval
889887

890888
std::set<CircuitPortDependency> circuitPortDependencies;
891889
std::set<CircuitNode> circuitNodeDependencies;
890+
std::set<EvalPosition> visitedEvalPositions;
892891
circuitNodeDependencies.insert(node.value());
893892
std::optional<EvalConnectionPoint> connectionPoint =
894-
getConnectionPoint(evalCircuitId, portPosition, direction, circuitPortDependencies, circuitNodeDependencies, false);
893+
getConnectionPoint(evalCircuitId, portPosition, direction, circuitPortDependencies, circuitNodeDependencies, visitedEvalPositions, false);
895894

896895
if (connectionPoint.has_value()) {
897-
traceOutwardsIC(pauseGuard, evalCircuitId, portPosition, direction, connectionPoint.value(), circuitPortDependencies, circuitNodeDependencies);
896+
traceOutwardsIC(pauseGuard, evalCircuitId, portPosition, direction, connectionPoint.value(), circuitPortDependencies, circuitNodeDependencies, visitedEvalPositions);
898897
} else {
899898
logError("Connection point not found for position {}", "Evaluator::checkToCreateExternalConnections", portPosition.toString());
900899
}
900+
for (const EvalPosition& evalPosition : visitedEvalPositions) {
901+
dirtyNodes.insert(evalPosition);
902+
}
901903
}
902904
}
903905

@@ -908,8 +910,9 @@ void Evaluator::traceOutwardsIC(
908910
Direction direction,
909911
const EvalConnectionPoint& targetConnectionPoint,
910912
std::set<CircuitPortDependency>& circuitPortDependencies,
911-
std::set<CircuitNode>& circuitNodeDependencies
912-
) {
913+
std::set<CircuitNode>& circuitNodeDependencies,
914+
std::set<EvalPosition>& visitedEvalPositions
915+
) {
913916
EvalCircuit* evalCircuit = evalCircuitContainer.getCircuit(evalCircuitId);
914917
if (!evalCircuit) {
915918
logError("EvalCircuit with id {} not found", "Evaluator::traceOutwardsIC", evalCircuitId);
@@ -1022,7 +1025,7 @@ void Evaluator::traceOutwardsIC(
10221025
std::set<CircuitNode> circuitNodeDependenciesCopy = circuitNodeDependencies;
10231026
// get connection point
10241027
std::optional<EvalConnectionPoint> connectionPoint =
1025-
getConnectionPoint(parentEvalCircuitId, targetConnectionPointPosition, !direction, circuitPortDependenciesCopy, circuitNodeDependenciesCopy, false);
1028+
getConnectionPoint(parentEvalCircuitId, targetConnectionPointPosition, !direction, circuitPortDependenciesCopy, circuitNodeDependenciesCopy, visitedEvalPositions, false);
10261029
if (!connectionPoint.has_value()) {
10271030
continue;
10281031
}
@@ -1050,7 +1053,8 @@ void Evaluator::traceOutwardsIC(
10501053
direction,
10511054
targetConnectionPoint,
10521055
circuitPortDependencies,
1053-
circuitNodeDependencies
1056+
circuitNodeDependencies,
1057+
visitedEvalPositions
10541058
);
10551059
}
10561060

src/backend/evaluator/evaluator.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,18 @@ class Evaluator {
148148

149149
std::optional<connection_end_id_t> getPortId(const circuit_id_t circuitId, const Position blockPosition, const Position portPosition, Direction direction) const;
150150
std::optional<connection_end_id_t> getPortId(const BlockContainer* blockContainer, const Position blockPosition, const Position portPosition, Direction direction) const;
151-
std::optional<EvalConnectionPoint> getConnectionPoint(const eval_circuit_id_t evalCircuitId, const Position portPosition, Direction direction) const;
152-
std::optional<EvalConnectionPoint> getConnectionPoint(const eval_circuit_id_t evalCircuitId, const BlockContainer* blockContainer, const Position portPosition, Direction direction) const;
151+
std::optional<EvalConnectionPoint> getConnectionPoint(
152+
const eval_circuit_id_t evalCircuitId,
153+
const Position portPosition,
154+
Direction direction
155+
) const;
153156
std::optional<EvalConnectionPoint> getConnectionPoint(
154157
const eval_circuit_id_t evalCircuitId,
155158
const Position portPosition,
156159
Direction direction,
157160
std::set<CircuitPortDependency>& circuitPortDependencies,
158161
std::set<CircuitNode>& circuitNodeDependencies,
162+
std::set<EvalPosition>& visitedEvalPositions,
159163
bool isInterCircuit
160164
) const;
161165

@@ -168,7 +172,8 @@ class Evaluator {
168172
Direction direction,
169173
const EvalConnectionPoint& targetConnectionPoint,
170174
std::set<CircuitPortDependency>& circuitPortDependencies,
171-
std::set<CircuitNode>& circuitNodeDependencies
175+
std::set<CircuitNode>& circuitNodeDependencies,
176+
std::set<EvalPosition>& visitedEvalPositions
172177
);
173178
std::vector<simulator_id_t> dirtySimulatorIds;
174179
std::vector<middle_id_t> dirtyMiddleIds;

src/backend/evaluator/util/evalCircuitContainer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ struct EvalPosition {
2121
inline bool operator==(const EvalPosition& other) const {
2222
return position == other.position && evalCircuitId == other.evalCircuitId;
2323
}
24+
25+
inline auto operator<=>(const EvalPosition& other) const {
26+
if (auto cmp = evalCircuitId <=> other.evalCircuitId; cmp != 0) {
27+
return cmp;
28+
}
29+
return position <=> other.position;
30+
}
2431
};
2532

2633
template<>

src/backend/position/position.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ struct Position {
196196

197197
inline bool operator==(Position position) const noexcept { return x == position.x && y == position.y; }
198198
inline bool operator!=(Position position) const noexcept { return !operator==(position); }
199+
inline auto operator<=>(Position position) const noexcept {
200+
if (auto cmp = x <=> position.x; cmp != 0) {
201+
return cmp;
202+
}
203+
return y <=> position.y;
204+
}
199205
inline bool withinArea(Position small, Position large) const noexcept { return small.x <= x && small.y <= y && large.x >= x && large.y >= y; }
200206

201207
inline coordinate_t manhattenDistanceTo(Position position) const noexcept { return Abs(x - position.x) + Abs(y - position.y); }

0 commit comments

Comments
 (0)