Current section

Files

Jump to
perspective lib perspective reactor reactor.ex
Raw

lib/perspective/reactor/reactor.ex

defmodule Perspective.Reactor do
defmacro __using__(_) do
quote do
import Perspective.Reactor
use Perspective.ModuleRegistry
register_module(Perspective.Reactor)
@before_compile Perspective.Reactor
@updateable_events []
def initial_state, do: nil
defoverridable(initial_state: 0)
end
end
defmacro initial_state(do: block) do
quote do
def initial_state, do: unquote(block)
end
end
defmacro update(event, state, do: block) do
struct_type =
Perspective.Reactor.MacroParser.capture_event_name(event)
|> Macro.expand(__CALLER__)
quote do
@updateable_events [unquote(struct_type) | @updateable_events]
def update(unquote(event), unquote(state)), do: unquote(block)
end
end
defmacro __before_compile__(env) do
updateable_events = Module.get_attribute(env.module, :updateable_events)
calling_module = __CALLER__.module
Perspective.Reactor.DefineGenServer.define(calling_module, updateable_events, __CALLER__)
Perspective.Reactor.DefineSupervisor.define(calling_module, __CALLER__)
genserver_name = Perspective.Reactor.Names.server(calling_module)
quote do
defdelegate state, to: unquote(genserver_name)
defdelegate data, to: unquote(genserver_name)
defdelegate get, to: unquote(genserver_name), as: :state
defdelegate send(event), to: unquote(genserver_name)
def updateable_events do
unquote(updateable_events)
end
def update(event, _state) do
raise Perspective.Reactor.UnsupportedEvent, reactor: unquote(calling_module), event: event
end
end
end
end