connectInterfaces function
- InterfaceReference<
PairInterface> intf1, - InterfaceReference<
PairInterface> intf2, { - String? intf1PathNewName,
- String? intf2PathNewName,
- bool allowIntf1PathUniquification = true,
- bool allowIntf2PathUniquification = true,
- SameModuleConnectionType? sameModuleConnectionType,
- Set<
String> ? exceptPorts,
Connects intf1 to intf2, creating all necessary ports through the
hierarchy.
If intf1PathNewName or intf2PathNewName are provided, then it will
prefer to name new interfaces with those names. If
allowIntf1PathUniquification or allowIntf2PathUniquification are
false, then the interface names will not be uniquified on those paths.
Uniquification also respects BridgeModule.allowUniquification at each
level. The exceptPorts parameter is an optional set of strings
representing the logical port names to be excluded.
When intf1 and intf2 are on the same module,
sameModuleConnectionType selects whether their external-facing
(SameModuleConnectionType.loopback) or internal-facing
(SameModuleConnectionType.passthrough) interfaces are connected. If it is
omitted, loopback behavior is used for backwards compatibility.
Implementation
void connectInterfaces(
InterfaceReference intf1,
InterfaceReference intf2, {
String? intf1PathNewName,
String? intf2PathNewName,
bool allowIntf1PathUniquification = true,
bool allowIntf2PathUniquification = true,
SameModuleConnectionType? sameModuleConnectionType,
Set<String>? exceptPorts,
// TODO(mkorbel): finish these,
// possibly wont be needed for connectInterfaces
// String Function(String logical, String? physical)? portUniquify1,
// String Function(String logical, String? physical)? portUniquify2,
}) {
if (intf1.module.hasBuilt || intf2.module.hasBuilt) {
throw RohdBridgeException('Cannot connect interfaces after build.');
}
final intf1Instance = intf1.module;
final intf2Instance = intf2.module;
if (sameModuleConnectionType != null && intf1Instance != intf2Instance) {
throw RohdBridgeException(
'SameModuleConnectionType should only be provided when connecting '
'interfaces on the same module, but $intf1 is on $intf1Instance and '
'$intf2 is on $intf2Instance.');
}
if (intf1Instance == intf2Instance) {
intf1.connectTo(
intf2,
sameModuleConnectionType: sameModuleConnectionType,
exceptPorts: exceptPorts,
);
return;
}
if (intf1.role != intf2.role) {
// up and down case
final commonParent = findCommonParent(intf1Instance, intf2Instance);
if (commonParent == intf1Instance || commonParent == intf2Instance) {
throw RohdBridgeException(
'Vertical connections should have the same role, but the common'
' parent of $intf1Instance and $intf2Instance is $commonParent,'
' but with mismatched roles ${intf1.role} and ${intf2.role},'
' respectively.');
}
if (commonParent == null) {
throw RohdBridgeException('No common parent found between'
' $intf1Instance and $intf2Instance');
}
final unusedPortsOnDriver = intf1.getUnmappedInterfacePorts();
final unusedPortOnReceiver = intf2.getUnmappedInterfacePorts();
if (exceptPorts != null && exceptPorts.isNotEmpty) {
unusedPortsOnDriver.removeWhere(exceptPorts.contains);
unusedPortOnReceiver.removeWhere(exceptPorts.contains);
}
if (unusedPortsOnDriver.isNotEmpty || unusedPortOnReceiver.isNotEmpty) {
var errorString = 'Cannot connect interface ${intf1.name} '
'at ${intf1Instance.name} to interface '
'${intf2.name} at ${intf2Instance.name} '
'because there are unmapped ports';
if (unusedPortsOnDriver.isNotEmpty) {
errorString += ' : $unusedPortsOnDriver on driver';
}
if (unusedPortOnReceiver.isNotEmpty) {
errorString += ' : $unusedPortOnReceiver on receiver';
}
throw RohdBridgeException(errorString);
}
final intf1Top =
(commonParent.getHierarchyDownTo(intf1Instance)![1] as BridgeModule)
.pullUpInterface(
intf1,
newIntfName: intf1PathNewName,
allowIntfUniquification: allowIntf1PathUniquification,
exceptPorts: exceptPorts,
);
final intf2Top =
(commonParent.getHierarchyDownTo(intf2Instance)![1] as BridgeModule)
.pullUpInterface(
intf2,
newIntfName: intf2PathNewName,
allowIntfUniquification: allowIntf2PathUniquification,
exceptPorts: exceptPorts,
);
intf1Top.connectTo(
intf2Top,
sameModuleConnectionType: sameModuleConnectionType,
exceptPorts: exceptPorts,
);
} else if (intf1.role == intf2.role) {
final intf1ToIntf2Path = intf1Instance.getHierarchyDownTo(intf2Instance);
final intf2ToIntf1Path = intf2Instance.getHierarchyDownTo(intf1Instance);
final intf1ContainsIntf2 = intf1ToIntf2Path != null;
final intf2ContainsIntf1 = intf2ToIntf1Path != null;
if (intf1ContainsIntf2) {
intf1.module._pullUpInterfaceAndConnect(
intf2,
newIntfName: intf2PathNewName,
allowIntfUniquification: allowIntf2PathUniquification,
topToConnect: intf1,
exceptPorts: exceptPorts,
);
} else if (intf2ContainsIntf1) {
intf2.module._pullUpInterfaceAndConnect(
intf1,
newIntfName: intf1PathNewName,
allowIntfUniquification: allowIntf1PathUniquification,
topToConnect: intf2,
exceptPorts: exceptPorts,
);
} else {
// e.g. feed-through
throw RohdBridgeException(
'Unhandled directionality and hierarchy of driver and receiver.');
}
} else {
throw RohdBridgeException(
'Unknown directionality and hierarchy of driver and receiver.');
}
}