#pragma once #include #include "window.hpp" #include #include class renderer { daguerre::image framebuffer; daguerre::image double_buffer; daguerre::image background; daguerre::image cursor; daguerre::hilbert_color cursor_background; int cursor_x; int cursor_y; std::mutex mut; euler::syscall::stream_handle dispatcher_handle_1, dispatcher_handle_2; void do_render(); public: //all of the shown windows, sorted from furthest back to furthest front. //while the renderer is not locked, the contents of this can change and //iterators can be invalided. this should not be reordered, added to, or //have elements removed from outside the renderer. std::list windows; renderer( daguerre::image &&framebuffer, daguerre::image &&background, daguerre::hilbert_color background_color, daguerre::image &&cursor, daguerre::hilbert_color cursor_background); inline ~renderer() { euler::syscall::close_stream(dispatcher_handle_1); euler::syscall::close_stream(dispatcher_handle_2); } renderer(const renderer &) = delete; renderer &operator =(const renderer &) = delete; [[noreturn]] void render_thread_main(); inline void lock() { mut.lock(); } inline void unlock() { mut.unlock(); } inline void dispatch_render() { uint8_t byte = 0; euler::syscall::write_to_stream(dispatcher_handle_1, 1, &byte); } //gets the current position of the cursor. this should //only be called while the renderer is locked. void get_cursor(int &x_out, int &y_out); //this adds x_offset and y_offset to the current cursor position, and then //clamps the cursor position to have its top-left pixel inside the frame. //this should only be called while the renderer is locked. void bump_cursor(int x_offset, int y_offset); //moves the pointed to window to the front of the window stack. //this should only be called while the renderer is locked. void move_window_to_front(std::list::iterator w); void add_window(window *w); void remove_window(window *w); inline bool is_top(window *w) { return windows.size() != 0 && w == windows.back(); } };