YODAU 1.0
YEAR OF THE DEPEND ADULT UNDERGARMENT
Loading...
Searching...
No Matches
yodau::backend::cli_client Class Reference

Simple interactive CLI (REPL) for controlling a stream_manager. More...

#include <backend/include/cli_client.hpp>

Collaboration diagram for yodau::backend::cli_client:

Public Member Functions

 cli_client (backend::stream_manager &mgr)
 Construct a CLI client operating on an existing manager.
int run () const
 Run the interactive command loop.

Private Member Functions

void dispatch_command (const std::string &cmd, const std::vector< std::string > &args) const
 Dispatch a command to its handler.
void cmd_list_streams (const std::vector< std::string > &args) const
 Handler for list-streams.
void cmd_add_stream (const std::vector< std::string > &args) const
 Handler for add-stream.
void cmd_start_stream (const std::vector< std::string > &args) const
 Handler for start-stream.
void cmd_stop_stream (const std::vector< std::string > &args) const
 Handler for stop-stream.
void cmd_list_lines (const std::vector< std::string > &args) const
 Handler for list-lines.
void cmd_add_line (const std::vector< std::string > &args) const
 Handler for add-line.
void cmd_set_line (const std::vector< std::string > &args) const
 Handler for set-line.

Static Private Member Functions

static std::vector< std::string > tokenize (const std::string &line)
 Split a line into whitespace-separated tokens.
static cxxopts::ParseResult parse_with_cxxopts (const std::string &cmd, const std::vector< std::string > &args, cxxopts::Options &options)
 Parse command arguments using cxxopts.

Private Attributes

backend::stream_managerstream_mgr
 Stream manager controlled by this CLI.

Detailed Description

Simple interactive CLI (REPL) for controlling a stream_manager.

The cli_client provides a text-based command loop that allows the user to:

  • list/add/start/stop streams,
  • list/add lines,
  • connect lines to streams, using cxxopts-style option parsing.

The client does not own the manager; it holds a reference and issues synchronous calls to it.

Note
When compiled with YODAU_OPENCV, the constructor installs OpenCV-based daemon start and motion frame processor hooks (see implementation).

Definition at line 28 of file cli_client.hpp.

Constructor & Destructor Documentation

◆ cli_client()

yodau::backend::cli_client::cli_client ( backend::stream_manager & mgr)
explicit

Construct a CLI client operating on an existing manager.

The manager reference must remain valid for the lifetime of this client.

Parameters
mgrStream manager to control.

Definition at line 5 of file cli_client.cpp.

6 : stream_mgr(mgr) {
7#ifdef YODAU_OPENCV
8 stream_mgr.set_daemon_start_hook(opencv_daemon_start);
9 stream_mgr.set_frame_processor(opencv_motion_processor);
10#endif
11}
backend::stream_manager & stream_mgr
Stream manager controlled by this CLI.

References stream_mgr.

Referenced by main().

Here is the caller graph for this function:

Member Function Documentation

◆ cmd_add_line()

void yodau::backend::cli_client::cmd_add_line ( const std::vector< std::string > & args) const
private

Handler for add-line.

Positional arguments:

  • path (required; coordinates string like "0,0;100,100")
  • name (optional)
  • close (optional: true/false)

Options:

  • –dir / -d to set tripwire direction.
Parameters
argsTokenized arguments.

Definition at line 244 of file cli_client.cpp.

246 {
247 const std::string cmd = "add-line";
248 cxxopts::Options options("add-line", "Add a new line to a stream");
249 options.allow_unrecognised_options();
250 options.positional_help("<path> [<name>] [<close>]");
251 options.add_options()
252 ("h,help", "Print help")
253 ("path", "Line coordinates, e.g. 0,0;100,100", cxxopts::value<std::string>())
254 ("name", "Name of the line", cxxopts::value<std::string>()->default_value(""))
255 ("close", "Whether the line is closed (true/false)", cxxopts::value<bool>()->default_value("false"))
256 ("d,dir", "Tripwire direction (any/neg_to_pos/pos_to_neg)",
257 cxxopts::value<std::string>()->default_value("any"));
258 options.parse_positional({ "path", "name", "close" });
259 try {
260 const auto result = parse_with_cxxopts("add-line", args, options);
261 if (result.count("help")) {
262 std::cout << options.help() << std::endl;
263 return;
264 }
265 if (!result.count("path")) {
266 std::cerr << "Error: 'path' argument is required." << std::endl;
267 return;
268 }
269 const std::string path = result["path"].as<std::string>();
270 const std::string name = result["name"].as<std::string>();
271 const bool close = result["close"].as<bool>();
272 const std::string dir_str = result["dir"].as<std::string>();
273
274 const auto& line = stream_mgr.add_line(path, close, name);
275
276 try {
277 const auto dir = parse_tripwire_dir(dir_str);
278 stream_mgr.set_line_dir(line->name, dir);
279 } catch (const std::exception& e) {
280 std::cerr << "bad dir: " << e.what() << std::endl;
281 }
282
283 line->dump(std::cout);
284 std::cout << std::endl;
285
286 } catch (const cxxopts::exceptions::exception& e) {
287 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
288 << std::endl;
289 std::cout << options.help() << std::endl;
290 }
291}
static cxxopts::ParseResult parse_with_cxxopts(const std::string &cmd, const std::vector< std::string > &args, cxxopts::Options &options)
Parse command arguments using cxxopts.
static yodau::backend::tripwire_dir parse_tripwire_dir(const std::string &s)

