Current section
Files
Jump to
Current section
Files
lib/nop/element/logic_element.ex
defmodule NOP.Element.LogicElement do
defmacro __using__([]) do
quote do
use NOP.Element.ElementBase
require Logger
def handle_call(:evaluate, _from, state) do
{:reply, get_result_from_state(state), state}
end
def handle_cast({:link_condition, condition, element_name}, state) do
Logger.debug("Linked logic element #{get_name(state)} to condition #{element_name}")
state = link_to_condition(condition, state)
{:noreply, state}
end
def handle_cast({:notify_condition, element_value, element_name}, state) do
Logger.debug("Element #{get_name(state)} notified by element #{element_name} that its new assert is #{element_value}")
state = update_element_value(state, element_name, element_value)
state = add_statistics_to_state(state, 1)
{:noreply, state}
end
defp notify_conditions(state, new_result, name) do
condition_list = get_condition_list_from_state(state)
notify_conditions_int(condition_list, new_result, name)
end
defp notify_conditions_int([], _, _) do
# End of list
end
defp notify_conditions_int([condition | condition_list], new_result, name) do
GenServer.cast(condition, {:notify_condition, new_result, name})
notify_conditions_int(condition_list, new_result, name)
end
defp init_condition_list(state) do
Map.put(state, :condition_list, [])
end
defp get_condition_list_from_state(state) do
Map.get(state, :condition_list)
end
defp set_condtion_list_to_state(state, condition_list) do
Map.put(state, :condition_list, condition_list)
end
defp link_to_condition(condition, state) do
condition_list = get_condition_list_from_state(state)
condition_list = condition_list ++ [condition]
set_condtion_list_to_state(state, condition_list)
end
defp get_result_from_state(state) do
Map.get(state, :result)
end
defp set_result_to_state(state, result) do
Map.put(state, :result, result)
end
defp link_to_elements([element | elements], pid, element_name) do
GenServer.cast(element, {:link_condition, pid , element_name})
link_to_elements(elements, pid, element_name)
end
defp link_to_elements([], _, _) do
#Empty list -> Stop
end
def evaluate_elements(element_name, element_list) do
values = %{}
evaluate_elements_int(element_name, element_list, values)
end
def init_element_values(state, element_name, element_list) do
values = evaluate_elements(element_name, element_list)
set_values_to_state(state, values)
end
defp evaluate_elements_int(_, [], values) do
values
end
defp evaluate_elements_int(element_name, [element | element_list], values) do
result = GenServer.call(element, :evaluate, :infinity)
name = GenServer.call(element, :get_name, :infinity)
Logger.debug("Asserting value for logic element #{name} with intial value #{result}")
evaluate_elements_int(element_name, element_list, Map.put(values, String.to_atom(name), result))
end
defp get_values_from_state(state) do
Map.get(state, :values)
end
defp set_values_to_state(state, values) do
Map.put(state, :values, values)
end
defp update_element_value(state, element_name, element_value) do
values = get_values_from_state(state)
values = Map.put(values, String.to_atom(element_name), element_value)
old_result = get_result_from_state(state)
name = get_name(state)
Logger.debug("Updating assert from element #{element_name} in element #{get_name(state)}")
#update_my_state need to be defined!
result = update_my_state(state, name, element_name, values, old_result)
state = set_values_to_state(state, values)
if result != old_result do
notify_conditions(state, result, name)
end
set_result_to_state(state, result)
end
end
end
end