Skip to content

Commit 98c9f9e

Browse files
committed
initial
0 parents  commit 98c9f9e

19 files changed

+910
-0
lines changed

CMakeLists.txt

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#
2+
# Coding Dojo
3+
#
4+
5+
cmake_minimum_required(VERSION 3.7)
6+
7+
8+
project(dojo)
9+
10+
#
11+
# Compilation settings
12+
#
13+
14+
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
15+
16+
set(CMAKE_CXX_STANDARD 14)
17+
set(CMAKE_C_STANDARD 11)
18+
19+
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
20+
# ensure a clean code
21+
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wconversion")
22+
set(CMAKE_C_FLAGS "-Wall -Wextra -Wconversion")
23+
endif()
24+
25+
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
26+
# brewed zeromq doesn't have cppzmq
27+
file(DOWNLOAD https://raw.githubusercontent.com/zeromq/cppzmq/v4.3.0/zmq.hpp includes/zmq.hpp EXPECTED_HASH SHA1=5916eb5dd3196ec97591e64c110789341b03b678)
28+
file(DOWNLOAD https://raw.githubusercontent.com/zeromq/cppzmq/v4.3.0/zmq_addon.hpp includes/zmq_addon.hpp EXPECTED_HASH SHA1=ffcfb809d128c8fd5a63ca078874f12cd4c7a517)
29+
30+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
31+
# clang doesn't have the handy gcc STL header file
32+
configure_file(stdc++.h.in includes/bits/stdc++.h COPYONLY @ONLY)
33+
endif()
34+
include_directories(${CMAKE_CURRENT_BINARY_DIR}/includes)
35+
endif()
36+
37+
enable_testing()
38+
39+
#
40+
# Executables
41+
#
42+
43+
add_executable(logsrv examples/logsrv.c)
44+
target_link_libraries(logsrv PRIVATE zmq)
45+
46+
add_executable(logsrv2 examples/logsrv2.c)
47+
target_link_libraries(logsrv2 PRIVATE zmq czmq)
48+
49+
add_executable(demo examples/demo.cpp)
50+
target_link_libraries(demo PRIVATE ncurses)

README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# README
2+
3+
4+
## Prerequesites
5+
6+
Raspberry Pi (raspbian):
7+
```
8+
sudo apt install build-essential cmake
9+
sudo apt install libncurses5-dev libzmq3-dev libczmq-dev python3-zmq
10+
```
11+
12+
[Python 3.6+](https://www.python.org/downloads/)
13+
14+
15+
## GitHub
16+
17+
[thales6](https://github.com/thales6)
18+
19+
## ncurses
20+
21+
* [Homepage](https://invisible-island.net/ncurses/)
22+
* [HOWTO](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/)
23+
* [HOWTO Python3](https://docs.python.org/3/howto/curses.html)
24+
25+
## ZeroMQ
26+
27+
* [Web site](http://zeromq.org/)
28+
* [zguide](http://zguide.zeromq.org/) [explanations](http://zguide.zeromq.org/page:all#Sending-and-Receiving-Messages)
29+
* [examples](https://github.com/booksbyus/zguide)
30+
* [pyzmq](https://learning-0mq-with-pyzmq.readthedocs.io/)

examples/demo.cpp

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include <bits/stdc++.h>
2+
#include <ncurses.h>
3+
#include <unistd.h>
4+
#include <sys/time.h>
5+
#include <math.h>
6+
7+
void reset_screen()
8+
{
9+
delwin(stdscr);
10+
endwin();
11+
refresh();
12+
13+
puts("Bye.");
14+
}
15+
16+
int main()
17+
{
18+
initscr(); // start ncurses
19+
atexit(reset_screen); // vacuum
20+
21+
if (!has_colors())
22+
{
23+
exit(2); // we want colors
24+
}
25+
start_color(); // start colors
26+
27+
if (COLOR_PAIRS < 16)
28+
{
29+
exit(2); // at least 16 pairs
30+
}
31+
32+
init_pair(1, COLOR_BLUE, COLOR_BLACK);
33+
init_pair(2, COLOR_RED, COLOR_BLACK);
34+
init_pair(3, COLOR_BLACK, COLOR_YELLOW);
35+
36+
cbreak(); // line buffering disabled
37+
keypad(stdscr, true); // enables F_keys
38+
noecho(); // disables echoing of characters
39+
curs_set(0); // hide cursor
40+
41+
int x, y;
42+
getmaxyx(stdscr, y, x);
43+
44+
attron(COLOR_PAIR(3) | A_BLINK);
45+
mvaddstr(y / 2, x / 2 - 10, "WAITING FOR PLAYER...");
46+
attroff(COLOR_PAIR(3) | A_BLINK);
47+
48+
getch(); // blocking key input
49+
erase();
50+
51+
int last_key = -1;
52+
int angle = 0;
53+
int radius = 5;
54+
int speed = 5;
55+
56+
nodelay(stdscr, 1); // non blocking key input
57+
while (true)
58+
{
59+
int c = getch();
60+
61+
if (c == 27)
62+
break;
63+
if (c == 'q')
64+
break;
65+
66+
switch (c)
67+
{
68+
case KEY_RESIZE:
69+
getmaxyx(stdscr, y, x);
70+
break;
71+
case KEY_DOWN:
72+
speed = speed > -10 ? speed - 1 : -10;
73+
break;
74+
case KEY_UP:
75+
speed = speed < 10 ? speed + 1 : 10;
76+
break;
77+
case KEY_RIGHT:
78+
radius = radius < 10 ? radius + 1 : 10;
79+
break;
80+
case KEY_LEFT:
81+
radius = radius > 1 ? radius - 1 : 1;
82+
break;
83+
}
84+
85+
// clear screan
86+
erase();
87+
88+
// draw the XY axis
89+
mvvline(0, x / 2, ACS_VLINE, y);
90+
mvhline(y / 2, 0, ACS_HLINE, x);
91+
92+
// print CROSS at center of the screen
93+
attron(COLOR_PAIR(1));
94+
mvaddstr(y / 2, x / 2 - 2, "CROSS");
95+
attroff(COLOR_PAIR(1));
96+
97+
// print screen size
98+
attron(COLOR_PAIR(2));
99+
mvprintw(y - 2, 2, "x,y = %d,%d", x, y);
100+
attroff(COLOR_PAIR(2));
101+
102+
// print the last key
103+
if (c != -1)
104+
{
105+
last_key = c;
106+
}
107+
if (last_key >= 32 && last_key <= 126)
108+
{
109+
mvprintw(2, 2, "last key: %c 0x%x", last_key, last_key);
110+
}
111+
else if (last_key != -1)
112+
{
113+
mvprintw(2, 2, "last key: 0x%x 0%03o", last_key, last_key, last_key);
114+
}
115+
116+
// draw the radar pursuit
117+
int bx, by;
118+
bx = (int)(x / 2 + (x / 20.) * radius * cos(angle * M_PI / 180.));
119+
by = (int)(y / 2 - (y / 20.) * radius * sin(angle * M_PI / 180.));
120+
121+
if (mvinch(by, bx) != ' ')
122+
{
123+
// let's add some alea when hiting the cross
124+
if (rand() % 2)
125+
{
126+
// bounce the ball
127+
speed = -speed;
128+
}
129+
else
130+
{
131+
// accelerate or decelerate the ball
132+
int r = rand() % 3;
133+
if (r == 1 && speed < 10)
134+
speed++;
135+
else if (r == 2 && speed > -10)
136+
speed--;
137+
}
138+
}
139+
mvaddch(by, bx, '@');
140+
141+
// print the parameters
142+
mvprintw(0, x - 10, "a=%3d r=%2d", angle, radius);
143+
mvprintw(1, x - 9, "speed=%3d", speed);
144+
145+
struct timeval tv;
146+
gettimeofday(&tv, nullptr);
147+
mvprintw(1, 2, "%ld.%06ld", tv.tv_sec, tv.tv_usec);
148+
149+
// update
150+
angle = (angle + speed + 360) % 360;
151+
152+
//
153+
usleep(40000); // 40 ms ~ 25 Hz
154+
}
155+
156+
return 0;
157+
}

examples/logcli.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#! /usr/bin/env python3
2+
3+
"""
4+
PUSH/PULL log producer
5+
"""
6+
7+
import zmq
8+
import argparse
9+
import logging
10+
import zmq.log.handlers
11+
12+
13+
def main():
14+
parser = argparse.ArgumentParser()
15+
parser.add_argument("-v", "--verbose", help="increase verbosity", action='store_true')
16+
parser.add_argument("-t", "--topic", help="topic", default="")
17+
parser.add_argument("-l", "--level", help="level", default='debug',
18+
choices=['debug', 'info', 'warning', 'error', 'critical'])
19+
parser.add_argument("text", help="text", nargs='+')
20+
args = parser.parse_args()
21+
22+
# Prepare our context and sockets
23+
context = zmq.Context()
24+
25+
# logging with ZeroMQ
26+
zmqlog = context.socket(zmq.PUSH)
27+
zmqlog.connect("ipc:///tmp/pong_logger")
28+
29+
handler = zmq.log.handlers.PUBHandler(zmqlog)
30+
31+
# replace PUBHandler formatters
32+
handler.formatters[logging.DEBUG] = logging.Formatter("%(message)s\n")
33+
handler.formatters[logging.INFO] = logging.Formatter("%(message)s\n")
34+
handler.formatters[logging.WARN] = logging.Formatter("%(message)s\n")
35+
handler.formatters[logging.ERROR] = logging.Formatter("%(message)s\n")
36+
handler.formatters[logging.CRITICAL] = logging.Formatter("%(message)s\n")
37+
38+
handler.root_topic = args.topic
39+
logger = logging.getLogger()
40+
logger.setLevel(logging.DEBUG)
41+
logger.addHandler(handler)
42+
43+
# send the log
44+
getattr(logging, args.level)(" ".join(args.text))
45+
46+
47+
if __name__ == "__main__":
48+
main()

examples/logsrv.c

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// zmq example
3+
//
4+
5+
#include <zmq.h>
6+
#include <stdio.h>
7+
#include <assert.h>
8+
#include <time.h>
9+
#include <sys/time.h>
10+
11+
12+
int main()
13+
{
14+
void *context = zmq_ctx_new();
15+
16+
// Socket to send start of batch message on
17+
void *sink = zmq_socket(context, ZMQ_PULL);
18+
zmq_bind(sink, "ipc:///tmp/pong_logger");
19+
20+
// Process tasks forever
21+
while (1) {
22+
int more;
23+
int num_part = 0;
24+
25+
do {
26+
/* Create an empty ØMQ message to hold the message part */
27+
zmq_msg_t part;
28+
int rc = zmq_msg_init(&part);
29+
assert(rc == 0);
30+
31+
/* Block until a message is available to be received from socket */
32+
rc = zmq_msg_recv(&part, sink, 0);
33+
assert (rc != -1);
34+
35+
++num_part;
36+
37+
if (num_part == 1)
38+
{
39+
struct timeval now;
40+
gettimeofday(&now, NULL);
41+
char buf[sizeof "2018-11-23T09:00:00Z"];
42+
strftime(buf, sizeof buf, "%FT%T", localtime(&now.tv_sec));
43+
44+
printf("%s.%06ld", buf, (long)now.tv_usec);
45+
}
46+
47+
printf(" - ");
48+
fwrite(zmq_msg_data(&part), zmq_msg_size(&part), 1, stdout);
49+
50+
// Look if there is another part to come
51+
more = zmq_msg_more(&part);
52+
53+
zmq_msg_close(&part);
54+
} while (more);
55+
}
56+
57+
zmq_close(sink);
58+
zmq_ctx_destroy(context);
59+
return 0;
60+
}

0 commit comments

Comments
 (0)