From 74ff0f2d5282adf5ce36c9faeb2a5e85c358bf23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sun, 21 Jan 2018 18:22:07 +0100 Subject: Implement even more parts of the schema --- qtmips_gui/coreview/connection.cpp | 52 +++++++++++++++++++++++++++++++++++++- qtmips_gui/coreview/connection.h | 12 ++++++++- qtmips_gui/coreview/logicblock.cpp | 8 ++++-- qtmips_gui/coreview/registers.cpp | 26 +++++++++---------- 4 files changed, 81 insertions(+), 17 deletions(-) (limited to 'qtmips_gui/coreview') diff --git a/qtmips_gui/coreview/connection.cpp b/qtmips_gui/coreview/connection.cpp index 3355eed..31d93e5 100644 --- a/qtmips_gui/coreview/connection.cpp +++ b/qtmips_gui/coreview/connection.cpp @@ -1,4 +1,5 @@ #include "connection.h" +#include #include using namespace coreview; @@ -14,6 +15,10 @@ void Connector::setPos(qreal x, qreal y) { emit updated(vector()); } +void Connector::setPos(const QPointF &p) { + setPos(p.x(), p.y()); +} + enum Connector::Axis Connector::axis() const { return ax; } @@ -42,6 +47,7 @@ QLineF Connector::vector() const { case AX_MXY: return QLineF(p, p + QPoint(1, -1)); } + throw QTMIPS_EXCEPTION(Sanity, "Connection::vector() unknown axes set", QString::number(ax)); } Connection::Connection(const Connector *a, const Connector *b) : QGraphicsObject(nullptr) { @@ -134,13 +140,23 @@ Bus::Bus(const Connector *start, const Connector *end, unsigned width) : Connect pen_width = width; } +Bus::~Bus() { + for (int i = 0; i < conns.size(); i++) + delete conns[i].c; +} + +void Bus::setAxes(QVector axes) { + Connection::setAxes(axes); + conns_update(); +} + const Connector *Bus::new_connector(qreal x, qreal y, enum Connector::Axis axis) { Connector *c = new Connector(axis); conns.append({ .c = c, .p = QPoint(x, y) }); - // TODO update positions + conns_update(); return c; } @@ -148,6 +164,40 @@ const Connector *Bus::new_connector(const QPointF &p, enum Connector::Axis axis) return new_connector(p.x(), p.y(), axis); } +// Calculate closes point to given line. We do it by calculating rectangular intersection between given line and imaginary line crossing given point. +static qreal cu_closest(const QLineF &l, const QPointF &p, QPointF *intersec) { + // Closest point is on normal vector + QLineF normal = l.normalVector(); + // Now move normal vector to 0,0 and then to p + QLineF nline = normal.translated(-normal.p1()).translated(p); + // And now found intersection + SANITY_ASSERT(l.intersect(nline, intersec) != QLineF::NoIntersection, "We are calculating intersection with normal vector and that should always have intersection"); + // Now check if that point belongs to given line + // We know that this is intersection so just check if we are not outside of line limits + // TODO replace intersec if it's outside of given line with one of corner points + + return (p - *intersec).manhattanLength(); // return length from each other +} + +void Bus::conns_update() { + for (int i = 0; i < conns.size(); i++) { + QPointF closest; + qreal closest_range = 0; // Just to suppress warning. On first check the closest is null so we set it later on + + QPointF inter; + qreal range; + for (int y = 0; y < (points.size() - 1); y++) { + range = cu_closest(QLineF(points[y], points[y+1]), QPointF(conns[i].p), &inter); + if (closest.isNull() || closest_range > range) { + closest = inter; + closest_range = range; + } + } + + conns[i].c->setPos(closest); + } +} + Signal::Signal(const Connector *start, const Connector *end) : Connection(start, end) { color = QColor(0, 0, 255); } diff --git a/qtmips_gui/coreview/connection.h b/qtmips_gui/coreview/connection.h index 88ad1da..fa40d95 100644 --- a/qtmips_gui/coreview/connection.h +++ b/qtmips_gui/coreview/connection.h @@ -20,6 +20,7 @@ public: Connector(enum Axis axis = AX_X); void setPos(qreal x, qreal y); + void setPos(const QPointF&); enum Axis axis() const; qreal x() const; @@ -48,7 +49,7 @@ public: void setHasText(bool has); void setText(QString val); - void setAxes(QVector); + virtual void setAxes(QVector); private slots: void moved_start(QLineF); @@ -71,6 +72,9 @@ protected: class Bus : public Connection { public: Bus(const Connector *start, const Connector *end, unsigned width = 4); + ~Bus(); + + void setAxes(QVector); // This creates connector snapped to closes point to x,y that is on bus const Connector *new_connector(qreal x, qreal y, enum Connector::Axis = Connector::AX_X); @@ -82,6 +86,7 @@ protected: QPointF p; }; QVector conns; + void conns_update(); // TODO because of this we have to overload setAxis function and update that in there }; @@ -90,6 +95,11 @@ public: Signal(const Connector *start, const Connector *end); }; +#define CON_AX_X (coreview::Connector::AX_X) +#define CON_AX_Y (coreview::Connector::AX_Y) +#define CON_AX_XY (coreview::Connector::AX_XY) +#define CON_AX_MXY (coreview::Connector::AX_MXY) + #define CON_AXIS_X(Y) QLineF(QPointF(0, Y), QPointF(1, Y)) #define CON_AXIS_Y(X) QLineF(QPointF(X, 0), QPointF(X, 1)) diff --git a/qtmips_gui/coreview/logicblock.cpp b/qtmips_gui/coreview/logicblock.cpp index 2e74a77..35ff0c4 100644 --- a/qtmips_gui/coreview/logicblock.cpp +++ b/qtmips_gui/coreview/logicblock.cpp @@ -91,7 +91,11 @@ const Connector *LogicBlock::new_connector(qreal x, qreal y) { QPointF LogicBlock::con_pos(qreal x, qreal y) { qreal px, py; - px = (box.right() - GAP) * x + (GAP * sign(x)); - py = (box.bottom()/2 - GAP) * (y + 1) + (GAP * sign(y)); + px = (box.right() - GAP) * x; + py = (box.bottom()/2 - GAP) * (y + 1) + GAP; + if (fabs(x) == 1) + px += GAP * sign(x); + if (fabs(y) == 1) + py += GAP * sign(y); return QPointF(px, py); } diff --git a/qtmips_gui/coreview/registers.cpp b/qtmips_gui/coreview/registers.cpp index 9a4fcff..2b1c1b5 100644 --- a/qtmips_gui/coreview/registers.cpp +++ b/qtmips_gui/coreview/registers.cpp @@ -10,12 +10,12 @@ using namespace coreview; ////////////////////// Registers::Registers() : QGraphicsObject(nullptr), name("Registers", this) { - con_read1 = new Connector(Connector::AX_Y); - con_read1_reg = new Connector(Connector::AX_Y); - con_read2 = new Connector(Connector::AX_Y); - con_read2_reg = new Connector(Connector::AX_Y); - con_write = new Connector(Connector::AX_Y); - con_write_reg = new Connector(Connector::AX_Y); + con_read1 = new Connector(Connector::AX_X); + con_read1_reg = new Connector(Connector::AX_X); + con_read2 = new Connector(Connector::AX_X); + con_read2_reg = new Connector(Connector::AX_X); + con_write = new Connector(Connector::AX_X); + con_write_reg = new Connector(Connector::AX_X); con_ctl_write = new Connector(Connector::AX_Y); // TODO do we want to have any hooks on real registers? @@ -52,14 +52,14 @@ void Registers::paint(QPainter *painter, const QStyleOptionGraphicsItem *option void Registers::setPos(qreal x, qreal y) { QGraphicsObject::setPos(x, y); - con_read1_reg->setPos(x + 30, y + HEIGHT); - con_read2_reg->setPos(x + 40, y + HEIGHT); - con_read1->setPos(x + 60, y + HEIGHT); - con_read2->setPos(x + 70, y + HEIGHT); + con_read1_reg->setPos(x, y + 10); + con_read2_reg->setPos(x, y + 30); + con_read1->setPos(x + WIDTH, y + 10); + con_read2->setPos(x + WIDTH, y + 30); - con_write_reg->setPos(x + WIDTH - 40, y + HEIGHT); - con_write->setPos(x + WIDTH - 30, y + HEIGHT); - con_ctl_write->setPos(x + WIDTH - 20, y + HEIGHT); + con_write_reg->setPos(x + WIDTH/2, y); + con_write->setPos(x, y + HEIGHT - 10); + con_ctl_write->setPos(x, y + HEIGHT - 20); } const Connector *Registers::connector_read1() const { -- cgit v1.2.3