#include "backend.hpp" #include "guecs/ui.hpp" #include #include "dbc.hpp" #include "constants.hpp" #include "slides_ui.hpp" #include "control_ui.hpp" #include "parser.hpp" #include #include #include #include using namespace std::chrono_literals; std::shared_ptr load_slides(const std::string& input_md, std::shared_ptr backend) { try { auto data = parse_slides(input_md, [&](nlohmann::json& config) { backend->set_font(config["font_file"]); guecs::init(backend.get()); }); fmt::println("FONT FILE: {}", backend->$font_file); auto slides = std::make_shared(data, sf::Vector2u{WINDOW_WIDTH, WINDOW_HEIGHT}); slides->init(); return slides; } catch(...) { fmt::println("ERROR!"); return nullptr; } } struct ChangeDetector { std::string input_md; sf::Clock timer{}; std::filesystem::file_time_type last_mod_time = std::filesystem::last_write_time(input_md); bool changed() { if(timer.getElapsedTime().toDuration() > 500ms) { try { auto mod_time = std::filesystem::last_write_time(input_md); if(last_mod_time < mod_time) { last_mod_time = mod_time; return true; } else { return false; } } catch(const std::filesystem::filesystem_error& err) { fmt::println("failed to open {}: {}", err.path1().string(), err.what()); timer.restart(); return false; } } return false; } }; int main(int argc, char *argv[]) { dbc::check(argc >= 2, "USAGE: bezos my_fucking_slides.md"); auto& modes = sf::VideoMode::getFullscreenModes(); auto screen_mode = std::find_if(modes.begin(), modes.end(), [=](const auto& a) -> bool { return a.size.x == WINDOW_WIDTH && a.size.y == WINDOW_HEIGHT; }); sf::RenderWindow controller(sf::VideoMode({CONTROL_WIDTH, CONTROL_HEIGHT}), "Bezos Loves Control"); sf::RenderWindow presenter(*screen_mode, "Bezos Loves Slides", sf::Style::None, sf::State::Windowed); presenter.setFramerateLimit(FRAME_LIMIT); presenter.setVerticalSyncEnabled(VSYNC); auto backend = std::make_shared(); auto slides = load_slides(argv[1], backend); if(!slides) { fmt::println("ERROR in your .md file"); return 1; } ControlUI control_ui(presenter); control_ui.init(); dbc::check(control_ui.$status != nullptr, "bad ptr"); ChangeDetector slides_reloader{argv[1]}; ChangeDetector layout_reloader{slides->$deck->config["layouts"]}; while(controller.isOpen()) { while (const auto event = presenter.pollEvent()) { if(event) slides->handle_events(presenter, *event); } while (const auto event = controller.pollEvent()) { if(event) control_ui.handle_events(controller, *event); } slides->render(presenter); control_ui.render(controller); presenter.display(); controller.display(); if(slides_reloader.changed() || layout_reloader.changed()) { // save the current slide auto current_slide = slides->$current; // load the new one auto new_slides = load_slides(argv[1], backend); if(new_slides) { new_slides->set_slide(current_slide); slides = new_slides; } } } }