#pragma once #include #include namespace Dive { using Keycode = int; /* * Renderer struct * Dive's abstraction over ncurses, which allows easy screen manipulation. * * Call Renderer().init() before using any other methods, this will set up the ncurses * screen for you. All other methods will do nothing without the renderer being init'd. * * You don't have to do Renderer().close(), as the destructor will do this for you, * unless you want to exit the window early. The Renderer will keep track of whether * it is init'd, and can be reused after being closed by using init again. */ struct Renderer { /* * Initialises ncurses in the terminal. When called, will wipe the terminal and * ensure it is ready for all other functions. * * This method sets up ncurses in the way which Dive expects it to function, * please do not mess with ncurses while the renderer is init'ed. */ void init(); /* * Closes ncurses in the terminal. Use when you're done. Automatically called by * the destructor. */ void close(); /* * Displays anything currently in the buffer, waiting to be displayed. */ void display(); /* * Clears the buffer, ready for new contents. */ void clear(); /* * Waits for the user to press a key on their keyboard. * This blocks the thread until a key is pressed. */ Keycode wait(); /* * Puts a string into a buffer, at the specified x and y positioning. Moves the * cursor to the needed position. */ void putString(int x, int y, std::string str); /* * Puts a string into the buffer at the current position of the cursor. Useful * for status bars. */ void appendString(std::string str); /* * Sets the position of the cursor on screen. */ void setPos(int x, int y); Renderer() = default; ~Renderer() { if (hasInit) close(); } private: /* * Ensures that the renderer always knows if ncurses is ready or not. */ bool hasInit = false; }; }