From c1e3bfc17029c692da9cd2fc8be29a3100377226 Mon Sep 17 00:00:00 2001 From: lthms Date: Sat, 13 Jan 2018 20:19:54 +0000 Subject: systems: Allow to inject per-system options when registering a puppet --- lib/lkn/core/instance.ex | 15 ++++++++++----- lib/lkn/core/system.ex | 14 +++++++------- test/core_test.exs | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/lib/lkn/core/instance.ex b/lib/lkn/core/instance.ex index 6e223ed..40d5f9a 100644 --- a/lib/lkn/core/instance.ex +++ b/lib/lkn/core/instance.ex @@ -218,9 +218,9 @@ defmodule Lkn.Core.Instance do Under the hood, this function dispatches the register event to each system the Puppet has a Component for. """ - @spec register_puppet(k, Puppet.k) :: boolean - def register_puppet(instance_key, puppet_key) do - GenServer.call(Lkn.Core.Name.instance(instance_key), {:register_puppet, puppet_key}) + @spec register_puppet(k, Puppet.k, %{Lkn.Core.System.m => Keyworld.t}) :: boolean + def register_puppet(instance_key, puppet_key, opts \\ %{}) do + GenServer.call(Lkn.Core.Name.instance(instance_key), {:register_puppet, puppet_key, opts}) end @doc """ @@ -310,7 +310,7 @@ defmodule Lkn.Core.Instance do {:zombie, _} -> {:stop, :normal, true, state} end end - def handle_call({:register_puppet, puppet_key}, _from, state) do + def handle_call({:register_puppet, puppet_key, sys_opts}, _from, state) do # add the puppet to our list if MapSet.member?(state.puppets, puppet_key) do {:reply, false, state} @@ -331,7 +331,12 @@ defmodule Lkn.Core.Instance do _ = Enum.map(sys_map, fn sys -> try do - Lkn.Core.System.register_puppet(state.instance_key, sys, puppet_key) + Lkn.Core.System.register_puppet( + state.instance_key, + sys, + puppet_key, + Map.get(sys_opts, sys, []) + ) rescue _ -> nil end diff --git a/lib/lkn/core/system.ex b/lib/lkn/core/system.ex index c57dd54..a15ab3e 100644 --- a/lib/lkn/core/system.ex +++ b/lib/lkn/core/system.ex @@ -38,7 +38,7 @@ defmodule Lkn.Core.System do # return some state end - def puppet_enter(state, _instance_key, _map_key, _puppets, _puppet_key) + def puppet_enter(state, _instance_key, _map_key, _puppets, _puppet_key, opts) # we do nothing, but we could state end @@ -200,7 +200,7 @@ defmodule Lkn.Core.System do instance. With the `map_key`, you can request through the Map Component some information about the map. """ - @callback init_state(instance_key :: Instance.k, map_key :: Map.k) :: state + @callback init_state(instance_key :: Instance.k, map_key :: Map.k, opts :: Keyword.t) :: state @doc """ A hook function which is called when a “compatible” puppet enters the Instance. @@ -278,10 +278,10 @@ defmodule Lkn.Core.System do {:noreply, state} end - defp priv_handle_call({:register_puppet, entity_key}, _from, state) do + defp priv_handle_call({:register_puppet, entity_key, opts}, _from, state) do if Lkn.Core.Entity.has_component?(entity_key, __MODULE__) do state = PrivateState.put(state, entity_key) - opts = puppet_enter(state.state, state.instance_key, state.map_key, state.puppets, entity_key) + opts = puppet_enter(state.state, state.instance_key, state.map_key, state.puppets, entity_key, opts) {:reply, true, PrivateState.update(state, opts)} else @@ -343,9 +343,9 @@ defmodule Lkn.Core.System do end @doc false - @spec register_puppet(Instance.k, m, Puppet.k) :: boolean - def register_puppet(instance_key, system, puppet_key) do - GenServer.call(Name.system(instance_key, system), {:priv, {:register_puppet, puppet_key}}) + @spec register_puppet(Instance.k, m, Puppet.k, Keyword.t) :: boolean + def register_puppet(instance_key, system, puppet_key, opts) do + GenServer.call(Name.system(instance_key, system), {:priv, {:register_puppet, puppet_key, opts}}) end @doc false diff --git a/test/core_test.exs b/test/core_test.exs index 5d7d205..76409dd 100644 --- a/test/core_test.exs +++ b/test/core_test.exs @@ -207,6 +207,38 @@ defmodule Lkn.Core.Test do end end + test "register_puppet and option for system" do + map_key = UUID.uuid4() + puppeteer_key = UUID.uuid4() + + {:ok, _} = Test.Puppeteer.start_link(puppeteer_key) + + {:ok, _} = Test.Map.start_link(map_key) + :ok = Lkn.Core.Pool.spawn_pool(map_key) + + instance_key = Puppeteer.find_instance(puppeteer_key, map_key) + + entity_key = UUID.uuid4() + + {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self()) + + Lkn.Core.Instance.register_puppet( + instance_key, + entity_key, + Map.put(Map.new, Test.System, [ping: self()]) + ) + + receive do + :pong -> :ok + after 100 -> assert false + end + + receive do + {:enter, x} -> assert x == entity_key + after 100 -> raise "Waiting for 100ms the message {:enter, #{inspect entity_key}}" + end + end + test "level up" do map_key = UUID.uuid4() puppeteer_key = UUID.uuid4() @@ -415,7 +447,12 @@ defsystem Test.System do Lkn.Core.System.start_link(__MODULE__, instance_key, map_key) end - def puppet_enter(:ok, _instance_key, _map_key, _entities, key) do + def puppet_enter(:ok, _instance_key, _map_key, _entities, key, opts) do + if Keyword.has_key?(opts, :ping) do + target = Keyword.fetch!(opts, :ping) + send target, :pong + end + notify(&(Test.Puppeteer.Specs.emit(&1, {:enter, key}))) cast_return() -- cgit v1.2.3