root/main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <curl/curl.h>
#include <locale.h>
#include <ncurses.h>
#include <pthread.h>
#include <unistd.h>
#include "TvShows.h"
#include "EpisodePage.h"
#include "Player.h"
#include "Colors.h"
#include "ServerEvents.h"

void printServerShit(const char* event, const char* data, void* userdata) {
    printf("ev: %s\n dataa: %s\n userdata:%p", event, data, userdata);
}

struct NetworkThreadData {
    struct ServerEvents* se;
    const char* url;
    bool* quit;
    CURLM* multiHandle;
};

void* networkThreadFn(void* userdata) {
    struct NetworkThreadData* data = userdata;
    ServerEvents_connect(data->se, data->url, data->multiHandle);
    int runningHandles = 0;
    while (!(*data->quit)) {
        curl_multi_perform(data->multiHandle, &runningHandles);
        usleep(100000);
    }
    return userdata;
}

int main(int argc, const char* argv[]) {
    char* url = NULL;
    if (argc >= 2) {
        url = (char*)argv[1];
    } else {
        url = "localhost:8082";
    }

    /* lib init */
    curl_global_init(CURL_GLOBAL_SSL);

    setlocale(LC_ALL, "");
    initscr();
    if (!has_colors()) {
        puts("terminal doesn't support colors\n");
    }
    start_color();
    Colors_init();
    Colors_set(Colors_Default);

    // init ncurses io settings
    cbreak(); // allow ctrl-Z, ctrl-C and other keys to keep their default actions
    noecho();
    keypad(stdscr, TRUE);

    printw("%s fetching lists...\n", url);
    refresh();

    /* page init */
    struct TvShows shows;
    TvShows_init(&shows);

    struct Player player;
    Player_init(&player);

    struct EpisodePage epPage;
    EpisodePage_init(&epPage);
    epPage.baseUrl = url;

    epPage.startPage = &shows;
    shows.episodePage = &epPage;

    void* activePage = &shows;
    epPage.activePage = &activePage;
    shows.activePage = &activePage;

    /* network thread */
    bool quit = false;
    CURLM* multiHandle = curl_multi_init();
    struct ServerEvents se;
    ServerEvents_init(&se);
    ServerEvents_addCallback(&se, Player_onServerEvent, &player);
    ServerEvents_addCallback(&se, EpisodePage_onServerEvent, &epPage);

    pthread_t networkThread;
    struct NetworkThreadData ntdata = {
        .se = &se,
        .url = url,
        .quit = &quit,
        .multiHandle = multiHandle
    };
    int threadError = pthread_create(&networkThread, NULL, networkThreadFn, &ntdata);
    if (threadError) {
        return 1;
    }

    /* update */
    TvShows_fetch(&shows, url);
    refresh();

    Player_fetch(&player, url);
    refresh();

    TvShows_printAll(&shows, NULL);
    /* main loop */
    do {
        int c = getch();
        if (c == 27 || c == 'q') {
            quit = true;
        } else if (c == KEY_RESIZE) {
            refresh();
        }
        bool handled = false;
        handled = TvShows_handleInput(&shows, c);
        handled = handled ? handled : EpisodePage_handleInput(&epPage, c);
        handled = handled ? handled : Player_handleInput(&player, c);

        Player_draw(&player);
        refresh();
    } while (!quit);

    pthread_cancel(networkThread);
    curl_multi_cleanup(multiHandle);
    ServerEvents_destroyMembers(&se);
    /* pthread_join(networkThread, NULL); */

    TvShows_destroyMembers(&shows);
    endwin();
    return 0;
}