--- a/sources/interface.cpp Fri May 15 18:36:22 2015 +0300 +++ b/sources/interface.cpp Fri May 15 20:03:35 2015 +0300 @@ -37,46 +37,16 @@ static const int g_pageSize = 10; -enum InputState -{ - INPUTSTATE_NORMAL, - INPUTSTATE_ADDRESS, - INPUTSTATE_PASSWORD, - INPUTSTATE_CONFIRM_DISCONNECTION, -}; - -static StringList InputHistory; -static int InputCursor = 0; -static int CursorPosition = 0; -static int InputPanning = 0; -static bool NeedRefresh = false; -static bool NeedStatusBarRender = false; -static bool NeedInputRender = false; -static bool NeedOutputRender = false; -static bool NeedNicklistRender = false; -static struct { char ch; int x; } CursorCharacter; -static Vector<ColoredLine> OutputLines; -static int OutputScroll = 0; -static String Title; -static InputState CurrentInputState = INPUTSTATE_NORMAL; -static Function<void (void)> DisconnectConfirmFunction = nullptr; -static IPAddress CurrentAddress; -static String StatusBarText; -static StringList PlayerNames; -static String PasteBuffer; - // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_color_pair (Color fg, Color bg) -> int +int Interface::color_pair (Color fg, Color bg) { return COLOR_PAIR ((int (fg) * NUM_COLORS) + int (bg)); } // ------------------------------------------------------------------------------------------------- // -static FUNCTION -current_input() -> const String& +const String& Interface::current_input() { return InputHistory[InputCursor]; } @@ -85,8 +55,7 @@ // // Makes current_input() the lastmost input (so that we won't modify history) // -static FUNCTION -detach_input() -> void +void Interface::detach_input() { if (InputCursor > 0) { @@ -98,8 +67,7 @@ // ------------------------------------------------------------------------------------------------- // A version of current_input() that allows changing the contents of it. // -static FUNCTION -mutable_current_input() -> String& +String& Interface::mutable_current_input() { detach_input(); return InputHistory[InputCursor]; @@ -107,8 +75,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -move_input_cursor (int delta) -> void +void Interface::move_input_cursor (int delta) { // No input history when inputting addresses or passwords if (CurrentInputState != INPUTSTATE_NORMAL) @@ -129,8 +96,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_prompt_string() -> String +String Interface::prompt_string() { String prompt; @@ -147,8 +113,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -set_input_state (InputState newstate) -> void +void Interface::set_input_state (InputState newstate) { // Clear the input row (unless going to or from confirm state) if (newstate != INPUTSTATE_CONFIRM_DISCONNECTION @@ -175,8 +140,8 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::initialize() -> void +Interface::Interface() : + Session (this) { ::initscr(); ::start_color(); @@ -207,12 +172,11 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_render_titlebar() -> void +void Interface::render_titlebar() { if (Title.length() <= COLS) { - int pair = interface_color_pair (WHITE, BLUE); + int pair = color_pair (WHITE, BLUE); int startx = (COLS - Title.length()) / 2; int endx = startx + Title.length(); attron (pair); @@ -227,19 +191,17 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::set_title (const String& title) -> void +void Interface::set_title (const String& title) { Title = title; - interface_render_titlebar(); + render_titlebar(); } // ------------------------------------------------------------------------------------------------- // -static FUNCTION -safe_disconnect (Function<void()> afterwards) -> void +void Interface::safe_disconnect (Function<void()> afterwards) { - if (RCONSession::get_session()->is_active()) + if (Session.is_active()) { DisconnectConfirmFunction = afterwards; set_input_state (INPUTSTATE_CONFIRM_DISCONNECTION); @@ -250,8 +212,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_nicklist_width() -> int +int Interface::nicklist_width() { // Allocate at least 12 characters, at most 24 characters, for the nicklist. If we cannot // afford that (o_O) then we probably shouldn't draw the nicklist at all I think. @@ -267,9 +228,7 @@ // Renders the given colored line onto the screen. Will wrap if allowWrap is true. Returns the // 'y' value for the next line. // -static FUNCTION -interface_render_colorline (int y, int x0, int width, - const ColoredLine& line, bool allowWrap) -> int +int Interface::render_colorline (int y, int x0, int width, const ColoredLine& line, bool allowWrap) { int x = x0; @@ -299,7 +258,7 @@ case RLINE_ON_MAGENTA: case RLINE_ON_CYAN: case RLINE_ON_WHITE: - attron (interface_color_pair (Color (byte - RLINE_ON_BLACK), DEFAULT)); + attron (color_pair (Color (byte - RLINE_ON_BLACK), DEFAULT)); break; case RLINE_OFF_BLACK: @@ -310,7 +269,7 @@ case RLINE_OFF_MAGENTA: case RLINE_OFF_CYAN: case RLINE_OFF_WHITE: - attroff (interface_color_pair (Color (byte - RLINE_OFF_BLACK), DEFAULT)); + attroff (color_pair (Color (byte - RLINE_OFF_BLACK), DEFAULT)); break; case RLINE_ON_BOLD: @@ -328,8 +287,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_render_output() -> void +void Interface::render_output() { if (OutputLines.size() == 1) return; @@ -337,7 +295,7 @@ OutputScroll = clamp (OutputScroll, 0, OutputLines.size() - 1); int height = LINES - 3; - int width = COLS - interface_nicklist_width(); + int width = COLS - nicklist_width(); int printOffset = 0; int end = OutputLines.size() - 1 - OutputScroll; int start = end; @@ -397,7 +355,7 @@ y += printOffset; for (int i = start; i < end; ++i) - y = interface_render_colorline (y, 0, width, OutputLines[i], true); + y = render_colorline (y, 0, width, OutputLines[i], true); NeedOutputRender = false; NeedRefresh = true; @@ -405,10 +363,9 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_render_nicklist() -> void +void Interface::render_nicklist() { - int width = interface_nicklist_width(); + int width = nicklist_width(); int height = LINES- 3; int y = 1; int x = COLS - width; @@ -442,10 +399,9 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_render_input() -> void +void Interface::render_input() { - int promptColor = interface_color_pair (WHITE, BLUE); + int promptColor = color_pair (WHITE, BLUE); // If we're asking the user if they want to disconnect, we don't render any input strings, // just the confirmation message. @@ -459,7 +415,7 @@ return; } - String prompt = interface_prompt_string(); + String prompt = prompt_string(); int displayLength = COLS - prompt.length() - 2; String displayString = current_input(); int y = LINES - 2; @@ -504,10 +460,9 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_render_statusbar() -> void +void Interface::render_statusbar() { - int color = interface_color_pair (WHITE, BLUE); + int color = color_pair (WHITE, BLUE); int y = LINES - 1; attron (color); mvhline (y, 0, ' ', COLS); @@ -519,13 +474,11 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::update_statusbar() -> void +void Interface::update_statusbar() { String text; - RCONSession* session = RCONSession::get_session(); - switch (session->state()) + switch (Session.state()) { case RCON_DISCONNECTED: text = "Disconnected."; @@ -533,15 +486,20 @@ case RCON_CONNECTING: case RCON_AUTHENTICATING: - text = "Connecting to " + session->address().to_string (IP_WITH_PORT) + "..."; + text = "Connecting to " + Session.address().to_string (IP_WITH_PORT) + "..."; break; case RCON_CONNECTED: { - String adminText = (session->num_admins() == 0) ? "No other admins" - : format ("%1 other admin%s1", session->num_admins()); - text = format ("%1 | %2 | %3", session->address().to_string (IP_WITH_PORT), - session->level(), adminText); + String adminText; + + if (Session.num_admins() == 0) + adminText = "No other admins"; + else + adminText = format ("%1 other admin%s1", Session.num_admins()); + + text = format ("%1 | %2 | %3", Session.address().to_string (IP_WITH_PORT), + Session.level(), adminText); } break; } @@ -560,21 +518,19 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::render_full() -> void +void Interface::render_full() { update_statusbar(); - interface_render_titlebar(); - interface_render_output(); - interface_render_statusbar(); - interface_render_input(); - interface_render_nicklist(); + render_titlebar(); + render_output(); + render_statusbar(); + render_input(); + render_nicklist(); } // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_position_cursor() -> void +void Interface::position_cursor() { // This is only relevant if the input string is being drawn if (CurrentInputState == INPUTSTATE_CONFIRM_DISCONNECTION) @@ -585,13 +541,12 @@ if (CursorCharacter.ch != '\0') mvprintw (y, CursorCharacter.x, "%c", CursorCharacter.ch); else - mvprintw (y, interface_prompt_string().length(), " "); + mvprintw (y, prompt_string().length(), " "); } // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_find_previous_word() -> int +int Interface::find_previous_word() { const String& input = current_input(); int pos = CursorPosition; @@ -609,8 +564,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -interface_find_next_word() -> int +int Interface::find_next_word() { const String& input = current_input(); int pos = CursorPosition; @@ -628,8 +582,7 @@ // ------------------------------------------------------------------------------------------------- // -static FUNCTION -yank (int a, int b) -> void +void Interface::yank (int a, int b) { if (a >= b) return; @@ -645,8 +598,7 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::handle_input() -> void +void Interface::handle_input() { int ch = ::getch(); @@ -661,7 +613,7 @@ { if (ch == 'y' or ch == 'Y') { - RCONSession::get_session()->disconnect(); + Session.disconnect(); DisconnectConfirmFunction(); } else if (ch == 'n' or ch == 'N') @@ -684,13 +636,11 @@ break; case INPUTSTATE_NORMAL: - safe_disconnect ([]() + safe_disconnect ([&]() { - RCONSession* session = RCONSession::get_session(); - - if (session->is_active()) + if (Session.is_active()) { - session->disconnect(); + Session.disconnect(); set_input_state (INPUTSTATE_NORMAL); } else @@ -791,7 +741,7 @@ break; case 'W' - 'A' + 1: // readline ^W - delete from previous word bounary to current - yank (interface_find_previous_word(), CursorPosition); + yank (find_previous_word(), CursorPosition); break; case 'Y' - 'A' + 1: // readline ^Y - paste previously deleted text @@ -808,11 +758,11 @@ int space = current_input().find (" "); if (CurrentInputState == INPUTSTATE_NORMAL - and InputCursor > 0 - and (space == -1 or space >= InputCursor)) + and CursorPosition > 0 + and (space == -1 or space >= CursorPosition)) { - String start = current_input().mid (0, InputCursor); - RCONSession::get_session()->request_tab_complete (start); + String start = current_input().mid (0, CursorPosition); + Session.request_tab_complete (start); } } break; @@ -844,16 +794,15 @@ case INPUTSTATE_PASSWORD: if (CurrentInputState == INPUTSTATE_PASSWORD and not current_input().is_empty()) { - RCONSession* session = RCONSession::get_session(); - session->disconnect(); - session->set_password (current_input()); - session->connect (CurrentAddress); + Session.disconnect(); + Session.set_password (current_input()); + Session.connect (CurrentAddress); set_input_state (INPUTSTATE_NORMAL); } break; case INPUTSTATE_NORMAL: - if (RCONSession::get_session()->send_command (current_input())) + if (Session.send_command (current_input())) { InputHistory.insert (0, ""); NeedInputRender = true; @@ -864,7 +813,7 @@ case 'N' - 'A' + 1: // ^N if (CurrentInputState == INPUTSTATE_NORMAL) - safe_disconnect ([]() {set_input_state (INPUTSTATE_ADDRESS);}); + safe_disconnect ([&]() {set_input_state (INPUTSTATE_ADDRESS);}); break; case '\e': // Escape @@ -878,21 +827,21 @@ case 'b': case 'B': // readline alt-b - move one word to the left - CursorPosition = interface_find_previous_word(); + CursorPosition = find_previous_word(); NeedInputRender = true; break; case 'f': case 'F': // readline alt-f - move one word to the right - CursorPosition = interface_find_next_word(); + CursorPosition = find_next_word(); NeedInputRender = true; break; case 'd': case 'D': // readline alt-d - delete from here till next word boundary - yank (CursorPosition, interface_find_next_word()); + yank (CursorPosition, find_next_word()); break; } } @@ -912,17 +861,16 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::render() -> void +void Interface::render() { - if (NeedStatusBarRender) interface_render_statusbar(); - if (NeedInputRender) interface_render_input(); - if (NeedOutputRender) interface_render_output(); - if (NeedNicklistRender) interface_render_nicklist(); + if (NeedStatusBarRender) render_statusbar(); + if (NeedInputRender) render_input(); + if (NeedOutputRender) render_output(); + if (NeedNicklistRender) render_nicklist(); if (NeedRefresh) { - interface_position_cursor(); + position_cursor(); refresh(); NeedRefresh = false; } @@ -930,10 +878,10 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION print_to_console (String a) -> void +void Interface::print_to_console (String a) { - // Zandronum is retarded and SOMETIMES sends color codes as "\\c" and sometimes as "\x1C". - // Let's correct that on our end and HOPE this won't cause conflicts. + // Zandronum sometimes sends color codes as "\\c" and sometimes as "\x1C". + // Let's correct that on our end and hope this won't cause conflicts. a.replace ("\\c", "\x1C"); for (char ch : a) @@ -964,8 +912,7 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::connect (String address, String password) -> void +void Interface::connect (String address, String password) { try { @@ -980,16 +927,14 @@ if (CurrentAddress.port == 0) CurrentAddress.port = 10666; - RCONSession* session = RCONSession::get_session(); - session->disconnect(); - session->set_password (password); - session->connect (CurrentAddress); + Session.disconnect(); + Session.set_password (password); + Session.connect (CurrentAddress); } // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::set_player_names (const StringList& names) -> void +void Interface::set_player_names (const StringList& names) { PlayerNames = names; NeedNicklistRender = true; @@ -997,8 +942,7 @@ // ------------------------------------------------------------------------------------------------- // -FUNCTION -Interface::tab_complete (const String& part, String complete) -> void +void Interface::tab_complete (const String& part, String complete) { String& input = mutable_current_input(); @@ -1008,7 +952,7 @@ complete += ' '; input.replace (0, part.length(), complete); - InputCursor = complete.length(); + CursorPosition = complete.length(); NeedInputRender = true; } }