References parse_tripwire_dir(), and stream_mgr.

Here is the call graph for this function:

◆ cmd_add_stream()

void yodau::backend::cli_client::cmd_add_stream ( const std::vector< std::string > & args) const
private

Handler for add-stream.

Positional arguments:

  • path (required)
  • name (optional)
  • type (optional: local/file/rtsp/http)
  • loop (optional: true/false)
Parameters
argsTokenized arguments.

Definition at line 113 of file cli_client.cpp.

115 {
116 const std::string cmd = "add-stream";
117 cxxopts::Options options(cmd, "Add a new stream");
118 options.allow_unrecognised_options();
119 options.positional_help("<path> [<name>] [<type>] [<loop>]");
120 options.add_options()
121 ("h,help", "Print help")
122 ("path", "Path to the device, media file or stream URL", cxxopts::value<std::string>())
123 ("name", "Name of the stream", cxxopts::value<std::string>()->default_value(""))
124 ("type", "Type of the stream (local/file/rtsp/http)", cxxopts::value<std::string>()->default_value(""))
125 ("loop", "Whether to loop the stream (true/false)", cxxopts::value<bool>()->default_value("true"));
126 options.parse_positional({ "path", "name", "type", "loop" });
127 try {
128 const auto result = parse_with_cxxopts(cmd, args, options);
129 if (result.count("help")) {
130 std::cout << options.help() << std::endl;
131 return;
132 }
133 if (!result.count("path")) {
134 std::cerr << "Error: 'path' argument is required." << std::endl;
135 return;
136 }
137 const std::string path = result["path"].as<std::string>();
138 const std::string name = result["name"].as<std::string>();
139 const std::string type = result["type"].as<std::string>();
140 const bool loop = result["loop"].as<bool>();
141 const auto& stream = stream_mgr.add_stream(path, name, type, loop);
142 stream.dump(std::cout, true);
143 std::cout << std::endl;
144 } catch (const cxxopts::exceptions::exception& e) {
145 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
146 << std::endl;
147 std::cout << options.help() << std::endl;
148 }
149}

References stream_mgr.

◆ cmd_list_lines()

void yodau::backend::cli_client::cmd_list_lines ( const std::vector< std::string > & args) const
private

Handler for list-lines.

Lists all stored lines in the manager.

Parameters
argsTokenized arguments.

Definition at line 209 of file cli_client.cpp.

211 {
212 const std::string cmd = "list-lines";
213 cxxopts::Options options("list-lines", "List all lines in a stream");
214 options.allow_unrecognised_options();
215 options.add_options()("h,help", "Print help");
216 try {
217 const auto result = parse_with_cxxopts("list-lines", args, options);
218 if (result.count("help")) {
219 std::cout << options.help() << std::endl;
220 return;
221 }
222 stream_mgr.dump_lines(std::cout);
223 std::cout << std::endl;
224 } catch (const cxxopts::exceptions::exception& e) {
225 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
226 << std::endl;
227 std::cout << options.help() << std::endl;
228 }
229}

References stream_mgr.

◆ cmd_list_streams()

void yodau::backend::cli_client::cmd_list_streams ( const std::vector< std::string > & args) const
private

Handler for list-streams.

Supports optional --connections to show connected line names.

Parameters
argsTokenized arguments.

Definition at line 87 of file cli_client.cpp.

89 {
90 const std::string cmd = "list-streams";
91 cxxopts::Options options(cmd, "List all streams");
92 options.allow_unrecognised_options();
93 options.add_options()("h,help", "Print help")(
94 "c,connections", "Show connected lines",
95 cxxopts::value<bool>()->default_value("false")
96 );
97 try {
98 const auto result = parse_with_cxxopts(cmd, args, options);
99 if (result.count("help")) {
100 std::cout << options.help() << std::endl;
101 return;
102 }
103 const bool show_connections = result["connections"].as<bool>();
104 stream_mgr.dump_stream(std::cout, show_connections);
105 std::cout << std::endl;
106 } catch (const cxxopts::exceptions::exception& e) {
107 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
108 << std::endl;
109 std::cout << options.help() << std::endl;
110 }
111}

