Improve circuit plotting.
This commit is contained in:
parent
6274c41a80
commit
df450a7be0
17 changed files with 321 additions and 13 deletions
|
@ -9,6 +9,7 @@ list(APPEND HEADERS
|
||||||
gates/LogicGate.h
|
gates/LogicGate.h
|
||||||
gates/BasicLogicGates.h
|
gates/BasicLogicGates.h
|
||||||
visuals/ElectronicCircuitNode.h
|
visuals/ElectronicCircuitNode.h
|
||||||
|
visuals/CircuitElementNode.h
|
||||||
visuals/WireNode.h
|
visuals/WireNode.h
|
||||||
visuals/TerminalNode.h
|
visuals/TerminalNode.h
|
||||||
visuals/LogicGateNode.h
|
visuals/LogicGateNode.h
|
||||||
|
@ -24,6 +25,7 @@ list(APPEND SOURCES
|
||||||
gates/BasicLogicGates.cpp
|
gates/BasicLogicGates.cpp
|
||||||
gates/LogicGate.cpp
|
gates/LogicGate.cpp
|
||||||
visuals/ElectronicCircuitNode.cpp
|
visuals/ElectronicCircuitNode.cpp
|
||||||
|
visuals/CircuitElementNode.cpp
|
||||||
visuals/WireNode.cpp
|
visuals/WireNode.cpp
|
||||||
visuals/TerminalNode.cpp
|
visuals/TerminalNode.cpp
|
||||||
visuals/LogicGateNode.cpp
|
visuals/LogicGateNode.cpp
|
||||||
|
|
|
@ -25,11 +25,21 @@ public:
|
||||||
return mInputTerminals;
|
return mInputTerminals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<Terminal*>& getOutputTerminals() const
|
||||||
|
{
|
||||||
|
return mOutputTerminals;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<LogicGate*>& getLogicGates() const
|
const std::vector<LogicGate*>& getLogicGates() const
|
||||||
{
|
{
|
||||||
return mLogicGates;
|
return mLogicGates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<Wire*>& getWires() const
|
||||||
|
{
|
||||||
|
return mWires;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Terminal*> mInputTerminals;
|
std::vector<Terminal*> mInputTerminals;
|
||||||
std::vector<Terminal*> mOutputTerminals;
|
std::vector<Terminal*> mOutputTerminals;
|
||||||
|
|
|
@ -29,7 +29,7 @@ std::size_t NInMOutLogicGate::getNumInputs() const
|
||||||
return mNumIn;
|
return mNumIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t NInMOutLogicGate::getNumOutputputs() const
|
std::size_t NInMOutLogicGate::getNumOutputs() const
|
||||||
{
|
{
|
||||||
return mNumOut;
|
return mNumOut;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
|
|
||||||
virtual std::size_t getNumInputs() const = 0;
|
virtual std::size_t getNumInputs() const = 0;
|
||||||
|
|
||||||
virtual std::size_t getNumOutputputs() const = 0;
|
virtual std::size_t getNumOutputs() const = 0;
|
||||||
|
|
||||||
virtual Wire* getInput(std::size_t idx) const = 0;
|
virtual Wire* getInput(std::size_t idx) const = 0;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
std::size_t getNumInputs() const override;
|
std::size_t getNumInputs() const override;
|
||||||
|
|
||||||
std::size_t getNumOutputputs() const override;
|
std::size_t getNumOutputs() const override;
|
||||||
|
|
||||||
Wire* getInput(std::size_t idx) const override;
|
Wire* getInput(std::size_t idx) const override;
|
||||||
|
|
||||||
|
|
12
plugins/circuits/src/visuals/CircuitElementNode.cpp
Normal file
12
plugins/circuits/src/visuals/CircuitElementNode.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "CircuitElementNode.h"
|
||||||
|
|
||||||
|
CircuitElementNode::CircuitElementNode(const Transform& transform)
|
||||||
|
: AbstractVisualNode(transform)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CircuitElementNode::~CircuitElementNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
15
plugins/circuits/src/visuals/CircuitElementNode.h
Normal file
15
plugins/circuits/src/visuals/CircuitElementNode.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AbstractVisualNode.h"
|
||||||
|
|
||||||
|
class Wire;
|
||||||
|
|
||||||
|
class CircuitElementNode : public AbstractVisualNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CircuitElementNode(const Transform& transform);
|
||||||
|
|
||||||
|
virtual ~CircuitElementNode();
|
||||||
|
|
||||||
|
virtual Point getConnectionLocation(Wire* wire) const = 0;
|
||||||
|
};
|
|
@ -4,6 +4,8 @@
|
||||||
#include "WireNode.h"
|
#include "WireNode.h"
|
||||||
#include "LogicGateNode.h"
|
#include "LogicGateNode.h"
|
||||||
|
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
ElectronicCircuitNode::ElectronicCircuitNode(const Transform& transform)
|
ElectronicCircuitNode::ElectronicCircuitNode(const Transform& transform)
|
||||||
: AbstractVisualNode(transform)
|
: AbstractVisualNode(transform)
|
||||||
{
|
{
|
||||||
|
@ -21,17 +23,48 @@ void ElectronicCircuitNode::setContent(ElectronicCircuit* content)
|
||||||
mContentDirty = true;
|
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*)
|
void ElectronicCircuitNode::createOrUpdateGeometry(SceneInfo*)
|
||||||
{
|
{
|
||||||
mInputTerminalNodes.clear();
|
mInputTerminalNodes.clear();
|
||||||
mWireNodes.clear();
|
mWireNodes.clear();
|
||||||
mLogicGateNodes.clear();
|
mLogicGateNodes.clear();
|
||||||
|
|
||||||
|
buildWireConnections();
|
||||||
|
|
||||||
// Layout terminals
|
// Layout terminals
|
||||||
double terminal_vertical_spacing = 100;
|
double terminal_vertical_spacing = 100;
|
||||||
double terminal_left_margin = 10;
|
double terminal_left_margin = 10;
|
||||||
|
|
||||||
double terminal_y = 0;
|
double terminal_y = 10;
|
||||||
for (auto terminal : mContent->getInputTerminals())
|
for (auto terminal : mContent->getInputTerminals())
|
||||||
{
|
{
|
||||||
Point loc{ terminal_left_margin, terminal_y };
|
Point loc{ terminal_left_margin, terminal_y };
|
||||||
|
@ -40,6 +73,8 @@ void ElectronicCircuitNode::createOrUpdateGeometry(SceneInfo*)
|
||||||
terminal_node->setContent(terminal);
|
terminal_node->setContent(terminal);
|
||||||
|
|
||||||
addChild(terminal_node.get());
|
addChild(terminal_node.get());
|
||||||
|
|
||||||
|
mNodesForContent[terminal] = terminal_node.get();
|
||||||
mInputTerminalNodes.push_back(std::move(terminal_node));
|
mInputTerminalNodes.push_back(std::move(terminal_node));
|
||||||
|
|
||||||
terminal_y += terminal_vertical_spacing;
|
terminal_y += terminal_vertical_spacing;
|
||||||
|
@ -59,12 +94,48 @@ void ElectronicCircuitNode::createOrUpdateGeometry(SceneInfo*)
|
||||||
gate_node->setContent(gate);
|
gate_node->setContent(gate);
|
||||||
|
|
||||||
addChild(gate_node.get());
|
addChild(gate_node.get());
|
||||||
|
|
||||||
|
mNodesForContent[gate] = gate_node.get();
|
||||||
mLogicGateNodes.push_back(std::move(gate_node));
|
mLogicGateNodes.push_back(std::move(gate_node));
|
||||||
|
|
||||||
gate_x += logic_gate_vertical_spacing;
|
gate_x += logic_gate_vertical_spacing;
|
||||||
gate_y += logic_gate_horizontal_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)
|
void ElectronicCircuitNode::update(SceneInfo* sceneInfo)
|
||||||
|
|
|
@ -4,9 +4,13 @@
|
||||||
|
|
||||||
#include "ElectronicCircuit.h"
|
#include "ElectronicCircuit.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class WireNode;
|
class WireNode;
|
||||||
class TerminalNode;
|
class TerminalNode;
|
||||||
class LogicGateNode;
|
class LogicGateNode;
|
||||||
|
class Wire;
|
||||||
|
class CircuitElementNode;
|
||||||
|
|
||||||
class ElectronicCircuitNode : public AbstractVisualNode
|
class ElectronicCircuitNode : public AbstractVisualNode
|
||||||
{
|
{
|
||||||
|
@ -22,10 +26,18 @@ public:
|
||||||
private:
|
private:
|
||||||
void createOrUpdateGeometry(SceneInfo* sceneInfo);
|
void createOrUpdateGeometry(SceneInfo* sceneInfo);
|
||||||
|
|
||||||
|
void buildWireConnections();
|
||||||
|
|
||||||
ElectronicCircuit* mContent{ nullptr };
|
ElectronicCircuit* mContent{ nullptr };
|
||||||
bool mContentDirty{ true };
|
bool mContentDirty{ true };
|
||||||
|
|
||||||
std::vector<std::unique_ptr<TerminalNode> > mInputTerminalNodes;
|
std::vector<std::unique_ptr<TerminalNode> > mInputTerminalNodes;
|
||||||
|
std::vector<std::unique_ptr<TerminalNode> > mOutputTerminalNodes;
|
||||||
std::vector<std::unique_ptr<WireNode> > mWireNodes;
|
std::vector<std::unique_ptr<WireNode> > mWireNodes;
|
||||||
std::vector<std::unique_ptr<LogicGateNode> > mLogicGateNodes;
|
std::vector<std::unique_ptr<LogicGateNode> > mLogicGateNodes;
|
||||||
|
|
||||||
|
std::unordered_map<Wire*, CircuitElement*> mWireInputConnections;
|
||||||
|
std::unordered_map<Wire*, CircuitElement*> mWireOutputConnections;
|
||||||
|
|
||||||
|
std::unordered_map<CircuitElement*, CircuitElementNode*> mNodesForContent;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "LogicGatePrimitiveShapes.h"
|
#include "LogicGatePrimitiveShapes.h"
|
||||||
|
|
||||||
LogicGateNode::LogicGateNode(const Transform& transform)
|
LogicGateNode::LogicGateNode(const Transform& transform)
|
||||||
: AbstractVisualNode(transform)
|
: CircuitElementNode(transform)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,45 @@ LogicGateNode::~LogicGateNode()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point LogicGateNode::getConnectionLocation(Wire* wire) const
|
||||||
|
{
|
||||||
|
bool is_input{ false };
|
||||||
|
std::size_t connection_id{ 0 };
|
||||||
|
|
||||||
|
for (std::size_t idx = 0; idx < mContent->getNumInputs(); idx++)
|
||||||
|
{
|
||||||
|
if (mContent->getInput(idx) == wire)
|
||||||
|
{
|
||||||
|
is_input = true;
|
||||||
|
connection_id = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t idx = 0; idx < mContent->getNumOutputs(); idx++)
|
||||||
|
{
|
||||||
|
if (mContent->getOutput(idx) == wire)
|
||||||
|
{
|
||||||
|
connection_id = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Point loc;
|
||||||
|
if (mContent->getGateType() == LogicGate::GateType::AND)
|
||||||
|
{
|
||||||
|
loc = LogicGatePrimitiveShapes::getAndGateConnectionLocation(is_input, connection_id);
|
||||||
|
}
|
||||||
|
else if (mContent->getGateType() == LogicGate::GateType::OR)
|
||||||
|
{
|
||||||
|
loc = LogicGatePrimitiveShapes::getOrGateConnectionLocation(is_input, connection_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
loc.move(mTransform.getLocation().getX(), mTransform.getLocation().getY());
|
||||||
|
return loc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void LogicGateNode::setContent(LogicGate* content)
|
void LogicGateNode::setContent(LogicGate* content)
|
||||||
{
|
{
|
||||||
mContent = content;
|
mContent = content;
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AbstractVisualNode.h"
|
#include "CircuitElementNode.h"
|
||||||
|
|
||||||
#include "CircleNode.h"
|
#include "CircleNode.h"
|
||||||
|
|
||||||
class LogicGate;
|
class LogicGate;
|
||||||
class PathNode;
|
class PathNode;
|
||||||
|
|
||||||
class LogicGateNode : public AbstractVisualNode
|
class LogicGateNode : public CircuitElementNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LogicGateNode(const Transform& transform);
|
LogicGateNode(const Transform& transform);
|
||||||
|
|
||||||
virtual ~LogicGateNode();
|
virtual ~LogicGateNode();
|
||||||
|
|
||||||
|
Point getConnectionLocation(Wire* wire) const override;
|
||||||
|
|
||||||
void setContent(LogicGate* content);
|
void setContent(LogicGate* content);
|
||||||
|
|
||||||
void update(SceneInfo* sceneInfo);
|
void update(SceneInfo* sceneInfo);
|
||||||
|
|
|
@ -5,7 +5,45 @@ std::string LogicGatePrimitiveShapes::getAndGateShape()
|
||||||
return "M4 8 h24 a16 16 0 0 1 0 32 h-24Z";
|
return "M4 8 h24 a16 16 0 0 1 0 32 h-24Z";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point LogicGatePrimitiveShapes::getAndGateConnectionLocation(bool isInput, std::size_t idx)
|
||||||
|
{
|
||||||
|
if (isInput)
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
return { 4.0, 18.66 };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { 4.0, 29.33 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {44.0, 24.0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string LogicGatePrimitiveShapes::getOrGateShape()
|
std::string LogicGatePrimitiveShapes::getOrGateShape()
|
||||||
{
|
{
|
||||||
return "M4 8 h16 q16 2 24 16 q-12 16 -24 16 h-16 q12 -16 0 -32Z";
|
return "M4 8 h16 q16 2 24 16 q-12 16 -24 16 h-16 q12 -16 0 -32Z";
|
||||||
|
}
|
||||||
|
|
||||||
|
Point LogicGatePrimitiveShapes::getOrGateConnectionLocation(bool isInput, std::size_t idx)
|
||||||
|
{
|
||||||
|
if (isInput)
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
return { 8.0, 18.66 };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { 8.0, 29.33 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { 44.0, 24.0 };
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Point.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class LogicGatePrimitiveShapes
|
class LogicGatePrimitiveShapes
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static Point getAndGateConnectionLocation(bool isInput, std::size_t idx);
|
||||||
|
|
||||||
static std::string getAndGateShape();
|
static std::string getAndGateShape();
|
||||||
|
|
||||||
|
static Point getOrGateConnectionLocation(bool isInput, std::size_t idx);
|
||||||
|
|
||||||
static std::string getOrGateShape();
|
static std::string getOrGateShape();
|
||||||
};
|
};
|
|
@ -3,7 +3,7 @@
|
||||||
#include "CircleNode.h"
|
#include "CircleNode.h"
|
||||||
|
|
||||||
TerminalNode::TerminalNode(const Transform& transform)
|
TerminalNode::TerminalNode(const Transform& transform)
|
||||||
: AbstractVisualNode(transform)
|
: CircuitElementNode(transform)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ void TerminalNode::createOrUpdateGeometry(SceneInfo*)
|
||||||
{
|
{
|
||||||
if (!mMarker)
|
if (!mMarker)
|
||||||
{
|
{
|
||||||
mMarker = std::make_unique<CircleNode>(Transform{}, 5);
|
mMarker = std::make_unique<CircleNode>(Transform{}, 3);
|
||||||
mMarker->setFillColor(Color(0, 0, 0));
|
mMarker->setFillColor(Color(0, 0, 0));
|
||||||
mMarker->setHasStrokeColor(false);
|
mMarker->setHasStrokeColor(false);
|
||||||
|
|
||||||
|
@ -33,3 +33,8 @@ void TerminalNode::update(SceneInfo* sceneInfo)
|
||||||
mContentDirty = false;
|
mContentDirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point TerminalNode::getConnectionLocation(Wire*) const
|
||||||
|
{
|
||||||
|
return mTransform.getLocation();
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AbstractVisualNode.h"
|
#include "CircuitElementNode.h"
|
||||||
|
|
||||||
#include "Terminal.h"
|
#include "Terminal.h"
|
||||||
|
|
||||||
class CircleNode;
|
class CircleNode;
|
||||||
|
|
||||||
class TerminalNode : public AbstractVisualNode
|
class TerminalNode : public CircuitElementNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TerminalNode(const Transform& transform);
|
TerminalNode(const Transform& transform);
|
||||||
|
|
||||||
|
Point getConnectionLocation(Wire* wire) const override;
|
||||||
|
|
||||||
void setContent(Terminal* terminal);
|
void setContent(Terminal* terminal);
|
||||||
|
|
||||||
void update(SceneInfo* sceneInfo) override;
|
void update(SceneInfo* sceneInfo) override;
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "WireNode.h"
|
||||||
|
|
||||||
|
#include "LineNode.h"
|
||||||
|
|
||||||
|
WireNode::WireNode(const Transform& transform)
|
||||||
|
: AbstractVisualNode(transform)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireNode::setContent(Wire* wire)
|
||||||
|
{
|
||||||
|
mContent = wire;
|
||||||
|
mContentDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireNode::setInputLocation(const Point& point)
|
||||||
|
{
|
||||||
|
if (mInputLocation != point)
|
||||||
|
{
|
||||||
|
mContentDirty = true;
|
||||||
|
mInputLocation = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireNode::setOutputLocation(const Point& point)
|
||||||
|
{
|
||||||
|
if (mOutputLocation != point)
|
||||||
|
{
|
||||||
|
mContentDirty = true;
|
||||||
|
mOutputLocation = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireNode::update(SceneInfo* sceneInfo)
|
||||||
|
{
|
||||||
|
if (mContentDirty)
|
||||||
|
{
|
||||||
|
createOrUpdateGeometry(sceneInfo);
|
||||||
|
mContentDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireNode::createOrUpdateGeometry(SceneInfo*)
|
||||||
|
{
|
||||||
|
if (!mLine)
|
||||||
|
{
|
||||||
|
auto loc = mOutputLocation;
|
||||||
|
loc.move(-mInputLocation.getX(), -mInputLocation.getY(), -mInputLocation.getZ());
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
|
||||||
|
if (loc.getY() == 0.0)
|
||||||
|
{
|
||||||
|
points = { loc };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto join0 = Point(loc.getX() * 3.0 / 4.0, 0.0);
|
||||||
|
auto join1 = Point(loc.getX() * 3.0 / 4.0, loc.getY());
|
||||||
|
points = { join0, join1 , loc};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mLine = std::make_unique<LineNode>(Transform(mInputLocation), points);
|
||||||
|
|
||||||
|
addChild(mLine.get());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,30 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class WireNode
|
#include "AbstractVisualNode.h"
|
||||||
{
|
|
||||||
|
|
||||||
|
#include "Wire.h"
|
||||||
|
|
||||||
|
class LineNode;
|
||||||
|
|
||||||
|
class WireNode : public AbstractVisualNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WireNode(const Transform& transform);
|
||||||
|
|
||||||
|
void setContent(Wire* wire);
|
||||||
|
|
||||||
|
void setInputLocation(const Point& point);
|
||||||
|
|
||||||
|
void setOutputLocation(const Point& point);
|
||||||
|
|
||||||
|
void update(SceneInfo* sceneInfo);
|
||||||
|
private:
|
||||||
|
void createOrUpdateGeometry(SceneInfo* sceneInfo);
|
||||||
|
Wire* mContent{ nullptr };
|
||||||
|
bool mContentDirty{ true };
|
||||||
|
|
||||||
|
Point mInputLocation;
|
||||||
|
Point mOutputLocation;
|
||||||
|
|
||||||
|
std::unique_ptr<LineNode> mLine;
|
||||||
};
|
};
|
|
@ -52,6 +52,7 @@ TEST_CASE(TestElectronicCircuit, "circuits")
|
||||||
circuit->addWire(std::move(wire1));
|
circuit->addWire(std::move(wire1));
|
||||||
circuit->addWire(std::move(wire2));
|
circuit->addWire(std::move(wire2));
|
||||||
circuit->addWire(std::move(wire3));
|
circuit->addWire(std::move(wire3));
|
||||||
|
circuit->addWire(std::move(wire4));
|
||||||
|
|
||||||
circuit->addInputTerminal(std::move(input0));
|
circuit->addInputTerminal(std::move(input0));
|
||||||
circuit->addInputTerminal(std::move(input1));
|
circuit->addInputTerminal(std::move(input1));
|
||||||
|
|
Loading…
Reference in a new issue