Changeset 254:4111d8583c56 in finroc_tools_finstruct-java


Ignore:
Timestamp:
08.06.2017 03:33:29 (20 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Message:

Makes finstruct support new Finroc 17 features: type conversion, and connector objects with options in particular. Adapts to changes in dependencies.

Files:
1 added
19 edited

Legend:

Unmodified
Added
Removed
  • Finstruct.java

    r243 r254  
    260260 
    261261        // settings menu 
    262         miAllowDirectConnecting = new JCheckBoxMenuItem("Allow direct connecting of ports across component boundaries (deprecated)"); 
     262        miAllowDirectConnecting = new JCheckBoxMenuItem("Allow direct connecting of ports across component boundaries"); 
    263263        miAllowDirectConnecting.setMnemonic(KeyEvent.VK_A); 
     264        miAllowDirectConnecting.setEnabled(true); 
    264265        getSettingsMenu().add(miAllowDirectConnecting); 
    265266        menuBar.setVisible(true); 
  • FinstructConnectionPanel.java

    r249 r254  
    2626import java.awt.Graphics; 
    2727import java.awt.Point; 
     28import java.awt.Rectangle; 
    2829import java.awt.event.ActionEvent; 
    2930import java.awt.event.MouseEvent; 
     
    4849import org.finroc.core.port.AbstractPort; 
    4950import org.finroc.core.port.ThreadLocalCache; 
    50 import org.finroc.core.port.net.NetPort; 
    51 import org.finroc.core.portdatabase.FinrocTypeInfo; 
     51import org.finroc.core.remote.Definitions; 
    5252import org.finroc.core.remote.HasUid; 
    5353import org.finroc.core.remote.ModelNode; 
    5454import org.finroc.core.remote.PortWrapper; 
     55import org.finroc.core.remote.RemoteConnector; 
    5556import org.finroc.core.remote.RemoteFrameworkElement; 
    5657import org.finroc.core.remote.RemotePort; 
    5758import org.finroc.core.remote.RemoteRuntime; 
     59import org.finroc.core.remote.RemoteUriConnector; 
     60import org.finroc.tools.finstruct.SmartConnecting.MayConnectResult; 
    5861import org.finroc.tools.finstruct.actions.AddPortsToInterfaceAction; 
    5962import org.finroc.tools.finstruct.actions.CompositeAction; 
     63import org.finroc.tools.finstruct.actions.ConnectAction; 
    6064import org.finroc.tools.finstruct.actions.FinstructAction; 
     65import org.finroc.tools.finstruct.dialogs.CreateConnectorOptionsDialog; 
    6166import org.finroc.tools.gui.ConnectionPanel; 
    6267import org.finroc.tools.gui.ConnectorIcon; 
     
    6570import org.rrlib.logging.Log; 
    6671import org.rrlib.logging.LogLevel; 
     72import org.rrlib.serialization.rtti.DataTypeBase; 
    6773 
    6874/** 
     
    8591    private final JMenuItem miOpenInNewWindow; 
    8692 
    87     /** Temporary storage for edge destinations - used only by AWT Thread for painting connections */ 
    88     private final ArrayList<AbstractPort> tempDestinationList = new ArrayList<AbstractPort>(); 
    89  
    9093    /** Temporary storage hypotheticalConnections - used only by AWT Thread */ 
    9194    private final ArrayList<RemotePort> tempConnectList1 = new ArrayList<RemotePort>(); 
    9295    private final ArrayList<ModelNode> tempConnectList2 = new ArrayList<ModelNode>(); 
     96    private final ArrayList<RemoteConnector> tempConnectorList = new ArrayList<RemoteConnector>(); 
    9397 
    9498    /** More colors */ 
     
    96100    public static final Color rootViewColor = new Color(211, 211, 211); 
    97101    public static final Color inactiveTextColor = new Color(160, 160, 160); 
     102    public static final ConnectorIcon.IconColor errorColor = connectionPartnerMissingColor; 
     103    public static final ConnectorIcon.IconColor connectorNoConversion = connectedColor; 
     104    public static final Color connectorImplicitConversion = new Color(80, 200, 30); 
     105    public static final Color connectorExplicitConversion = new Color(160, 230, 30); 
     106    public static final Color connectorDeprecatedConversion = new Color(230, 140, 30); 
     107    public static final Color connectorNetwork = new Color(40, 40, 200); 
     108 
     109    public static final ConnectorIcon.IconColor portSelected20 = createConnectionCandidateColor(0.2); 
     110    public static final ConnectorIcon.IconColor portSelected40 = createConnectionCandidateColor(0.4); 
     111    public static final ConnectorIcon.IconColor portSelected60 = createConnectionCandidateColor(0.6); 
     112    public static final ConnectorIcon.IconColor portSelected80 = createConnectionCandidateColor(0.8); 
     113 
     114    public static final ConnectorIcon.IconColor[] candidatePortRatingColors = new ConnectorIcon.IconColor[] { 
     115        defaultColor, 
     116        portSelected20, 
     117        portSelected40, 
     118        portSelected60, 
     119        portSelected60, 
     120        portSelected60, 
     121        portSelected60, 
     122        portSelected80, 
     123        portSelected80, 
     124        selectedColor 
     125    }; 
    98126 
    99127    /** Tooltip-related */ 
     
    132160                    ((o2 instanceof RemoteFrameworkElement) && ((RemoteFrameworkElement)o2).getAnnotation(ParameterInfo.TYPE) != null && o1.getClass() == ConfigFileModel.ConfigEntryWrapper.class)); 
    133161        } else if (o1 instanceof RemotePort && o2 instanceof RemotePort) { 
    134             return canConnectPorts((RemotePort)o1, (RemotePort)o2).length() == 0; 
     162            return canConnectPorts((RemotePort)o1, (RemotePort)o2).isConnectingPossible(); 
    135163        } 
    136164        return false; 
     
    142170     * @param p1 Port 1 
    143171     * @param p2 Port 2 
    144      * @return "" if they can be connected. Otherwise the reason why not. 
    145      */ 
    146     private String canConnectPorts(RemotePort p1, RemotePort p2) { 
    147         if (p1.isConnectedTo(p2)) { 
    148             return "Ports are connected already"; 
     172     * @return If connecting is possible: SmartConnecting.CAN_CONNECT, CAN_CONNECT_IMPLICIT_CAST, or CAN_CONNECT_EXPLICIT_CAST (all 'possible' strings start with CAN_CONNECT). If connecting is not possible, reason for this. 
     173     */ 
     174    private SmartConnecting.MayConnectResult canConnectPorts(RemotePort p1, RemotePort p2) { 
     175        if (RemoteRuntime.arePortsConnected(p1, p2)) { 
     176            return new SmartConnecting.MayConnectResult("Ports are connected already"); 
    149177        } 
    150178 
     
    157185        tempConnectList2.add(p2); 
    158186        return SmartConnecting.mayConnect(tempConnectList1, tempConnectList2, finstruct.allowDirectConnectingAcrossGroupBoundaries()); // TODO: this can be optimized 
     187    } 
     188 
     189    /** 
     190     * Create color for candidate ports for connections 
     191     * 
     192     * @param redFactor The amount of red in color (0...1) 
     193     * @return Color 
     194     */ 
     195    private static ConnectorIcon.IconColor createConnectionCandidateColor(double redFactor) { 
     196        ConnectorIcon.IconColor base = defaultColor; 
     197        ConnectorIcon.IconColor red = selectedColor; 
     198        double baseFactor = 1 - redFactor; 
     199        return new ConnectorIcon.IconColor((int)(baseFactor * base.getRed() + redFactor * red.getRed()), (int)(baseFactor * base.getGreen() + redFactor * red.getGreen()), (int)(baseFactor * base.getBlue() + redFactor * red.getBlue())); 
    159200    } 
    160201 
     
    203244 
    204245    @Override 
    205     protected Object hypotheticalConnectionImplementation(Object tn) { 
     246    protected CheckConnectResult checkConnect(Object other, CheckConnectResult resultBuffer) { 
    206247        if (getRightTree() instanceof ConfigFileModel) { 
    207             return super.hypotheticalConnectionImplementation(tn); 
    208         } 
    209  
    210         MJTree<Object> selTree = selectionFromRight ? rightTree : leftTree; 
     248            return super.checkConnect(other, resultBuffer); 
     249        } 
     250 
     251        // Init objects 
     252        resultBuffer.partnerNodes.clear(); 
     253        resultBuffer.connectionScores.clear(); 
     254        resultBuffer.minScore = Definitions.TypeConversionRating.IMPOSSIBLE; 
     255        resultBuffer.impossibleHint = ""; 
     256        if (other == null) { 
     257            resultBuffer.impossibleHint = "Partner object is null"; 
     258            return resultBuffer; 
     259        } 
     260 
     261        MJTree<Object> selectionTree = selectionFromRight ? rightTree : leftTree; 
    211262 
    212263        // scan nodes to connect 
    213         RemoteFrameworkElement nonPortNode = processSourceNodesToConnect(tempConnectList1, selTree.getSelectedObjects()); 
     264        RemoteFrameworkElement nonPortNode = processSourceNodesToConnect(tempConnectList1, selectionTree.getSelectedObjects()); 
    214265        if (tempConnectList1.size() == 0) { 
    215             return nonPortNode != null && nonPortNode.isInterface() ? "Selected interface in other tree is empty" : "Only ports and interfaces can be connected (dragged)"; 
     266 
     267            resultBuffer.impossibleHint = nonPortNode != null && nonPortNode.isInterface() ? "Selected interface in other tree is empty" : "Only ports and interfaces can be connected (dragged)"; 
     268            return resultBuffer; 
    216269        } 
    217270 
    218271        if (nonPortNode != null) { 
    219272            // only connect to other non-port nodes 
    220             if (tn instanceof RemotePort) { 
    221                 return "Interfaces cannot be connected to ports (you may try the other way round)"; 
     273            if (other instanceof RemotePort) { 
     274                resultBuffer.impossibleHint = "Interfaces cannot be connected to ports (you may try the other way round)"; 
     275                return resultBuffer; 
    222276            } 
    223277 
    224278            tempConnectList2.clear(); 
    225279            for (int i = 0; i < tempConnectList1.size(); i++) { 
    226                 tempConnectList2.add((ModelNode)tn); 
    227             } 
    228             String reason = SmartConnecting.mayConnect(tempConnectList1, tempConnectList2, finstruct.allowDirectConnectingAcrossGroupBoundaries()); 
    229             if (reason.length() > 0) { 
    230                 return reason; 
    231             } 
    232             ArrayList<Object> result = new ArrayList<Object>(); 
    233             result.add(tn); 
    234             return result; 
    235         } 
    236  
    237         if (tn instanceof RemotePort) { 
     280                tempConnectList2.add((ModelNode)other); 
     281            } 
     282            MayConnectResult mayConnect = SmartConnecting.mayConnect(tempConnectList1, tempConnectList2, finstruct.allowDirectConnectingAcrossGroupBoundaries()); 
     283            if (!mayConnect.isConnectingPossible()) { 
     284                resultBuffer.impossibleHint = mayConnect.impossibleHint; 
     285                return resultBuffer; 
     286            } 
     287            resultBuffer.partnerNodes.add(other); 
     288            resultBuffer.connectionScores.add(mayConnect.rating); 
     289            resultBuffer.minScore = mayConnect.rating; 
     290            return resultBuffer; 
     291        } 
     292 
     293        if (other instanceof RemotePort) { 
    238294            if (tempConnectList1.size() == 1) { 
    239295                // Optimized implementation for only one selected port 
    240                 String reason = canConnectPorts(tempConnectList1.get(0), (RemotePort)tn); 
    241                 if (reason.length() > 0) { 
    242                     return reason; 
    243                 } 
    244                 ArrayList<Object> result = new ArrayList<Object>(); 
    245                 result.add(tn); 
    246                 return result; 
     296                SmartConnecting.MayConnectResult mayConnect = canConnectPorts(tempConnectList1.get(0), (RemotePort)other); 
     297                if (!mayConnect.isConnectingPossible()) { 
     298                    resultBuffer.impossibleHint = mayConnect.impossibleHint; 
     299                    return resultBuffer; 
     300                } 
     301                resultBuffer.partnerNodes.add(other); 
     302                resultBuffer.connectionScores.add(mayConnect.rating); 
     303                resultBuffer.minScore = mayConnect.rating; 
     304                return resultBuffer; 
    247305            } 
    248306 
    249307            // Standard hypotheticalConnectionImplementation from base class 
    250             return super.hypotheticalConnectionImplementation(tn); 
     308            return super.checkConnect(other, resultBuffer); 
    251309        } else { 
    252310            // Connect all ports to non-port tree node 
    253311            tempConnectList2.clear(); 
    254312            for (int i = 0; i < tempConnectList1.size(); i++) { 
    255                 tempConnectList2.add((ModelNode)tn); 
    256             } 
    257             String reason = SmartConnecting.mayConnect(tempConnectList1, tempConnectList2, finstruct.allowDirectConnectingAcrossGroupBoundaries()); 
    258             if (reason.length() > 0) { 
    259                 return reason; 
    260             } 
    261             ArrayList<Object> result = new ArrayList<Object>(); 
    262             result.addAll(tempConnectList2); 
    263             return result; 
     313                tempConnectList2.add((ModelNode)other); 
     314            } 
     315            MayConnectResult mayConnect = SmartConnecting.mayConnect(tempConnectList1, tempConnectList2, finstruct.allowDirectConnectingAcrossGroupBoundaries()); 
     316            if (!mayConnect.isConnectingPossible()) { 
     317                resultBuffer.impossibleHint = mayConnect.impossibleHint; 
     318                return resultBuffer; 
     319            } 
     320            resultBuffer.partnerNodes.add(other); 
     321            resultBuffer.connectionScores.add(mayConnect.rating); 
     322            resultBuffer.minScore = mayConnect.rating; 
     323            return resultBuffer; 
    264324        } 
    265325    } 
     
    309369                int choice = JOptionPane.showConfirmDialog(finstruct, "This will create " + createConnectionPortCreationString(action) + ". Continue?", "Create Ports?", JOptionPane.YES_NO_OPTION); 
    310370                if (choice == JOptionPane.NO_OPTION) { 
     371                    return; 
     372                } 
     373            } 
     374 
     375            // Query for any type conversions 
     376            boolean showCreateConnectorDialog = false; 
     377            for (FinstructAction a : ((CompositeAction)action).getActions()) { 
     378                if (a instanceof ConnectAction) { 
     379                    showCreateConnectorDialog |= ((ConnectAction)a).getConnectOptions().requiresOperationSelection() || FinstructAction.findRemoteRuntime(((ConnectAction)a).getSourceLink()) != FinstructAction.findRemoteRuntime(((ConnectAction)a).getDestinationLink()); 
     380                } 
     381            } 
     382            if (showCreateConnectorDialog) { 
     383                CreateConnectorOptionsDialog dialog = new CreateConnectorOptionsDialog(finstruct); 
     384                dialog.show(((CompositeAction)action).getActions()); 
     385                if (dialog.cancelled()) { 
    311386                    return; 
    312387                } 
     
    354429                AdminClient ac = rr.getAdminInterface(); 
    355430                pi.setConfigEntry("/" + ((HasUid)configNode).getUid(), true); 
    356                 ac.setAnnotation(((RemotePort)parameter).getRemoteHandle(), pi); 
     431                ac.setAnnotation(((RemotePort)parameter).getRemoteHandle(), ParameterInfo.TYPE.getName(), pi); 
    357432                return; 
    358433            } 
     
    362437 
    363438    @Override 
    364     protected List<Object> getConnectionPartners(Object port) { 
    365         return getConnectionPartners(port, false); 
    366     } 
    367  
    368     /** Implementation of getConnectionPartners */ 
    369     protected List<Object> getConnectionPartners(final Object treeNode, boolean includeSourcePorts) { 
     439    protected List<Object> getConnectionPartners(Object treeNode) { 
    370440        final List<Object> result = new ArrayList<Object>(); 
    371441        if (!(treeNode instanceof RemotePort)) { 
     
    383453            return result; 
    384454        } else { 
    385             result.addAll(port.getOutgoingConnections()); 
    386  
    387             if (includeSourcePorts) { // computationally expensive 
    388                 result.addAll(port.getIncomingConnections()); 
     455            RemoteRuntime runtime = RemoteRuntime.find(port); 
     456            ArrayList<RemoteConnector> connectors = new ArrayList<>(); 
     457            runtime.getConnectors(connectors, port); 
     458            for (RemoteConnector connector : connectors) { 
     459                result.add(connector.getPartnerPort(port, runtime)); 
    389460            } 
    390461            return result; 
     
    413484                            AdminClient ac = rr.getAdminInterface(); 
    414485                            pi.setConfigEntry(""); 
    415                             ac.setAnnotation(remotePort.getRemoteHandle(), pi); 
     486                            ac.setAnnotation(remotePort.getRemoteHandle(), ParameterInfo.TYPE.getName(), pi); 
    416487                        } 
    417488                    } 
     
    421492                    ParameterInfo pi = (ParameterInfo)((RemotePort)object).getAnnotation(ParameterInfo.TYPE); 
    422493                    pi.setConfigEntry(""); 
    423                     ac.setAnnotation(((RemotePort)object).getRemoteHandle(), pi); 
     494                    ac.setAnnotation(((RemotePort)object).getRemoteHandle(), ParameterInfo.TYPE.getName(), pi); 
    424495                } 
    425496                return; 
    426497            } else if (object instanceof RemotePort) { 
    427498                RemotePort port = (RemotePort)object; 
    428                 List<Object> partners = getConnectionPartners(port, true); 
    429                 NetPort np1 = port.getPort().asNetPort(); 
    430                 AdminClient ac = RemoteRuntime.find(np1).getAdminInterface(); 
     499                RemoteRuntime runtime = RemoteRuntime.find(port); 
     500                if (runtime == null || runtime.getAdminInterface() == null) { 
     501                    return; 
     502                } 
     503                ArrayList<RemoteConnector> connectors = new ArrayList<>(); 
     504                runtime.getConnectors(connectors, port); 
    431505                MJTree<Object> otherTree = popupOnRight ? leftTree : rightTree; 
    432506 
    433                 if (ac != null) { 
    434                     if (visibleConnectionsOnly) { 
    435                         for (Object partner : partners) { 
    436                             if (otherTree.isVisible(partner) && (partner instanceof RemotePort)) { 
    437                                 ac.disconnect(np1, ((RemotePort)partner).getPort().asNetPort()); 
    438                             } 
    439                         } 
    440                     } else { 
    441                         ac.disconnectAll(np1); 
    442                     } 
    443                     timer.restart(); 
    444                 } 
    445  
    446  
    447                 // Remove any network connections in reverse direction 
    448                 for (Object partner : partners) { 
    449                     ArrayList<AbstractPort> result = new ArrayList<AbstractPort>(); 
    450                     NetPort partnerNetPort = ((RemotePort)partner).getPort().asNetPort(); 
    451                     int reverseIndex = partnerNetPort.getRemoteEdgeDestinations(result); 
    452                     for (int i = 0; i < reverseIndex; i++) { 
    453                         AdminClient partnerClient = RemoteRuntime.find(partnerNetPort).getAdminInterface(); 
    454                         if (partnerClient != null && ac != partnerClient && result.get(i) == np1.getPort() && ((!visibleConnectionsOnly) || otherTree.isVisible(partner))) { 
    455                             partnerClient.networkConnect(partnerNetPort, "", RemoteRuntime.find(np1).uuid, ((RemotePort)port).getRemoteHandle(), ((HasUid)port).getUid(), true); 
    456                             timer.restart(); 
     507                if (visibleConnectionsOnly) { 
     508                    for (RemoteConnector connector : connectors) { 
     509                        RemotePort partnerPort = connector.getPartnerPort(port, runtime); 
     510                        if (otherTree.isVisible(partnerPort)) { 
     511                            runtime.getAdminInterface().disconnect(connector); 
    457512                        } 
    458513                    } 
    459                 } 
     514                } else { 
     515                    runtime.getAdminInterface().disconnectAll(port); 
     516                } 
     517                timer.restart(); 
     518 
     519 
     520                // Remove any network connections in reverse direction 
     521//                for (Object partner : partners) { 
     522//                    ArrayList<AbstractPort> result = new ArrayList<AbstractPort>(); 
     523//                    NetPort partnerNetPort = ((RemotePort)partner).getPort().asNetPort(); 
     524//                    int reverseIndex = partnerNetPort.getRemoteEdgeDestinations(result); 
     525//                    for (int i = 0; i < reverseIndex; i++) { 
     526//                        AdminClient partnerClient = RemoteRuntime.find(partnerNetPort).getAdminInterface(); 
     527//                        if (partnerClient != null && ac != partnerClient && result.get(i) == np1.getPort() && ((!visibleConnectionsOnly) || otherTree.isVisible(partner))) { 
     528//                            partnerClient.networkConnect(partnerNetPort, "", RemoteRuntime.find(np1).uuid, ((RemotePort)port).getRemoteHandle(), ((HasUid)port).getUid(), true); 
     529//                            timer.restart(); 
     530//                        } 
     531//                    } 
     532//                } 
    460533                return; 
    461534            } 
     
    475548            tooltip = null; 
    476549        } else { 
    477             Object result = hypotheticalConnectionImplementation(element); 
    478             if (result != null && result.getClass().equals(String.class)) { 
    479                 tooltip = result.toString(); 
     550            CheckConnectResult result = new CheckConnectResult(); 
     551            checkConnect(element, result); 
     552            if (result.minScore == Definitions.TypeConversionRating.IMPOSSIBLE) { 
     553                tooltip = result.impossibleHint; 
    480554            } 
    481555        } 
     
    559633    @Override 
    560634    protected void drawConnections(Graphics g) { 
    561         drawConnectionsHelper(g, leftTree, rightTree); 
    562         if (!(getRightTree() instanceof ConfigFileModel)) { 
    563             drawConnectionsHelper(g, rightTree, leftTree); 
     635        if (getRightTree() instanceof ConfigFileModel) { 
     636            drawConnectionsHelper(g, leftTree, rightTree); 
     637        } else if (showRightTree) { 
     638 
     639            Rectangle visible = this.getVisibleRect(); 
     640            List<Object> visibleNodesLeft = leftTree.getVisibleObjects(); 
     641            ArrayList<RemoteConnector> connectorList = new ArrayList<RemoteConnector>(); 
     642            finstruct.getIoInterface().updateUriConnectors(); 
     643 
     644            for (Object node : visibleNodesLeft) { 
     645                if (node instanceof RemotePort) { 
     646                    RemotePort portLeft = (RemotePort)node; 
     647                    RemoteRuntime runtime = RemoteRuntime.find(portLeft); 
     648                    runtime.getConnectors(connectorList, portLeft); 
     649                    for (RemoteConnector connector : connectorList) { 
     650                        RemotePort portRight = connector.getPartnerPort(portLeft, runtime); 
     651                        if (portRight != null && rightTree.isVisible(portRight)) { 
     652                            Point p1 = getLineStartPoint(leftTree, portLeft, getLineStartPosition(connector, portLeft, portRight)); 
     653                            Point p2 = getLineStartPoint(rightTree, portRight, getLineStartPosition(connector, portRight, portLeft)); 
     654                            RemoteRuntime runtimeRight = RemoteRuntime.find(portRight); 
     655                            Color color = connectedColor; 
     656                            if (runtime != runtimeRight) { 
     657                                color = connectorNetwork; 
     658                            } else { 
     659                                boolean leftIsSource = connector.getSourceHandle() == portLeft.getRemoteHandle(); 
     660                                Definitions.TypeConversionRating rating = connector.getRemoteConnectOptions().getTypeConversionRating(leftIsSource ? portLeft : portRight, runtime, leftIsSource ? portRight : portLeft); 
     661                                switch (rating) { 
     662                                case NO_CONVERSION: 
     663                                    color = connectorNoConversion; 
     664                                    break; 
     665                                case IMPOSSIBLE: 
     666                                case DEPRECATED_CONVERSION: 
     667                                    color = connectorDeprecatedConversion; 
     668                                    break; 
     669                                case IMPLICIT_CAST: 
     670                                case TWO_IMPLICIT_CASTS: 
     671                                    color = connectorImplicitConversion; 
     672                                    break; 
     673                                default: 
     674                                    color = connectorExplicitConversion; 
     675                                    break; 
     676                                } 
     677                            } 
     678                            if (mouseOver != null) { 
     679                                if (mouseOver == portLeft || mouseOver == portRight) { 
     680                                    color = color.brighter(); 
     681                                } 
     682                            } 
     683                            if (visible.contains(p1) && visible.contains(p2)) { 
     684                                drawLine(g, p1, p2, color, true, false); 
     685                            } else if (g.getClipBounds().intersectsLine(p1.x, p1.y, p2.x, p2.y)) { 
     686                                drawLine(g, p1, p2, color, false, false); 
     687                            } 
     688                        } 
     689                    } 
     690                } 
     691            } 
    564692        } 
    565693    } 
     
    659787                MJTree<Object> otherTree = popupOnRight ? leftTree : rightTree; 
    660788                Object portWrapper = getTreeNodeFromPos(ptree); 
    661                 List<Object> partners = getConnectionPartners(portWrapper, true); 
     789                List<Object> partners = getConnectionPartners(portWrapper); 
    662790 
    663791                for (Object partner : partners) { 
     
    688816    } 
    689817 
    690  
    691  
    692818    @Override 
    693819    protected NodeRenderingStyle getNodeAppearance(Object node, MJTree<Object> tree, boolean selected) { 
     
    707833                result.iconType |= ConnectorIcon.OUTPUT & (mouseOverFlag ? ConnectorIcon.BRIGHTER_COLOR : 0); 
    708834            } 
    709         } else if (node instanceof RemotePort) { 
    710             RemotePort port = (RemotePort)node; 
    711             result.textColor = tree.getBackground(); 
    712             boolean rpc = FinrocTypeInfo.isMethodType(port.getDataType(), true); 
    713             boolean mouseOverFlag = (mouseOver instanceof RemotePort) && ((port.getPort() == ((RemotePort)mouseOver).getPort()) || port.isConnectedTo((RemotePort)mouseOver)); 
    714             result.nodeColor = selected ? selectedColor : defaultColor; 
    715             if (getRightTree() instanceof ConfigFileModel) { 
    716                 ParameterInfo pi = (ParameterInfo)port.getAnnotation(ParameterInfo.TYPE); 
    717                 if (pi != null) { 
    718                     mouseOverFlag |= pi != null && pi.getConfigEntry() != null && pi.getConfigEntry().length() > 0 && ((ConfigFileModel)getRightTree()).get(pi.getConfigEntry()) == mouseOver; 
    719                 } else { 
    720                     result.nodeColor = lightGrayColor; 
    721                 } 
    722             } 
    723             result.iconType = (port.getFlag(FrameworkElementFlags.OUTPUT_PORT) ? ConnectorIcon.OUTPUT : 0) | 
    724                               (port.isProxy() ? ConnectorIcon.PROXY : 0) | 
    725                               (rpc ? ConnectorIcon.RPC : 0) | 
    726                               (mouseOverFlag ? ConnectorIcon.BRIGHTER_COLOR : 0); 
    727         } else { 
    728             if (node.getClass().equals(RemoteFrameworkElement.class)) { 
    729                 RemoteFrameworkElement element = (RemoteFrameworkElement)node; 
     835        } else if (node instanceof RemoteFrameworkElement) { 
     836            // erroneous element? 
     837            RemoteFrameworkElement element = (RemoteFrameworkElement)node; 
     838            RemoteRuntime runtime = RemoteRuntime.find(element); 
     839            boolean configFileMode = getRightTree() instanceof ConfigFileModel; 
     840            if (runtime != null && (!configFileMode)) { 
     841                for (RemoteFrameworkElement errorElement : runtime.getElementsInErrorState()) { 
     842                    if (element.isNodeAncestor(errorElement)) { 
     843                        result.nodeColor = errorColor; 
     844                        break; 
     845                    } 
     846                } 
     847            } 
     848 
     849            if (node.getClass().equals(RemotePort.class)) { 
     850                RemotePort port = (RemotePort)element; 
     851                result.textColor = tree.getBackground(); 
     852                boolean rpc = (port.getDataType().getTypeTraits() & DataTypeBase.IS_RPC_TYPE) != 0; 
     853                boolean mouseOverFlag = (mouseOver instanceof RemotePort) && ((port.getPort() == ((RemotePort)mouseOver).getPort()) || RemoteRuntime.arePortsConnected(port, (RemotePort)mouseOver)); 
     854                result.nodeColor = selected ? selectedColor : (result.nodeColor != errorColor ? defaultColor : errorColor); 
     855                if (otherTreeSelection) { 
     856                    Definitions.TypeConversionRating rating = highlightedElementRatings.get(node); 
     857                    if (rating != null) { 
     858                        result.nodeColor = candidatePortRatingColors[rating.ordinal()]; 
     859                    } 
     860                } 
     861                if (configFileMode) { 
     862                    ParameterInfo pi = (ParameterInfo)port.getAnnotation(ParameterInfo.TYPE); 
     863                    if (pi != null) { 
     864                        mouseOverFlag |= pi != null && pi.getConfigEntry() != null && pi.getConfigEntry().length() > 0 && ((ConfigFileModel)getRightTree()).get(pi.getConfigEntry()) == mouseOver; 
     865                    } else { 
     866                        result.nodeColor = lightGrayColor; 
     867                    } 
     868                } 
     869                result.iconType = (port.getFlag(FrameworkElementFlags.OUTPUT_PORT) ? ConnectorIcon.OUTPUT : 0) | 
     870                                  (port.isProxy() ? ConnectorIcon.PROXY : 0) | 
     871                                  (rpc ? ConnectorIcon.RPC : 0) | 
     872                                  (mouseOverFlag ? ConnectorIcon.BRIGHTER_COLOR : 0); 
     873            } else { 
    730874                if (element.isInterface()) { 
    731875                    result.nodeColor = otherTreeSelection ? selectedColor : (element.isSensorInterface() ? sensorInterfaceColor : (element.isControllerInterface() ? controllerInterfaceColor : interfaceColor)); 
     
    739883                } 
    740884            } 
    741             if ((!otherTreeSelection) && node instanceof ModelNode && finstruct.getCurrentView() != null && !((ModelNode)node).isNodeAncestor(finstruct.getCurrentView().getRootElement()) && node != finstruct.getCurrentView().getRootElement()) { 
    742                 result.textColor = inactiveTextColor; 
    743             } 
     885        } 
     886        if (result.textColor == null && (!otherTreeSelection) && node instanceof ModelNode && finstruct.getCurrentView() != null && !((ModelNode)node).isNodeAncestor(finstruct.getCurrentView().getRootElement()) && node != finstruct.getCurrentView().getRootElement()) { 
     887            result.textColor = inactiveTextColor; 
    744888        } 
    745889 
     
    765909            return ConnectorIcon.LineStart.Default; 
    766910        } 
    767         NetPort np = port instanceof RemotePort ? ((RemotePort)port).getPort().asNetPort() : null; 
    768         if (np != null && partner instanceof RemotePort) { 
     911        if (port instanceof RemotePort && partner instanceof RemotePort) { 
     912            RemotePort remotePort = (RemotePort)port; 
    769913            RemotePort partnerPort = (RemotePort)partner; 
    770             int firstReverse = np.getRemoteEdgeDestinations(tempDestinationList); 
    771             int partnerIndex = tempDestinationList.indexOf(partnerPort.getPort()); 
    772             if (partnerIndex >= 0) { 
    773                 return partnerIndex < firstReverse ? ConnectorIcon.LineStart.Outgoing : ConnectorIcon.LineStart.Incoming; 
    774             } else if (partnerPort.getPort().asNetPort() != null) { 
    775                 NetPort npPartner = partnerPort.getPort().asNetPort(); 
    776                 firstReverse = npPartner.getRemoteEdgeDestinations(tempDestinationList); 
    777                 partnerIndex = tempDestinationList.indexOf(np.getPort()); 
    778                 if (partnerIndex >= 0) { 
    779                     return partnerIndex < firstReverse ? ConnectorIcon.LineStart.Incoming : ConnectorIcon.LineStart.Outgoing; 
    780                 } 
    781                 // Ok, there's no connection yet 
     914            RemoteRuntime runtime = RemoteRuntime.find(remotePort); 
     915            runtime.getConnectors(tempConnectorList, remotePort); 
     916            for (RemoteConnector connector : tempConnectorList) { 
     917                if (connector.getPartnerPort(remotePort, runtime) == partner) { 
     918                    return getLineStartPosition(connector, remotePort, partnerPort); 
     919                } 
    782920            } 
    783921        } 
    784922        return ConnectorIcon.LineStart.Default; 
     923    } 
     924 
     925    /** 
     926     * Get line start position for remote connector 
     927     * 
     928     * @param connector Remote connector 
     929     * @param port Port in question 
     930     * @param partner Partner port 
     931     * @return Line starting position 
     932     */ 
     933    protected LineStart getLineStartPosition(RemoteConnector connector, RemotePort port, RemotePort partner) { 
     934        if (connector instanceof RemoteUriConnector) { 
     935            return SmartConnecting.inferConnectDirection(port, partner) == AbstractPort.ConnectDirection.TO_TARGET ? ConnectorIcon.LineStart.Outgoing : ConnectorIcon.LineStart.Incoming; 
     936        } else { 
     937            return connector.getSourceHandle() == port.getRemoteHandle() ? ConnectorIcon.LineStart.Outgoing : ConnectorIcon.LineStart.Incoming; 
     938        } 
    785939    } 
    786940 
     
    794948 
    795949        // Check whether port has any visible connections 
    796         List<Object> partners = getConnectionPartners(treeNode, true); 
     950        List<Object> partners = getConnectionPartners(treeNode); 
    797951        MJTree<Object> otherTree = popupOnRight ? leftTree : rightTree; 
    798952        boolean hasVisibleConnections = false; 
  • FinstructInterfaceTreeModel.java

    r238 r254  
    2929import org.finroc.core.remote.ModelNode; 
    3030import org.finroc.core.remote.RemoteFrameworkElement; 
     31import org.finroc.core.remote.RemoteRuntime; 
    3132import org.finroc.tools.gui.util.treemodel.InterfaceTreeModel; 
    3233 
     
    9394    private void processSubtree(ModelNode node) { 
    9495        if (node instanceof RemoteFrameworkElement && ((RemoteFrameworkElement)node).isCompositeComponent()) { 
    95             frameworkElementsToCheckForInterface.add((RemoteFrameworkElement)node); 
     96            RemoteRuntime r = RemoteRuntime.find((RemoteFrameworkElement)node); 
     97            if (r != null && r.getSerializationInfo().getRevision() == 0) { 
     98                frameworkElementsToCheckForInterface.add((RemoteFrameworkElement)node); 
     99            } 
    96100        } 
    97101        for (int i = 0; i < node.getChildCount(); i++) { 
     
    99103        } 
    100104    } 
     105 
     106    /** 
     107     * Update/resolve URI connector connection partners using current model. 
     108     * When model changes, this needs to be computed again (suggestion: do before redraw) 
     109     * May only be called by thread that builds remote model 
     110     */ 
     111    public void updateUriConnectors() { 
     112        // TODO: make this more general when required (handle runtimes that are not two levels below root) 
     113        for (int i = 0; i < getRoot().getChildCount(); i++) { 
     114            ModelNode transportRoot = getRoot().getChildAt(i); 
     115            for (int j = 0; j < transportRoot.getChildCount(); j++) { 
     116                ModelNode node = transportRoot.getChildAt(j); 
     117                if (node instanceof RemoteRuntime) { 
     118                    ((RemoteRuntime)node).updateUriConnectors(); 
     119                } 
     120            } 
     121        } 
     122    } 
     123 
    101124} 
  • FinstructRightPanel.java

    r250 r254  
    6565import org.finroc.core.FrameworkElementFlags; 
    6666import org.finroc.core.datatype.CoreString; 
    67 import org.finroc.core.parameter.ConstructorParameters; 
    6867import org.finroc.core.parameter.StaticParameterList; 
    69 import org.finroc.core.plugin.RemoteCreateModuleAction; 
    7068import org.finroc.core.portdatabase.FinrocTypeInfo; 
    7169import org.finroc.core.remote.ModelNode; 
     70import org.finroc.core.remote.RemoteCreateAction; 
    7271import org.finroc.core.remote.RemoteFrameworkElement; 
    7372import org.finroc.core.remote.RemotePort; 
    7473import org.finroc.core.remote.RemoteRuntime; 
    75 import org.finroc.core.remote.RemoteType; 
     74import org.finroc.core.remote.RemoteStaticParameterList; 
    7675import org.finroc.tools.finstruct.propertyeditor.ConnectingPortAccessor; 
    7776import org.finroc.tools.finstruct.propertyeditor.FinrocComponentFactory; 
     
    8786import org.finroc.tools.gui.util.propertyeditor.PropertyAccessor; 
    8887import org.finroc.tools.gui.util.propertyeditor.StandardComponentFactory; 
     88import org.rrlib.logging.Log; 
     89import org.rrlib.logging.LogLevel; 
     90import org.rrlib.serialization.Register; 
    8991import org.rrlib.serialization.rtti.DataTypeBase; 
    9092 
     
    133135 
    134136    /** UI elements for component creation panel */ 
    135     private RemoteCreateModuleAction selectedCreateAction; 
     137    private RemoteCreateAction selectedCreateAction; 
    136138    private JPanel componentCreationPanel = new JPanel(); 
    137139    private JLabel componentInfoText = new JLabel(); //"", SwingConstants.CENTER); 
     
    140142    private JLabel componentDescription = new JLabel(); //"", SwingConstants.CENTER); 
    141143    private CoreString componentCreateName = new CoreString(); 
    142     private ConstructorParameters componentConstructorParameters; 
     144    private RemoteStaticParameterList componentConstructorParameters; 
    143145 
    144146    /** UI elements for component properties */ 
    145147    private RemoteFrameworkElement selectedComponent; 
    146     private StaticParameterList selectedComponentStaticParameterList; 
     148    private RemoteStaticParameterList selectedComponentStaticParameterList; 
    147149    private JPanel componentPropertyPanel = new JPanel(); 
    148150    private JLabel componentPropertyPanelText = new JLabel(); 
     
    285287        if (runtime != null) { 
    286288            // TODO: transform to asynchronous call in order to increase GUI responsiveness (furthermore, we can be sure that all subelements have been added) 
    287             selectedComponentStaticParameterList = (StaticParameterList)runtime.getAdminInterface().getAnnotation(element.getRemoteHandle(), StaticParameterList.TYPE); 
    288             if (selectedComponentStaticParameterList != null) { 
    289                 for (int i = 0; i < selectedComponentStaticParameterList.size(); i++) { 
    290                     selectedComponentStaticParameterList.get(i).resetChanged(); 
    291                     //System.out.println(i + ":" + selectedComponentStaticParameterList.get(i).hasChanged()); 
    292                 } 
     289            selectedComponentStaticParameterList = new RemoteStaticParameterList(); 
     290            try { 
     291                selectedComponentStaticParameterList.deserialize(runtime.getAdminInterface().getAnnotation(element.getRemoteHandle(), StaticParameterList.TYPE.getName(), runtime)); 
     292            } catch (Exception e) { 
     293                Log.log(LogLevel.ERROR, e); 
    293294            } 
    294295 
     
    353354                RemoteRuntime runtime = RemoteRuntime.find(rootElement); 
    354355                if (runtime != null) { 
    355                     runtime.getAdminInterface().setAnnotation(selectedComponent.getRemoteHandle(), selectedComponentStaticParameterList); 
     356                    runtime.getAdminInterface().setAnnotation(selectedComponent.getRemoteHandle(), StaticParameterList.TYPE.getName(), selectedComponentStaticParameterList); 
    356357                } else { 
    357358                    Finstruct.showErrorMessage("Cannot set static parameter: connection to remote runtime lost", false, false); 
     
    401402                    RemotePort port = (RemotePort)interfaceElement.getChildAt(i); 
    402403                    DataTypeBase type = port.getPort().getDataType(); 
    403                     if (type.getJavaClass() != null && (FinrocTypeInfo.isCCType(type) || FinrocTypeInfo.isStdType(type) || ((type instanceof RemoteType) && ((RemoteType)type).isAdaptable()))) { 
     404                    if (type.getJavaClass() != null && (FinrocTypeInfo.isCCType(type) || FinrocTypeInfo.isStdType(type))) { 
    404405                        ConnectingPortAccessor portAccess = new ConnectingPortAccessor((RemotePort)interfaceElement.getChildAt(i), prefix ? interfaceElement.getParent().getQualifiedName('/') : interfaceElement.getQualifiedName('/')); 
    405406                        componentPropertyAccessPorts.add(portAccess); 
     
    430431        String shortName; // library name without prefix 
    431432        boolean loaded; // Is this a loaded library? 
    432         ArrayList<RemoteCreateModuleAction> actions = new ArrayList<RemoteCreateModuleAction>(); // Create actions in this library (temporary) 
     433        ArrayList<RemoteCreateAction> actions = new ArrayList<RemoteCreateAction>(); // Create actions in this library (temporary) 
    433434 
    434435        @Override 
     
    466467        if (runtime != null) { 
    467468            try { 
    468                 ArrayList<RemoteCreateModuleAction> createActions = runtime.getAdminInterface().getRemoteModuleTypes(); 
     469                Register<RemoteCreateAction> createActions = runtime.getCreateActions(); 
    469470                if (createActions.size() == 0) { 
    470471                    DefaultMutableTreeNode root = new DefaultMutableTreeNode(); 
     
    486487 
    487488                // Add all existing components 
    488                 for (RemoteCreateModuleAction action : createActions) { 
    489                     SharedLibraryCategoryAndName categoryAndName = getSharedLibraryCategoryAndName(action.groupName); 
     489                for (int i = 0, n = createActions.size(); i < n; i++) { 
     490                    RemoteCreateAction action = createActions.get(i); 
     491                    SharedLibraryCategoryAndName categoryAndName = getSharedLibraryCategoryAndName(action.getGroupName()); 
    490492                    HashMap<String, SharedLibrary> categoryMap = categoryMaps[categoryAndName.category.ordinal()]; 
    491493                    SharedLibrary library = categoryMap.get(categoryAndName.name); 
    492494                    if (library == null) { 
    493495                        library = new SharedLibrary(); 
    494                         library.name = action.groupName; 
     496                        library.name = action.getGroupName(); 
    495497                        library.shortName = categoryAndName.name; 
    496498                        library.loaded = true; 
     
    518520                        categoryNodes[i].add(node); 
    519521                        Collections.sort(sharedLibrary.actions); 
    520                         for (RemoteCreateModuleAction action : sharedLibrary.actions) { 
     522                        for (RemoteCreateAction action : sharedLibrary.actions) { 
    521523                            node.add(new DefaultMutableTreeNode(action)); 
    522524                        } 
     
    574576                this.validate(); 
    575577 
    576             } else if (selectedElement.getUserObject() instanceof RemoteCreateModuleAction) { 
     578            } else if (selectedElement.getUserObject() instanceof RemoteCreateAction) { 
    577579 
    578580                // show creation info 
    579                 selectedCreateAction = (RemoteCreateModuleAction)selectedElement.getUserObject(); 
    580                 componentInfoText.setText("<html><b>" + simpleHtmlEscape(selectedCreateAction.name) + "</b></html>"); 
     581                selectedCreateAction = (RemoteCreateAction)selectedElement.getUserObject(); 
     582                componentInfoText.setText("<html><b>" + simpleHtmlEscape(selectedCreateAction.getName()) + "</b></html>"); 
    581583 
    582584                // unique component name by default 
    583                 componentCreateName.set(selectedCreateAction.name); 
     585                componentCreateName.set(selectedCreateAction.getName()); 
    584586                int i = 0; 
    585587                while (rootElement.getChildByName(componentCreateName.toString()) != null) { 
    586588                    i++; 
    587                     componentCreateName.set(selectedCreateAction.name + " (" + i + ")"); 
    588                 } 
    589                 componentConstructorParameters = selectedCreateAction.parameters != null ? selectedCreateAction.parameters.instantiate() : null; 
     589                    componentCreateName.set(selectedCreateAction.getName() + " (" + i + ")"); 
     590                } 
     591                componentConstructorParameters = selectedCreateAction.getParameters() != null ? selectedCreateAction.getParameters().instantiate() : null; 
    590592 
    591593                // Create property accessor list 
     
    617619                try { 
    618620                    TreePath selectedPath = componentLibraryTree.getSelectionPath(); 
    619                     runtime.getAdminInterface().loadModuleLibrary(selectedLibrary.name); 
     621                    runtime.loadModuleLibrary(selectedLibrary.name); 
    620622                    new PanelUpdateThread((RemoteFrameworkElement)rootElement).run();  // note that we are calling run() here to execute update synchronously 
    621623                    TreePath newSelectedPath = componentLibraryTree.findPath(selectedPath.getPath()); 
  • SmartConnecting.java

    r246 r254  
    2424 
    2525import java.util.ArrayList; 
     26import java.util.Collections; 
    2627import java.util.HashMap; 
    2728import java.util.HashSet; 
     
    3334import org.finroc.core.datatype.DataTypeReference; 
    3435import org.finroc.core.datatype.PortCreationList; 
    35 import org.finroc.core.portdatabase.FinrocTypeInfo; 
     36import org.finroc.core.port.AbstractPort; 
     37import org.finroc.core.remote.Definitions; 
     38import org.finroc.core.remote.Definitions.TypeConversionRating; 
    3639import org.finroc.core.remote.ModelNode; 
     40import org.finroc.core.remote.RemoteConnectOptions; 
    3741import org.finroc.core.remote.RemoteFrameworkElement; 
    3842import org.finroc.core.remote.RemotePort; 
    3943import org.finroc.core.remote.RemoteRuntime; 
     44import org.finroc.core.remote.RemoteType; 
    4045import org.finroc.tools.finstruct.actions.AddPortsToInterfaceAction; 
    4146import org.finroc.tools.finstruct.actions.CompositeAction; 
    4247import org.finroc.tools.finstruct.actions.ConnectAction; 
    4348import org.finroc.tools.finstruct.actions.FinstructAction; 
     49import org.rrlib.serialization.Register; 
     50import org.rrlib.serialization.rtti.DataTypeBase; 
    4451 
    4552/** 
     
    5360public class SmartConnecting { 
    5461 
     62//    public static final String CAN_CONNECT = "Yes"; 
     63//    public static final String CAN_CONNECT_IMPLICIT_CAST = "Yes - Implicit Cast"; 
     64//    public static final String CAN_CONNECT_EXPLICIT_CAST = "Yes - Explicit Cast"; 
     65 
     66    /** 
     67     * Result of mayConnect* methods 
     68     * Used like a struct -> public fields. 
     69     */ 
     70    public static class MayConnectResult { 
     71 
     72        /** Connection rating */ 
     73        public Definitions.TypeConversionRating rating; 
     74 
     75        /** If there is no suitable combination to connect source nodes to partner nodes: contains hint/reason why not (as may be displayed as tool tip atop tree node) */ 
     76        public String impossibleHint; 
     77 
     78        /** 
     79         * @return Whether connecting is possible 
     80         */ 
     81        public boolean isConnectingPossible() { 
     82            return rating != Definitions.TypeConversionRating.IMPOSSIBLE; 
     83        } 
     84 
     85        public MayConnectResult(String impossibleHint) { 
     86            rating = TypeConversionRating.IMPOSSIBLE; 
     87            this.impossibleHint = impossibleHint; 
     88        } 
     89 
     90        public MayConnectResult(TypeConversionRating rating) { 
     91            this.rating = rating; 
     92            this.impossibleHint = null; 
     93        } 
     94    } 
     95 
     96    /** 
     97     * Result of getStreamableTypes method 
     98     */ 
     99    public static class StreamableType implements Comparable<StreamableType> { 
     100 
     101        /** Rating of connection */ 
     102        public Definitions.TypeConversionRating rating; 
     103 
     104        /** Name of type (in both runtimes) */ 
     105        public String name; 
     106 
     107        @Override 
     108        public int compareTo(StreamableType o) { 
     109            int c = Integer.compare(o.rating.ordinal(), rating.ordinal()); 
     110            return c != 0 ? c : name.compareTo(o.name); 
     111        } 
     112 
     113        @Override 
     114        public String toString() { 
     115            return name; 
     116        } 
     117    } 
     118 
    55119    /** 
    56120     * Checks whether remote ports can be connected directly (ignoring component boundaries) 
     
    59123     * @param destinationPort Second remote port 
    60124     * @param alsoCheckReverse If false, only checks one direction (from source to destination). If true, checks both directions. 
    61      * @return Empty string if connecting is possible. If connecting is not possible, reason for this. 
    62      */ 
    63     public static String mayConnectDirectly(RemotePort sourcePort, RemotePort destinationPort, boolean alsoCheckReverse) { 
     125     * @return Result: if and how connecting is possible 
     126     */ 
     127    public static MayConnectResult mayConnectDirectly(RemotePort sourcePort, RemotePort destinationPort, boolean alsoCheckReverse) { 
     128        MayConnectResult result = new MayConnectResult(Definitions.TypeConversionRating.IMPOSSIBLE); 
     129        boolean forwardPossible = true, reversePossible = alsoCheckReverse; 
    64130        RemoteRuntime sourceRuntime = RemoteRuntime.find(sourcePort); 
    65131        if (sourceRuntime == null) { 
    66             return "No runtime found for '" + sourcePort.getQualifiedLink() + "'"; 
     132            result.impossibleHint = "No runtime found for '" + sourcePort.getQualifiedLink() + "'"; 
     133            return result; 
    67134        } 
    68135        RemoteRuntime destinationRuntime = RemoteRuntime.find(destinationPort); 
    69136        if (destinationRuntime == null) { 
    70             return "No runtime found for '" + destinationPort.getQualifiedLink() + "'"; 
     137            result.impossibleHint = "No runtime found for '" + destinationPort.getQualifiedLink() + "'"; 
     138            return result; 
    71139        } 
    72140 
    73141        if (alsoCheckReverse) { 
    74142            if (!(sourcePort.getFlag(FrameworkElementFlags.EMITS_DATA) || destinationPort.getFlag(FrameworkElementFlags.EMITS_DATA))) { 
    75                 return "Neither port emits data ('" + sourcePort.getQualifiedLink() + "' and '" + destinationPort.getQualifiedLink() + "')"; 
     143                result.impossibleHint = "Neither port emits data ('" + sourcePort.getQualifiedLink() + "' and '" + destinationPort.getQualifiedLink() + "')"; 
     144                return result; 
    76145            } 
    77146            if (!(sourcePort.getFlag(FrameworkElementFlags.ACCEPTS_DATA) || destinationPort.getFlag(FrameworkElementFlags.ACCEPTS_DATA))) { 
    78                 return "Neither port accepts data ('" + sourcePort.getQualifiedLink() + "' and '" + destinationPort.getQualifiedLink() + "')"; 
    79             } 
     147                result.impossibleHint = "Neither port accepts data ('" + sourcePort.getQualifiedLink() + "' and '" + destinationPort.getQualifiedLink() + "')"; 
     148                return result; 
     149            } 
     150            if (!(sourcePort.getFlag(FrameworkElementFlags.ACCEPTS_DATA) || sourcePort.getFlag(FrameworkElementFlags.EMITS_DATA))) { 
     151                result.impossibleHint = sourcePort.getQualifiedLink() + " neither emits nor accepts data"; 
     152                return result; 
     153            } 
     154            if (!(destinationPort.getFlag(FrameworkElementFlags.ACCEPTS_DATA) || destinationPort.getFlag(FrameworkElementFlags.EMITS_DATA))) { 
     155                result.impossibleHint = destinationPort.getQualifiedLink() + " neither emits nor accepts data"; 
     156                return result; 
     157            } 
     158            forwardPossible = sourcePort.getFlag(FrameworkElementFlags.EMITS_DATA) && destinationPort.getFlag(FrameworkElementFlags.ACCEPTS_DATA); 
     159            reversePossible = destinationPort.getFlag(FrameworkElementFlags.EMITS_DATA) && sourcePort.getFlag(FrameworkElementFlags.ACCEPTS_DATA); 
    80160        } else if (!sourcePort.getFlag(FrameworkElementFlags.EMITS_DATA)) { 
    81             return "Source port (" + sourcePort.getQualifiedLink() + ") does not emit data"; 
     161            result.impossibleHint = "Source port (" + sourcePort.getQualifiedLink() + ") does not emit data"; 
     162            return result; 
    82163        } else if (!destinationPort.getFlag(FrameworkElementFlags.ACCEPTS_DATA)) { 
    83             return "Destination port (" + sourcePort.getQualifiedLink() + ") does not accept data"; 
    84         } 
    85  
    86         if (sourcePort.getDataType() != destinationPort.getDataType()) { 
    87             return "Ports have different types ('" + sourcePort.getQualifiedLink() + "' has type '" + sourcePort.getDataType().getName() + "' and '" + destinationPort.getQualifiedLink() + "' has type '" + destinationPort.getDataType().getName() + "')"; 
     164            result.impossibleHint = "Destination port (" + sourcePort.getQualifiedLink() + ") does not accept data"; 
     165            return result; 
    88166        } 
    89167 
    90168        if (sourceRuntime != destinationRuntime) { 
    91169            if ((!sourcePort.getFlag(FrameworkElementFlags.SHARED)) && (!destinationPort.getFlag(FrameworkElementFlags.SHARED))) { 
    92                 return "Neither port is shared ('" + sourcePort.getQualifiedLink() + "' and '" + destinationPort.getQualifiedLink() + "')"; 
    93             } 
    94             if (!((sourceRuntime.getAdminInterface() != null && destinationPort.getFlag(FrameworkElementFlags.SHARED)) || (destinationRuntime.getAdminInterface() != null && sourcePort.getFlag(FrameworkElementFlags.SHARED)))) { 
    95                 return "One non-shared port needs admin interface"; 
     170                result.impossibleHint = "Neither port is shared ('" + sourcePort.getQualifiedLink() + "' and '" + destinationPort.getQualifiedLink() + "')"; 
     171                return result; 
    96172            } 
    97173 
    98174            ModelNode commonParent = findCommonParent(sourcePort, destinationPort); 
    99175            if (commonParent == Finstruct.getInstance().getIoInterface().getRoot()) { 
    100                 return "Ports need to be connected to the same protocol/interface. Are parts connected to each other."; 
    101             } 
    102         } 
    103  
    104         return ""; 
     176                result.impossibleHint = "Ports need to be connected to the same protocol/interface. Are parts connected to each other?"; 
     177                return result; 
     178            } 
     179 
     180            if (forwardPossible) { 
     181                result.rating = getInterRuntimeTypeConversionRating(sourceRuntime, sourcePort.getDataType(), destinationRuntime, destinationPort.getDataType()); 
     182            } else { 
     183                result.rating = getBestRating(result.rating, getInterRuntimeTypeConversionRating(destinationRuntime, destinationPort.getDataType(), sourceRuntime, sourcePort.getDataType())); 
     184            } 
     185 
     186        } else { 
     187            result.rating = getBestRating(forwardPossible ? sourceRuntime.getTypeConversionRating(sourcePort.getDataType(), destinationPort.getDataType()) : Definitions.TypeConversionRating.IMPOSSIBLE, 
     188                                          reversePossible ? sourceRuntime.getTypeConversionRating(sourcePort.getDataType(), destinationPort.getDataType()) : Definitions.TypeConversionRating.IMPOSSIBLE); 
     189        } 
     190 
     191        if (result.rating == Definitions.TypeConversionRating.IMPOSSIBLE) { 
     192            if (forwardPossible && reversePossible) { 
     193                result.impossibleHint = "Types " + sourcePort.getDataType().getName() + " and " + destinationPort.getDataType().getName() + " cannot be converted to each other in either way"; 
     194            } else if (forwardPossible) { 
     195                result.impossibleHint = "Type " + sourcePort.getDataType().getName() + " cannot be converted to " + destinationPort.getDataType().getName(); 
     196            } else if (reversePossible) { 
     197                result.impossibleHint = "Type " + destinationPort.getDataType().getName() + " cannot be converted to " + sourcePort.getDataType().getName(); 
     198            } 
     199        } 
     200        result.impossibleHint = ""; 
     201        return result; 
    105202    } 
    106203 
     
    113210     * @param nodes2 Second collection (possibly containing interface and components) 
    114211     * @param allowDirectConnecting Allow direct connecting across component boundaries? 
    115      * @return Empty string if connecting is possible. If connecting is not possible, reason for this. 
    116      */ 
    117     public static String mayConnect(List<RemotePort> nodes1, List<ModelNode> nodes2, boolean allowDirectConnecting) { 
     212     * @return Result: if and how connecting is possible 
     213     */ 
     214    public static MayConnectResult mayConnect(List<RemotePort> nodes1, List<ModelNode> nodes2, boolean allowDirectConnecting) { 
     215        MayConnectResult result = new MayConnectResult(Definitions.TypeConversionRating.IMPOSSIBLE); 
    118216        try { 
    119217            // TODO: can be optimized 
    120             getConnectActionImplementation(nodes1, nodes2, allowDirectConnecting, false, false); 
     218            List<CompositeAction> actions = getConnectActionImplementation(nodes1, nodes2, allowDirectConnecting, false, false); 
     219            for (CompositeAction compositeAction : actions) { 
     220                Definitions.TypeConversionRating minRating = Definitions.TypeConversionRating.NO_CONVERSION; 
     221                for (FinstructAction action : compositeAction.getActions()) { 
     222                    if (action instanceof ConnectAction) { 
     223                        Definitions.TypeConversionRating actionRating = ((ConnectAction)action).getConversionRating(); 
     224                        if (actionRating.ordinal() < minRating.ordinal()) { 
     225                            minRating = actionRating; 
     226                        } 
     227                    } 
     228                } 
     229                if (minRating.ordinal() > result.rating.ordinal()) { 
     230                    result.rating = minRating; 
     231                } 
     232            } 
    121233        } catch (Exception e) { 
    122             return e.getMessage(); 
    123         } 
    124         return ""; 
    125     } 
     234            result.impossibleHint = e.getMessage(); 
     235        } 
     236        return result; 
     237    } 
     238 
     239    /** 
     240     * Infer direction in which remote ports ought to be connected. 
     241     * 
     242     * @param port1 First port 
     243     * @param port2 Second port 
     244     * @return Returns TO_TARGET if port2 should be destination port - otherwise TO_SOURCE. In doubt, returns TO_TARGET. 
     245     */ 
     246    public static AbstractPort.ConnectDirection inferConnectDirection(RemotePort port1, RemotePort port2) { 
     247        ModelNode commonParent = SmartConnecting.findCommonParent(port1, port2); 
     248 
     249        // Inner-group connection to group's interface port 
     250        if (port1.getParent() != null && port1.getParent().isInterface() && port1.getParent().getParent() == commonParent) { 
     251            return port1.getFlag(FrameworkElementFlags.IS_OUTPUT_PORT) ? AbstractPort.ConnectDirection.TO_SOURCE : AbstractPort.ConnectDirection.TO_TARGET; 
     252        } 
     253        if (port2.getParent() != null && port2.getParent().isInterface() && port2.getParent().getParent() == commonParent) { 
     254            return port2.getFlag(FrameworkElementFlags.IS_OUTPUT_PORT) ? AbstractPort.ConnectDirection.TO_TARGET : AbstractPort.ConnectDirection.TO_SOURCE; 
     255        } 
     256 
     257        // Standard case 
     258        return port1.getFlag(FrameworkElementFlags.IS_OUTPUT_PORT) ? AbstractPort.ConnectDirection.TO_TARGET : AbstractPort.ConnectDirection.TO_SOURCE; 
     259    } 
     260 
     261    /** 
     262     * If two ports to be connected are in different runtime environments, returns type conversion rating of best conversion option 
     263     * 
     264     * @param sourceRuntime Source runtime 
     265     * @param sourceType Source port data type 
     266     * @param destinationRuntime Destination runtime 
     267     * @param destinationType Destination port data type 
     268     * @return List of all streamable types together with connection rating of the best option 
     269     * @throws Throws exception if runtimes are identical 
     270     */ 
     271    public static Definitions.TypeConversionRating getInterRuntimeTypeConversionRating(RemoteRuntime sourceRuntime, RemoteType sourceType, RemoteRuntime destinationRuntime, RemoteType destinationType) { 
     272        if (sourceRuntime == destinationRuntime) { 
     273            throw new RuntimeException("Runtimes are identical"); 
     274        } 
     275 
     276        RemoteType.CachedConversionRatings ratings = sourceRuntime.getTypeConversionRatings(sourceType); 
     277        Register<RemoteType> types = sourceRuntime.getTypes(); 
     278        Definitions.TypeConversionRating result = Definitions.TypeConversionRating.IMPOSSIBLE; 
     279        for (int j = 0; j < ratings.size(); j++) { 
     280            RemoteType interTypeSource = types.get(j); 
     281            Definitions.TypeConversionRating rating = ratings.getRating(interTypeSource); 
     282            if (interTypeSource != sourceType && rating.ordinal() > result.ordinal()) { 
     283                RemoteType interTypeDestination = destinationRuntime.getRemoteType(interTypeSource.getName()); 
     284                if (interTypeDestination != null) { 
     285                    Definitions.TypeConversionRating rating2 = destinationRuntime.getTypeConversionRating(interTypeDestination, destinationType); 
     286                    if ((rating == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_TO_GENERIC_TYPE && rating2 == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_FROM_GENERIC_TYPE) || 
     287                            (rating == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_FROM_GENERIC_TYPE && rating2 == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_TO_GENERIC_TYPE)) { 
     288                        rating2 = Definitions.TypeConversionRating.DEPRECATED_CONVERSION; 
     289                    } 
     290                    if (rating2.ordinal() > result.ordinal()) { 
     291                        result = getWorstRating(rating, rating2); 
     292                    } 
     293                } 
     294            } 
     295        } 
     296        return result; 
     297    } 
     298 
     299    /** 
     300     * If two ports to be connected are in different runtime environments, returns types that would be suitable for serialization/deserialization over the network 
     301     * 
     302     * @param sourceRuntime Source runtime 
     303     * @param sourceType Source port data type 
     304     * @param destinationRuntime Destination runtime 
     305     * @param destinationType Destination port data type 
     306     * @return List of all streamable types together with connection rating of the best option 
     307     * @throws Throws exception if runtimes are identical 
     308     */ 
     309    public static List<StreamableType> getStreamableTypes(RemoteRuntime sourceRuntime, RemoteType sourceType, RemoteRuntime destinationRuntime, RemoteType destinationType) { 
     310        if (sourceRuntime == destinationRuntime) { 
     311            throw new RuntimeException("Runtimes are identical"); 
     312        } 
     313 
     314        ArrayList<StreamableType> result = new ArrayList<StreamableType>(); 
     315        RemoteType.CachedConversionRatings ratings = sourceRuntime.getTypeConversionRatings(sourceType); 
     316        Register<RemoteType> types = sourceRuntime.getTypes(); 
     317        for (int i = 0; i < ratings.size(); i++) { 
     318            RemoteType interTypeSource = types.get(i); 
     319            Definitions.TypeConversionRating rating = ratings.getRating(interTypeSource); 
     320            if (interTypeSource != sourceType && rating != Definitions.TypeConversionRating.IMPOSSIBLE) { 
     321                RemoteType interTypeDestination = destinationRuntime.getRemoteType(interTypeSource.getName()); 
     322                if (interTypeDestination != null) { 
     323                    Definitions.TypeConversionRating rating2 = destinationRuntime.getTypeConversionRating(interTypeDestination, destinationType); 
     324                    if (rating2 != Definitions.TypeConversionRating.IMPOSSIBLE) { 
     325                        StreamableType option = new StreamableType(); 
     326                        option.name = interTypeSource.getName(); 
     327                        option.rating = getWorstRating(rating, rating2); 
     328                        if ((rating == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_TO_GENERIC_TYPE && rating2 == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_FROM_GENERIC_TYPE) || 
     329                                (rating == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_FROM_GENERIC_TYPE && rating2 == Definitions.TypeConversionRating.EXPLICIT_CONVERSION_TO_GENERIC_TYPE)) { 
     330                            option.rating = Definitions.TypeConversionRating.DEPRECATED_CONVERSION; 
     331                        } 
     332                        result.add(option); 
     333                    } 
     334                } 
     335            } 
     336        } 
     337        Collections.sort(result); 
     338        return result; 
     339    } 
     340 
     341    /** 
     342     * @param rating1 First rating 
     343     * @param rating2 Second rating 
     344     * @return Maximum (best) rating of the two 
     345     */ 
     346    public static Definitions.TypeConversionRating getBestRating(Definitions.TypeConversionRating rating1, Definitions.TypeConversionRating rating2) { 
     347        return Definitions.TypeConversionRating.values()[Math.max(rating1.ordinal(), rating2.ordinal())]; 
     348    } 
     349 
     350    /** 
     351     * @param rating1 First rating 
     352     * @param rating2 Second rating 
     353     * @return Minimum (worst) rating of the two 
     354     */ 
     355    public static Definitions.TypeConversionRating getWorstRating(Definitions.TypeConversionRating rating1, Definitions.TypeConversionRating rating2) { 
     356        return Definitions.TypeConversionRating.values()[Math.min(rating1.ordinal(), rating2.ordinal())]; 
     357    } 
     358 
    126359 
    127360    /** 
     
    131364        RemotePort port; 
    132365        String portName; 
     366        RemoteType portDataType; 
     367        PortCreationList.Entry createEntry; 
    133368        RemoteFrameworkElement interface_; 
    134369        RemoteFrameworkElement component; 
     
    228463            for (int i = 0; i < nodes1.size(); i++) { 
    229464 
     465                RemoteRuntime node1Runtime = RemoteRuntime.find(nodes1.get(i)); 
     466                RemoteRuntime node2Runtime = RemoteRuntime.find(nodes2.get(i)); 
     467 
    230468                // Initialize ports 
    231469                TraceElement element1 = new TraceElement(), element2 = new TraceElement(); 
     
    237475                element1.port = nodes1.get(i); 
    238476                element1.portName = element1.port.getName(); 
     477                element1.portDataType = element1.port.getDataType(); 
    239478                if ((!(element1.port.getParent() instanceof RemoteFrameworkElement)) || (!(element1.port.getParent().getParent() instanceof RemoteFrameworkElement))) { 
    240479                    throw new Exception("Port must be below two framework elements"); 
     
    244483 
    245484                // Element 2 
     485                element2.portDataType = element1.portDataType; 
    246486                if (nodes2.get(i) instanceof RemotePort) { 
    247487                    element2.port = (RemotePort)nodes2.get(i); 
    248488                    element2.portName = element2.port.getName(); 
     489                    element2.portDataType = element2.port.getDataType(); 
    249490                    if ((!(element2.port.getParent() instanceof RemoteFrameworkElement)) || (!(element2.port.getParent().getParent() instanceof RemoteFrameworkElement))) { 
    250491                        throw new Exception("Port must be below two framework elements"); 
     
    328569                for (int j = 0; j < 2; j++) { 
    329570                    ArrayList<TraceElement> trace = j == 0 ? outwardTrace1 : outwardTrace2; 
     571                    RemoteRuntime traceRuntime = j == 0 ? node1Runtime : node2Runtime; 
    330572                    for (int k = 0; k < trace.size(); k++) { 
    331573                        TraceElement currentElement = trace.get(k); 
     
    347589                                for (RemoteFrameworkElement candidate : currentElement.component.getEditableInterfaces()) { 
    348590                                    int score = 0; 
    349                                     boolean rpcType = FinrocTypeInfo.isMethodType(element1.port.getDataType(), true); 
     591                                    boolean rpcType = (element1.portDataType.getTypeTraits() & DataTypeBase.IS_RPC_TYPE) != 0; 
    350592                                    boolean rpcPortInDataInterface = rpcType && (!element1.interface_.getFlag(FrameworkElementFlags.INTERFACE_FOR_RPC_PORTS)); 
    351593                                    boolean checkForRpcType = rpcType && (!rpcPortInDataInterface); 
     
    395637                        // Check or create port 
    396638                        ModelNode childElement = currentElement.interface_.getChildByName(lastElement.portName); 
     639                        Definitions.TypeConversionRating conversionRating = Definitions.TypeConversionRating.NO_CONVERSION; 
    397640                        if (childElement != null) { 
    398641                            // Check port 
     
    407650                                throw new Exception("Relevant interface has port with same name which is no proxy '" + port.getQualifiedLink() + "'"); 
    408651                            } 
    409                             if (port.getDataType() != outwardTrace1.get(0).port.getDataType()) { 
    410                                 throw new Exception("Relevant interface has port with same name and wrong data type '" + port.getQualifiedLink() + "'"); 
     652                            if (port.getDataType() != lastElement.portDataType) { 
     653                                conversionRating = traceRuntime.getTypeConversionRating(outputPorts ? lastElement.portDataType : port.getDataType(), outputPorts ? port.getDataType() : lastElement.portDataType); 
     654                                if (conversionRating == Definitions.TypeConversionRating.IMPOSSIBLE) { 
     655                                    throw new Exception("Relevant interface has port with same name and incompatible data types '" + port.getQualifiedLink() + "'"); 
     656                                } 
    411657                            } 
    412658                            currentElement.port = port; 
    413659                            currentElement.portName = port.getName(); 
     660                            currentElement.portDataType = port.getDataType(); 
    414661                        } else { 
    415662                            // Create port (?) 
    416663                            currentElement.portName = lastElement.portName; 
     664                            currentElement.portDataType = lastElement.portDataType; 
    417665                            AddPortsToInterfaceAction addPortAction = addPortActions.get(currentElement.component); 
    418666                            if (addPortAction == null) { 
     
    430678                            for (PortCreationList.Entry entry : addList) { 
    431679                                if (entry.name.equals(currentElement.portName)) { 
    432                                     if (entry.type.get() != outwardTrace1.get(0).port.getDataType()) { 
    433                                         throw new Exception("Existing port '" + currentElement.getPortLink() + "' needs same data type"); 
    434                                     } else { 
    435                                         found = true; 
     680                                    RemoteType existingEntryType = traceRuntime.getRemoteType(entry.type.toString()); 
     681                                    if (existingEntryType == null) { 
     682                                        throw new Exception("Remote type in PortCreationList not found (logic error)"); 
    436683                                    } 
     684                                    if (existingEntryType != currentElement.portDataType) { 
     685                                        conversionRating = traceRuntime.getTypeConversionRating(outputPorts ? lastElement.portDataType : existingEntryType, outputPorts ? existingEntryType : lastElement.portDataType); 
     686                                        if (conversionRating == Definitions.TypeConversionRating.IMPOSSIBLE) { 
     687                                            throw new Exception("Relevant interface has port (to be created) with same name and incompatible data types '" + existingEntryType + "'"); 
     688                                        } 
     689                                        currentElement.portDataType = existingEntryType; 
     690                                    } 
     691                                    currentElement.createEntry = entry; 
     692                                    found = true; 
    437693                                    break; 
    438694                                } 
     
    440696 
    441697                            if (!found) { 
    442                                 addList.add(new PortCreationList.Entry(currentElement.portName, new DataTypeReference(outwardTrace1.get(0).port.getDataType()), outputPorts ? PortCreationList.CREATE_OPTION_OUTPUT : 0)); 
     698                                currentElement.createEntry = new PortCreationList.Entry(currentElement.portName, new DataTypeReference(outwardTrace1.get(0).port.getDataType()), outputPorts ? PortCreationList.CREATE_OPTION_OUTPUT : 0); 
     699                                addList.add(currentElement.createEntry); 
    443700                            } 
    444701                        } 
    445702 
    446703                        // Create connection? 
    447                         if (k > 0 && (lastElement.port == null || currentElement.port == null || (!lastElement.port.isConnectedTo(currentElement.port)))) { 
    448                             ConnectAction connectAction = new ConnectAction(lastElement.getPortLink(), currentElement.getPortLink()); 
     704                        if (k > 0 && (lastElement.port == null || currentElement.port == null || (!RemoteRuntime.arePortsConnected(lastElement.port, currentElement.port)))) { 
     705                            ConnectAction connectAction = new ConnectAction(lastElement.getPortLink(), currentElement.getPortLink(), lastElement.portDataType.getName(), currentElement.portDataType.getName(), new RemoteConnectOptions(conversionRating), !outputPorts); 
    449706                            action.getActions().add(connectAction); 
    450707                        } 
     
    456713                TraceElement lastElement2 = outwardTrace2.get(outwardTrace2.size() - 1); 
    457714                if (lastElement1.port instanceof RemotePort && lastElement2.port instanceof RemotePort) { 
    458                     String result = mayConnectDirectly((RemotePort)lastElement1.port, (RemotePort)lastElement2.port, true); 
    459                     if (result.length() > 0) { 
    460                         throw new Exception(result); 
    461                     } 
    462                 } 
    463                 if (lastElement1.port == null || lastElement2.port == null || (!lastElement1.port.isConnectedTo(lastElement2.port))) { 
    464                     ConnectAction connectAction = new ConnectAction(lastElement1.getPortLink(), lastElement2.getPortLink()); 
     715                    boolean port1IsSource = inferConnectDirection(lastElement1.port, lastElement2.port) == AbstractPort.ConnectDirection.TO_TARGET; 
     716                    MayConnectResult result = mayConnectDirectly(port1IsSource ? lastElement1.port : lastElement2.port, port1IsSource ? lastElement2.port : lastElement1.port, false); 
     717                    if (result.impossibleHint != null && result.impossibleHint.length() > 0) { 
     718                        throw new Exception(result.impossibleHint); 
     719                    } 
     720 
     721                    ConnectAction connectAction = new ConnectAction(lastElement1.getPortLink(), lastElement2.getPortLink(), lastElement1.portDataType.getName(), lastElement2.portDataType.getName(), new RemoteConnectOptions(result.rating), !port1IsSource); 
     722                    action.getActions().add(connectAction); 
     723 
     724                } else if (lastElement1.port == null || lastElement2.port == null || (!RemoteRuntime.arePortsConnected(lastElement1.port, lastElement2.port))) { 
     725                    Definitions.TypeConversionRating conversionRating = Definitions.TypeConversionRating.NO_CONVERSION; 
     726                    boolean port1IsSourcePort = port1IsOutput && ((!outwardOnlyConnection) || outwardTrace1.size() > outwardTrace2.size()); 
     727                    RemoteType sourceType = port1IsSourcePort ? lastElement1.portDataType : lastElement2.portDataType; 
     728                    RemoteType destinationType = port1IsSourcePort ? lastElement2.portDataType : lastElement1.portDataType; 
     729                    if (node1Runtime == node2Runtime && lastElement1.portDataType != lastElement2.portDataType) { 
     730                        conversionRating = node1Runtime.getTypeConversionRating(sourceType, destinationType); 
     731                        if (conversionRating == Definitions.TypeConversionRating.IMPOSSIBLE) { 
     732                            throw new Exception("Ports have incompatible data types: '" + sourceType.getName() + "' and '" + destinationType.getName() + "'"); 
     733                        } 
     734                    } else if (node1Runtime != node2Runtime && (!lastElement1.portDataType.getName().equals(lastElement2.portDataType.getName()))) { 
     735                        conversionRating = port1IsSourcePort ? getInterRuntimeTypeConversionRating(node1Runtime, lastElement1.portDataType, node2Runtime, lastElement2.portDataType) : 
     736                                           getInterRuntimeTypeConversionRating(node2Runtime, lastElement2.portDataType, node1Runtime, lastElement1.portDataType); 
     737                        if (conversionRating == Definitions.TypeConversionRating.IMPOSSIBLE) { 
     738                            throw new Exception("Ports have incompatible data types: '" + sourceType.getName() + "' and '" + destinationType.getName() + "'"); 
     739                        } 
     740                        // TODO: maybe shared option needs to be set for port to be created in some scenarios 
     741                    } 
     742 
     743                    ConnectAction connectAction = new ConnectAction(lastElement1.getPortLink(), lastElement2.getPortLink(), lastElement1.portDataType.getName(), lastElement2.portDataType.getName(), new RemoteConnectOptions(conversionRating), !port1IsSourcePort); 
    465744                    action.getActions().add(connectAction); 
    466745                } 
     
    502781        return result; 
    503782    } 
     783 
     784    /** 
     785     * @param port Port whose URI path to obtain 
     786     * @return URI path of port 
     787     */ 
     788    public static String getUriPath(RemotePort port) { 
     789        String result = ""; 
     790        ModelNode currentElement = port; 
     791        while (currentElement != null) { 
     792            if ((currentElement instanceof RemoteRuntime) || (!(currentElement instanceof RemoteFrameworkElement))) { 
     793                break; 
     794            } 
     795            result = "/" + port.getName().replace("/", "%2F") + result; 
     796            currentElement = currentElement.getParent(); 
     797        } 
     798        return result; 
     799    } 
    504800} 
  • actions/AddPortsToInterfaceAction.java

    r238 r254  
    2727 
    2828import org.finroc.core.datatype.PortCreationList; 
    29 import org.finroc.core.finstructable.EditableInterfaces; 
     29import org.finroc.core.remote.RemoteEditableInterfaces; 
    3030import org.finroc.core.remote.ModelNode; 
    3131import org.finroc.core.remote.RemoteFrameworkElement; 
     
    7474        } 
    7575        if (undoAction) { 
    76             runtime.getAdminInterface().setAnnotation(((RemoteFrameworkElement)node).getRemoteHandle(), originalInterface); 
     76            runtime.getAdminInterface().setAnnotation(((RemoteFrameworkElement)node).getRemoteHandle(), RemoteEditableInterfaces.TYPE_NAME, originalInterface); 
    7777            return; 
    7878        } 
    7979 
    8080        originalInterface = ((RemoteFrameworkElement)node).getEditableInterfacesObject(); // TODO: optimization: could be done asynchronously 
    81         EditableInterfaces newInterface = Serialization.deepCopy(originalInterface); 
     81        RemoteEditableInterfaces newInterface = Serialization.deepCopy(originalInterface); 
    8282 
    8383        // Add ports to interfaces 
     
    8686            for (int i = 0; i < newInterface.getStaticParameterList().size(); i++) { 
    8787                if (newInterface.getStaticParameterList().get(i).getName().equals(entry.getKey())) { 
    88                     interfaceList = (PortCreationList)newInterface.getStaticParameterList().get(i).valPointer().getData(); 
     88                    interfaceList = (PortCreationList)newInterface.getStaticParameterList().get(i).getValue().getData(); 
    8989                    break; 
    9090                } 
     
    110110 
    111111        // Commit to remote runtime 
    112         runtime.getAdminInterface().setAnnotation(((RemoteFrameworkElement)node).getRemoteHandle(), newInterface); 
     112        runtime.getAdminInterface().setAnnotation(((RemoteFrameworkElement)node).getRemoteHandle(), RemoteEditableInterfaces.TYPE_NAME, newInterface); 
    113113    } 
    114114 
     
    225225 
    226226    // private constructor for undo action 
    227     private AddPortsToInterfaceAction(String link, EditableInterfaces originalInterface) { 
     227    private AddPortsToInterfaceAction(String link, RemoteEditableInterfaces originalInterface) { 
    228228        this.link = link; 
    229         this.originalInterface = new EditableInterfaces(); 
     229        this.originalInterface = new RemoteEditableInterfaces(); 
    230230        this.editableInterfaces = null; 
    231231        undoAction = true; 
     
    242242 
    243243    /** Original interface (for undo) */ 
    244     private EditableInterfaces originalInterface; 
     244    private RemoteEditableInterfaces originalInterface; 
    245245 
    246246    /** Undo action for add ports */ 
  • actions/CompositeAction.java

    r246 r254  
    6969        } catch (Exception e) { 
    7070            String result = menuDescription + " failed:\n  " + e.getMessage(); 
     71            //e.printStackTrace(); 
    7172            if (tryUndoExecutedActionsOnError) { 
    7273                CompositeAction undoStepsAction = (CompositeAction)getUndoActionImplementation(); 
  • actions/ConnectAction.java

    r238 r254  
    2222package org.finroc.tools.finstruct.actions; 
    2323 
     24import java.net.URI; 
     25import java.util.ArrayList; 
     26 
    2427import org.finroc.core.FrameworkElementFlags; 
     28import org.finroc.core.remote.Definitions; 
    2529import org.finroc.core.remote.ModelNode; 
     30import org.finroc.core.remote.RemoteConnectOptions; 
     31import org.finroc.core.remote.RemoteConnector; 
    2632import org.finroc.core.remote.RemotePort; 
    2733import org.finroc.core.remote.RemoteRuntime; 
     34import org.finroc.core.remote.RemoteUriConnector; 
    2835import org.finroc.tools.finstruct.Finstruct; 
    2936import org.finroc.tools.finstruct.SmartConnecting; 
     
    3340 * @author Max Reichardt 
    3441 * 
    35  * Action connecting two ports. 
     42 * Action connecting two ports 
    3643 */ 
    3744public class ConnectAction extends FinstructAction { 
    3845 
    3946    /** 
    40      * @param source Fully qualified name of source 
    41      * @param destination Fully qualified name of destination 
    42      */ 
    43     public ConnectAction(String source, String destination) { 
    44         this.sourceLink = source; 
    45         this.destinationLink = destination; 
    46     } 
    47  
    48     @Override 
    49     protected void executeImplementation() throws Exception { 
    50         connectImplementation(false, "Connecting"); 
     47     * Note that the connect direction must be correct (if reverse if false, sourceLink must refer to the actual source port; if reverse is true, destinationLink must refer to the actual source port) 
     48     * 
     49     * @param source Fully qualified name of source port 
     50     * @param destination Fully qualified name of destination port 
     51     * @param sourceTypeName Name of source port data type 
     52     * @param destinationTypeName Name of destination port data type 
     53     * @param connectOptions Connect Options. If selection of connect options is to be deferred to later, can be null. They must, however, be set before executing action. 
     54     * @param reverse Whether destinationLink refers to the actual source port 
     55     */ 
     56    public ConnectAction(String sourceLink, String destinationLink, String sourceTypeName, String destinationTypeName, RemoteConnectOptions connectOptions, boolean reverse) { 
     57        this.sourceLink = reverse ? destinationLink : sourceLink; 
     58        this.destinationLink = reverse ? sourceLink : destinationLink; 
     59        this.sourceTypeName = reverse ? destinationTypeName : sourceTypeName; 
     60        this.destinationTypeName = reverse ? sourceTypeName : destinationTypeName; 
     61        this.connectOptions = connectOptions; 
    5162    } 
    5263 
     
    6172            return "Connecting failed: '" + destinationLink + "' no longer exists"; 
    6273        } 
    63         if (((RemotePort)sourceNode).isConnectedTo((RemotePort)destinationNode)) { 
     74        if (RemoteRuntime.arePortsConnected((RemotePort)sourceNode, (RemotePort)destinationNode)) { 
    6475            return ""; 
    6576        } 
    6677        return null; 
    67     } 
    68  
    69     @Override 
    70     protected FinstructAction getUndoActionImplementation() { 
    71         return new DisconnectAction(sourceLink, destinationLink); 
    72     } 
    73  
    74     @Override 
    75     public String getDescriptionForEditMenu() { 
    76         return "Connect " + getReadableLinkForMenu(sourceLink); 
    7778    } 
    7879 
     
    8485     */ 
    8586    protected void connectImplementation(boolean disconnect, String actionString) throws Exception { 
    86         ModelNode sourceNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(sourceLink, LINK_SEPARATOR); 
    87         ModelNode destinationNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(destinationLink, LINK_SEPARATOR); 
    88         if (sourceNode == null && destinationNode == null) { 
    89             throw new Exception(actionString + " failed: Neither '" + sourceLink + "' nor '" + destinationLink + "' found"); 
    90         } 
    91         if (sourceNode == null) { 
    92             throw new Exception(actionString + " failed: '" + sourceLink + "' not found"); 
    93         } 
    94         if (!(sourceNode instanceof RemotePort)) { 
    95             throw new Exception(actionString + " failed: '" + sourceLink + "' is not a port"); 
    96         } 
    97         if (destinationNode == null) { 
    98             throw new Exception(actionString + " failed: '" + destinationLink + "' not found"); 
    99         } 
    100         if (!(destinationNode instanceof RemotePort)) { 
    101             throw new Exception(actionString + " failed: '" + destinationLink + "' is not a port"); 
    102         } 
    103  
    104         RemotePort sourcePort = (RemotePort)sourceNode; 
    105         RemotePort destinationPort = (RemotePort)destinationNode; 
    106         String reason = SmartConnecting.mayConnectDirectly(sourcePort, destinationPort, true); 
     87        RemotePort sourcePort = getSourcePort(); 
     88        RemotePort destinationPort = getDestinationPort(); 
     89        if (sourcePort == null && destinationPort == null) { 
     90            throw new Exception(actionString + " failed: Neither '" + sourceLink + "' nor '" + destinationLink + "' found/available"); 
     91        } 
     92        if (sourcePort == null) { 
     93            throw new Exception(actionString + " failed: '" + sourceLink + "' not found/available"); 
     94        } 
     95        if (destinationPort == null) { 
     96            throw new Exception(actionString + " failed: '" + destinationLink + "' not found/available"); 
     97        } 
     98        if (connectOptions == null) { 
     99            throw new Exception(actionString + " failed: remote connect options need to be set"); 
     100        } 
     101 
     102        String reason = SmartConnecting.mayConnectDirectly(sourcePort, destinationPort, true).impossibleHint; 
    107103        if (reason.length() > 0) { 
    108104            throw new Exception(actionString + " failed: " + reason); 
     
    117113        } 
    118114 
     115        String result = null; 
    119116        if (sourceRuntime != null && sourceRuntime == destinationRuntime) { 
    120117 
    121118            if (disconnect) { 
    122                 sourceRuntime.getAdminInterface().disconnect(sourcePort.getPort().asNetPort(), destinationPort.getPort().asNetPort()); 
     119                sourceRuntime.getAdminInterface().disconnect(sourcePort, destinationPort); 
    123120            } else { 
    124121                //if (!sourcePort.isConnectedTo(destinationPort)) {  // removed in order to avoid issues with any parallel incomplete actions 
    125                 sourceRuntime.getAdminInterface().connect(sourcePort.getPort().asNetPort(), destinationPort.getPort().asNetPort()); 
     122                if (sourceRuntime.getSerializationInfo().getRevision() == 0) { 
     123                    sourceRuntime.getAdminInterface().connectPorts(sourcePort, destinationPort, null); 
     124                } else { 
     125                    result = sourceRuntime.getAdminInterface().connectPorts(sourcePort, destinationPort, connectOptions);  // TODO are synchronous calls to connect sufficiently responsive? 
     126                } 
    126127            } 
    127128        } else { 
    128             String result = "No port is shared"; 
     129            result = "No port is shared"; 
     130            boolean legacyRuntime = sourceRuntime.getSerializationInfo().getRevision() == 0; 
     131 
     132            if (disconnect) { 
     133                ArrayList<RemoteConnector> connectors = new ArrayList<>(); 
     134                sourceRuntime.getConnectors(connectors, sourcePort); 
     135                for (RemoteConnector connector : connectors) { 
     136                    if ((connector instanceof RemoteUriConnector) && connector.getPartnerPort(sourcePort, sourceRuntime) == destinationPort) { 
     137                        sourceRuntime.getAdminInterface().disconnect(connector); 
     138                        result = null; 
     139                    } 
     140                } 
     141                if (result == null) { 
     142                    return; 
     143                } 
     144            } 
     145 
    129146            if (sourceRuntime.getAdminInterface() != null && destinationPort.getFlag(FrameworkElementFlags.SHARED)) { 
    130                 result = sourceRuntime.getAdminInterface().networkConnect(sourcePort.getPort().asNetPort(), "", RemoteRuntime.find(destinationPort.getPort().asNetPort()).uuid, destinationPort.getRemoteHandle(), destinationPort.getUid(), false); 
     147                if (legacyRuntime) { 
     148                    result = sourceRuntime.getAdminInterface().networkConnect(sourcePort, "", RemoteRuntime.find(destinationPort).uuid, destinationPort.getRemoteHandle(), destinationPort.getUid(), disconnect); 
     149                } else if (!disconnect) { 
     150                    URI uri = new URI("tcp", "", SmartConnecting.getUriPath(destinationPort), ""); 
     151                    org.finroc.core.net.generic_protocol.Definitions.setServerSideConversionOptions(connectOptions, destinationConnectOptions, serializedType); 
     152                    result = sourceRuntime.getAdminInterface().createUriConnector(sourcePort, uri.normalize().toString(), connectOptions); 
     153                } 
    131154            } 
    132155            if (result != null && destinationRuntime.getAdminInterface() != null && sourcePort.getFlag(FrameworkElementFlags.SHARED)) { 
    133                 result = destinationRuntime.getAdminInterface().networkConnect(destinationPort.getPort().asNetPort(), "", RemoteRuntime.find(sourcePort.getPort().asNetPort()).uuid, sourcePort.getRemoteHandle(), sourcePort.getUid(), false); 
    134             } 
    135             if (result != null) { 
    136                 throw new Exception(actionString + " failed: " + result); 
    137             } 
    138         } 
    139     } 
     156                if (legacyRuntime) { 
     157                    result = destinationRuntime.getAdminInterface().networkConnect(destinationPort, "", RemoteRuntime.find(sourcePort).uuid, sourcePort.getRemoteHandle(), sourcePort.getUid(), disconnect); 
     158                } else if (!disconnect) { 
     159                    URI uri = new URI("tcp", "", SmartConnecting.getUriPath(sourcePort), ""); 
     160                    org.finroc.core.net.generic_protocol.Definitions.setServerSideConversionOptions(destinationConnectOptions, connectOptions, serializedType); 
     161                    result = destinationRuntime.getAdminInterface().createUriConnector(destinationPort, uri.normalize().toString(), destinationConnectOptions); 
     162                } 
     163            } 
     164        } 
     165        if (result != null && result.length() > 0) { 
     166            throw new Exception(actionString + " failed: " + result); 
     167        } 
     168    } 
     169 
     170    @Override 
     171    protected void executeImplementation() throws Exception { 
     172        connectImplementation(false, "Connecting"); 
     173    } 
     174 
     175 
     176    /** 
     177     * @return Remote connect options. null if they have not been set. 
     178     */ 
     179    public RemoteConnectOptions getConnectOptions() { 
     180        return connectOptions; 
     181    } 
     182 
     183    /** 
     184     * @return Conversion rating of connection to create 
     185     */ 
     186    public Definitions.TypeConversionRating getConversionRating() { 
     187        return (connectOptions != null) ? connectOptions.conversionRating : Definitions.TypeConversionRating.NO_CONVERSION; 
     188    } 
     189 
     190    @Override 
     191    public String getDescriptionForEditMenu() { 
     192        return "Connect " + getReadableLinkForMenu(sourceLink); 
     193    } 
     194 
     195    /** 
     196     * @return Fully qualified name of destination port 
     197     */ 
     198    public String getDestinationLink() { 
     199        return destinationLink; 
     200    } 
     201 
     202    /** 
     203     * @return Remote connect options in destination runtime if this is connecting ports in two different runtimes. null if they have not been set. 
     204     */ 
     205    public RemoteConnectOptions getDestinationConnectOptions() { 
     206        return destinationConnectOptions; 
     207    } 
     208 
     209    /** 
     210     * @return Destination port. null if is currently not available 
     211     */ 
     212    public RemotePort getDestinationPort() { 
     213        ModelNode destinationNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(destinationLink, LINK_SEPARATOR); 
     214        return (destinationNode != null && destinationNode instanceof RemotePort) ? (RemotePort)destinationNode : null; 
     215    } 
     216 
     217    /** 
     218     * @return Destination type name 
     219     */ 
     220    public String getDestinationTypeName() { 
     221        return destinationTypeName; 
     222    } 
     223 
     224    /** 
     225     * @return Fully qualified name of source port 
     226     */ 
     227    public String getSourceLink() { 
     228        return sourceLink; 
     229    } 
     230 
     231    /** 
     232     * @return Source port. null if is currently not available 
     233     */ 
     234    public RemotePort getSourcePort() { 
     235        ModelNode sourceNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(sourceLink, LINK_SEPARATOR); 
     236        return (sourceNode != null && sourceNode instanceof RemotePort) ? (RemotePort)sourceNode : null; 
     237    } 
     238 
     239    /** 
     240     * @return Source type name 
     241     */ 
     242    public String getSourceTypeName() { 
     243        return sourceTypeName; 
     244    } 
     245 
     246    @Override 
     247    protected FinstructAction getUndoActionImplementation() { 
     248        return new DisconnectAction(sourceLink, destinationLink, sourceTypeName, destinationTypeName, connectOptions, false); 
     249    } 
     250 
     251    /** 
     252     * Set variant when ports in the same runtime are connected 
     253     * 
     254     * @param connectOptions Connect options to be used 
     255     */ 
     256    public void setConnectOptions(RemoteConnectOptions connectOptions) { 
     257        this.connectOptions = connectOptions; 
     258    } 
     259 
     260    /** 
     261     * Set variant when ports in different runtimes are connected 
     262     * 
     263     * @param connectOptions Connect options to be used in source runtime 
     264     * @param serializedType Type serialized/sent over the network 
     265     * @param destinationConnectOptions Connect options to be used in destination runtime 
     266     */ 
     267    public void setConnectOptions(RemoteConnectOptions sourceConnectOptions, String serializedType, RemoteConnectOptions destinationConnectOptions) { 
     268        this.connectOptions = sourceConnectOptions; 
     269        this.serializedType = serializedType; 
     270        this.destinationConnectOptions = destinationConnectOptions; 
     271    } 
     272 
    140273 
    141274    /** Qualified links to source and destination ports to connect */ 
    142275    private String sourceLink, destinationLink; 
     276 
     277    /** Names of source and destination types */ 
     278    private String sourceTypeName, destinationTypeName; 
     279 
     280    /** Remote connect options if they have been set */ 
     281    private RemoteConnectOptions connectOptions; 
     282 
     283    /** Remote connect options in destination runtime if this is connecting ports in two different runtimes. null if they have not been set */ 
     284    private RemoteConnectOptions destinationConnectOptions; 
     285 
     286    /** Type serialized/sent over the network if this is connecting ports in two different runtimes. null if it has not been set */ 
     287    private String serializedType; 
     288 
    143289} 
  • actions/DisconnectAction.java

    r238 r254  
    2323 
    2424import org.finroc.core.remote.ModelNode; 
     25import org.finroc.core.remote.RemoteConnectOptions; 
    2526import org.finroc.core.remote.RemotePort; 
     27import org.finroc.core.remote.RemoteRuntime; 
    2628import org.finroc.tools.finstruct.Finstruct; 
    2729 
     
    3537 
    3638    /** 
    37      * @param source Fully qualified name of source 
    38      * @param destination Fully qualified name of destination 
     39     * @param source Fully qualified name of source port 
     40     * @param destination Fully qualified name of destination port 
     41     * @param sourceTypeName Name of source port data type 
     42     * @param destinationTypeName Name of destination port data type 
     43     * @param currentConnectOptions Connect Options of current connection (required for undo) 
     44     * @param reverse Whether destinationLink refers to the actual source port 
    3945     */ 
    40     public DisconnectAction(String source, String destination) { 
    41         super(source, destination); 
     46    public DisconnectAction(String sourceLink, String destinationLink, String sourceTypeName, String destinationTypeName, RemoteConnectOptions currentConnectOptions, boolean reverse) { 
     47        super(sourceLink, destinationLink, sourceTypeName, destinationTypeName, new RemoteConnectOptions(), reverse); 
     48        this.currentConnectOptions = currentConnectOptions; 
    4249    } 
    4350 
     
    4956    @Override 
    5057    protected String checkSuccessImplementation() { 
    51         ModelNode sourceNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(sourceLink, LINK_SEPARATOR); 
     58        ModelNode sourceNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(super.getSourceLink(), LINK_SEPARATOR); 
    5259        if (!(sourceNode instanceof RemotePort)) { 
    5360            return ""; 
    5461        } 
    55         ModelNode destinationNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(destinationLink, LINK_SEPARATOR); 
     62        ModelNode destinationNode = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(super.getDestinationLink(), LINK_SEPARATOR); 
    5663        if (!(destinationNode instanceof RemotePort)) { 
    5764            return ""; 
    5865        } 
    59         if (!((RemotePort)sourceNode).isConnectedTo((RemotePort)destinationNode)) { 
     66        if (!RemoteRuntime.arePortsConnected((RemotePort)sourceNode, (RemotePort)destinationNode)) { 
    6067            return ""; 
    6168        } 
     
    6572    @Override 
    6673    protected FinstructAction getUndoActionImplementation() { 
    67         return new ConnectAction(sourceLink, destinationLink); 
     74        return new ConnectAction(super.getSourceLink(), super.getDestinationLink(), super.getSourceTypeName(), super.getDestinationTypeName(), currentConnectOptions, false); 
    6875    } 
    6976 
    7077    @Override 
    7178    public String getDescriptionForEditMenu() { 
    72         return "Disonnect " + getReadableLinkForMenu(sourceLink); 
     79        return "Disconnect " + getReadableLinkForMenu(super.getSourceLink()); 
    7380    } 
    7481 
    75     /** Qualified links to source and destination ports to connect */ 
    76     private String sourceLink, destinationLink; 
     82 
     83    /** Connect Options of current connection (required for undo) */ 
     84    private RemoteConnectOptions currentConnectOptions; 
    7785} 
  • actions/FinstructAction.java

    r238 r254  
    2929 
    3030import javax.swing.Timer; 
     31 
     32import org.finroc.core.remote.ModelNode; 
     33import org.finroc.core.remote.RemoteRuntime; 
     34import org.finroc.tools.finstruct.Finstruct; 
    3135 
    3236 
     
    186190 
    187191    /** 
     192     * Finds remote runtime for element with specified link (qualified name) 
     193     * 
     194     * @param link Link 
     195     * @return Runtime for specified link. Null if no such runtime exists. 
     196     */ 
     197    public static RemoteRuntime findRemoteRuntime(String link) { 
     198        ModelNode element = Finstruct.getInstance().getIoInterface().getChildByQualifiedName(link, LINK_SEPARATOR, true); 
     199        return RemoteRuntime.find(element); 
     200    } 
     201 
     202 
     203    /** 
    188204     * Must only be called after action was successfully executed. 
    189205     * 
  • dialogs/CreateInterfacesDialog.java

    r164 r254  
    3939import org.finroc.core.finstructable.GroupInterface.DataClassification; 
    4040import org.finroc.core.finstructable.GroupInterface.PortDirection; 
    41 import org.finroc.core.parameter.StaticParameterBool; 
    42 import org.finroc.core.parameter.StaticParameterEnum; 
    4341import org.finroc.core.parameter.StaticParameterList; 
    44 import org.finroc.core.plugin.RemoteCreateModuleAction; 
    4542import org.finroc.core.port.ThreadLocalCache; 
     43import org.finroc.core.remote.RemoteCreateAction; 
    4644import org.finroc.core.remote.RemoteFrameworkElement; 
    4745import org.finroc.core.remote.RemoteRuntime; 
     46import org.finroc.core.remote.RemoteStaticParameterList; 
    4847import org.finroc.tools.finstruct.Finstruct; 
    4948import org.finroc.tools.finstruct.propertyeditor.FinrocComponentFactory; 
     
    5958import org.rrlib.logging.Log; 
    6059import org.rrlib.logging.LogLevel; 
     60import org.rrlib.serialization.Register; 
    6161 
    6262/** 
     
    114114 
    115115    /** Remote action for creating interfaces */ 
    116     private RemoteCreateModuleAction createInterfaceAction; 
     116    private RemoteCreateAction createInterfaceAction; 
    117117 
    118118    /** Tree model of remote framework elements */ 
     
    137137 
    138138        RemoteRuntime rr = RemoteRuntime.find(element); 
    139         for (RemoteCreateModuleAction a : rr.getAdminInterface().getRemoteModuleTypes()) { 
    140             if (a.groupName.equals("core") || a.groupName.equals("finroc_plugins_runtime_construction") && a.name.equals("Interface")) { 
    141                 createInterfaceAction = a; 
     139        Register<RemoteCreateAction> createActions = rr.getCreateActions(); 
     140        for (int i = 0, n = createActions.size(); i < n; i++) { 
     141            RemoteCreateAction action = createActions.get(i); 
     142            if (action.getGroupName().equals("core") || action.getGroupName().equals("finroc_plugins_runtime_construction") && action.getName().equals("Interface")) { 
     143                createInterfaceAction = action; 
    142144                break; 
    143145            } 
     
    309311                    for (CreationTask task : creation.tasks) { 
    310312                        if (task.create) { 
    311                             StaticParameterList spl = new StaticParameterList(); 
    312                             spl.add(new StaticParameterEnum<GroupInterface.DataClassification>("", task.dataClassification)); 
    313                             spl.add(new StaticParameterEnum<GroupInterface.PortDirection>("", task.portDirection)); 
    314                             spl.add(new StaticParameterBool("", task.shared)); 
    315                             spl.add(new StaticParameterBool("", task.globallyUniqueLinks)); 
    316                             String error = rr.getAdminInterface().createModule(createInterfaceAction, task.name, element.getRemoteHandle(), spl); 
     313                            RemoteStaticParameterList parameters = createInterfaceAction.getParameters().instantiate(); 
     314                            parameters.get(0).setValue(task.dataClassification); 
     315                            parameters.get(1).setValue(task.portDirection); 
     316                            parameters.get(2).setValue(task.shared); 
     317                            parameters.get(3).setValue(task.globallyUniqueLinks); 
     318                            String error = rr.getAdminInterface().createModule(createInterfaceAction, task.name, element.getRemoteHandle(), parameters); 
    317319                            if (error.length() == 0 && task.portCreationList.getSize() > 0) { 
    318320                                setPortListCount++; 
     
    363365                                    RemoteRuntime rr = RemoteRuntime.find(element); 
    364366                                    int handle = element.getRemoteHandle(); 
    365                                     StaticParameterList elementParamList = (StaticParameterList)rr.getAdminInterface().getAnnotation(handle, StaticParameterList.TYPE); 
     367                                    RemoteStaticParameterList elementParamList = new RemoteStaticParameterList(); 
     368                                    elementParamList.deserialize(rr.getAdminInterface().getAnnotation(handle, StaticParameterList.TYPE.getName(), rr)); 
    366369                                    elementParamList.get(0).setValue(task.portCreationList); 
    367                                     rr.getAdminInterface().setAnnotation(handle, elementParamList); 
    368  
     370                                    rr.getAdminInterface().setAnnotation(handle, StaticParameterList.TYPE.getName(), elementParamList); 
    369371                                    setPortListCount--; 
    370372                                    break; 
  • dialogs/CreateModuleDialog.java

    r149 r254  
    2727import java.awt.event.ActionEvent; 
    2828import java.awt.event.ActionListener; 
     29import java.util.ArrayList; 
    2930import java.util.List; 
    3031import java.util.SortedSet; 
     
    4849import javax.swing.event.TreeModelListener; 
    4950 
    50 import org.finroc.core.parameter.StaticParameterList; 
    51 import org.finroc.core.plugin.RemoteCreateModuleAction; 
     51import org.finroc.core.remote.RemoteCreateAction; 
    5252import org.finroc.core.remote.RemoteFrameworkElement; 
    5353import org.finroc.core.remote.RemoteRuntime; 
     54import org.finroc.core.remote.RemoteStaticParameterList; 
    5455import org.finroc.tools.finstruct.Finstruct; 
    5556import org.finroc.tools.finstruct.util.FilteredList; 
    5657import org.finroc.tools.gui.util.treemodel.InterfaceTreeModel; 
     58import org.rrlib.serialization.Register; 
    5759 
    5860/** 
     
    6163 * Create Module Dialog 
    6264 */ 
    63 public class CreateModuleDialog extends MGridBagDialog implements ActionListener, CaretListener, ListSelectionListener, FilteredList.Filter<RemoteCreateModuleAction>, ListDataListener, TreeModelListener { 
     65public class CreateModuleDialog extends MGridBagDialog implements ActionListener, CaretListener, ListSelectionListener, FilteredList.Filter<RemoteCreateAction>, ListDataListener, TreeModelListener { 
    6466 
    6567    /** UID */ 
     
    6870    /** Dialog components */ 
    6971    private JTextField filter, name; 
    70     private JComboBox group; 
    71     private FilteredList<RemoteCreateModuleAction> jlist; 
     72    private JComboBox<Object> group; 
     73    private FilteredList<RemoteCreateAction> jlist; 
    7274    private JButton next, cancel, create, load; 
    7375 
     
    109111 
    110112        // create components 
    111         jlist = new FilteredList<RemoteCreateModuleAction>(this); 
     113        jlist = new FilteredList<>(this); 
    112114        name = new JTextField(); 
    113115        name.addCaretListener(this); 
     
    120122        bl.setHgap(4); 
    121123        library.setLayout(bl); 
    122         group = new JComboBox(); 
     124        group = new JComboBox<>(); 
    123125        group.addActionListener(jlist); 
    124126        library.add(group, BorderLayout.CENTER); 
     
    142144 
    143145        // get create module actions 
    144         updateCreateModuleActions(RemoteRuntime.find(parent).getAdminInterface().getRemoteModuleTypes()); 
     146        Register<RemoteCreateAction> createActions = RemoteRuntime.find(parent).getCreateActions(); 
     147        updateCreateModuleActions(createActions); 
    145148 
    146149        // show dialog 
     
    156159     * @param createModuleActions Current create module actions 
    157160     */ 
    158     public void updateCreateModuleActions(List<RemoteCreateModuleAction> createModuleActions) { 
     161    public void updateCreateModuleActions(Register<RemoteCreateAction> createModuleActions) { 
    159162        if (createModuleActions == null) { 
    160163            return; 
    161164        } 
    162165        SortedSet<Object> groups = new TreeSet<Object>(); 
     166        ArrayList<RemoteCreateAction> actions = new ArrayList<>(createModuleActions.size()); 
    163167        groups.add("all"); 
    164         for (RemoteCreateModuleAction rcma : createModuleActions) { 
    165             groups.add(rcma.groupName); 
    166         } 
    167         group.setModel(new DefaultComboBoxModel(groups.toArray())); 
     168        for (int i = 0, n = createModuleActions.size(); i < n; i++) { 
     169            RemoteCreateAction action = createModuleActions.get(i); 
     170            groups.add(action.getGroupName()); 
     171            actions.add(action); 
     172        } 
     173        group.setModel(new DefaultComboBoxModel<Object>(groups.toArray())); 
    168174        updateButtonState(); 
    169         jlist.setElements(createModuleActions); 
    170     } 
    171  
    172     @Override 
    173     public int accept(RemoteCreateModuleAction rcma) { 
     175        jlist.setElements(actions); 
     176    } 
     177 
     178    @Override 
     179    public int accept(RemoteCreateAction rcma) { 
    174180        String f = filter.getText(); 
    175181        String g = group.getSelectedItem().toString(); 
     
    177183            g = null; 
    178184        } 
    179         if (g == null || rcma.groupName.equals(g)) { 
    180             if (rcma.name.toLowerCase().contains(f.toLowerCase())) { 
    181                 if (rcma.name.toLowerCase().startsWith(f.toLowerCase())) { 
     185        if (g == null || rcma.getGroupName().equals(g)) { 
     186            if (rcma.getName().toLowerCase().contains(f.toLowerCase())) { 
     187                if (rcma.getName().toLowerCase().startsWith(f.toLowerCase())) { 
    182188                    return 0; 
    183189                } else { 
     
    205211                String load = new LoadModuleLibraryDialog((JFrame)getOwner()).show(libs); 
    206212                if (load != null) { 
    207                     updateCreateModuleActions(rr.getAdminInterface().loadModuleLibrary(load)); 
     213                    updateCreateModuleActions(rr.loadModuleLibrary(load)); 
    208214                } 
    209215            } else { 
     
    211217            } 
    212218        } else if (e.getSource() == next || e.getSource() == create) { 
    213             RemoteCreateModuleAction rcma = jlist.getSelectedValue(); 
    214             StaticParameterList spl = null; 
     219            RemoteCreateAction rcma = jlist.getSelectedValue(); 
     220            RemoteStaticParameterList spl = null; 
    215221            if (e.getSource() == next) { 
    216                 spl = rcma.parameters.instantiate(); 
     222                spl = rcma.getParameters().instantiate(); 
    217223                ParameterEditDialog ped = new ParameterEditDialog(this); 
    218224                setVisible(false); 
     
    264270            return; 
    265271        } else if (name.getText().equals(autoSetName)) { 
    266             autoSetName = jlist.getSelectedValue().name; 
     272            autoSetName = jlist.getSelectedValue().getName(); 
    267273            name.setText(autoSetName); 
    268274        } else { 
     
    275281     */ 
    276282    private void updateButtonState() { 
    277         RemoteCreateModuleAction rcma = jlist.getSelectedValue(); 
     283        RemoteCreateAction rcma = jlist.getSelectedValue(); 
    278284        boolean b = rcma != null && name.getText().length() > 0; 
    279         create.setEnabled(b && rcma.parameters.size() == 0); 
    280         next.setEnabled(b && rcma.parameters.size() > 0); 
     285        boolean hasParameters = b && rcma.getParameters() != null && rcma.getParameters().size() > 0; 
     286        create.setEnabled(b && (!hasParameters)); 
     287        next.setEnabled(b && hasParameters); 
    281288    } 
    282289 
     
    306313 
    307314                    // possibly show edit dialog 
    308                     new ParameterEditDialog(this).show(createdModule, false, false); 
     315                    try { 
     316                        new ParameterEditDialog(this).show(createdModule, false, false); 
     317                    } catch (Exception exception) { 
     318                        Finstruct.showErrorMessage(exception, true); 
     319                    } 
    309320                    close(); 
    310321                    return; 
  • dialogs/LoadModuleLibraryDialog.java

    r149 r254  
    5353    /** Buttons */ 
    5454    private JButton load, cancel; 
    55     private JList list; 
     55    private JList<String> list; 
    5656    private String selected; 
    5757 
     
    7979 
    8080        // create components 
    81         list = new JList(moduleLibraries.toArray()); 
     81        list = new JList<String>(moduleLibraries.toArray(new String[0])); 
    8282        //list.setPreferredSize(new Dimension(350, 550)); 
    8383        list.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
  • dialogs/ParameterEditDialog.java

    r157 r254  
    3131import javax.swing.JPanel; 
    3232 
    33 import org.finroc.core.finstructable.EditableInterfaces; 
    3433import org.finroc.core.parameter.StaticParameterList; 
     34import org.finroc.core.remote.RemoteEditableInterfaces; 
    3535import org.finroc.core.remote.RemoteFrameworkElement; 
    3636import org.finroc.core.remote.RemoteRuntime; 
     37import org.finroc.core.remote.RemoteStaticParameterList; 
    3738import org.finroc.tools.finstruct.Finstruct; 
    3839import org.finroc.tools.finstruct.propertyeditor.FinrocComponentFactory; 
     
    6869 
    6970    /** Remote Element property list */ 
    70     private StaticParameterList elementParamList; 
     71    private RemoteStaticParameterList elementParamList; 
    7172 
    7273    /** 
     
    8990     * @param editInterfaces Edit element's interfaces instead of parameters? 
    9091     */ 
    91     public void show(RemoteFrameworkElement element, boolean warnIfNoParameters, boolean editInterfaces) { 
     92    public void show(RemoteFrameworkElement element, boolean warnIfNoParameters, boolean editInterfaces) throws Exception { 
    9293        this.editInterfaces = editInterfaces; 
    9394        setTitle((editInterfaces ? "Edit Interfaces of " : "Edit Static Parameters of ") + element.getQualifiedName('/')); 
    9495        this.element = element; 
    9596        RemoteRuntime rr = RemoteRuntime.find(element); 
     97        elementParamList = new RemoteStaticParameterList(); 
    9698        if (!editInterfaces) { 
    97             elementParamList = (StaticParameterList)rr.getAdminInterface().getAnnotation(element.getRemoteHandle(), StaticParameterList.TYPE); 
     99            elementParamList.deserialize(rr.getAdminInterface().getAnnotation(element.getRemoteHandle(), StaticParameterList.TYPE.getName(), rr)); 
    98100        } else { 
    99             elementParamList = ((EditableInterfaces)rr.getAdminInterface().getAnnotation(element.getRemoteHandle(), EditableInterfaces.TYPE)). 
    100                                getStaticParameterList(); 
     101            RemoteEditableInterfaces interfaces = new RemoteEditableInterfaces(); 
     102            interfaces.deserialize(rr.getAdminInterface().getAnnotation(element.getRemoteHandle(), RemoteEditableInterfaces.TYPE_NAME, rr)); 
     103            elementParamList = interfaces.getStaticParameterList(); 
    101104        } 
    102105        if (elementParamList != null) { 
     
    115118     * @param fe Framework element (edited - or parent) 
    116119     */ 
    117     public void show(StaticParameterList spl, RemoteFrameworkElement fe) { 
     120    public void show(RemoteStaticParameterList spl, RemoteFrameworkElement fe) { 
    118121 
    119122        // Create property panel 
     
    160163                RemoteRuntime rr = RemoteRuntime.find(element); 
    161164                if (!editInterfaces) { 
    162                     rr.getAdminInterface().setAnnotation(element.getRemoteHandle(), elementParamList); 
     165                    rr.getAdminInterface().setAnnotation(element.getRemoteHandle(), StaticParameterList.TYPE.getName(), elementParamList); 
    163166                } else { 
    164                     EditableInterfaces editableInterfaces = new EditableInterfaces(); 
     167                    RemoteEditableInterfaces editableInterfaces = new RemoteEditableInterfaces(); 
    165168                    editableInterfaces.setStaticParameterList(elementParamList); 
    166                     rr.getAdminInterface().setAnnotation(element.getRemoteHandle(), editableInterfaces); 
     169                    rr.getAdminInterface().setAnnotation(element.getRemoteHandle(), RemoteEditableInterfaces.TYPE_NAME, editableInterfaces); 
    167170                } 
    168171            } 
  • propertyeditor/FinrocComponentFactory.java

    r251 r254  
    3232import org.finroc.core.datatype.PortCreationList; 
    3333import org.finroc.core.datatype.XML; 
    34 import org.finroc.core.portdatabase.FinrocTypeInfo; 
    3534import org.finroc.core.portdatabase.SerializationHelper; 
    3635import org.finroc.core.remote.ModelNode; 
    3736import org.finroc.core.remote.RemoteRuntime; 
    3837import org.finroc.core.remote.RemoteType; 
    39 import org.finroc.core.remote.RemoteTypes; 
    4038import org.finroc.tools.gui.util.propertyeditor.BooleanEditor; 
    4139import org.finroc.tools.gui.util.propertyeditor.ComponentFactory; 
     
    5149import org.finroc.plugins.data_types.ContainsStrings; 
    5250import org.finroc.plugins.data_types.PaintablePortData; 
    53 import org.rrlib.finroc_core_utils.jc.ArrayWrapper; 
    54 import org.rrlib.finroc_core_utils.jc.container.SafeConcurrentlyIterableList; 
    5551import org.rrlib.serialization.BinarySerializable; 
    5652import org.rrlib.serialization.EnumValue; 
    5753import org.rrlib.serialization.PortDataListImpl; 
     54import org.rrlib.serialization.Register; 
    5855import org.rrlib.serialization.Serialization; 
    5956import org.rrlib.serialization.StringInputStream; 
     
    8481     */ 
    8582    public static boolean isTypeSupported(DataTypeBase dt) { 
    86         if (FinrocTypeInfo.isCCType(dt) || FinrocTypeInfo.isStdType(dt) || ((dt instanceof RemoteType) && ((RemoteType)dt).isAdaptable())) { 
     83        if ((dt.getTypeTraits() & DataTypeBase.IS_DATA_TYPE) != 0) { 
    8784            Class<?> type = dt.getJavaClass(); 
    8885            if (type != null) { 
     
    112109        } else if (DataTypeReference.class.equals(type)) { 
    113110            RemoteRuntime rr = RemoteRuntime.find(commonParent); 
    114             ArrayList<DataTypeReference> types = new ArrayList<DataTypeReference>(); 
     111            ArrayList<Object> types = new ArrayList<Object>(); 
    115112            if (rr == null) { // use local data types 
    116113                for (short i = 0; i < DataTypeBase.getTypeCount(); i++) { 
    117114                    DataTypeBase dt = DataTypeBase.getType(i); 
    118115                    if (dt != null) { 
    119                         types.add(new DataTypeReference(dt)); 
     116                        types.add(dt); 
    120117                    } 
    121118                } 
    122119            } else { 
    123                 SafeConcurrentlyIterableList<RemoteTypes.Entry> remoteTypes = rr.getRemoteTypes().getTypes(); 
    124                 ArrayWrapper<RemoteTypes.Entry> iterable = remoteTypes.getIterable(); 
    125                 for (int i = 0, n = iterable.size(); i < n; i++) { 
    126                     RemoteTypes.Entry entry = iterable.get(i); 
    127                     if (entry != null && entry.getLocalDataType() != null) { 
    128                         types.add(new DataTypeReference(entry.getLocalDataType())); 
     120                Register<RemoteType> remoteTypes = rr.getRemoteTypes(); 
     121                for (int i = 0, n = remoteTypes.size(); i < n; i++) { 
     122                    RemoteType entry = remoteTypes.get(i); 
     123                    if (entry != null) { 
     124                        types.add(entry); 
    129125                    } 
    130126                } 
    131127            } 
    132             wpec = new DataTypeEditor(types.toArray(new DataTypeReference[0]), null, panel); 
     128            wpec = new DataTypeEditor(types.toArray(new Object[0]), null, panel); 
    133129            //acc = new CoreSerializableAdapter((PropertyAccessor<BinarySerializable>)acc, type, DataTypeReference.TYPE); 
    134130        } else if (PaintablePortData.class.isAssignableFrom(type)) { 
  • propertyeditor/PortAccessor.java

    r215 r254  
    9393    @Override 
    9494    public Class<T> getType() { 
    95         return (wrapped.getDataType().getJavaClass() == null && (wrapped.getDataType().getType() == DataTypeBase.Classification.LIST || wrapped.getDataType().getType() == DataTypeBase.Classification.PTR_LIST)) ? 
    96                (Class<T>)PortDataListImpl.class : (Class<T>)wrapped.getDataType().getJavaClass(); 
     95        return (wrapped.getDataType().getJavaClass() == null && (wrapped.getDataType().getTypeTraits() == DataTypeBase.IS_LIST_TYPE)) ? (Class<T>)PortDataListImpl.class : (Class<T>)wrapped.getDataType().getJavaClass(); 
    9796    } 
    9897 
     
    128127                CCPortDataManager c = ThreadLocalCache.get().getUnusedInterThreadBuffer(DataTypeBase.findType(newValue.getClass(), ap.getDataType())); 
    129128                Serialization.deepCopy(newValue, c.getObject().getData()); 
    130                 RemoteRuntime.find(RemotePort.get(ap)[0]).getAdminInterface().setRemotePortValue(ap.asNetPort(), c.getObject(), errorPrinter); 
     129                RemoteRuntime.find(RemotePort.get(ap)[0]).getAdminInterface().setRemotePortValue(RemotePort.get(ap)[0], c.getObject(), errorPrinter); 
    131130            } else { 
    132131                CCPortDataManagerTL c = ThreadLocalCache.get().getUnusedBuffer(DataTypeBase.findType(newValue.getClass(), ap.getDataType())); 
     
    139138            Serialization.deepCopy(newValue, result.getObject().getData(), null); 
    140139            if (ap.getFlag(FrameworkElementFlags.NETWORK_ELEMENT)) { 
    141                 RemoteRuntime.find(RemotePort.get(ap)[0]).getAdminInterface().setRemotePortValue(ap.asNetPort(), result.getObject(), errorPrinter); 
     140                RemoteRuntime.find(RemotePort.get(ap)[0]).getAdminInterface().setRemotePortValue(RemotePort.get(ap)[0], result.getObject(), errorPrinter); 
    142141            } else { 
    143142                ((PortBase)wrapped).publish(result); 
  • propertyeditor/StaticParameterAccessor.java

    r222 r254  
    2929import org.finroc.core.parameter.StaticParameterBase; 
    3030import org.finroc.core.parameter.StaticParameterList; 
     31import org.finroc.core.remote.RemoteStaticParameterList; 
    3132import org.finroc.tools.gui.util.propertyeditor.PropertyAccessor; 
    3233import org.rrlib.serialization.Serialization; 
     
    4142 
    4243    /** Wrapped parameter */ 
    43     protected final StaticParameterBase wrapped; 
     44    protected final RemoteStaticParameterList.Parameter wrapped; 
    4445 
    4546    protected final String namePrefix; 
    4647 
    47     public StaticParameterAccessor(StaticParameterBase wrapped, String namePrefix) { 
     48    public StaticParameterAccessor(RemoteStaticParameterList.Parameter wrapped, String namePrefix) { 
    4849        this.wrapped = wrapped; 
    4950        this.namePrefix = namePrefix; 
     
    5556            return String.class; 
    5657        } else { 
    57             return wrapped.getType().getJavaClass(); 
     58            return wrapped.getType().getDefaultLocalDataType().getJavaClass(); 
    5859        } 
    5960    } 
     
    6162    @Override 
    6263    public Object get() throws Exception { 
    63         return Serialization.deepCopy(wrapped.valPointer().getData()); 
     64        return Serialization.deepCopy(wrapped.getValue().getData()); 
    6465    } 
    6566 
    6667    @Override 
    6768    public void set(Object newValue) throws Exception { 
    68         if (newValue instanceof String) { 
    69             wrapped.setValue(new CoreString(newValue.toString())); 
    70         } else { 
    71             wrapped.setValue(newValue); 
    72         } 
     69        wrapped.setValue(newValue); 
    7370    } 
    7471 
     
    8885     * @return List of accessors for list 
    8986     */ 
    90     public static List < PropertyAccessor<? >> createForList(StaticParameterList spl, String namePrefix) { 
     87    public static List < PropertyAccessor<? >> createForList(RemoteStaticParameterList spl, String namePrefix) { 
    9188        ArrayList < PropertyAccessor<? >> result = new ArrayList < PropertyAccessor<? >> (); 
    9289        for (int i = 0; i < spl.size(); i++) { 
     
    9592        return result; 
    9693    } 
    97     public static List < PropertyAccessor<? >> createForList(StaticParameterList spl) { 
     94    public static List < PropertyAccessor<? >> createForList(RemoteStaticParameterList spl) { 
    9895        return createForList(spl, ""); 
    9996    } 
  • views/AbstractGraphView.java

    r234 r254  
    4343import org.finroc.core.Annotatable; 
    4444import org.finroc.core.FrameworkElementFlags; 
    45 import org.finroc.core.port.AbstractPort; 
    46 import org.finroc.core.port.net.NetPort; 
    47 import org.finroc.core.portdatabase.FinrocTypeInfo; 
    4845import org.finroc.core.remote.ModelNode; 
     46import org.finroc.core.remote.RemoteConnector; 
    4947import org.finroc.core.remote.RemoteFrameworkElement; 
    5048import org.finroc.core.remote.RemotePort; 
    5149import org.finroc.core.remote.RemoteRuntime; 
     50import org.finroc.core.remote.RemoteUriConnector; 
    5251import org.finroc.plugins.data_types.StdStringList; 
    5352import org.finroc.tools.finstruct.FinstructConnectionPanel; 
     
    5857import org.rrlib.logging.Log; 
    5958import org.rrlib.logging.LogLevel; 
     59import org.rrlib.serialization.rtti.DataTypeBase; 
    6060import org.rrlib.xml.XMLNode; 
    6161 
     
    217217                if (fe.getChildAt(i) instanceof RemotePort) { 
    218218                    RemotePort remotePort = (RemotePort)fe.getChildAt(i); 
    219                     if (!FinrocTypeInfo.isMethodType(remotePort.getPort().getDataType(), true)) { 
     219                    if ((remotePort.getDataType().getTypeTraits() & DataTypeBase.IS_RPC_TYPE) == 0) { 
    220220                        boolean output = (remotePort.getFlags() & FrameworkElementFlags.IS_OUTPUT_PORT) != 0; 
    221221                        one |= output; 
     
    239239                if (fe.getChildAt(i) instanceof RemotePort) { 
    240240                    RemotePort remotePort = (RemotePort)fe.getChildAt(i); 
    241                     if (!FinrocTypeInfo.isMethodType(remotePort.getPort().getDataType(), true)) { 
     241                    if ((remotePort.getDataType().getTypeTraits() & DataTypeBase.IS_RPC_TYPE) == 0) { 
    242242                        boolean input = (remotePort.getFlags() & FrameworkElementFlags.IS_OUTPUT_PORT) == 0; 
    243243                        one |= input; 
     
    402402    @SuppressWarnings("unchecked") 
    403403    public Collection<E> getEdges(final ModelNode root, Collection<V> allVertices) { 
    404         final TreeMap<E, E> result = new TreeMap<E, E>(); 
    405         final HashMap<ModelNode, V> lookup = new HashMap<ModelNode, V>(); 
    406         final ArrayList<AbstractPort> remoteEdgeDestinations = new ArrayList<AbstractPort>(); 
     404        final TreeMap<E, E> result = new TreeMap<>(); 
     405        final HashMap<ModelNode, V> lookup = new HashMap<>(); 
     406        final ArrayList<RemoteConnector> remoteConnectors = new ArrayList<>(); 
    407407        for (V v : allVertices) { 
    408408            lookup.put(v.getModelElement(), v); 
    409409        } 
    410410        for (RemotePort port : root.getPortsBelow(null)) { 
    411             NetPort np = port.getPort().asNetPort(); 
    412             remoteEdgeDestinations.clear(); 
    413             int reverseIndex = np.getRemoteEdgeDestinations(remoteEdgeDestinations); 
    414             for (int i = 0; i < remoteEdgeDestinations.size(); i++) { 
    415                 AbstractPort destPort = remoteEdgeDestinations.get(i); 
    416                 boolean reverseEdge = (i >= reverseIndex); 
    417                 GetParentResult src = getParentInGraph(lookup, port); 
    418                 for (RemotePort destTemp : RemotePort.get(destPort)) { 
    419                     GetParentResult dest = getParentInGraph(lookup, destTemp); 
    420                     if (src.parent != null && dest.parent != null && src.parent != dest.parent) { 
    421                         GetParentResult src2 = reverseEdge ? dest : src; 
    422                         GetParentResult dest2 = reverseEdge ? src : dest; 
    423                         E eNew = createEdgeInstance(src2.parent, dest2.parent); 
    424                         eNew.source = src2.parent; 
    425                         eNew.destination = dest2.parent; 
    426                         E e = result.get(eNew); 
    427                         if (e == null) { 
    428                             e = eNew; 
    429                             result.put(eNew, eNew); 
     411            //NetPort np = port.getPort().asNetPort(); 
     412            remoteConnectors.clear(); 
     413            RemoteRuntime remoteRuntime = RemoteRuntime.find(port); 
     414            remoteRuntime.getConnectors(remoteConnectors, port); 
     415            //int reverseIndex = np.getRemoteEdgeDestinations(remoteConnectors); 
     416            for (int i = 0; i < remoteConnectors.size(); i++) { 
     417                RemoteConnector connector = remoteConnectors.get(i); 
     418                if (port.getRemoteHandle() == connector.getOwnerPortHandle() && remoteRuntime == connector.getOwnerRuntime()) { // avoid processing connectors twice: as both ports of relevant edges are below graph, only process when 'port' is owner port 
     419                    boolean reverseEdge = (connector instanceof RemoteUriConnector) && ((RemoteUriConnector)connector).getCurrentPartner() == port; 
     420                    GetParentResult src = getParentInGraph(lookup, port); 
     421                    RemotePort destinationPort = connector.getPartnerPort(port, remoteRuntime); 
     422                    for (RemotePort destTemp : RemotePort.get(destinationPort.getPort())) { 
     423                        GetParentResult dest = getParentInGraph(lookup, destTemp); 
     424                        if (src.parent != null && dest.parent != null && src.parent != dest.parent) { 
     425                            GetParentResult src2 = reverseEdge ? dest : src; 
     426                            GetParentResult dest2 = reverseEdge ? src : dest; 
     427                            E eNew = createEdgeInstance(src2.parent, dest2.parent); 
     428                            eNew.source = src2.parent; 
     429                            eNew.destination = dest2.parent; 
     430                            E e = result.get(eNew); 
     431                            if (e == null) { 
     432                                e = eNew; 
     433                                result.put(eNew, eNew); 
     434                            } 
     435                            e.dataTypeFlags |= src2.dataTypeFlags | dest2.dataTypeFlags; 
     436                            e.addConnection(port, destTemp); 
    430437                        } 
    431                         e.dataTypeFlags |= src2.dataTypeFlags | dest2.dataTypeFlags; 
    432                         e.addConnection(port, destTemp); 
    433438                    } 
    434439                } 
  • views/StandardViewGraphViz.java

    r232 r254  
    6969import org.finroc.core.FrameworkElementFlags; 
    7070import org.finroc.core.RuntimeEnvironment; 
    71 import org.finroc.core.finstructable.EditableInterfaces; 
    7271import org.finroc.core.parameter.StaticParameterList; 
    73 import org.finroc.core.port.AbstractPort; 
    7472import org.finroc.core.port.ThreadLocalCache; 
    75 import org.finroc.core.port.net.NetPort; 
     73import org.finroc.core.remote.RemoteEditableInterfaces; 
    7674import org.finroc.core.remote.ModelNode; 
     75import org.finroc.core.remote.RemoteConnector; 
    7776import org.finroc.core.remote.RemoteFrameworkElement; 
    7877import org.finroc.core.remote.RemotePort; 
    7978import org.finroc.core.remote.RemoteRuntime; 
     79import org.finroc.core.remote.RemoteStaticParameterList; 
    8080import org.finroc.core.util.Files; 
    8181import org.finroc.plugins.data_types.StdStringList; 
     
    9393import org.rrlib.logging.Log; 
    9494import org.rrlib.logging.LogLevel; 
     95import org.rrlib.serialization.BinaryInputStream; 
    9596import org.rrlib.xml.XMLNode; 
    9697 
     
    353354            } 
    354355            if (!keepVerticesAndEdges) { 
     356                getFinstruct().getIoInterface().updateUriConnectors(); 
    355357                final ModelNode root = getRootElement(); 
    356358 
     
    11501152            final ArrayList<ModelNode> srcPorts = new ArrayList<ModelNode>(); 
    11511153            final HashSet<ModelNode> destPorts = new HashSet<ModelNode>(); 
    1152             final ArrayList<AbstractPort> remoteEdgeDestinations = new ArrayList<AbstractPort>(); 
    1153  
    1154             // all forward edges 
    1155             if (getSource().getModelElement() != null) { 
     1154            final ArrayList<RemoteConnector> remoteConnectors = new ArrayList<RemoteConnector>(); 
     1155 
     1156            if (getSource().getModelElement() != null && getDestination().getModelElement() != null) { 
    11561157                ArrayList<RemotePort> remotePorts = getSource().getModelElement().getPortsBelow(null); 
    11571158                for (RemotePort remotePort : remotePorts) { 
    1158                     NetPort np = remotePort.getPort().asNetPort(); 
    1159                     if (np != null) { 
    1160                         boolean added = false; 
    1161                         remoteEdgeDestinations.clear(); 
    1162                         int reverseIndex = np.getRemoteEdgeDestinations(remoteEdgeDestinations); 
    1163                         for (int i = 0; i < reverseIndex; i++) { 
    1164                             AbstractPort port = remoteEdgeDestinations.get(i); 
    1165                             for (RemotePort remoteDestPort : RemotePort.get(port)) { 
    1166                                 if (remoteDestPort.isNodeAncestor(getDestination().getModelElement())) { 
    1167                                     destPorts.add(remoteDestPort); 
    1168                                     if (!added) { 
    1169                                         srcPorts.add(remotePort); 
    1170                                         added = true; 
    1171                                     } 
    1172                                 } 
    1173                             } 
    1174                         } 
    1175                     } 
    1176                 } 
    1177             } 
    1178  
    1179             // reverse network edges 
    1180             if (getDestination().getModelElement() != null) { 
    1181                 ArrayList<RemotePort> remotePorts = getDestination().getModelElement().getPortsBelow(null); 
    1182                 for (RemotePort remotePort : remotePorts) { 
    1183                     NetPort np = remotePort.getPort().asNetPort(); 
    1184                     if (np != null) { 
    1185                         remoteEdgeDestinations.clear(); 
    1186                         int reverseIndex = np.getRemoteEdgeDestinations(remoteEdgeDestinations); 
    1187                         for (int i = reverseIndex; i < remoteEdgeDestinations.size(); i++) { 
    1188                             AbstractPort port = remoteEdgeDestinations.get(i); 
    1189                             for (RemotePort remoteSourcePort : RemotePort.get(port)) { 
    1190                                 if (remoteSourcePort.isNodeAncestor(getSource().getModelElement())) { 
    1191                                     if (!srcPorts.contains(remoteSourcePort)) { 
    1192                                         srcPorts.add(remoteSourcePort); 
    1193                                     } 
    1194                                     if (!destPorts.contains(remotePort)) { 
    1195                                         destPorts.add(remotePort); 
    1196                                     } 
     1159                    boolean added = false; 
     1160                    remoteConnectors.clear(); 
     1161                    RemoteRuntime remoteRuntime = RemoteRuntime.find(remotePort); 
     1162                    remoteRuntime.getConnectors(remoteConnectors, remotePort); 
     1163                    for (RemoteConnector connector : remoteConnectors) { 
     1164                        RemotePort partner = connector.getPartnerPort(remotePort, remoteRuntime); 
     1165                        for (RemotePort remoteDestPort : RemotePort.get(partner.getPort())) { 
     1166                            if (remoteDestPort.isNodeAncestor(getDestination().getModelElement())) { 
     1167                                destPorts.add(remoteDestPort); 
     1168                                if (!added) { 
     1169                                    srcPorts.add(remotePort); 
     1170                                    added = true; 
    11971171                                } 
    11981172                            } 
     
    15131487        } else if (ae.getSource() == miEditModule) { 
    15141488            if (rightClickedOn instanceof RemoteFrameworkElement) { 
    1515                 new ParameterEditDialog(getFinstruct()).show((RemoteFrameworkElement)rightClickedOn, true, false); 
     1489                try { 
     1490                    new ParameterEditDialog(getFinstruct()).show((RemoteFrameworkElement)rightClickedOn, true, false); 
     1491                } catch (Exception e) { 
     1492                    Finstruct.showErrorMessage(e, true); 
     1493                } 
    15161494                refreshViewAfter(500); 
    15171495            } 
     
    15231501        } else if (ae.getSource() == miEditInterfaces) { 
    15241502            if (rightClickedOn instanceof RemoteFrameworkElement) { 
    1525                 new ParameterEditDialog(getFinstruct()).show((RemoteFrameworkElement)rightClickedOn, true, true); 
     1503                try { 
     1504                    new ParameterEditDialog(getFinstruct()).show((RemoteFrameworkElement)rightClickedOn, true, true); 
     1505                } catch (Exception e) { 
     1506                    Finstruct.showErrorMessage(e, true); 
     1507                } 
    15261508                refreshViewAfter(500); 
    15271509            } 
     
    16941676                    if (rightClickedOn instanceof RemoteFrameworkElement) { 
    16951677                        try { 
    1696                             StaticParameterList parameterList = (StaticParameterList)rr.getAdminInterface().getAnnotation( 
    1697                                                                     ((RemoteFrameworkElement)rightClickedOn).getRemoteHandle(), StaticParameterList.TYPE); 
    1698                             miEditModule.setEnabled(parameterList != null); 
     1678                            BinaryInputStream staticParameterListStream = rr.getAdminInterface().getAnnotation(((RemoteFrameworkElement)rightClickedOn).getRemoteHandle(), StaticParameterList.TYPE.getName(), rr); 
     1679                            miEditModule.setEnabled(staticParameterListStream != null); 
    16991680                        } catch (Exception exception) {} 
    17001681                    } 
     
    17131694                            if (structureFile.length() == 0) { 
    17141695                                try { 
    1715                                     StaticParameterList parameterList = (StaticParameterList)rr.getAdminInterface().getAnnotation( 
    1716                                                                             finstructableGroup.getRemoteHandle(), StaticParameterList.TYPE); 
     1696                                    RemoteStaticParameterList parameterList = new RemoteStaticParameterList(); 
     1697                                    parameterList.deserialize(rr.getAdminInterface().getAnnotation(finstructableGroup.getRemoteHandle(), StaticParameterList.TYPE.getName(), rr)); 
    17171698                                    for (int i = 0; i < parameterList.size(); i++) { 
    17181699                                        if (parameterList.get(i).getName().equalsIgnoreCase("xml file")) { 
    1719                                             structureFile = parameterList.get(i).valPointer().getData().toString(); 
     1700                                            structureFile = parameterList.get(i).getValue().getData().toString(); 
    17201701                                            break; 
    17211702                                        } 
     
    17361717                        if (((RemoteFrameworkElement)rightClickedOn).getFlag(FrameworkElementFlags.FINSTRUCTABLE_GROUP)) { 
    17371718                            try { 
    1738                                 EditableInterfaces editableInterfaces = (EditableInterfaces)rr.getAdminInterface().getAnnotation( 
    1739                                         ((RemoteFrameworkElement)rightClickedOn).getRemoteHandle(), EditableInterfaces.TYPE); 
    1740                                 miEditInterfaces.setEnabled(editableInterfaces != null); 
     1719                                BinaryInputStream editableInterfacesStream = rr.getAdminInterface().getAnnotation(((RemoteFrameworkElement)rightClickedOn).getRemoteHandle(), RemoteEditableInterfaces.TYPE_NAME, rr); 
     1720                                miEditInterfaces.setEnabled(editableInterfacesStream != null); 
    17411721                            } catch (Exception exception) {} 
    17421722                        } 
Note: See TracChangeset for help on using the changeset viewer.