diff --git a/lib/csys/csys.ex b/lib/csys/csys.ex index 4c36062..ee76c68 100644 --- a/lib/csys/csys.ex +++ b/lib/csys/csys.ex @@ -82,15 +82,13 @@ defmodule Scopes.CSys do # helpers def compose(ops) do - fn msg -> - Enum.reduce(ops, msg, - fn op, val -> - case val do - nil -> nil - val -> op.(val) - end - end - ) + fn msg -> Enum.reduce(ops, msg, &bind/2) end + end + + defp bind(op, val) do + case val do + nil -> nil + val -> op.(val) end end end diff --git a/lib/csys/program.ex b/lib/csys/program.ex index 90f958b..493b8c7 100644 --- a/lib/csys/program.ex +++ b/lib/csys/program.ex @@ -1,5 +1,6 @@ defmodule Scopes.CSys.Program do - alias Scopes.CSys + require Logger +alias Scopes.CSys alias Scopes.Shape defmodule State do @@ -59,7 +60,7 @@ defmodule Scopes.CSys.Program do def basic(msg, scope) do case Shape.head(msg) do [:csys, :set | _rest] -> set(msg, scope) - #[:csys, :data | rest] -> process_data(rest, Shape.data(msg), scope) + [:csys, :data | _rest] -> process_data(msg, scope) [:csys, :connect | _rest] -> CSys.connect(msg, scope) [:csys, :create, :succ | _rest] -> create_succ(msg, scope) [:csys, :create, :pred | _rest] -> create_pred(msg, scope) @@ -71,6 +72,22 @@ defmodule Scopes.CSys.Program do # message handlers // proc steps + def process_data(msg, scope) do + data = Shape.data(msg) + state = CSys.state(scope) + value_n = state.value + data.value + Logger.info([data: data.value, state: state.value, threshold: state.threshold]) + if value_n >= state.threshold do + msg = Shape.create(Shape.head(msg), data: %{data | value: value_n}) + CSys.forward(msg, scope) || CSys.notify(msg, scope) + state_n = %{state | value: 0} + CSys.update(put_elem(scope, 0, state_n)) + else + state_n = %{state | value: value_n} + CSys.update(put_elem(scope, 0, state_n)) + end + end + def set(msg, scope) do data = Shape.data(msg) state = CSys.state(scope) diff --git a/test/csys_test.exs b/test/csys_test.exs index 2970e7f..1f146d6 100644 --- a/test/csys_test.exs +++ b/test/csys_test.exs @@ -27,22 +27,22 @@ defmodule Scopes.CSysTest do CSys.send_value(zero, 0) assert 0 = receive_data().value #CSys.send_message(zero, [:csys, :create, :pred], %{op: neg_only()}) - CSys.send_message(zero, [:csys, :create, :pred], %{op: Program.negate()}) - one = receive_data([:csys, :created]).new - CSys.send_message(one, [:csys, :create, :succ], + CSys.send_message(zero, [:csys, :create, :pred], %{op: CSys.compose([CSys.data_only(), Program.negate()])}) + one = receive_data([:csys, :created]).new + CSys.send_message(one, [:csys, :create, :succ], %{op: CSys.data_only()}) two = receive_data([:csys, :created]).new Process.sleep(1) CSys.send_value(one, 1) assert receive_data().value in [-1, 1] - assert receive_data().value in [-1, 1] + #assert receive_data().value in [-1, 1] CSys.send_message(two, [:csys, :create, :pred]) three = receive_data([:csys, :created]).new CSys.send_message(three, [:csys, :connect], %{target: zero}) Process.sleep(2) CSys.send_value(three, 3) - assert 3 = receive_data().value - assert 3 = receive_data().value + assert receive_data().value in [2, 3] + assert receive_data().value in [2, 3] Process.sleep(50) refute_received msg, "unhandled message(s): #{inspect(msg)}" end