116 lines
5.0 KiB
C++
116 lines
5.0 KiB
C++
#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<ConnectionInstance*> Schema::getConnections(string &component, string &pin) {
|
|
std::vector<ConnectionInstance*> pinConnections;
|
|
for (auto &conn: connections) {
|
|
if (conn->instance->name == component && conn->connection.getComponent().pin == pin) {
|
|
pinConnections.push_back(conn.get());
|
|
}
|
|
auto dirConn = dynamic_cast<DirectConnectionInstance *>(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<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(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<BusConnectionInstance*>(conn.get());
|
|
if(busConnection->instance == instance && busConnection->bus == entry.busInstance.value()) {
|
|
return true;
|
|
}
|
|
} else {
|
|
auto directConnection = dynamic_cast<DirectConnectionInstance*>(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
|