Skip to content

Commit 8c23f55

Browse files
committed
event loop
Signed-off-by: Pavel Kalugin <[email protected]>
1 parent e5f148c commit 8c23f55

File tree

11 files changed

+128
-21
lines changed

11 files changed

+128
-21
lines changed

include/buffer.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace fs = std::filesystem;
99

10+
namespace rang
11+
{
1012
class buffer
1113
{
1214
public:
@@ -32,4 +34,5 @@ class directory_listing : public buffer
3234

3335
void update();
3436
};
37+
} // namespace rang
3538
#endif

include/evloop.hpp

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef __EVLOOP_HPP
2+
#define __EVLOOP_HPP
3+
4+
#include <boost/asio.hpp>
5+
#include <functional>
6+
#include <string>
7+
#include <vector>
8+
9+
#undef timeout
10+
11+
namespace rang
12+
{
13+
class event_loop
14+
{
15+
private:
16+
boost::asio::io_context io_context;
17+
boost::asio::signal_set signals;
18+
boost::asio::posix::stream_descriptor input;
19+
20+
public:
21+
event_loop();
22+
23+
template <class duration>
24+
void add_regular_job(const std::function<void()> callback,
25+
const duration &interval); // TODO implementation
26+
27+
template <class time_point>
28+
void add_job(const std::function<void()> callback, time_point &time); // TODO implementation
29+
30+
void set_input_reaction(const std::function<void(int)> callback);
31+
32+
void run();
33+
34+
void stop();
35+
36+
private:
37+
void handle_input(const std::function<void(int)> &callback);
38+
};
39+
} // namespace rang
40+
#endif

include/rwindow.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
#ifndef __NWINDOW_HPP
2-
#define __NWINDOW_HPP
1+
#ifndef __RWINDOW_HPP
2+
#define __RWINDOW_HPP
33

44
#include "buffer.hpp"
55
#include "console_io.hpp"
66

7+
namespace rang
8+
{
79
class window
810
{
911
private:
@@ -18,5 +20,6 @@ class window
1820

1921
void scroll_viewport(int shift);
2022
};
23+
} // namespace rang
2124

2225
#endif

src/CMakeLists.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
add_subdirectory(console_io)
22

3-
add_executable (rang rang.cpp buffer.cpp rwindow.cpp)
3+
add_executable (rang evloop.cpp buffer.cpp rwindow.cpp rang.cpp)
4+
5+
find_package(Boost 1.70.0 REQUIRED COMPONENTS system thread)
46

57
target_compile_features(rang PUBLIC cxx_std_17)
68
target_include_directories(rang PUBLIC ${CURSES_INCLUDE_DIRS})
7-
target_link_libraries(rang PUBLIC ${CURSES_LIBRARIES} console_io)
9+
target_link_libraries(rang PUBLIC ${CURSES_LIBRARIES} ${Boost_LIBRARIES} console_io)

src/buffer.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "buffer.hpp"
22
#include <algorithm>
33

4+
using namespace rang;
5+
46
directory_listing::directory_listing(fs::path _directory) : directory(_directory)
57
{
68
}

src/console_io/include/console_io.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
#define __CONSOLE_IO_HPP
33
#include "base.hpp"
44
#include "window.hpp"
5+
6+
#undef timeout
57
#endif

src/console_io/include/window.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class window
4545
void outputln(int y, std::string s) const;
4646

4747
window subwindow(int _size_x, int _size_y, int offset_x, int offset_y);
48+
49+
int set_keypad(bool value) const;
4850
};
4951
} // namespace console_io
5052

src/console_io/src/window.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,8 @@ window window::subwindow(int _size_x, int _size_y, int offset_x, int offset_y)
9898
subwindows.push_back(result);
9999
return result;
100100
}
101+
102+
int window::set_keypad(bool value) const
103+
{
104+
return keypad(win_ptr, (value ? TRUE : FALSE));
105+
}

src/evloop.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "evloop.hpp"
2+
#include <iostream>
3+
#include <ncurses.h>
4+
5+
#undef timeout
6+
7+
using namespace rang;
8+
9+
event_loop::event_loop()
10+
: signals(io_context, SIGINT, SIGTERM), // handle SIGINT and SIGTERM signals
11+
input(io_context, STDIN_FILENO) // take input from stdin stream
12+
{
13+
signals.async_wait([&](auto, auto) { io_context.stop(); });
14+
}
15+
16+
void event_loop::run()
17+
{
18+
io_context.run();
19+
}
20+
21+
void event_loop::stop()
22+
{
23+
io_context.stop();
24+
}
25+
26+
void event_loop::set_input_reaction(const std::function<void(int)> callback)
27+
{
28+
input.cancel();
29+
handle_input(callback);
30+
}
31+
32+
void event_loop::handle_input(const std::function<void(int)> &callback)
33+
{
34+
input.async_wait(boost::asio::posix::stream_descriptor::wait_read,
35+
[this, callback](auto error) {
36+
if (!error) {
37+
callback(getch());
38+
}
39+
handle_input(callback);
40+
});
41+
}

src/rang.cpp

+22-17
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,53 @@
11
#include "buffer.hpp"
22
#include "console_io.hpp"
3+
#include "evloop.hpp"
34
#include "rwindow.hpp"
45
#include <algorithm>
56
#include <iostream>
67
#include <ncurses.h>
78

89
int main(int argc, char *argv[])
910
{
10-
int width;
11-
int height;
12-
1311
console_io::ncurses root;
14-
cbreak(); /* Line buffering disabled, Pass on
15-
* everty thing to me */
16-
keypad(stdscr, TRUE); /* I need that nifty F1 */
12+
cbreak(); /* Line buffering disabled, Pass on
13+
*everty thing to me */
14+
root.set_keypad(true); /* I need that nifty F1 */
15+
keypad(stdscr, TRUE);
1716
noecho();
1817
curs_set(0);
1918
root.refresh();
2019
console_io::window mywin =
2120
root.subwindow(root.get_size_x() - 2, root.get_size_y() - 2, 1, 1);
22-
directory_listing lst(".");
21+
rang::directory_listing lst(".");
2322
lst.update();
24-
window main(std::move(mywin), lst);
23+
rang::window main(std::move(mywin), lst);
2524
root.refresh();
2625
int ch;
2726
main.refresh();
28-
while ((ch = getch()) != KEY_F(1)) {
27+
rang::event_loop loop;
28+
std::function<void(int)> reaction_func = [&](int ch) {
29+
if (ch == KEY_F(1)) {
30+
loop.stop();
31+
return;
32+
}
2933
try {
3034
switch (ch) {
31-
case 'j':
3235
case KEY_DOWN:
36+
case 'j':
3337
main.scroll_viewport(1);
3438
break;
35-
case 'k':
3639
case KEY_UP:
40+
case 'k':
3741
main.scroll_viewport(-1);
3842
break;
43+
default:
44+
return;
3945
}
40-
root.outputln(root.get_size_y() - 1, "OK");
41-
} catch (int) {
42-
root.outputln(root.get_size_y() - 1, "Error found");
46+
main.refresh();
47+
} catch (error_t) {
4348
}
44-
root.refresh();
45-
main.refresh();
46-
}
49+
};
50+
loop.set_input_reaction(reaction_func);
51+
loop.run();
4752
return 0;
4853
}

src/rwindow.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "rwindow.hpp"
22

3+
using namespace rang;
4+
35
window::window(console_io::window &&_win, buffer &_tied_buf) : win(_win), tied_buf(_tied_buf)
46
{
57
}

0 commit comments

Comments
 (0)