-module(gmhc_events). -vsn("0.4.8"). -export([subscribe/1, ensure_subscribed/1, unsubscribe/1, ensure_unsubscribed/1, publish/2]). -export([debug/0]). -export_type([event/0]). -type event() :: pool_notification | {pool_notification, atom()} | error | puzzle | result | connected | disconnected. -spec publish(event(), any()) -> ok. publish(Event, Info) -> Data = #{sender => self(), time => os:timestamp(), info => Info}, _ = gproc_ps:publish(l, Event, Data), ok. -spec subscribe(event()) -> true. subscribe(Event) -> gproc_ps:subscribe(l, Event). -spec ensure_subscribed(event()) -> true. %% @doc Subscribes to Event. Will not crash if called more than once. ensure_subscribed(Event) -> try subscribe(Event) catch error:badarg -> %% This assertion should not be needed, since there is %% no other scenario that would cause subscribe/1 to fail, %% other than gproc not running (would also cause a badarg) _ = gproc:get_value({p,l,{gproc_ps_event, Event}}, self()), true end. -spec unsubscribe(event()) -> true. unsubscribe(Event) -> gproc_ps:unsubscribe(l, Event). -spec ensure_unsubscribed(event()) -> true. ensure_unsubscribed(Event) -> case lists:member(self(), gproc_ps:list_subs(l,Event)) of true -> unsubscribe(Event); false -> true end. debug() -> ok = application:ensure_started(gproc), spawn(fun() -> subscribe(pool_notification), subscribe({pool_notification, new_generation}), subscribe(connected), subscribe(puzzle), subscribe(result), subscribe(error), subscribe(disconnected), loop() end). loop() -> receive stop -> ok; {gproc_ps_event, E, Data} -> io:fwrite("EVENT ~p: ~p~n", [E, Data]), loop() end.