defmodule Manganese.EntityKit.Structs.EntitiesUpdate do alias Manganese.EntityKit.Structs @type t :: %Structs.EntitiesUpdate{ entities: Structs.EntitiesCollection.t, removed_entities: Structs.EntityReferencesCollection.t } defstruct [ entities: Structs.EntitiesCollection.new, removed_entities: Structs.EntityReferencesCollection.new ] # Utilities @doc """ An empty entities update. """ @spec new :: t def new, do: %Structs.EntitiesUpdate{} @doc """ """ @spec put_entity(t, atom, term) :: t def put_entity(entities_update, entity_type, entity) do entities_update |> Map.put( :entities, (entities_update.entities || Structs.EntitiesCollection.new()) |> Structs.EntitiesCollection.put_entity(entity_type, entity) ) end @doc """ """ @spec put_entities(t, atom, [ term ]) :: t def put_entities(entities_update, entity_type, entities) do entities_update |> Map.put( :entities, (entities_update.entities || Structs.EntitiesCollection.new()) |> Structs.EntitiesCollection.put_entities(entity_type, entities) ) end @doc """ """ @spec put_entities_collection(t, Structs.EntitiesCollection.t) :: t def put_entities_collection(entities_update, entities_collection) do entities_update |> Map.put( :entities, (entities_update.entities || Structs.EntitiesCollection.new()) |> Structs.EntitiesCollection.merge(entities_collection) ) end @doc """ """ @spec put_removed_entity_id(t, atom, pos_integer) :: t def put_removed_entity_id(entities_update, entity_type, removed_entity_id) do entities_update |> Map.put( :removed_entities, (entities_update.removed_entities || Structs.EntityReferencesCollection.new) |> Structs.EntityReferencesCollection.put_entity_id(entity_type, removed_entity_id) ) end @doc """ """ @spec put_removed_entity_ids(t, atom, [ pos_integer ]) :: t def put_removed_entity_ids(entities_update, entity_type, removed_entity_ids) do entities_update |> Map.put( :removed_entities, (entities_update.removed_entities || Structs.EntityReferencesCollection.new) |> Structs.EntityReferencesCollection.put_entity_ids(entity_type, removed_entity_ids) ) end @doc """ """ @spec put_removed_entity(t, atom, term) :: t def put_removed_entity(entities_update, entity_type, removed_entity) do entities_update |> put_removed_entity_id(entity_type, removed_entity.id) end @doc """ """ @spec put_removed_entities(t, atom, [ term ]) :: t def put_removed_entities(entities_update, entity_type, removed_entities) do removed_entity_ids = removed_entities |> Enum.map(fn entity -> entity.id end) entities_update |> put_removed_entity_ids(entity_type, removed_entity_ids) end @doc """ """ @spec put_removed_entity_references_collection(t, Structs.EntityReferencesCollection.t) :: t def put_removed_entity_references_collection(entities_update, removed_entity_references_collection) do entities_update |> Map.put( :removed_entities, (entities_update.removed_entities || Structs.EntityReferencesCollection.new) |> Structs.EntityReferencesCollection.merge(removed_entity_references_collection) ) end @doc """ """ @spec merge(t, t) :: t def merge(entities_update1, entities_update2) do new() |> put_entities_collection( Structs.EntitiesCollection.merge( entities_update1.entities, entities_update2.entities ) ) |> put_removed_entity_references_collection( Structs.EntityReferencesCollection.merge( entities_update1.removed_entities, entities_update2.removed_entities ) ) end @doc """ """ @spec filter(t, (atom, Behaviors.Entity.id -> boolean)) :: map def filter(entities_update, filter) do %Structs.EntitiesUpdate{ entities: entities_update.entities |> Structs.EntitiesCollection.filter(filter), removed_entities: entities_update.removed_entities |> Structs.EntityReferencesCollection.filter(filter) } end @doc """ """ @spec serialize(t, (term -> term)) :: map def serialize(entities_update, serializer) do %{ "entities" => entities_update.entities |> Structs.EntitiesCollection.serialize(serializer), "removed_entities" => entities_update.removed_entities |> Structs.EntityReferencesCollection.serialize } end @doc """ """ @spec filter_and_serialize(t, (term -> term), (atom, Behaviors.Entity.id -> boolean)) :: map def filter_and_serialize(entities_update, filter, serializer) do %{ "entities" => entities_update.entities |> Structs.EntitiesCollection.filter(filter) |> Structs.EntitiesCollection.serialize(serializer), "removed_entities" => entities_update.removed_entities |> Structs.EntityReferencesCollection.filter(filter) |> Structs.EntityReferencesCollection.serialize } end end