#include "schema.h" namespace domain { bool Schema::hasConnection(string &component, string &pin) { return getConnection(component, pin) != nullptr; } ConnectionInstance *Schema::getConnection(string &component, string &pin) { auto pinConnections = getConnections(component, pin); if(pinConnections.empty()) { return nullptr; } else { return pinConnections[0]; } } std::vector Schema::getConnections(string &component, string &pin) { std::vector pinConnections; for (auto &conn: connections) { if (conn->instance->name == component && conn->connection.getComponent().pin == pin) { pinConnections.push_back(conn.get()); } auto dirConn = dynamic_cast(conn.get()); if (dirConn != nullptr) { if (dirConn->secondInstance->name == component && conn->connection.getSecondComponent()->pin == pin) { pinConnections.push_back(conn.get()); } } } return pinConnections; } BusInstance *Schema::getBusInstance(string &name) { for (auto &instance: busInstances) { if (instance->name == name) { return instance.get(); } } return nullptr; } ComponentInstance *Schema::getComponentInstance(string &name) { for (auto &instance: componentInstances) { if (instance->name == name) { return instance.get(); } } 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