Improve circuit plotting.

This commit is contained in:
jmsgrogan 2023-01-24 12:59:00 +00:00
parent 6274c41a80
commit df450a7be0
17 changed files with 321 additions and 13 deletions

View file

@ -4,6 +4,8 @@
#include "WireNode.h"
#include "LogicGateNode.h"
#include "FileLogger.h"
ElectronicCircuitNode::ElectronicCircuitNode(const Transform& transform)
: AbstractVisualNode(transform)
{
@ -21,17 +23,48 @@ void ElectronicCircuitNode::setContent(ElectronicCircuit* content)
mContentDirty = true;
}
void ElectronicCircuitNode::buildWireConnections()
{
mWireInputConnections.clear();
mWireOutputConnections.clear();
for (auto terminal : mContent->getInputTerminals())
{
mWireOutputConnections[terminal->getConnection()] = terminal;
}
for (auto gate : mContent->getLogicGates())
{
for (std::size_t idx = 0; idx < gate->getNumInputs(); idx++)
{
mWireInputConnections[gate->getInput(idx)] = gate;
}
for (std::size_t idx = 0; idx < gate->getNumOutputs(); idx++)
{
mWireOutputConnections[gate->getOutput(idx)] = gate;
}
}
for (auto terminal : mContent->getOutputTerminals())
{
mWireInputConnections[terminal->getConnection()] = terminal;
}
}
void ElectronicCircuitNode::createOrUpdateGeometry(SceneInfo*)
{
mInputTerminalNodes.clear();
mWireNodes.clear();
mLogicGateNodes.clear();
buildWireConnections();
// Layout terminals
double terminal_vertical_spacing = 100;
double terminal_left_margin = 10;
double terminal_y = 0;
double terminal_y = 10;
for (auto terminal : mContent->getInputTerminals())
{
Point loc{ terminal_left_margin, terminal_y };
@ -40,6 +73,8 @@ void ElectronicCircuitNode::createOrUpdateGeometry(SceneInfo*)
terminal_node->setContent(terminal);
addChild(terminal_node.get());
mNodesForContent[terminal] = terminal_node.get();
mInputTerminalNodes.push_back(std::move(terminal_node));
terminal_y += terminal_vertical_spacing;
@ -59,12 +94,48 @@ void ElectronicCircuitNode::createOrUpdateGeometry(SceneInfo*)
gate_node->setContent(gate);
addChild(gate_node.get());
mNodesForContent[gate] = gate_node.get();
mLogicGateNodes.push_back(std::move(gate_node));
gate_x += logic_gate_vertical_spacing;
gate_y += logic_gate_horizontal_spacing;
}
// Layout output terminals
terminal_y = 10;
double terminal_right_margin = 10;
unsigned width = 500;
for (auto terminal : mContent->getOutputTerminals())
{
Point loc{ width - terminal_right_margin, terminal_y };
auto node = std::make_unique<TerminalNode>(Transform(loc));
node->setContent(terminal);
addChild(node.get());
mNodesForContent[terminal] = node.get();
mOutputTerminalNodes.push_back(std::move(node));
terminal_y += terminal_vertical_spacing;
}
// Add wires
for (auto wire : mContent->getWires())
{
auto start_node = mNodesForContent[mWireOutputConnections[wire]];
auto end_node = mNodesForContent[mWireInputConnections[wire]];
auto wire_node = std::make_unique<WireNode>(Transform());
wire_node->setInputLocation(start_node->getConnectionLocation(wire));
wire_node->setOutputLocation(end_node->getConnectionLocation(wire));
addChild(wire_node.get());
mWireNodes.push_back(std::move(wire_node));
}
}
void ElectronicCircuitNode::update(SceneInfo* sceneInfo)