aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlthms <contact@thomasletan.fr>2017-12-29 14:42:32 +0000
committerThomas Letan <contact@thomasletan.fr>2018-01-24 08:11:28 +0100
commitd9ae0b46fdfebb67f88cb06185e8b052af3fac06 (patch)
treeba1b0c340cd7ddb45ca680043a73755e2fc36715
parentdocs: Simplify the ChangeLog and make it part of the documentation (diff)
entity: Add stop/1 and stop/2 to kill an entity in a clean way
-rw-r--r--lib/lkn/core/entity.ex22
-rw-r--r--test/core_test.exs42
2 files changed, 52 insertions, 12 deletions
diff --git a/lib/lkn/core/entity.ex b/lib/lkn/core/entity.ex
index 715970a..c87b51d 100644
--- a/lib/lkn/core/entity.ex
+++ b/lib/lkn/core/entity.ex
@@ -86,8 +86,8 @@ defmodule Lkn.Core.Entity do
This map is used by
"""
@callback init_properties(init_args) :: %{prop => value}
-
@callback digest(entity :: %{prop => value}) :: digest
+ @callback destroy(key :: k, entity :: %{prop => value}, reason :: term) :: any
defmacro __using__(components: comps) do
quote location: :keep do
@@ -97,7 +97,7 @@ defmodule Lkn.Core.Entity do
def init(key: entity_key, args: args) do
props = init_properties(args)
- props = Map.put(props, :make_digest, & __MODULE__.digest(&1))
+ props = Map.put(props, :module, __MODULE__)
sys = Enum.map(unquote(comps), &(&1.specs().system()))
@@ -117,9 +117,9 @@ defmodule Lkn.Core.Entity do
"""
@spec digest(entity_key :: k) :: digest
def digest(entity_key) do
- Option.some(di) = Lkn.Core.Entity.read(entity_key, :make_digest)
+ Option.some(mod) = Lkn.Core.Entity.read(entity_key, :module)
- Lkn.Core.Properties.compute(entity_key, di)
+ Lkn.Core.Properties.compute(entity_key, &mod.digest(&1))
end
@doc """
@@ -152,4 +152,18 @@ defmodule Lkn.Core.Entity do
def read(key, prop) do
Lkn.Core.Properties.read(key, prop)
end
+
+ @doc """
+ Stop the given Entity
+
+ This
+ """
+ def stop(key, reason \\ :normal) do
+ # clean up
+ Option.some(mod) = Lkn.Core.Entity.read(key, :module)
+ Lkn.Core.Properties.compute(key, &mod.destroy(key, &1, reason))
+
+ # and exit
+ Supervisor.stop(Name.entity(key), reason)
+ end
end
diff --git a/test/core_test.exs b/test/core_test.exs
index 0e95c6b..a2e08e7 100644
--- a/test/core_test.exs
+++ b/test/core_test.exs
@@ -49,13 +49,25 @@ defmodule Lkn.Core.Test do
test "spawning entity" do
entity_key = UUID.uuid4()
- {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4)
+ {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self())
+ end
+
+ test "spawning then stoping entity" do
+ entity_key = UUID.uuid4()
+
+ {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self())
+ Lkn.Core.Entity.stop(entity_key)
+
+ receive do
+ {:destroyed, key, :normal} -> assert key == entity_key
+ after 100 -> assert false
+ end
end
test "has component" do
entity_key = UUID.uuid4()
- {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4)
+ {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self())
assert Lkn.Core.Entity.has_component?(entity_key, Test.System)
assert !Lkn.Core.Entity.has_component?(entity_key, Test.NoSystem)
@@ -64,7 +76,7 @@ defmodule Lkn.Core.Test do
test "spawning entity and read level" do
entity_key = UUID.uuid4()
- {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4)
+ {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self())
Option.some(4) = Lkn.Core.Entity.read(entity_key, :level)
end
@@ -100,7 +112,7 @@ defmodule Lkn.Core.Test do
entity_key = UUID.uuid4()
ghost_key = UUID.uuid4()
- {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4)
+ {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self())
{:ok, _} = Test.Ghost.start_link(ghost_key)
0 = Lkn.Core.System.population_size(instance_key, Test.System)
@@ -142,7 +154,7 @@ defmodule Lkn.Core.Test do
entity_key = UUID.uuid4()
- {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4)
+ {:ok, _} = Test.Entity.start_link(entity_key, name: "lkn", level: 4, owner: self())
Lkn.Core.Instance.register_puppet(instance_key, entity_key)
@@ -385,6 +397,10 @@ defmap Test.Map do
def digest(_props) do
%{}
end
+
+ def destroy(_key, _props, _reason) do
+ :ok
+ end
end
######################################################################
@@ -407,17 +423,23 @@ end
defpuppet Test.Entity do
@components [Test.Entity.Component]
- def start_link(key, args = [name: _name, level: _level]) do
+ def start_link(key, args = [name: _name, level: _level, owner: _owner]) do
Lkn.Core.Entity.start_link(__MODULE__, key, args)
end
- def init_properties(name: name, level: level) do
- %{:name => name, :level => level}
+ def init_properties(name: name, level: level, owner: owner) do
+ %{:name => name, :level => level, :owner => owner}
end
def digest(props) do
props
end
+
+ def destroy(key, props, reason) do
+ target = Map.get(props, :owner)
+ send target, {:destroyed, key, reason}
+ :ok
+ end
end
defpuppet Test.Ghost do
@@ -434,6 +456,10 @@ defpuppet Test.Ghost do
def digest(props) do
props
end
+
+ def destroy(_key, _props, _reason) do
+ :ok
+ end
end
######################################################################