defmodule Scopes.CSys do require Logger alias Scopes.Core.Actor alias Scopes.Shape def neuron(scope) do #Logger.info([scope: inspect(scope)]) Actor.create(fn msg -> process(msg, scope) end) end def update_neuron(scope) do Actor.become(self(), fn msg -> process(msg, scope) end) end def synapse(rcvr, op, delay \\ 0) do fn msg -> Actor.send(rcvr, op.(msg), delay) end end # message handlers / proc steps def process(msg, scope) do proc(scope).(msg, scope) end def notify(msg, scope) do Actor.send(env(scope), msg) end def forward(msg, scope) do Enum.reduce(syns(scope), false, fn s, _acc -> s.(msg); true end) end # synapse operations def noop(), do: fn msg -> msg end def filter_head(pat) do fn msg -> if List.starts_with?(Shape.head(msg), pat), do: msg end end def data_only(), do: filter_head([:csys, :data]) # send shortcuts def send_message(rcvr, head, data \\ %{}) do Logger.info([rcvr: inspect(rcvr), head: inspect(head), data: inspect(data)]) Actor.send(rcvr, Shape.create(head, data: data)) end def send_value(rcvr, val) do send_message(rcvr, [:csys, :data], %{value: val}) end # notifications def notify_created(new, scope) do msg = Shape.create([:csys, :created], data: %{old: self(), new: new}) notify(msg, scope) end # scope access shortcuts def state(scope), do: elem(scope, 0) def proc(scope), do: elem(scope, 1) def syns(scope), do: elem(scope, 2) def env(scope), do: elem(scope, 3) end