45 lines
1.1 KiB
Elixir
45 lines
1.1 KiB
Elixir
defmodule Scopes.CSys.Environ do
|
|
|
|
alias Scopes.CSys
|
|
alias Scopes.Shape
|
|
|
|
defmodule State do
|
|
defstruct [neurons: [], cells: %{}, init_seq: []]
|
|
end
|
|
|
|
def setup({state, proc}, seq \\ []) do
|
|
scope = {%State{init_seq: seq}, &proc_env/2, [], self()}
|
|
env = CSys.neuron(scope)
|
|
CSys.create(Shape.create([:csys, :zero]), {state, proc, [], env})
|
|
env
|
|
end
|
|
|
|
def proc_env(msg, scope) do
|
|
case Shape.head(msg) do
|
|
[:csys, :created | _rest] -> process_creation(msg, scope)
|
|
_ -> nil
|
|
end
|
|
send(CSys.env(scope), msg)
|
|
end
|
|
|
|
def process_creation(msg, {state, proc, syns, env}) do
|
|
data = Shape.data(msg)
|
|
new = data.new
|
|
addr = data[:addr]
|
|
cells = if addr do
|
|
[dom, cat, item] = addr
|
|
Map.update(state.cells, {dom, cat}, %{item => new},
|
|
fn x -> Map.put(x, item, new) end)
|
|
else
|
|
state.cells
|
|
end
|
|
neurons = [new | state.neurons]
|
|
{step, seq} = List.pop_at(state.init_seq, 0)
|
|
state1 = %State{neurons: neurons, cells: cells, init_seq: seq}
|
|
CSys.update({state1, proc, syns, env})
|
|
if step do
|
|
Process.sleep(1)
|
|
step.(env, state1)
|
|
end
|
|
end
|
|
end
|