sources/interface.cpp

changeset 72
1b9c53e0c846
parent 71
4f7c2c944637
child 73
07dda51a7a8e
--- 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;
 	}
 }

mercurial