From 5aed3b80e9d3c31d7b41422bdab2d9a90b8b1eeb Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Fri, 9 May 2025 10:40:55 +0200 Subject: [PATCH] Added many comments to main objects used. --- CMakeLists.txt | 2 +- include/event.h | 49 ++++++++++++++++++++++++++++++++++++++++---- include/logger.h | 36 +++++++++++++++++++++++++++++++- include/pages/page.h | 13 ++++++++++++ include/ui.h | 48 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa54bc3..d014988 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project( HOMEPAGE_URL "https://www.etheryo.fr/" LANGUAGES CXX C ) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 17) # Because using std::any, ftxui uses C++17 too. set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/include/event.h b/include/event.h index e6f2fd6..a7b398a 100644 --- a/include/event.h +++ b/include/event.h @@ -10,6 +10,7 @@ enum class EventType : uint8_t { SWITCH_SCREEN, SEND_TEXT, + // Add you own event here STOP, }; @@ -19,30 +20,70 @@ struct EventPayload std::any data; }; +/** + * @brief Main thread-safe event handler. You can set a custom function in it that will be called once the + * loop is starting. It is recommended to run the eventhandler in a separated thread. + * + * Each event that is added or handled is thread safe. + */ class EventHandler { public: EventHandler(); + + /** + * @brief setting the function to be called in the loop. + * + * @param function + */ void set_handler(std::function function); + + /** + * @brief Blocking loop function that will run the handled events. + */ void loop(); + + /** + * @brief Stopping the currently running loop. + */ void stop(); -protected: - void add_event(const EventPayload &payload); - friend class EventPage; - private: + friend class EventPage; + void add_event(const EventPayload &payload); bool _is_running; std::function _handler; std::deque _event_buffer; std::mutex _mutex; }; +/** + * @brief inherited by any class that wants to send an event with a proper payload. + * Each event handler linked is independent. + */ class EventPage { public: + /** + * @brief Creating the event object with its proper handler + * + * @param EventHandler& the handler reference. + */ EventPage(EventHandler &eventhandler); + + /** + * @brief sending an event with a proper payload. + * + * @param EventPayload payload + */ void send_event(const EventPayload &payload); + + /** + * @brief sending an event with a proper payload. + * + * @param EventType type of the payload + * @param std::any the data in the payload + */ void send_event(const EventType &type, std::any data = {}); private: diff --git a/include/logger.h b/include/logger.h index c862b9e..1a7b8df 100644 --- a/include/logger.h +++ b/include/logger.h @@ -11,10 +11,14 @@ enum class LoggerType : uint8_t _UNDEFINED, PRINT, COMMAND, - // You can add more here + // Add your own type of log here _COUNT }; +/** + * @brief Stored as two vectors in the logger, + * one that is a general vector, and the other that is shown on the screen. + */ struct LoggerData { std::string str; @@ -22,6 +26,11 @@ struct LoggerData LoggerType type; }; +/** + * @brief 'Logger' is a general Logger that can be instanciated anywhere as a singleton. + * It can have a maximum size for its buffer that can be changed on the go. + * Each LoggerType can be gathered from each data which can lead to multiple ways to print out a log. + */ class Logger { public: @@ -30,13 +39,38 @@ public: static Logger instance; return instance; } + + /** + * @brief set the max size for the returned buffer by get_buffer(). + * If it goes beyond the actual stored buffer, it shows only this buffer. + * + * @param int the size of the wanted buffer + */ void set_max_size(int size); + + /** + * @brief Adding a log to the buffer. you can add a logger type. + * The epoch is automatically calculated here. + * + * @param std::string the string to put to the buffer + * @param LoggerType the type of log (default: UNDEFINED) + */ void push_back(std::string str, LoggerType type = LoggerType::_UNDEFINED); + + /** + * @brief Gather the buffer from the size set in set_max_size() + * + * @return std::vector& reference of the data. + */ const std::vector &get_buffer(void) noexcept; private: Logger(); ~Logger(); + + /** + * @brief Updating the _view buffer with the current size. + */ void update_view(); size_t _maxSize; diff --git a/include/pages/page.h b/include/pages/page.h index 484f275..a76d5b4 100644 --- a/include/pages/page.h +++ b/include/pages/page.h @@ -4,6 +4,13 @@ #include #include "event.h" +/** + * @brief 'Page' is a child class that can be inherited by any new page. + * In your constructor you should build the _page given by it. Otherwise this + * class should not be instanciated whatsover. + * + * Each Page is inherited from an EventPage and can send signals. to the main event handler. + */ class Page : public EventPage { public: @@ -12,6 +19,12 @@ public: { } + /** + * @brief Gather the current page from any parent. + * This function may be overwritten. + * + * @return ftxui::Component the current page + */ ftxui::Component *getPage() { return &_page; diff --git a/include/ui.h b/include/ui.h index 0c4658f..f289858 100644 --- a/include/ui.h +++ b/include/ui.h @@ -8,6 +8,10 @@ #include #include +/** + * @brief 'UserInterface' is the main object that can be instanciated anywhere as a singleton + * you can add any pages to it and cycle through them using the select_screen function. + */ class UserInterface { public: @@ -17,22 +21,66 @@ public: return instance; } + /** + * @brief return the actual terminal used for fullscreen. + * + * @return ftxui::ScreenInteractive + */ ftxui::ScreenInteractive *get_screen(); + + /** + * @brief Adding a page to the list. Only to be called before start(). + * Each page's lifetime has to be take into account as it is not copied into the object. + * + * @param Page* pointer to the parent Page + */ void add_screen(Page *p); + + /** + * @brief Can be called anytime. Changes the selected page. + * + * @param size_t the index, it has to be inferior or equal to the pages given to the UI. + */ void select_screen(size_t index); + + /** + * @brief Can be called anytime. Changes the selected page. + * + * @param Page* pointer to the parent Page, it has to be added to the list before hand. + */ void select_screen(const Page *p); + + /** + * @brief Blocking function to render to the terminal. + */ void start(); + + /** + * @brief Updates the terminal. Can be useful when doing custom manipulations to diverse object. + * Will redraw the entire terminal. + */ void update(); private: + /** + * @brief UserInterface cannot be created and can be called from anywhere in the executable. + */ UserInterface(); ~UserInterface(); ftxui::ScreenInteractive _screen; std::vector _pages; + /** + * @brief each ftxui::Component in this object is stored directly because it has to be called by the + * rendering pipeline. + */ ftxui::Component _page_container; ftxui::Component _main_container; ftxui::Component _main_renderer; + /** + * @brief Used in the ftxui::Container::Tab which can switch between + * each pages renderer. (or get_page()) + */ int _page_index; };