Moved connection determination to schema
This commit is contained in:
parent
1ec8b10ef5
commit
1759adf25a
|
@ -42,7 +42,7 @@ bool Application::loadLibrary(std::string &filename, std::ostream &errorOutput)
|
||||||
if (library.has_value()) {
|
if (library.has_value()) {
|
||||||
libraryPath = filename;
|
libraryPath = filename;
|
||||||
// on library load we create a new schema
|
// on library load we create a new schema
|
||||||
schema = new domain::Schema();
|
schema = new domain::Schema(library.value());
|
||||||
} else {
|
} else {
|
||||||
errorOutput << "Failed creating library model" << std::endl;
|
errorOutput << "Failed creating library model" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -132,9 +132,13 @@ namespace display {
|
||||||
auto instance = context.pin->getComponentInstance();
|
auto instance = context.pin->getComponentInstance();
|
||||||
auto &pin = context.pin->getPin();
|
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) {
|
if(buses[bus->name] == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -163,9 +167,11 @@ namespace display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pinInstances = getAvailableConnectionPins(instance, pin);
|
for (auto &connection: availableConnections) {
|
||||||
|
if(connection.type != domain::ConnectionEntry::COMPONENT) {
|
||||||
for (auto &pinInstance: pinInstances) {
|
continue;
|
||||||
|
}
|
||||||
|
auto pinInstance = domain::ConnectionComponent{connection.componentInstance.value()->name, connection.pin.value().getName()};
|
||||||
auto rect = pins[pinInstance]->boundingRect();
|
auto rect = pins[pinInstance]->boundingRect();
|
||||||
rect.setX(pins[pinInstance]->scenePos().x());
|
rect.setX(pins[pinInstance]->scenePos().x());
|
||||||
rect.setY(pins[pinInstance]->scenePos().y());
|
rect.setY(pins[pinInstance]->scenePos().y());
|
||||||
|
@ -218,9 +224,13 @@ namespace display {
|
||||||
void Schema::showConnectable(Pin *domainPin) {
|
void Schema::showConnectable(Pin *domainPin) {
|
||||||
auto &pin = domainPin->getPin();
|
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];
|
auto &group = buses[bus->name];
|
||||||
if(group == nullptr) {
|
if(group == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -238,10 +248,11 @@ namespace display {
|
||||||
scene.addItem(rect);
|
scene.addItem(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<domain::ConnectionComponent> pinInstances = getAvailableConnectionPins(
|
for (auto &connection: availableConnections) {
|
||||||
domainPin->getComponentInstance(), domainPin->getPin());
|
if(connection.type != domain::ConnectionEntry::COMPONENT) {
|
||||||
|
continue;
|
||||||
for (auto &pinInstance: pinInstances) {
|
}
|
||||||
|
auto pinInstance = domain::ConnectionComponent{connection.componentInstance.value()->name, connection.pin.value().getName()};
|
||||||
auto &instance = pins[pinInstance];
|
auto &instance = pins[pinInstance];
|
||||||
auto rect = new QGraphicsRectItem(instance->boundingRect());
|
auto rect = new QGraphicsRectItem(instance->boundingRect());
|
||||||
rect->setPen(selectedPen);
|
rect->setPen(selectedPen);
|
||||||
|
@ -258,31 +269,6 @@ namespace display {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<domain::BusInstance *>
|
|
||||||
Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) {
|
|
||||||
std::vector<domain::BusInstance *> 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<domain::ConnectionComponent>
|
|
||||||
Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) {
|
|
||||||
std::vector<domain::ConnectionComponent> 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<domain::InstanceAttribute> Schema::populateAttributes(std::vector<domain::Attribute>& attributes) {
|
std::vector<domain::InstanceAttribute> Schema::populateAttributes(std::vector<domain::Attribute>& attributes) {
|
||||||
std::vector<domain::InstanceAttribute> instanceAttributes;
|
std::vector<domain::InstanceAttribute> instanceAttributes;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace domain {
|
||||||
return second;
|
return second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Connection::getBus() {
|
std::string &Connection::getBus() {
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,15 @@ namespace domain {
|
||||||
|
|
||||||
bool isConnecting(ConnectionComponent first, ConnectionComponent second);
|
bool isConnecting(ConnectionComponent first, ConnectionComponent second);
|
||||||
|
|
||||||
|
bool operator==(const Connection& connection) {
|
||||||
|
return (first == connection.first && bus == connection.bus && second == connection.second);
|
||||||
|
}
|
||||||
|
|
||||||
ConnectionComponent getComponent();
|
ConnectionComponent getComponent();
|
||||||
|
|
||||||
std::optional<ConnectionComponent> getSecondComponent();
|
std::optional<ConnectionComponent> getSecondComponent();
|
||||||
|
|
||||||
std::string getBus();
|
std::string &getBus();
|
||||||
|
|
||||||
std::vector<Attribute>& getAttributes();
|
std::vector<Attribute>& getAttributes();
|
||||||
|
|
||||||
|
|
|
@ -39,4 +39,72 @@ namespace domain {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ConnectionEntry> Schema::availableConnections(std::string instanceName, std::string pinName, bool onlyConnectable) {
|
||||||
|
std::vector<ConnectionEntry> 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<DirectConnectionInstance*>(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
|
} // namespace domain
|
||||||
|
|
|
@ -3,14 +3,33 @@
|
||||||
|
|
||||||
#include "connection_instance.h"
|
#include "connection_instance.h"
|
||||||
#include "instance.h"
|
#include "instance.h"
|
||||||
|
#include "library.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
|
struct ConnectionEntry {
|
||||||
|
enum Type {
|
||||||
|
BUS,
|
||||||
|
COMPONENT
|
||||||
|
};
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
std::optional<BusInstance*> busInstance;
|
||||||
|
std::optional<ComponentInstance*> componentInstance;
|
||||||
|
std::optional<Pin> pin;
|
||||||
|
|
||||||
|
Connection connection;
|
||||||
|
};
|
||||||
|
|
||||||
class Schema {
|
class Schema {
|
||||||
|
private:
|
||||||
|
Library library;
|
||||||
public:
|
public:
|
||||||
Schema() = default;
|
Schema(Library library): library(std::move(library)) {}
|
||||||
|
|
||||||
std::vector<shared_ptr<BusInstance>> busInstances;
|
std::vector<shared_ptr<BusInstance>> busInstances;
|
||||||
std::vector<shared_ptr<ComponentInstance>> componentInstances;
|
std::vector<shared_ptr<ComponentInstance>> componentInstances;
|
||||||
|
@ -21,6 +40,8 @@ namespace domain {
|
||||||
ComponentInstance *getComponentInstance(std::string &name);
|
ComponentInstance *getComponentInstance(std::string &name);
|
||||||
bool hasConnection(string &component, string &pin);
|
bool hasConnection(string &component, string &pin);
|
||||||
ConnectionInstance *getConnection(string &component, string &pin);
|
ConnectionInstance *getConnection(string &component, string &pin);
|
||||||
|
|
||||||
|
std::vector<ConnectionEntry> availableConnections(std::string instance, std::string pin, bool onlyConnectable);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -866,7 +866,7 @@ namespace domain {
|
||||||
|
|
||||||
|
|
||||||
Schema *SchemaCreator::loadSchema(SchemaNode node, Library &library) {
|
Schema *SchemaCreator::loadSchema(SchemaNode node, Library &library) {
|
||||||
auto *schema = new Schema();
|
auto *schema = new Schema(library);
|
||||||
|
|
||||||
for (auto &instance: node.instances) {
|
for (auto &instance: node.instances) {
|
||||||
if (library.hasComponent(instance.component.value)) {
|
if (library.hasComponent(instance.component.value)) {
|
||||||
|
|
Loading…
Reference in New Issue