2121 * @author Dan Royer
2222 * @since 2022-02-01
2323 */
24- public class Graph extends Node {
24+ public class Graph {
2525 private static final Logger logger = LoggerFactory .getLogger (Graph .class );
2626
2727 /**
@@ -34,11 +34,21 @@ public class Graph extends Node {
3434 */
3535 private final List <Connection > connections = new ArrayList <>();
3636
37+ /**
38+ * the {@link Input} ports of this graph. The ports are owned by nodes in this graph.
39+ */
40+ private final List <Input <?>> inputs = new ArrayList <>();
41+
42+ /**
43+ * the {@link Output} ports of this graph. The ports are owned by nodes in this graph.
44+ */
45+ private final List <Output <?>> outputs = new ArrayList <>();
46+
3747 /**
3848 * Constructor for subclasses to call. Creates an empty {@link Graph}.
3949 */
4050 public Graph () {
41- super ("Graph" );
51+ super ();
4252 }
4353
4454 /**
@@ -340,11 +350,10 @@ public boolean isEmpty() {
340350 public Rectangle getBounds () {
341351 if (nodes .isEmpty ()) return null ;
342352
343- Rectangle r =new Rectangle (nodes .get (0 ).getRectangle ());
344- for (Node n : nodes ) {
345- r .add (n .getRectangle ());
346- // for very small graphs this is a redundant union with self.
347- // For very large graphs this avoids any 'if' in the loop and saves time.
353+ var i = nodes .iterator ();
354+ Rectangle r = new Rectangle (i .next ().getRectangle ());
355+ while (i .hasNext ()) {
356+ r .add (i .next ().getRectangle ());
348357 }
349358 return r ;
350359 }
@@ -359,15 +368,14 @@ public void updateBounds() {
359368 }
360369
361370 public @ Nonnull JSONObject toJSON () {
362- JSONObject jo = super . toJSON ();
371+ JSONObject jo = new JSONObject ();
363372 jo .put ("nodes" ,getAllNodesAsJSON ());
364373 jo .put ("connections" ,getAllNodeConnectionsAsJSON ());
365374 return jo ;
366375 }
367376
368377 public void fromJSON (JSONObject jo ) throws JSONException {
369378 clear ();
370- super .fromJSON (jo );
371379 parseAllNodesFromJSON (jo .getJSONArray ("nodes" ));
372380 parseAllConnectionsFromJSON (jo .getJSONArray ("connections" ));
373381 }
@@ -494,7 +502,7 @@ public List<Connection> getInteriorConnections(List<Node> selectedNodes) {
494502 private List <Connection > getConnectionsCounted (List <Node > selectedNodes , int count ) {
495503 ArrayList <Connection > found = new ArrayList <>();
496504
497- for (Connection c : getConnections () ) {
505+ for (Connection c : connections ) {
498506 int hits =0 ;
499507 for (Node n : selectedNodes ) {
500508 if (c .isConnectedTo (n )) {
@@ -520,9 +528,61 @@ public void reset() {
520528 * @return true if the {@link Port} is attached to a {@link Connection}.
521529 */
522530 public boolean isPortConnected (Port <?> port ) {
523- for (Connection c : getConnections () ) {
531+ for (Connection c : connections ) {
524532 if (c .getInput ()==port || c .getOutput ()==port ) return true ;
525533 }
526534 return false ;
527535 }
536+
537+ /**
538+ *
539+ * @param selectedNodes the set of {@link Node}s.
540+ * @return a list of all {@link Port} in the input and output list that are owned by the selected {@link Node}s.
541+ */
542+ public List <Port <?>> getGraphPorts (List <Node > selectedNodes ) {
543+ List <Port <?>> list = new ArrayList <>();
544+ for (Node n : selectedNodes ) {
545+ for (Port <?> p : n .getPorts ()) {
546+ if (p instanceof Output <?> out && !outputs .contains (out )) list .add (out );
547+ else if (p instanceof Input <?> in && !inputs .contains (in )) list .add (in );
548+ }
549+ }
550+ return list ;
551+ }
552+
553+ /**
554+ * Remove some externally visible {@link Port}s from the graph.
555+ * @param graphPorts the list of {@link Port}s to remove.
556+ */
557+ public void removePorts (List <Port <?>> graphPorts ) {
558+ for (Port <?> p : graphPorts ) {
559+ if (p instanceof Output <?> out ) outputs .remove (out );
560+ else if (p instanceof Input <?> in ) inputs .remove (in );
561+ }
562+ }
563+
564+ /**
565+ * Add some externally visible {@link Port}s to the graph.
566+ * @param graphPorts the list of {@link Port}s to add.
567+ */
568+ public void addPorts (List <Port <?>> graphPorts ) {
569+ for (Port <?> p : graphPorts ) {
570+ if (p instanceof Output <?> out ) outputs .add (out );
571+ else if (p instanceof Input <?> in ) inputs .add (in );
572+ }
573+ }
574+
575+ /**
576+ * @return a copy of the list of externally visible {@link Input}s.
577+ */
578+ public List <Input <?>> getInputs () {
579+ return new ArrayList <>(inputs );
580+ }
581+
582+ /**
583+ * @return a copy of the list of externally visible {@link Output}s.
584+ */
585+ public List <Output <?>> getOutputs () {
586+ return new ArrayList <>(outputs );
587+ }
528588}
0 commit comments