From b1bdb86b767fb4cde5185c61ad597d65a034d884 Mon Sep 17 00:00:00 2001 From: Ritchie Cunningham Date: Sun, 28 Sep 2025 00:09:26 +0100 Subject: [PATCH] [Add] Implement screen manager state machine. --- client/src/game_state.cpp | 120 ++++++++++++++++++++++++-------------- client/src/game_state.h | 9 +++ client/src/ui/desktop.cpp | 5 ++ 3 files changed, 90 insertions(+), 44 deletions(-) diff --git a/client/src/game_state.cpp b/client/src/game_state.cpp index 9f70213..15bf2f4 100644 --- a/client/src/game_state.cpp +++ b/client/src/game_state.cpp @@ -9,73 +9,105 @@ #include "ui/desktop.h" #include "ui/ui_window.h" -GameState::GameState(void) = default; +void GameState::_init_desktop(void) { + _desktop = std::make_unique(); + + auto term = std::make_unique(_network.get()); + auto term_window = std::make_unique("Terminal", 100, 100, 800, 500); + term_window->set_content(std::move(term)); + _desktop->add_window(std::move(term_window)); +} + +GameState::GameState(void) : _current_screen(Screen::MAIN_MENU) {} GameState::~GameState(void) = default; void GameState::init(void) { /* Create and connect the network client. */ _network = std::make_unique(); - if(_network->connect("127.0.0.1", 1337)) { - /* TODO: handle connection success message. */ - } else { - /* TODO: handle connection failure. */ + + /* TODO: For now, connect immediately, later, trigger by menu option. */ + if(!_network->connect("127.0.0.1", 1337)) { + /* TODO: Handle connection failure. */ } - - /* Create the desktop. */ - _desktop = std::make_unique(); - - /* - * Create initial terminal window. - */ - auto term = std::make_unique(_network.get()); /* Pass network connection. */ - auto term_window = std::make_unique("Terminal", 100, 100, 800, 500); - term_window->set_content(std::move(term)); - _desktop->add_window(std::move(term_window)); + _current_screen = Screen::DESKTOP; + _init_desktop(); } void GameState::handle_event(SDL_Event* event) { - if(_desktop) { - _desktop->handle_event(event); + switch(_current_screen) { + case Screen::MAIN_MENU: + /* TODO: */ + break; + case Screen::BOOTING: + /* TODO: */ + break; + case Screen::DESKTOP: + if(_desktop) { + _desktop->handle_event(event); + } + break; } } void GameState::update(void) { - std::string server_msg; - while(_network->poll_message(server_msg)) { - UIWindow* focused_window = _desktop->get_focused_window(); - if(!focused_window) continue; + switch(_current_screen) { + case Screen::MAIN_MENU: + /* TODO: */ + break; + case Screen::BOOTING: + /* TODO: */ + break; + case Screen::DESKTOP: + std::string server_msg; + while(_network->poll_message(server_msg)) { + UIWindow* focused_window = _desktop->get_focused_window(); + if(!focused_window) + continue; - Terminal* terminal = focused_window->get_content(); - if(!terminal) continue; + Terminal* terminal = focused_window->get_content(); + if(!terminal) + continue; - /* Server sends "output\nprompt", split them. */ - size_t last_newline = server_msg.find_last_of("\n"); - if(last_newline != std::string::npos) { - std::string prompt = server_msg.substr(last_newline+1); - terminal->set_prompt(prompt); + /* Server sends "output\nprompt", split them. */ + size_t last_newline = server_msg.find_last_of('\n'); + if(last_newline != std::string::npos) { + std::string prompt = server_msg.substr(last_newline+1); + terminal->set_prompt(prompt); - std::string output = server_msg.substr(0, last_newline); - if(!output.empty()) { - /* split the multiline output and push each line to history. */ - std::stringstream ss(output); - std::string line; - while(std::getline(ss, line, '\n')) { - terminal->add_history(line); + std::string output = server_msg.substr(0, last_newline); + if(!output.empty()) { + /* Split multiline output and push each line to history. */ + std::stringstream ss(output); + std::string line; + while(std::getline(ss, line, '\n')) { + terminal->add_history(line); + } + } + } else { + terminal->add_history(server_msg); } } - } else { - terminal->add_history(server_msg); - } - } - if(_desktop) { - _desktop->update(); + if(_desktop) { + _desktop->update(); + } + break; } } void GameState::render(ShapeRenderer* shape_renderer, TextRenderer* txt_renderer, int screen_height, bool show_cursor) { - if(_desktop) { - _desktop->render(shape_renderer, txt_renderer, screen_height, show_cursor); + switch(_current_screen) { + case Screen::MAIN_MENU: + /* TODO: */ + break; + case Screen::BOOTING: + /* TODO: */ + break; + case Screen::DESKTOP: + if(_desktop) { + _desktop->render(shape_renderer, txt_renderer, screen_height, show_cursor); + } + break; } } diff --git a/client/src/game_state.h b/client/src/game_state.h index b6b1d46..40d6aa4 100644 --- a/client/src/game_state.h +++ b/client/src/game_state.h @@ -8,6 +8,12 @@ class ShapeRenderer; class TextRenderer; union SDL_Event; +enum class Screen { + MAIN_MENU, + BOOTING, + DESKTOP +}; + class GameState { public: GameState(void); @@ -22,4 +28,7 @@ public: private: std::unique_ptr _network; std::unique_ptr _desktop; + Screen _current_screen; + + void _init_desktop(void); }; diff --git a/client/src/ui/desktop.cpp b/client/src/ui/desktop.cpp index 4ab45f7..eac83fc 100644 --- a/client/src/ui/desktop.cpp +++ b/client/src/ui/desktop.cpp @@ -17,6 +17,11 @@ Desktop::~Desktop(void) {} void Desktop::add_window(std::unique_ptr window) { _windows.push_back(std::move(window)); + /* I'm sick of reaching for my mouse to focus the terminal.. Stop that! */ + if(_windows.size() == 1) { + _focused_window = _windows.back().get(); + _focused_window->set_focused(true); + } } void Desktop::handle_event(SDL_Event* event) {