22
33import com .google .common .eventbus .EventBus ;
44import com .google .common .eventbus .Subscribe ;
5+ import com .google .inject .Inject ;
6+ import com .google .inject .assistedinject .Assisted ;
57import com .thoughtworks .xstream .annotations .XStreamAlias ;
6- import edu .wpi .grip .core .events .ConnectionRemovedEvent ;
7- import edu .wpi .grip .core .events .SocketChangedEvent ;
8- import edu .wpi .grip .core .events .SourceRemovedEvent ;
9- import edu .wpi .grip .core .events .StepRemovedEvent ;
8+ import edu .wpi .grip .core .events .*;
109
1110import static com .google .common .base .Preconditions .checkArgument ;
12- import static com .google .common .base .Preconditions .checkNotNull ;
1311
1412/**
1513 * A connection is a rule that causes one socket to update to always the value of another socket.
1614 */
1715@ XStreamAlias (value = "grip:Connection" )
1816public class Connection <T > {
17+
1918 private final EventBus eventBus ;
2019 private final OutputSocket <? extends T > outputSocket ;
2120 private final InputSocket <T > inputSocket ;
2221
22+
23+ public interface Factory <T > {
24+ Connection <T > create (OutputSocket <? extends T > outputSocket , InputSocket <T > inputSocket );
25+ }
26+
2327 /**
24- * @param eventBus The Guava {@link EventBus} used by the application .
28+ * @param pipeline The pipeline to create the connection inside of .
2529 * @param outputSocket The socket to listen for changes in.
2630 * @param inputSocket A different socket to update when a change occurs in the first.
2731 */
28- public Connection (EventBus eventBus , OutputSocket <? extends T > outputSocket , InputSocket <T > inputSocket ) {
32+ @ Inject
33+ Connection (EventBus eventBus , Pipeline pipeline , @ Assisted OutputSocket <? extends T > outputSocket , @ Assisted InputSocket <T > inputSocket ) {
2934 this .eventBus = eventBus ;
3035 this .outputSocket = outputSocket ;
3136 this .inputSocket = inputSocket ;
32-
33- checkNotNull (inputSocket );
34- checkNotNull (outputSocket );
35- checkNotNull (eventBus );
36- checkArgument (Connection .canConnect (outputSocket , inputSocket ), "Cannot connect sockets" );
37-
38- inputSocket .setValueOptional (outputSocket .getValue ());
39-
40- eventBus .register (this );
41- }
42-
43- /**
44- * @return true if a connection can be made from the given output socket to the given input socket
45- */
46- @ SuppressWarnings ("unchecked" )
47- public static boolean canConnect (Socket socket1 , Socket socket2 ) {
48- final OutputSocket <?> outputSocket ;
49- final InputSocket <?> inputSocket ;
50-
51- // One socket must be an input and one must be an output
52- if (socket1 .getDirection () == socket2 .getDirection ()) {
53- return false ;
54- }
55-
56- if (socket1 .getDirection ().equals (Socket .Direction .OUTPUT )) {
57- outputSocket = (OutputSocket ) socket1 ;
58- inputSocket = (InputSocket ) socket2 ;
59- } else {
60- inputSocket = (InputSocket ) socket1 ;
61- outputSocket = (OutputSocket ) socket2 ;
62- }
63-
64- final SocketHint outputHint = socket1 .getSocketHint ();
65- final SocketHint inputHint = socket2 .getSocketHint ();
66-
67- // The input socket must be able to hold the type of value that the output socket contains
68- if (!inputHint .getType ().isAssignableFrom (outputHint .getType ())) {
69- return false ;
70- }
71-
72- // Input sockets can only be connected to one thing
73- if (!inputSocket .getConnections ().isEmpty ()) {
74- return false ;
75- }
76-
77- // If both sockets are in steps, the output must be before the input in the pipeline. This prevents "backwards"
78- // connections, which both enforces a well-organized pipeline and prevents feedback loops.
79- final boolean [] backwards = {false };
80- outputSocket .getStep ().ifPresent (outputStep -> inputSocket .getStep ().ifPresent (inputStep -> {
81- final Pipeline pipeline = checkNotNull (inputStep .getPipeline (), "Pipeline is null" );
82- if (!pipeline .isBefore (outputStep , inputStep )) {
83- backwards [0 ] = true ;
84- }
85- }));
86-
87- return !backwards [0 ];
88-
89-
37+ checkArgument (pipeline .canConnect (outputSocket , inputSocket ), "Cannot connect sockets" );
9038 }
9139
9240 public OutputSocket <? extends T > getOutputSocket () {
@@ -97,6 +45,13 @@ public InputSocket<T> getInputSocket() {
9745 return this .inputSocket ;
9846 }
9947
48+ @ Subscribe
49+ public void onConnectionAdded (ConnectionAddedEvent event ) {
50+ if (event .getConnection ().equals (this )) {
51+ inputSocket .setValueOptional (outputSocket .getValue ());
52+ }
53+ }
54+
10055 @ Subscribe
10156 public void onOutputChanged (SocketChangedEvent e ) {
10257 if (e .getSocket () == outputSocket ) {
0 commit comments