References stream_mgr.

◆ cmd_set_line()

void yodau::backend::cli_client::cmd_set_line ( const std::vector< std::string > & args) const
private

Handler for set-line.

Positional arguments:

  • stream (required; stream name)
  • line (required; line name)

Connects an existing line to an existing stream.

Parameters
argsTokenized arguments.

Definition at line 293 of file cli_client.cpp.

295 {
296 const std::string cmd = "set-line";
297 cxxopts::Options options("set-line", "Set a new line to a stream");
298 options.allow_unrecognised_options();
299 options
300 .add_options()("h,help", "Print help")("stream", "Stream name", cxxopts::value<std::string>())(
301 "line", "Line name", cxxopts::value<std::string>()
302 );
303 options.parse_positional({ "stream", "line" });
304 try {
305 const auto result = parse_with_cxxopts("set-line", args, options);
306 if (result.count("help")) {
307 std::cout << options.help() << std::endl;
308 return;
309 }
310 if (!result.count("stream") || !result.count("line")) {
311 std::cerr << "Error: 'stream' and 'line' arguments are required."
312 << std::endl;
313 return;
314 }
315 const std::string stream_name = result["stream"].as<std::string>();
316 const std::string line_name = result["line"].as<std::string>();
317 const auto& stream = stream_mgr.set_line(stream_name, line_name);
318 stream.dump(std::cout, true);
319 std::cout << std::endl;
320 } catch (const cxxopts::exceptions::exception& e) {
321 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
322 << std::endl;
323 std::cout << options.help() << std::endl;
324 }
325}

References stream_mgr.

◆ cmd_start_stream()

void yodau::backend::cli_client::cmd_start_stream ( const std::vector< std::string > & args) const
private

Handler for start-stream.

Positional argument:

  • name (required)
Parameters
argsTokenized arguments.

Definition at line 151 of file cli_client.cpp.

153 {
154 const std::string cmd = "start-stream";
155 cxxopts::Options options("start-stream", "Start a stream");
156 options.allow_unrecognised_options();
157 options.add_options()("h,help", "Print help")(
158 "name", "Name of the stream to start", cxxopts::value<std::string>()
159 );
160 options.parse_positional({ "name" });
161 try {
162 const auto result = parse_with_cxxopts("start-stream", args, options);
163 if (result.count("help")) {
164 std::cout << options.help() << std::endl;
165 return;
166 }
167 if (!result.count("name")) {
168 std::cerr << "Error: 'name' argument is required." << std::endl;
169 return;
170 }
171 const std::string name = result["name"].as<std::string>();
172 stream_mgr.start_stream(name);
173 } catch (const cxxopts::exceptions::exception& e) {
174 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
175 << std::endl;
176 std::cout << options.help() << std::endl;
177 }
178}

References stream_mgr.

◆ cmd_stop_stream()

void yodau::backend::cli_client::cmd_stop_stream ( const std::vector< std::string > & args) const
private

Handler for stop-stream.

Positional argument:

  • name (required)
Parameters
argsTokenized arguments.

Definition at line 180 of file cli_client.cpp.

182 {
183 const std::string cmd = "stop-stream";
184 cxxopts::Options options("stop-stream", "Stop a stream");
185 options.allow_unrecognised_options();
186 options.add_options()("h,help", "Print help")(
187 "name", "Name of the stream to stop", cxxopts::value<std::string>()
188 );
189 options.parse_positional({ "name" });
190 try {
191 const auto result = parse_with_cxxopts("stop-stream", args, options);
192 if (result.count("help")) {
193 std::cout << options.help() << std::endl;
194 return;
195 }
196 if (!result.count("name")) {
197 std::cerr << "Error: 'name' argument is required." << std::endl;
198 return;
199 }
200 const std::string name = result["name"].as<std::string>();
201 stream_mgr.stop_stream(name);
202 } catch (const cxxopts::exceptions::exception& e) {
203 std::cerr << "Error parsing command '" << cmd << "': " << e.what()
204 << std::endl;
205 std::cout << options.help() << std::endl;
206 }
207}

References stream_mgr.

◆ dispatch_command()

void yodau::backend::cli_client::dispatch_command ( const std::string & cmd,
const std::vector< std::string > & args ) const
private

Dispatch a command to its handler.

Looks up cmd in the internal command map and invokes the corresponding cmd_* method. Unknown commands print an error to stderr.

Parameters
cmdCommand name (e.g., "add-stream").
argsTokenized arguments excluding the command name.

Definition at line 45 of file cli_client.cpp.

