aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/MangaCombined.cpp
blob: 1745ee0f5032799a692d6b115edf7af75bad44d3 (plain)
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
#include "../../plugins/MangaCombined.hpp"

namespace QuickMedia {
    static const int SEARCH_TIMEOUT_MILLISECONDS = 5000;

    MangaCombinedSearchPage::MangaCombinedSearchPage(Program *program, std::vector<MangaPlugin> search_pages) :
        Page(program), search_pages(std::move(search_pages))
    {
        
    }

    using PluginFinishedState = std::pair<MangaPlugin*, std::unique_ptr<BodyItems>>;
    static void result_items_add_thread_results(std::vector<MangaCombinedSearchThread> &search_threads, BodyItems &result_items) {
        std::sort(search_threads.begin(), search_threads.end(), [](const MangaCombinedSearchThread &plugin1, const MangaCombinedSearchThread &plugin2){
            return plugin1.first->title < plugin2.first->title;
        });

        std::vector<PluginFinishedState> plugin_finished_state(search_threads.size());
        for(size_t i = 0; i < plugin_finished_state.size(); ++i) {
            plugin_finished_state[i].first = search_threads[i].first;
            plugin_finished_state[i].second = nullptr;
        }

        int accumulated_sleep_time = 0;
        while(true) {
            for(size_t i = 0; i < search_threads.size(); ++i) {
                auto &search_thread = search_threads[i];
                if(!search_thread.second.valid())
                    continue;

                if(!search_thread.second.ready())
                    continue;

                plugin_finished_state[i].second = std::make_unique<BodyItems>(search_thread.second.get());
                if(plugin_finished_state[i].second->empty())
                    continue;

                for(auto &new_body_item : *plugin_finished_state[i].second) {
                    new_body_item->userdata = search_thread.first->page.get();
                }
            }

            size_t num_finished_plugins = 0;
            for(auto &f : plugin_finished_state) {
                if(f.second)
                    ++num_finished_plugins;
            }

            if(num_finished_plugins == search_threads.size()) {
                for(auto &f : plugin_finished_state) {
                    if(f.second && !f.second->empty()) {
                        auto title_item = BodyItem::create("");
                        title_item->set_author("------------------------ " + f.first->title + " ------------------------");
                        result_items.push_back(std::move(title_item));
                        result_items.insert(result_items.end(), std::move_iterator(f.second->begin()), std::move_iterator(f.second->end()));
                    }
                }
                break;
            }

            int sleep_time_ms = 200;
            std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time_ms));
            accumulated_sleep_time += sleep_time_ms;
            if(accumulated_sleep_time >= SEARCH_TIMEOUT_MILLISECONDS) {
                for(auto &f : plugin_finished_state) {
                    if(f.second) {
                        if(!f.second->empty()) {
                            auto title_item = BodyItem::create("");
                            title_item->set_author("------------------------ " + f.first->title + " ------------------------");
                            result_items.push_back(std::move(title_item));
                            result_items.insert(result_items.end(), std::move_iterator(f.second->begin()), std::move_iterator(f.second->end()));
                        }
                    } else {
                        auto title_item = BodyItem::create("");
                        title_item->set_author("------------------------ " + f.first->title + " timed out ------------------------");
                        result_items.push_back(std::move(title_item));
                    }
                }
                break;
            }
        }
    }

    SearchResult MangaCombinedSearchPage::search(const std::string &str, BodyItems &result_items) {
        search_threads.clear();
        for(auto &search_page : search_pages) {
            search_threads.push_back(std::make_pair(&search_page, AsyncTask<BodyItems>([&str, &search_page]() {
                BodyItems search_page_body_items;
                search_page.page->search(str, search_page_body_items);
                return search_page_body_items;
            })));
        }

        result_items_add_thread_results(search_threads, result_items);
        return SearchResult::OK;
    }

    PluginResult MangaCombinedSearchPage::get_page(const std::string &str, int page, BodyItems &result_items) {
        search_threads.clear();
        for(auto &search_page : search_pages) {
            search_threads.push_back(std::make_pair(&search_page, AsyncTask<BodyItems>([&str, page, &search_page]() {
                BodyItems search_page_body_items;
                search_page.page->get_page(str, page, search_page_body_items);
                return search_page_body_items;
            })));
        }

        result_items_add_thread_results(search_threads, result_items);
        return PluginResult::OK;
    }

    PluginResult MangaCombinedSearchPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
        Page *page = (Page*)submit_body_item->userdata;
        if(!page) return PluginResult::OK;
        return page->submit(title, url, result_tabs);
    }
}