stuff-from-scratch/plugins/quantum_computing/src/visuals/QuantumCircuitNode.cpp
2023-12-27 12:20:02 +00:00

133 lines
3.6 KiB
C++

#include "QuantumCircuitNode.h"
#include "QuantumCircuit.h"
#include "QuantumCircuitElement.h"
#include "QuantumWire.h"
#include "QuantumCircuitElementNode.h"
#include "QuantumTerminalNode.h"
#include "QuantumWireNode.h"
#include "QuantumGateNode.h"
#include "LatexMathExpression.h"
#include "EquationNode.h"
QuantumCircuitNode::QuantumCircuitNode(const Transform& t)
: AbstractVisualNode(t)
{
}
void QuantumCircuitNode::setContent(QuantumCircuit* circuit)
{
mContent = circuit;
mContentDirty = true;
}
void QuantumCircuitNode::update(SceneInfo* sceneInfo)
{
if (mContentDirty)
{
createOrUpdateGeometry(sceneInfo);
mContentDirty = false;
}
}
void QuantumCircuitNode::buildWireConnections()
{
mWireInputConnections.clear();
mWireOutputConnections.clear();
for (auto terminal : mContent->getInputTerminals())
{
mWireOutputConnections[terminal->getConnection()] = terminal;
}
for (auto gate : mContent->getLogicGates())
{
for (size_t idx = 0; idx < gate->getNumInputs(); idx++)
{
mWireInputConnections[gate->getInput(idx)] = gate;
}
for (size_t idx = 0; idx < gate->getNumOutputs(); idx++)
{
mWireOutputConnections[gate->getOutput(idx)] = gate;
}
}
for (auto terminal : mContent->getOutputTerminals())
{
mWireInputConnections[terminal->getConnection()] = terminal;
}
}
void QuantumCircuitNode::createOrUpdateGeometry(SceneInfo*)
{
buildWireConnections();
double wire_vertical_spacing = 50;
double terminal_left_margin = 10;
double terminal_y = 10;
for (auto terminal : mContent->getInputTerminals())
{
Point loc{ terminal_left_margin, terminal_y };
auto terminal_node = std::make_unique<QuantumTerminalNode>(Transform(loc));
terminal_node->setContent(terminal);
addChild(terminal_node.get());
mNodesForContent[terminal] = terminal_node.get();
mInputTerminalNodes.push_back(std::move(terminal_node));
terminal_y += wire_vertical_spacing;
}
terminal_y = 10;
for (auto terminal : mContent->getOutputTerminals())
{
Point loc{ 150.0, terminal_y };
auto terminal_node = std::make_unique<QuantumTerminalNode>(Transform(loc));
terminal_node->setContent(terminal);
addChild(terminal_node.get());
mNodesForContent[terminal] = terminal_node.get();
mOutputTerminalNodes.push_back(std::move(terminal_node));
terminal_y += wire_vertical_spacing;
}
double gate_y = 0;
for (auto gate : mContent->getLogicGates())
{
Point loc{ 75.0, gate_y };
auto gate_node = std::make_unique<QuantumGateNode>(Transform(loc));
gate_node->setContent(gate);
addChild(gate_node.get());
mNodesForContent[gate] = gate_node.get();
mGateNodes.push_back(std::move(gate_node));
gate_y += wire_vertical_spacing;
}
for (auto wire : mContent->getQuantumWires())
{
auto start_node = mNodesForContent[mWireOutputConnections[wire]];
auto end_node = mNodesForContent[mWireInputConnections[wire]];
auto wire_node = std::make_unique<QuantumWireNode>(Transform());
auto start_loc = start_node->getConnectionLocation(wire);
wire_node->setInputLocation(start_loc);
auto end_loc = end_node->getConnectionLocation(wire);
auto straight_end_loc = Point2(end_loc.getX(), start_loc.getY());
wire_node->setOutputLocation(straight_end_loc);
addChild(wire_node.get());
mWireNodes.push_back(std::move(wire_node));
}
}