@@ -28,14 +28,15 @@ A cross-platform header only C++14 library for interactive command line interfac
2828
2929## Dependencies
3030
31+ The library has no dependencies if you don't need remote sessions.
32+
3133The library depends on asio (either the standalone version or the boost version)
32- only to provide telnet server.
33- Therefore, the library has no dependencies if you don't need remote sessions.
34+ * only* to provide telnet server (i.e., remote sessions).
3435
3536## Installation
3637
3738The library is header-only: it consists entirely of header files
38- containing templates and inline functions, and require no separately-compiled
39+ containing templates and inline functions, and requires no separately-compiled
3940library binaries or special treatment when linking.
4041
4142Extract the archive wherever you want.
@@ -49,7 +50,7 @@ If you fancy it, a Cmake script is provided. To install you can use:
4950 cmake ..
5051 sudo make install
5152
52- and , if you want to specify the installation path:
53+ or , if you want to specify the installation path:
5354
5455 mkdir build && cd build
5556 cmake .. -DCMAKE_INSTALL_PREFIX:PATH=<cli_install_location>
@@ -64,29 +65,47 @@ and linking pthread on linux (and optionally boost system).
6465
6566To compile the examples using cmake, use:
6667
67- mkdir build
68- cd build
68+ mkdir build && cd build
69+
70+ # compile only the examples that do not require boost/asio libraries
6971 cmake .. -DCLI_BuildExamples=ON
70- # or: cmake .. -DCLI_BuildExamples=ON -DBOOST_INCLUDEDIR=<boost_include_directory>
71- make all
72- # or: cmake --build .
72+
73+ # compile the examples by using boost asio libraries
74+ cmake .. -DCLI_BuildExamples=ON -DCLI_UseBoostAsio=ON
75+ # or: cmake .. -DCLI_BuildExamples=ON -DCLI_UseBoostAsio=ON -DBOOST_ROOT=<boost_path>
76+
77+ # compile the examples by using standalone asio library
78+ cmake .. -DCLI_BuildExamples=ON -DCLI_UseStandaloneAsio=ON
79+ # or: cmake .. -DCLI_BuildExamples=ON -DCLI_UseStandaloneAsio=ON -DASIO_INCLUDEDIR=<asio_path>
80+
81+ cmake --build .
7382
7483In the same directory you can also find:
7584
76- * a GNU make file (Makefile)
77- * a Windows nmake file (makefile.win)
85+ * GNU make files (Makefile.noasio, Makefile.boostasio, Makefile.standaloneasio )
86+ * Windows nmake files (makefile.noasio.win, makefile.boostasio.win, makefile.standaloneasio .win)
7887* a Visual Studio solution
7988
80- You can specify boost library path in the following ways:
89+ You can specify boost/asio library path in the following ways:
8190
8291### GNU Make
8392
93+ for boost:
94+
8495 make CXXFLAGS="-isystem <boost_include>" LDFLAGS="-L<boost_lib>"
8596
8697example:
8798
8899 make CXXFLAGS="-isystem /opt/boost_1_66_0/install/x86/include" LDFLAGS="-L/opt/boost_1_66_0/install/x86/lib"
89100
101+ for standalone asio:
102+
103+ make CXXFLAGS="-isystem <asio_include>"
104+
105+ example:
106+
107+ make CXXFLAGS="-isystem /opt/asio-1.18.0/include"
108+
90109(if you want to use clang instead of gcc, you can set the variable CXX=clang++)
91110
92111### Windows nmake
@@ -133,6 +152,91 @@ Some example:
133152 cli> echo "you can also show backslash \\ ... "
134153 you can also show backslash \ ...
135154
155+ ## Async programming and Schedulers
156+
157+ ` cli ` is an asynchronous library, and the handlers of commands are executed
158+ by a scheduler, in a thread provided by the user (possibly the main thread),
159+ this allows you to develop a single thread application
160+ without need to worry about synchronization.
161+
162+ So, your application must have a scheduler and pass it to ` CliLocalTerminalSession ` .
163+
164+ The library provides three schedulers:
165+
166+ - ` LoopScheduler `
167+ - ` BoostAsioScheduler `
168+ - ` StandaloneAsioScheduler `
169+
170+ ` LoopScheduler ` is the simplest: it does not depend on other libraries
171+ and should be your first choice if you don't need remote sessions.
172+
173+ ` BoostAsioScheduler ` and ` StandaloneAsioScheduler ` are wrappers around
174+ asio ` io_context ` objects.
175+ You should use one of them if you need a ` BoostAsioCliTelnetServer ` or a ` StandaloneAsioCliTelnetServer `
176+ because they internally use ` boost::asio ` and ` asio ` .
177+
178+ You should use one of them also if your application uses ` asio ` in some way.
179+
180+ After setting up your application, you must call ` Scheduler::Run() `
181+ to enter the scheduler loop. Each comamnd handler of the library
182+ will execute in the thread that called ` Scheduler::Run() ` .
183+
184+ You can exit the scheduler loop by calling ` Scheduler::Stop() `
185+ (e.g., as an action associated to the "exit" command).
186+
187+ You can submit work to be executed by the scheduler invoking the method
188+ ` Scheduler::Post(const std::function<void()>& f) ` .
189+ Schedulers are thread safe, so that you can post function object
190+ from any thread, to be executed in the scheduler thread.
191+
192+ This is an example of use of ` LoopScheduler ` :
193+
194+ ``` C++
195+ ...
196+ LoopScheduler scheduler;
197+ CliLocalTerminalSession localSession (cli, scheduler);
198+ ...
199+ // in another thread you can do:
200+ scheduler.Post([ ] ( ) { cout << "This will be executed in the scheduler thread" << endl; });
201+ ...
202+ // start the scheduler main loop
203+ // it will exit from this method only when scheduler.Stop() is called
204+ // each cli callback will be executed in this thread
205+ scheduler.Run();
206+ ...
207+ ```
208+
209+ This is an example of use of `BoostAsioScheduler`
210+
211+ ```C++
212+ ...
213+ BoostAsioScheduler scheduler;
214+ CliLocalTerminalSession localSession(cli, scheduler);
215+ BoostAsioCliTelnetServer server(cli, scheduler, 5000);
216+ ...
217+ scheduler.Run();
218+ ...
219+ ```
220+
221+ Finally, this is an example of use of ` BoostAsioScheduler `
222+ when your application already uses ` boost::asio ` and has
223+ a ` boost::asio::io_context ` object (the case of standalone asio is similar).
224+
225+ ``` C++
226+ ...
227+ // somewhere else in your application
228+ boost::asio::io_context ioc;
229+ ...
230+ // cli setup
231+ BoostAsioScheduler scheduler (ioc);
232+ CliLocalTerminalSession localSession(cli, scheduler);
233+ BoostAsioCliTelnetServer server(cli, scheduler, 5000);
234+ ...
235+ // somewhere else in your application
236+ ioc.run();
237+ ...
238+ ```
239+
136240## License
137241
138242Distributed under the Boost Software License, Version 1.0.
0 commit comments