Add a screen rotation class (time multiplexing).
[ccbs] / bigscreen / ccbs_bigscreen.cpp
1 #include <cstdio>
2 #include <cstring>
3 #include <iconv.h>
4 #include <unistd.h>
5 #include <pqxx/pqxx>
6 #include <tinyptc.h>
7 #include "flagtrigger.h"
8 #include "widestring.h"
9 #include "fetch_current_tournament.h"
10 #include "fetch_list_of_active_groups.h"
11 #include "fetch_group.h"
12 #include "fonts.h"
13 #include "groupscreen.h"
14 #include "splitscreen.h"
15 #include "rotatescreen.h"
16
17 Tournament active_tournament;
18 std::vector<SkeletonGroup> active_groups;
19 std::vector<GenericScreen *> screens;
20 //SplitScreen *mainscreen = NULL;
21 RotateScreen *mainscreen = NULL;
22 unsigned char framebuf[800 * 600 * 4], screenbuf[800 * 600 * 4];
23
24 void init(pqxx::connection &conn)
25 {
26         for (std::vector<GenericScreen *>::const_iterator i = screens.begin(); i != screens.end(); ++i) {
27                 delete *i;
28         }
29         screens.erase(screens.begin(), screens.end());
30         
31         delete mainscreen;
32         
33         conn.perform(FetchCurrentTournament(&active_tournament));
34         conn.perform(FetchListOfActiveGroups(&active_groups));
35
36         mainscreen = new RotateScreen();
37         
38         if (active_tournament.id == -1) {
39                 std::fprintf(stderr, "No active tournament\n");
40         } else {
41                 std::fprintf(stderr, "Current tournament is %d\n", active_tournament.id);
42
43                 for (std::vector<SkeletonGroup>::const_iterator i = active_groups.begin(); i != active_groups.end(); ++i) {
44                         std::fprintf(stderr, "tourn: %u  round: %u   parallel: %u\n",
45                                 i->tournament, i->round, i->parallel);
46
47                         screens.push_back(new GroupScreen(conn, i->tournament, i->round, i->parallel));
48                         mainscreen->add_screen(screens[screens.size() - 1]);
49                 }
50         }
51
52         // hack
53         screens.push_back(NULL);
54         screens.push_back(NULL);
55         screens.push_back(NULL);
56         screens.push_back(NULL);
57
58         //mainscreen = new SplitScreen(screens[0], screens[1], screens[2], screens[3]);
59 }
60
61 void main_loop(pqxx::connection &conn)
62 {
63         if (active_tournament.id == -1) {
64                 // No active tournament, sleep a second or so and exit
65                 conn.await_notification(1, 0);
66                 return;
67         }
68
69         if (mainscreen->check_invalidated()) {
70                 mainscreen->draw(framebuf);
71         }
72         ptc_update(framebuf);
73
74         conn.await_notification(0, 50000);
75 }
76
77 int main(int argc, char **argv)
78 {
79         ptc_open("CCBS bigscreen", 800, 600);
80         
81         try {
82                 init_freetype();
83                 pqxx::connection conn("dbname=ccbs host=altersex.samfundet.no user=ccbs password=GeT|>>B_");
84                 FlagTrigger tournament_changed(conn, "active_tournament");
85                 FlagTrigger rounds_changed(conn, "active_groups");
86                 
87                 // when active_tournament or active_rounds is changed, we destroy everything and start from scratch
88                 // (at least currently)
89                 for ( ;; ) {
90                         tournament_changed.reset_flag();
91                         rounds_changed.reset_flag();
92                         init(conn);
93                         do {
94                                 main_loop(conn);
95                                 conn.get_notifs();
96                         } while (!tournament_changed.get_flag() && !rounds_changed.get_flag());
97                         std::fprintf(stderr, "active_tournament or active_groups changed, resetting...\n");
98                 }
99         } catch (const std::exception &e) {
100                 std::fprintf(stderr, "Exception: %s\n", e.what());
101                 exit(1);
102         }
103         
104         return 0;
105 }