1212 start_record_stream /4 ,
1313 push_new_record /3 ,
1414 end_record_stream /2 ,
15+ send_keyboard_input /3 ,
1516 read_file /2 ]).
1617-export ([init /1 ,
1718 handle_call /3 ,
2122 code_change /3 ]).
2223
2324-record (? MODULE , {progname ,
24- record_streams = #{}}).
25+ record_streams = #{},
26+ kbd_reader = undefined ,
27+ kbd_subscribers = []}).
2528
2629start_link (Progname ) ->
2730 gen_server :start_link (rabbit_cli_io , #{progname => Progname }, []).
@@ -92,6 +95,14 @@ end_record_stream({transport, Transport}, #{name := Name}) ->
9295end_record_stream (IO , #{name := Name }) ->
9396 gen_server :cast (IO , {? FUNCTION_NAME , Name }).
9497
98+ send_keyboard_input ({transport , Transport }, ArgMap , Subscriber ) ->
99+ Transport ! {io_call , self (), {? FUNCTION_NAME , ArgMap , Subscriber }},
100+ receive Ret -> Ret end ;
101+ send_keyboard_input (IO , ArgMap , Subscriber )
102+ when is_pid (IO ) andalso
103+ is_map (ArgMap ) ->
104+ gen_server :call (IO , {? FUNCTION_NAME , ArgMap , Subscriber }).
105+
95106read_file ({transport , Transport }, ArgMap ) ->
96107 Transport ! {io_call , self (), {? FUNCTION_NAME , ArgMap }},
97108 receive Ret -> Ret end ;
@@ -116,14 +127,21 @@ handle_call(
116127
117128 {ok , State2 } = format_record_stream_start (Name , State1 ),
118129
119- {noreply , State2 };
130+ {noreply , State2 , compute_timeout (State2 )};
131+ handle_call (
132+ {send_keyboard_input , _ArgMap , Subscriber },
133+ _From ,
134+ #? MODULE {kbd_subscribers = Subscribers } = State ) ->
135+ Subscribers1 = [Subscriber | Subscribers ],
136+ State1 = State #? MODULE {kbd_subscribers = Subscribers1 },
137+ {reply , ok , State1 , compute_timeout (State1 )};
120138handle_call ({read_file , ArgMap }, From , State ) ->
121139 {ok , State1 } = do_read_file (ArgMap , From , State ),
122- {noreply , State1 };
140+ {noreply , State1 , compute_timeout ( State1 ) };
123141handle_call (stop , _From , State ) ->
124142 {stop , normal , ok , State };
125143handle_call (_Request , _From , State ) ->
126- {reply , ok , State }.
144+ {reply , ok , State , compute_timeout ( State ) }.
127145
128146handle_cast (
129147 {display_help , #{cmd_path := CmdPath , argparse_def := ArgparseDef }},
@@ -134,28 +152,51 @@ handle_cast(
134152 command => tl (CmdPath )},
135153 Help = argparse :help (ArgparseDef , Options ),
136154 io :format (" ~s~n " , [Help ]),
137- {noreply , State };
155+ {noreply , State , compute_timeout ( State ) };
138156handle_cast ({format , Format , Args }, State ) ->
139157 io :format (Format , Args ),
140- {noreply , State };
158+ {noreply , State , compute_timeout ( State ) };
141159handle_cast ({push_new_record , Name , Record }, State ) ->
142160 {ok , State1 } = format_record (Name , Record , State ),
143- {noreply , State1 };
161+ {noreply , State1 , compute_timeout ( State1 ) };
144162handle_cast ({end_record_stream , Name }, State ) ->
145163 {ok , State1 } = format_record_stream_end (Name , State ),
146- {noreply , State1 };
164+ {noreply , State1 , compute_timeout ( State1 ) };
147165handle_cast (_Request , State ) ->
148- {noreply , State }.
166+ {noreply , State , compute_timeout ( State ) }.
149167
168+ handle_info (timeout , #? MODULE {kbd_reader = Reader } = State )
169+ when is_pid (Reader ) ->
170+ {noreply , State };
171+ handle_info (timeout , #? MODULE {kbd_subscribers = []} = State ) ->
172+ {noreply , State };
173+ handle_info (timeout , #? MODULE {kbd_subscribers = Subscribers } = State ) ->
174+ Parent = self (),
175+ Reader = spawn_link (
176+ fun () ->
177+ Ret = io :read (" " ),
178+ lists :foreach (
179+ fun (Sub ) ->
180+ Sub ! {keypress , Ret }
181+ end , Subscribers ),
182+ erlang :unlink (Parent )
183+ end , Subscribers ),
184+ State1 = State #? MODULE {kbd_reader = Reader },
185+ {noreply , State1 , compute_timeout (State1 )};
150186handle_info (_Info , State ) ->
151- {noreply , State }.
187+ {noreply , State , compute_timeout ( State ) }.
152188
153189terminate (_Reason , _State ) ->
154190 ok .
155191
156192code_change (_OldVsn , State , _Extra ) ->
157193 {ok , State }.
158194
195+ compute_timeout (#? MODULE {kbd_subscribers = []}) ->
196+ infinity ;
197+ compute_timeout (#? MODULE {kbd_subscribers = _ }) ->
198+ 0 .
199+
159200format_record_stream_start (
160201 Name ,
161202 #? MODULE {record_streams = Streams } = State ) ->
0 commit comments