#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(library.getBus(conn.getBus()).getType() == Bus::REGULAR) { for(auto& bus: busInstances) { if(bus->bus.getName() == conn.getBus()) { entries.push_back({ConnectionEntry::BUS, bus.get(), nullopt, nullopt, conn}); } } } 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) { auto busConnection = dynamic_cast(conn.get()); if(busConnection->instance == instance && busConnection->bus == entry.busInstance.value()) { return true; } } else { auto directConnection = dynamic_cast(conn.get()); if(directConnection->instance == instance && directConnection->secondInstance == entry.componentInstance.value() || directConnection->secondInstance == instance && directConnection->instance == entry.componentInstance.value()) { return true; } } } } return false; }), entries.end() ); } return entries; } } // namespace domain