Explorar el Código

Changed the type of the switch operation.

switch now closes over the possible branches. This fixes edge cases where the
operation switches over a tag without any other input. With the old definition,
all branches would immediately fire, since they require no input.
Paul Downen hace 13 años
padre
commit
1b5c35c989
Se han modificado 2 ficheros con 19 adiciones y 16 borrados
  1. 7 4
      include/ebb_prim.hrl
  2. 12 12
      src/ebb_prim.erl

+ 7 - 4
include/ebb_prim.hrl

@@ -56,8 +56,11 @@
 %% merge_N(A_1 * ... * A_N, unit(A_1 * ... * A_N)) ::= { size = N : number }
 -record(merge, {size}).
 
-%% switch_I,N((T_1 + ... + T_I) * A_1 * ... * A_N, 
-%%            duplicate(I, A_1 * ... * A_N)) ::=
-%%   { in = 1+N : number, out = I*N : number,
-%%     map    : [ {T_J, J} || J <- [1..I] ] }
+%% switch_Op_1,...,Op_I((T_1 + ... + T_I) * A_1 * ... * A_N, 
+%%                      (B_1_1 + ... + B_I_1) * ... * (B_1_M + ... + B_I_M)) ::=
+%%   { in = 1+N : number, out = M : number,
+%%     map    : [ {T_J, Op_J} || J <- [1..I] ] }
+%%   where Op_1 : A_1 * ... * A_N |->| B_1_1 * ... * B_1_M
+%%         ...
+%%         Op_I : A_1 * ... * A_N |->| B_I_1 * ... * B_I_M
 -record(switch, {in, out, map}).

+ 12 - 12
src/ebb_prim.erl

@@ -6,7 +6,8 @@
 	 value/1, values/1,
 	 pipe/1, par/1,
 	 route/3, sync/1,
-	 split/1, merge/1, switch/2]).
+	 split/1, merge/1,
+	 switch/1]).
 
 %%% Operation querying
 -export([in_arity/1, out_arity/1, flatten_arity/1, can_connect/2]).
@@ -64,17 +65,16 @@ split(N) when is_number(N) -> #split{size=N}.
 
 merge(N) when is_number(N) -> #merge{size=N}.
 
-switch(N, Map = [_|_]) when is_number(N) ->
-    SMap = lists:ukeysort(2, Map),
-    try
-	lists:foldl(fun({_T_I, I}, Prev_I) when I == 1+Prev_I -> I;
-		       ({_T_I, _I}, _Prev_I) -> throw(missing_path)
-		    end,
-		    0, SMap)
-    of
-	I -> #switch{in=1+N, out=I*N, map=SMap}
-    catch
-	throw:missing_path -> erlang:error(badarg, [N, Map])
+switch(Map = [{_Tag1, Op1}|Rest]) ->
+    In = in_arity(Op1),
+    Out = out_arity(Op1),
+    Match = lists:all(fun({_T_I, Op}) ->
+			      in_arity(Op) == In andalso out_arity(Op) == Out
+		      end,
+		      Rest),
+    case Match of
+	true  -> #switch{in=1+In, out=Out, map=Map};
+	false -> erlang:error(badarg, [Map])
     end.
 
 %%%-----------------------------------------------------------------------------