47 {
48 static const std::unordered_map<
49 std::string,
50 void (cli_client::*)(const std::vector<std::string>& args) const>
51 command_map = { { "list-streams", &cli_client::cmd_list_streams },
52 { "add-stream", &cli_client::cmd_add_stream },
53 { "start-stream", &cli_client::cmd_start_stream },
54 { "stop-stream", &cli_client::cmd_stop_stream },
55 { "list-lines", &cli_client::cmd_list_lines },
56 { "add-line", &cli_client::cmd_add_line },
57 { "set-line", &cli_client::cmd_set_line } };
58 const auto it = command_map.find(cmd);
59 if (it == command_map.end()) {
60 std::cerr << "unknown command: " << cmd << std::endl;
61 return;
62 }
63 try {
64 const auto method = it->second;
65 (this->*method)(args);
66 } catch (const std::exception& e) {
67 std::cerr << "error executing command '" << cmd << "': " << e.what()
68 << std::endl;
69 }
70}
void cmd_start_stream(const std::vector< std::string > &args) const
Handler for start-stream.
void cmd_set_line(const std::vector< std::string > &args) const
Handler for set-line.
void cmd_add_line(const std::vector< std::string > &args) const
Handler for add-line.
void cmd_stop_stream(const std::vector< std::string > &args) const
Handler for stop-stream.
void cmd_list_streams(const std::vector< std::string > &args) const
Handler for list-streams.
void cmd_add_stream(const std::vector< std::string > &args) const
Handler for add-stream.
void cmd_list_lines(const std::vector< std::string > &args) const
Handler for list-lines.
cli_client(backend::stream_manager &mgr)
Construct a CLI client operating on an existing manager.
Definition cli_client.cpp:5

◆ parse_with_cxxopts()

cxxopts::ParseResult yodau::backend::cli_client::parse_with_cxxopts ( const std::string & cmd,
const std::vector< std::string > & args,
cxxopts::Options & options )
staticprivate

Parse command arguments using cxxopts.

Builds a temporary argv-like array from cmd and args and calls cxxopts::Options::parse.

Parameters
cmdCommand name (used as argv[0]).
argsCommand arguments.
optionsConfigured cxxopts options for this command.
Returns
cxxopts parse result.

Definition at line 72 of file cli_client.cpp.

75 {
76 std::vector<char*> argv;
77 argv.reserve(args.size() + 1);
78 argv.push_back(const_cast<char*>(cmd.data()));
79 for (const auto& arg : args) {
80 argv.push_back(const_cast<char*>(arg.data()));
81 }
82 const int argc = static_cast<int>(argv.size());
83 char** argv_ptr = argv.data();
84 return options.parse(argc, argv_ptr);
85}

◆ run()

int yodau::backend::cli_client::run ( ) const

Run the interactive command loop.

This function reads commands from stdin and prints results/errors to stdout/stderr until the user enters one of the quit commands: "quit", "q", or "exit".

Returns
0 on normal termination, non-zero if stdin closes / EOF occurs.

Definition at line 13 of file cli_client.cpp.

13 {
14 std::string line;
15 while (true) {
16 std::cout << "yodau> " << std::flush;
17 if (!std::getline(std::cin, line)) {
18 return 1;
19 }
20 auto tokens = tokenize(line);
21 if (tokens.empty()) {
22 continue;
23 }
24 const auto& cmd = tokens[0];
25 std::vector args(tokens.begin() + 1, tokens.end());
26 if (cmd == "quit" || cmd == "q" || cmd == "exit") {
27 break;
28 }
29 dispatch_command(cmd, args);
30 }
31 return 0;
32}
void dispatch_command(const std::string &cmd, const std::vector< std::string > &args) const
Dispatch a command to its handler.
static std::vector< std::string > tokenize(const std::string &line)
Split a line into whitespace-separated tokens.

Referenced by main().

Here is the caller graph for this function:

◆ tokenize()

std::vector< std::string > yodau::backend::cli_client::tokenize ( const std::string & line)
staticprivate

Split a line into whitespace-separated tokens.

Used to parse the REPL input into:

  • command name (first token),
  • positional/flag arguments (remaining tokens).
Parameters
lineRaw input line.
Returns
Vector of tokens; empty if line contains no tokens.

Definition at line 35 of file cli_client.cpp.

35 {
36 std::vector<std::string> tokens;
37 std::istringstream stream(line);
38 std::string token;
39 while (stream >> token) {
40 tokens.push_back(token);
41 }
42 return tokens;
43}

Member Data Documentation

◆ stream_mgr

backend::stream_manager& yodau::backend::cli_client::stream_mgr
private

Stream manager controlled by this CLI.

Non-owning reference.

Definition at line 176 of file cli_client.hpp.

Referenced by cli_client(), cmd_add_line(), cmd_add_stream(), cmd_list_lines(), cmd_list_streams(), cmd_set_line(), cmd_start_stream(), and cmd_stop_stream().


The documentation for this class was generated from the following files: