gmhive_client/src/gmhc_events.erl
2025-08-21 22:46:54 +02:00

82 lines
2.1 KiB
Erlang

-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.