Compare commits
2 commits
8efa448999
...
8919d99cbc
| Author | SHA1 | Date | |
|---|---|---|---|
| 8919d99cbc | |||
| 7105937324 |
5 changed files with 56 additions and 36 deletions
|
|
@ -3,13 +3,13 @@ defmodule Scopes.Core.Actor do
|
||||||
|
|
||||||
defp loop(bhv) do
|
defp loop(bhv) do
|
||||||
receive do
|
receive do
|
||||||
|
{:become, bhv_n} -> loop(bhv_n)
|
||||||
msg ->
|
msg ->
|
||||||
Logger.debug([msg: inspect(msg)])
|
Logger.debug([msg: inspect(msg)])
|
||||||
case msg do
|
case msg do
|
||||||
{:message, msg} ->
|
{:message, msg} ->
|
||||||
bhv.(msg)
|
bhv.(msg)
|
||||||
loop(bhv)
|
loop(bhv)
|
||||||
{:become, bhv_n} -> loop(bhv_n)
|
|
||||||
{:register, reg, name, value} ->
|
{:register, reg, name, value} ->
|
||||||
Registry.register(reg, name, value)
|
Registry.register(reg, name, value)
|
||||||
loop(bhv)
|
loop(bhv)
|
||||||
|
|
@ -19,11 +19,13 @@ defmodule Scopes.Core.Actor do
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(bhv) do
|
def create(bhv) do
|
||||||
spawn_link(fn -> loop(bhv) end)
|
#spawn_link(fn -> loop(bhv) end)
|
||||||
|
spawn(fn -> loop(bhv) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(bhv, reg, name, value \\ []) do
|
def create(bhv, reg, name, value \\ []) do
|
||||||
spawn_link(fn ->
|
#spawn_link(fn ->
|
||||||
|
spawn(fn ->
|
||||||
Registry.register(reg, name, value)
|
Registry.register(reg, name, value)
|
||||||
loop(bhv) end)
|
loop(bhv) end)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,13 @@ defmodule Scopes.Core do
|
||||||
fn msg -> if List.starts_with?(Shape.head(msg), pat), do: msg end
|
fn msg -> if List.starts_with?(Shape.head(msg), pat), do: msg end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def filter_address(pat) do
|
||||||
|
fn msg ->
|
||||||
|
[dom, _act | rest] = Shape.head(msg)
|
||||||
|
if List.starts_with?([dom | rest], pat), do: msg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def data_only(), do: filter_head([:csys, :data])
|
def data_only(), do: filter_head([:csys, :data])
|
||||||
|
|
||||||
# send shortcuts
|
# send shortcuts
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ defmodule Scopes.Core.Environ do
|
||||||
env_scope = {%State{init_seq: init_seq}, proc_env, [], self()}
|
env_scope = {%State{init_seq: init_seq}, proc_env, [], self()}
|
||||||
env = Core.neuron(env_scope)
|
env = Core.neuron(env_scope)
|
||||||
Actor.register(env, cells(), {:env, :c00})
|
Actor.register(env, cells(), {:env, :c00})
|
||||||
msg = Shape.create([:csys, :zero], data: %{addr: [:csys, :c00, "0-0"]})
|
msg = Shape.create([:csys, :zero], data: %{addr: {:csys, :c00, "0-0"}})
|
||||||
scope = {state, proc, [], env}
|
scope = {state, proc, [], env}
|
||||||
Core.create(msg, scope)
|
Core.create(msg, scope)
|
||||||
#{:ok, env}
|
#{:ok, env}
|
||||||
|
|
@ -33,18 +33,18 @@ defmodule Scopes.Core.Environ do
|
||||||
def proc_env(msg, scope = {state, _proc, _syns, env}) do
|
def proc_env(msg, scope = {state, _proc, _syns, env}) do
|
||||||
case Shape.head(msg) do
|
case Shape.head(msg) do
|
||||||
{:exec, func} -> func.(state)
|
{:exec, func} -> func.(state)
|
||||||
[:csys, :created | _rest] -> process_creation(msg, scope)
|
[:csys, :created | _rest] -> process_created(msg, scope)
|
||||||
_ -> send(env, msg) # forward message to application
|
_ -> send(env, msg) # forward message to application
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_creation(msg, {state, proc, syns, env}) do
|
def process_created(msg, {state, proc, syns, env}) do
|
||||||
data = Shape.data(msg)
|
data = Shape.data(msg)
|
||||||
new = data.new
|
new = data.new
|
||||||
addr = data[:addr]
|
addr = data[:addr]
|
||||||
cells = if addr do
|
cells = if addr do
|
||||||
[dom, cat, item] = addr
|
Actor.register(new, cells(), addr)
|
||||||
# update (or create and register) proxy cell
|
{dom, cat, item} = addr
|
||||||
Map.update(state.cells, {dom, cat}, %{item => new},
|
Map.update(state.cells, {dom, cat}, %{item => new},
|
||||||
fn x -> Map.put(x, item, new) end)
|
fn x -> Map.put(x, item, new) end)
|
||||||
else
|
else
|
||||||
|
|
@ -55,7 +55,8 @@ defmodule Scopes.Core.Environ do
|
||||||
Core.update({state1, proc, syns, env})
|
Core.update({state1, proc, syns, env})
|
||||||
if step do
|
if step do
|
||||||
Process.sleep(1)
|
Process.sleep(1)
|
||||||
step.(state1)
|
#step.(state1)
|
||||||
|
step.()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -72,9 +73,19 @@ defmodule Scopes.Core.Environ do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_message(addr, head, data) do
|
||||||
|
rcvr = get_cell(addr)
|
||||||
|
Core.send_message(rcvr, head, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def connect(addr = {dom, _cat, _item}, target, op \\ []) do
|
||||||
|
send_message(addr, [dom, :connect],
|
||||||
|
%{target: get_cell(target), op: op})
|
||||||
|
end
|
||||||
|
|
||||||
# accessing cell registry via state.cells
|
# accessing cell registry via state.cells
|
||||||
|
|
||||||
def get_cell(state, [dom, cat, item]) do
|
def get_cell(state, {dom, cat, item}) do
|
||||||
get_in(state.cells, [{dom, cat}, item])
|
get_in(state.cells, [{dom, cat}, item])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -83,7 +94,7 @@ defmodule Scopes.Core.Environ do
|
||||||
Core.send_message(cell, head, data)
|
Core.send_message(cell, head, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def connect(state, addr, target, op \\ []) do
|
def connect_state(state, addr, target, op \\ []) do
|
||||||
send_message(state, addr, ~w(csys connect)a,
|
send_message(state, addr, ~w(csys connect)a,
|
||||||
%{target: get_cell(state, target), op: op})
|
%{target: get_cell(state, target), op: op})
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -121,28 +121,28 @@ defmodule Scopes.Core.Program do
|
||||||
# demo init sequences
|
# demo init sequences
|
||||||
|
|
||||||
def init_seq_b1() do
|
def init_seq_b1() do
|
||||||
zero = [:csys, :c00, "0-0"]
|
zero = {:csys, :c00, "0-0"}
|
||||||
one = [:csys, :s01, "1-0"]
|
one = {:csys, :s01, "1-0"}
|
||||||
two = [:csys, :c00, "1-1"]
|
two = {:csys, :c00, "1-1"}
|
||||||
three = [:csys, :s01, "1-1"]
|
three = {:csys, :s01, "1-1"}
|
||||||
[
|
[
|
||||||
&Environ.send_message(&1, zero, ~w(csys create)a,
|
fn -> Environ.send_message(zero, ~w(csys create)a,
|
||||||
%{op: [Core.data_only(), negate()], addr: one, dir: :pred}),
|
%{op: [Core.data_only(), negate()], addr: one, dir: :pred}) end,
|
||||||
&Environ.send_message(&1, one, ~w(csys create)a,
|
fn -> Environ.send_message(one, ~w(csys create)a,
|
||||||
%{op: Core.data_only(), addr: two, dir: :succ}),
|
%{op: Core.data_only(), addr: two, dir: :succ}) end,
|
||||||
&Environ.send_message(&1, two, ~w(csys create)a,
|
fn -> Environ.send_message(two, ~w(csys create)a,
|
||||||
%{addr: three, dir: :pred}),
|
%{addr: three, dir: :pred}) end,
|
||||||
&Environ.connect(&1, three, zero)
|
fn -> Environ.connect(three, zero) end
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
def init_recursive_1() do
|
def init_recursive_1() do
|
||||||
zero = [:csys, :c00, "0-0"]
|
zero = {:csys, :c00, "0-0"}
|
||||||
[
|
[
|
||||||
&Environ.send_message(&1, zero, ~w(csys create)a, %{dir: :succ}),
|
fn -> Environ.send_message(zero, ~w(csys create)a, %{dir: :succ}) end,
|
||||||
&Environ.send_message(&1, zero, ~w(csys create)a,
|
fn -> Environ.send_message(zero, ~w(csys create)a,
|
||||||
%{addr: [:csys, :s01, "1-1"], dir: :pred}),
|
%{addr: {:csys, :s01, "1-1"}, dir: :pred}) end,
|
||||||
&Environ.connect(&1, zero, zero, negate())
|
fn -> Environ.connect(zero, zero, negate()) end
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -18,28 +18,28 @@ defmodule Scopes.CoreTest do
|
||||||
describe "core-basic:" do
|
describe "core-basic:" do
|
||||||
test "minimal-b1" do
|
test "minimal-b1" do
|
||||||
Environ.setup(Program.prepare_basic(), Program.init_seq_b1())
|
Environ.setup(Program.prepare_basic(), Program.init_seq_b1())
|
||||||
Process.sleep(10)
|
Process.sleep(5)
|
||||||
env = Environ.get_cell({:env, :c00})
|
env = Environ.get_cell({:env, :c00})
|
||||||
Environ.forward_value(env, [:csys, :c00, "0-0"], 0)
|
Environ.forward_value(env, {:csys, :c00, "0-0"}, 0)
|
||||||
assert 0 = receive_data().value
|
assert 0 = receive_data().value
|
||||||
Environ.forward_value(env, [:csys, :s01, "1-0"], 1)
|
Environ.forward_value(env, {:csys, :s01, "1-0"}, 1)
|
||||||
assert receive_data().value == 1
|
assert receive_data().value == 1
|
||||||
#assert receive_data().value in [-1, 1]
|
#assert receive_data().value in [-1, 1]
|
||||||
Environ.forward_value(env, [:csys, :s01, "1-1"], 3)
|
Environ.forward_value(env, {:csys, :s01, "1-1"}, 3)
|
||||||
assert receive_data().value in [2, 3]
|
assert receive_data().value in [2, 3]
|
||||||
assert receive_data().value in [2, 3]
|
assert receive_data().value in [2, 3]
|
||||||
refute_receive msg, 10, "unhandled message(s): #{inspect(msg)}"
|
refute_receive msg, 5, "unhandled message(s): #{inspect(msg)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "recursive-1" do
|
test "recursive-1" do
|
||||||
Environ.setup(Program.prepare_basic(), Program.init_recursive_1())
|
Environ.setup(Program.prepare_basic(), Program.init_recursive_1())
|
||||||
Process.sleep(10)
|
Process.sleep(5)
|
||||||
env = Environ.get_cell({:env, :c00})
|
env = Environ.get_cell({:env, :c00})
|
||||||
Environ.forward_value(env, [:csys, :s01, "1-1"], 42)
|
Environ.forward_value(env, {:csys, :s01, "1-1"}, 42)
|
||||||
assert receive_data().value == 42
|
assert receive_data().value == 42
|
||||||
Environ.forward_value(env, [:csys, :s01, "1-1"], 47)
|
Environ.forward_value(env, {:csys, :s01, "1-1"}, 47)
|
||||||
assert receive_data().value == 5
|
assert receive_data().value == 5
|
||||||
refute_receive msg, 10, "unhandled message(s): #{inspect(msg)}"
|
refute_receive msg, 5, "unhandled message(s): #{inspect(msg)}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue