From 1759adf25aa43acd08578a96b42d743461c25435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Borna=20Rajkovi=C4=87?= Date: Tue, 7 Jun 2022 21:13:21 +0200 Subject: [PATCH] Moved connection determination to schema --- application.cpp | 2 +- comdel/display/schema_display.cpp | 58 ++++++++++---------------- comdel/domain/connection.cpp | 2 +- comdel/domain/connection.h | 5 ++- comdel/domain/schema.cpp | 68 +++++++++++++++++++++++++++++++ comdel/domain/schema.h | 23 ++++++++++- comdel/domain/schema_creator.cpp | 2 +- 7 files changed, 119 insertions(+), 41 deletions(-) diff --git a/application.cpp b/application.cpp index c5f0855..7a47e19 100644 --- a/application.cpp +++ b/application.cpp @@ -42,7 +42,7 @@ bool Application::loadLibrary(std::string &filename, std::ostream &errorOutput) if (library.has_value()) { libraryPath = filename; // on library load we create a new schema - schema = new domain::Schema(); + schema = new domain::Schema(library.value()); } else { errorOutput << "Failed creating library model" << std::endl; return false; diff --git a/comdel/display/schema_display.cpp b/comdel/display/schema_display.cpp index c6a12e3..6e85831 100644 --- a/comdel/display/schema_display.cpp +++ b/comdel/display/schema_display.cpp @@ -132,9 +132,13 @@ namespace display { auto instance = context.pin->getComponentInstance(); auto &pin = context.pin->getPin(); - auto busInstances = getAvailableConnectionBusses(instance, pin); + auto availableConnections = schema->availableConnections(instance->name, pin.getName(), true); - for (auto &bus: busInstances) { + for(auto &connection: availableConnections) { + if(connection.type != domain::ConnectionEntry::BUS) { + continue; + } + auto bus = connection.busInstance.value(); if(buses[bus->name] == nullptr) { continue; } @@ -163,9 +167,11 @@ namespace display { } } - auto pinInstances = getAvailableConnectionPins(instance, pin); - - for (auto &pinInstance: pinInstances) { + for (auto &connection: availableConnections) { + if(connection.type != domain::ConnectionEntry::COMPONENT) { + continue; + } + auto pinInstance = domain::ConnectionComponent{connection.componentInstance.value()->name, connection.pin.value().getName()}; auto rect = pins[pinInstance]->boundingRect(); rect.setX(pins[pinInstance]->scenePos().x()); rect.setY(pins[pinInstance]->scenePos().y()); @@ -218,9 +224,13 @@ namespace display { void Schema::showConnectable(Pin *domainPin) { auto &pin = domainPin->getPin(); - auto busInstances = getAvailableConnectionBusses(domainPin->getComponentInstance(), domainPin->getPin()); + auto availableConnections = schema->availableConnections(domainPin->getComponentInstance()->name, pin.getName(), true); - for (auto bus: busInstances) { + for(auto &connection: availableConnections) { + if(connection.type != domain::ConnectionEntry::BUS) { + continue; + } + auto bus = connection.busInstance.value(); auto &group = buses[bus->name]; if(group == nullptr) { continue; @@ -238,10 +248,11 @@ namespace display { scene.addItem(rect); } - std::vector pinInstances = getAvailableConnectionPins( - domainPin->getComponentInstance(), domainPin->getPin()); - - for (auto &pinInstance: pinInstances) { + for (auto &connection: availableConnections) { + if(connection.type != domain::ConnectionEntry::COMPONENT) { + continue; + } + auto pinInstance = domain::ConnectionComponent{connection.componentInstance.value()->name, connection.pin.value().getName()}; auto &instance = pins[pinInstance]; auto rect = new QGraphicsRectItem(instance->boundingRect()); rect->setPen(selectedPen); @@ -258,31 +269,6 @@ namespace display { } - std::vector - Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) { - std::vector instances; - for (const auto &bus: schema->busInstances) { - if (library->hasConnection(domain::ConnectionComponent{instance->component.getName(), pin.getName()}, - bus->bus.getName())) { - instances.push_back(bus.get()); - } - } - return instances; - } - - std::vector - Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) { - std::vector instances; - domain::ConnectionComponent source{instance->component.getName(), pin.getName()}; - for (const auto &entry: pins) { - std::string name = components[entry.first.component]->getComponentInstance()->component.getName(); - if (library->hasConnection(source, domain::ConnectionComponent{name, entry.first.pin})) { - instances.push_back(entry.first); - } - } - return instances; - } - std::vector Schema::populateAttributes(std::vector& attributes) { std::vector instanceAttributes; diff --git a/comdel/domain/connection.cpp b/comdel/domain/connection.cpp index c42d09b..b6fb517 100644 --- a/comdel/domain/connection.cpp +++ b/comdel/domain/connection.cpp @@ -16,7 +16,7 @@ namespace domain { return second; } - std::string Connection::getBus() { + std::string &Connection::getBus() { return bus; } diff --git a/comdel/domain/connection.h b/comdel/domain/connection.h index a0a49c4..781f212 100644 --- a/comdel/domain/connection.h +++ b/comdel/domain/connection.h @@ -53,12 +53,15 @@ namespace domain { bool isConnecting(ConnectionComponent first, ConnectionComponent second); + bool operator==(const Connection& connection) { + return (first == connection.first && bus == connection.bus && second == connection.second); + } ConnectionComponent getComponent(); std::optional getSecondComponent(); - std::string getBus(); + std::string &getBus(); std::vector& getAttributes(); diff --git a/comdel/domain/schema.cpp b/comdel/domain/schema.cpp index 810a961..2bdf9a8 100644 --- a/comdel/domain/schema.cpp +++ b/comdel/domain/schema.cpp @@ -39,4 +39,72 @@ namespace domain { return nullptr; } + std::vector Schema::availableConnections(std::string instanceName, std::string pinName, bool onlyConnectable) { + std::vector entries; + + auto instance = getComponentInstance(instanceName); + + ConnectionComponent connectionComponent{instance->component.getName(), pinName}; + for(auto &conn: library.getConnections()) { + if(conn.isConnecting(connectionComponent)) { + // if bus connection + if(library.getBus(conn.getBus()).getType() == Bus::REGULAR) { + for(auto& bus: busInstances) { + if(bus->bus.getName() == conn.getBus()) { + ConnectionEntry entry{ConnectionEntry::BUS, bus.get(), nullopt, nullopt, conn}; + entries.emplace_back(entry); + } + } + } else { + for(auto& component: componentInstances) { + for(auto& pin: component->component.getPins()) { + if(conn.isConnecting(connectionComponent, {component->component.getName(), pin.getName()})) { + ConnectionEntry entry{ConnectionEntry::COMPONENT, nullopt, component.get(), pin, conn}; + entries.emplace_back(entry); + } + } + } + } + } + } + + if(onlyConnectable) { + entries.erase( + std::remove_if( + entries.begin(), + entries.end(), + [this, instance](ConnectionEntry &entry) { + auto& bus = this->library.getBus(entry.connection.getBus()); + // we allow duplicates of single automatic connections + if(bus.getType() == Bus::SINGLE_AUTOMATIC) { + return false; + } + for(auto& conn: this->connections) { + if(conn->connection == entry.connection) { + if(bus.getType() == Bus::REGULAR) { + if(entry.busInstance.value()->bus.getName() == conn->connection.getBus()) { + return true; + } + } else { + auto *directInstance = dynamic_cast(conn.get()); + ComponentInstance* secondInstance; + if(directInstance->instance == instance) { + secondInstance = directInstance->secondInstance; + } else { + secondInstance = directInstance->instance; + } + + return entry.componentInstance == secondInstance; + } + } + } + return false; + }), + entries.end() + ); + } + + return entries; + } + } // namespace domain diff --git a/comdel/domain/schema.h b/comdel/domain/schema.h index da72344..ef2d9f3 100644 --- a/comdel/domain/schema.h +++ b/comdel/domain/schema.h @@ -3,14 +3,33 @@ #include "connection_instance.h" #include "instance.h" +#include "library.h" +#include #include namespace domain { + struct ConnectionEntry { + enum Type { + BUS, + COMPONENT + }; + + Type type; + + std::optional busInstance; + std::optional componentInstance; + std::optional pin; + + Connection connection; + }; + class Schema { + private: + Library library; public: - Schema() = default; + Schema(Library library): library(std::move(library)) {} std::vector> busInstances; std::vector> componentInstances; @@ -21,6 +40,8 @@ namespace domain { ComponentInstance *getComponentInstance(std::string &name); bool hasConnection(string &component, string &pin); ConnectionInstance *getConnection(string &component, string &pin); + + std::vector availableConnections(std::string instance, std::string pin, bool onlyConnectable); }; } // namespace domain diff --git a/comdel/domain/schema_creator.cpp b/comdel/domain/schema_creator.cpp index 7f57c37..aa8c1cf 100644 --- a/comdel/domain/schema_creator.cpp +++ b/comdel/domain/schema_creator.cpp @@ -866,7 +866,7 @@ namespace domain { Schema *SchemaCreator::loadSchema(SchemaNode node, Library &library) { - auto *schema = new Schema(); + auto *schema = new Schema(library); for (auto &instance: node.instances) { if (library.hasComponent(instance.component.value)) {