Massive refactor

Fri, 15 May 2015 20:03:35 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Fri, 15 May 2015 20:03:35 +0300
changeset 72
1b9c53e0c846
parent 71
4f7c2c944637
child 73
07dda51a7a8e

Massive refactor

sources/format.h file | annotate | diff | comparison | revisions
sources/interface.cpp file | annotate | diff | comparison | revisions
sources/interface.h file | annotate | diff | comparison | revisions
sources/main.cpp file | annotate | diff | comparison | revisions
sources/network/rconsession.cpp file | annotate | diff | comparison | revisions
sources/network/rconsession.h file | annotate | diff | comparison | revisions
--- a/sources/format.h	Fri May 15 18:36:22 2015 +0300
+++ b/sources/format.h	Fri May 15 20:03:35 2015 +0300
@@ -203,33 +203,3 @@
 		fclose (handle);
 	}
 }
-
-// -------------------------------------------------------------------------------------------------
-//
-// Prints the formatting result to the console
-//
-template<typename... argtypes>
-void print (const String& fmtstr, const argtypes&... args)
-{
-	print_to_console (format (fmtstr, args...));
-}
-
-// -------------------------------------------------------------------------------------------------
-//
-// Prints the formatting result as a warning to the console
-//
-template<typename... argtypes>
-void print_warning (const String& fmtstr, const argtypes&... args)
-{
-	print_to_console (TEXTCOLOR_BrightYellow "-!- " + format (fmtstr, args...) + TEXTCOLOR_Reset);
-}
-
-// -------------------------------------------------------------------------------------------------
-//
-// Prints the formatting result as a warning to the console
-//
-template<typename... argtypes>
-void print_error (const String& fmtstr, const argtypes&... args)
-{
-	print_to_console (TEXTCOLOR_BrightRed "!!! " + format (fmtstr, args...) + TEXTCOLOR_Reset);
-}
\ No newline at end of file
--- 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;
 	}
 }
--- a/sources/interface.h	Fri May 15 18:36:22 2015 +0300
+++ b/sources/interface.h	Fri May 15 20:03:35 2015 +0300
@@ -30,17 +30,91 @@
 
 #pragma once
 #include "main.h"
+#include "network/ipaddress.h"
+#include "coloredline.h"
+#include "network/rconsession.h"
 
-namespace Interface
+class Interface
 {
-	FUNCTION initialize() -> void;
-	FUNCTION handle_input() -> void;
-	FUNCTION render() -> void;
-	FUNCTION render_full() -> void;
-	FUNCTION set_title (const String& message) -> void;
-	FUNCTION update_statusbar() -> void;
-	FUNCTION connect (String address, String password) -> void;
-	FUNCTION set_player_names (const StringList& names) -> void;
-	FUNCTION need_refresh() -> void;
-	FUNCTION tab_complete (const String& part, String complete) -> void;
+public:
+	enum InputState
+	{
+		INPUTSTATE_NORMAL,
+		INPUTSTATE_ADDRESS,
+		INPUTSTATE_PASSWORD,
+		INPUTSTATE_CONFIRM_DISCONNECTION,
+	};
+
+	Interface();
+	void handle_input();
+	void render();
+	void render_full();
+	void set_title (const String& message);
+	void update_statusbar();
+	void connect (String address, String password);
+	void set_player_names (const StringList& names);
+	void need_refresh();
+	void tab_complete (const String& part, String complete);
+	RCONSession* get_session() { return &Session; }
+
+	template<typename... argtypes>
+	void print (const String& fmtstr, const argtypes&... args)
+	{
+		print_to_console (format (fmtstr, args...));
+	}
+
+	template<typename... argtypes>
+	void print_warning (const String& fmtstr, const argtypes&... args)
+	{
+		print_to_console (TEXTCOLOR_BrightYellow "-!- " + format (fmtstr, args...) + TEXTCOLOR_Reset);
+	}
+
+	template<typename... argtypes>
+	void print_error (const String& fmtstr, const argtypes&... args)
+	{
+		print_to_console (TEXTCOLOR_BrightRed "!!! " + format (fmtstr, args...) + TEXTCOLOR_Reset);
+	}
+
+private:
+	StringList InputHistory;
+	int InputCursor = 0;
+	int CursorPosition = 0;
+	int InputPanning = 0;
+	bool NeedRefresh = false;
+	bool NeedStatusBarRender = false;
+	bool NeedInputRender = false;
+	bool NeedOutputRender = false;
+	bool NeedNicklistRender = false;
+	struct { char ch; int x; } CursorCharacter;
+	Vector<ColoredLine> OutputLines;
+	int OutputScroll = 0;
+	String Title;
+	InputState CurrentInputState = INPUTSTATE_NORMAL;
+	Function<void (void)> DisconnectConfirmFunction = nullptr;
+	IPAddress CurrentAddress;
+	String StatusBarText;
+	StringList PlayerNames;
+	String PasteBuffer;
+	RCONSession Session;
+
+	void render_titlebar();
+	void safe_disconnect (Function<void()> afterwards);
+	int render_colorline (int y, int x0, int width, const ColoredLine& line, bool allowWrap);
+	int nicklist_width();
+	void render_output();
+	void render_nicklist();
+	void render_input();
+	void render_statusbar();
+	void position_cursor();
+	int color_pair (Color fg, Color bg);
+	const String& current_input();
+	void detach_input();
+	String& mutable_current_input();
+	void move_input_cursor (int delta);
+	String prompt_string();
+	void set_input_state (InputState newstate);
+	void print_to_console (String a);
+	void yank (int a, int b);
+	int find_previous_word();
+	int find_next_word();
 };
--- a/sources/main.cpp	Fri May 15 18:36:22 2015 +0300
+++ b/sources/main.cpp	Fri May 15 20:03:35 2015 +0300
@@ -48,10 +48,10 @@
 		return EXIT_FAILURE;
 	}
 
-	Interface::initialize();
+	Interface iface;
 
 	if (argc == 3)
-		Interface::connect (argv[1], argv[2]);
+		iface.connect (argv[1], argv[2]);
 
 	try
 	{
@@ -65,24 +65,24 @@
 			FD_ZERO (&fdset);
 			FD_SET (0, &fdset);
 
-			{
-				int fd = RCONSession::get_session()->socket()->file_descriptor();
-				highest = max (highest, fd);
-				FD_SET (fd, &fdset);
-			}
+			int fd = iface.get_session()->socket()->file_descriptor();
+			highest = max (highest, fd);
+			FD_SET (fd, &fdset);
 
 			select (highest + 1, &fdset, nullptr, nullptr, &timeout);
 
 			if (FD_ISSET (0, &fdset))
+			{
 				// stdin is ready, what's incoming?
-				Interface::handle_input();
+				iface.handle_input();
+			}
 
-			RCONSession::get_session()->tick();
-			Interface::render();
+			iface.get_session()->tick();
+			iface.render();
 		}
 	}
 	catch (const Exitception&) {}
 
-	RCONSession::get_session()->disconnect();
+	iface.get_session()->disconnect();
 	return EXIT_SUCCESS;
 }
--- a/sources/network/rconsession.cpp	Fri May 15 18:36:22 2015 +0300
+++ b/sources/network/rconsession.cpp	Fri May 15 20:03:35 2015 +0300
@@ -3,10 +3,11 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-RCONSession::RCONSession() :
+RCONSession::RCONSession (Interface* iface) :
 	m_state (RCON_DISCONNECTED),
 	m_lastPing (0),
-	m_numAdmins (0)
+	m_numAdmins (0),
+	m_interface (iface)
 {
 	if (not m_socket.set_blocking (false))
 	{
@@ -22,19 +23,17 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::connect (IPAddress address) -> void
+void RCONSession::connect (IPAddress address)
 {
 	m_address = address;
 	m_state = RCON_CONNECTING;
-	Interface::update_statusbar();
+	m_interface->update_statusbar();
 	send_hello();
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::disconnect() -> void
+void RCONSession::disconnect()
 {
 	if (m_state > RCON_CONNECTING)
 	{
@@ -42,8 +41,8 @@
 		Bytestream packet;
 		packet.write_byte (CLRC_DISCONNECT);
 		this->send (packet);
-		print ("Disconnected from %1\n", m_address.to_string (IP_WITH_PORT));
-		Interface::update_statusbar();
+		m_interface->print ("Disconnected from %1\n", m_address.to_string (IP_WITH_PORT));
+		m_interface->update_statusbar();
 	}
 
 	m_state = RCON_DISCONNECTED;
@@ -51,16 +50,14 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::send (const Bytestream& packet) -> void
+void RCONSession::send (const Bytestream& packet)
 {
 	m_socket.send (m_address, packet);
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::tick() -> void
+void RCONSession::tick()
 {
 	if (m_state == RCON_DISCONNECTED)
 		return;
@@ -93,8 +90,7 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::handle_packet (Bytestream& packet, const IPAddress& from) -> void
+void RCONSession::handle_packet (Bytestream& packet, const IPAddress& from)
 {
 	if (from != m_address)
 		return;
@@ -108,12 +104,12 @@
 			switch (ServerResponse (header))
 			{
 			case SVRC_OLDPROTOCOL:
-				print_error ("Your RCON client is using outdated protocol.\n");
+				m_interface->print_error ("Your RCON client is using outdated protocol.\n");
 				m_state = RCON_DISCONNECTED;
 				break;
 
 			case SVRC_BANNED:
-				print_error ("You have been banned from the server.\n");
+				m_interface->print_error ("You have been banned from the server.\n");
 				m_state = RCON_DISCONNECTED;
 				break;
 
@@ -124,7 +120,7 @@
 				break;
 
 			case SVRC_INVALIDPASSWORD:
-				print_error ("Login failed.\n");
+				m_interface->print_error ("Login failed.\n");
 				m_state = RCON_DISCONNECTED;
 				break;
 
@@ -132,30 +128,30 @@
 				{
 					String message = packet.read_string();
 					message.normalize();
-					print ("%1\n", message);
+					m_interface->print ("%1\n", message);
 				}
 				break;
 
 			case SVRC_LOGGEDIN:
-				print ("Login successful!\n");
+				m_interface->print ("Login successful!\n");
 				m_serverProtocol = packet.read_byte();
 				m_hostname = packet.read_string();
-				Interface::set_title (m_hostname);
+				m_interface->set_title (m_hostname);
 				m_state = RCON_CONNECTED;
 
 				for (int i = packet.read_byte(); i > 0; --i)
 					process_server_updates (packet);
 
-				print ("Previous messages:\n");
+				m_interface->print ("Previous messages:\n");
 
 				for (int i = packet.read_byte(); i > 0; --i)
 				{
 					String message = packet.read_string();
 					message.normalize();
-					print ("--- %1\n", message);
+					m_interface->print ("--- %1\n", message);
 				}
 
-				print ("End of previous messages.\n");
+				m_interface->print ("End of previous messages.\n");
 				break;
 
 			case SVRC_UPDATE:
@@ -165,7 +161,7 @@
 			case SVRC_TOOMANYTABCOMPLETES:
 				{
 					unsigned int numCompletions = packet.read_short();
-					print ("%1 completions for '%2'.\n",
+					m_interface->print ("%1 completions for '%2'.\n",
 						int (numCompletions), m_lastTabComplete);
 				}
 				break;
@@ -178,16 +174,18 @@
 						completes << packet.read_string();
 
 					if (completes.size() == 1)
-						Interface::tab_complete (m_lastTabComplete, completes[0]);
+					{
+						m_interface->tab_complete (m_lastTabComplete, completes[0]);
+					}
 					else if (not completes.is_empty())
 					{
-						print ("Completions for '%1':\n", m_lastTabComplete);
+						m_interface->print ("Completions for '%1':\n", m_lastTabComplete);
 
 						for (int i = 0; i < completes.size(); i += 8)
 						{
 							Range<int> spliceRange (i, min (i + 8, completes.size() - 1));
 							StringList splice (completes.splice (spliceRange));
-							print ("- %1\n", splice.join (", "));
+							m_interface->print ("- %1\n", splice.join (", "));
 						}
 					}
 				}
@@ -197,12 +195,11 @@
 	}
 	catch (std::exception& e)
 	{
-		print_warning ("Couldn't process packet: %1\n", e.what());
+		m_interface->print_warning ("Couldn't process packet: %1\n", e.what());
 	}
 }
 
-METHOD
-RCONSession::process_server_updates (Bytestream& packet) -> void
+void RCONSession::process_server_updates (Bytestream& packet)
 {
 	int header = packet.read_byte();
 
@@ -215,40 +212,38 @@
 			for (int i = packet.read_byte(); i > 0; --i)
 				players.append (packet.read_string());
 
-			Interface::set_player_names (players);
+			m_interface->set_player_names (players);
 		}
 		break;
 
 	case SVRCU_ADMINCOUNT:
 		m_numAdmins = packet.read_byte();
-		Interface::update_statusbar();
+		m_interface->update_statusbar();
 		break;
 
 	case SVRCU_MAP:
 		m_level = packet.read_string();
-		Interface::update_statusbar();
+		m_interface->update_statusbar();
 		break;
 
 	default:
-		print_warning ("Unknown server update type: %d\n", header);
+		m_interface->print_warning ("Unknown server update type: %d\n", header);
 		break;
 	}
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::socket() -> UDPSocket*
+UDPSocket* RCONSession::socket()
 {
 	return &m_socket;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::send_hello() -> void
+void RCONSession::send_hello()
 {
-	print ("Connecting to %1...\n", m_address.to_string (IP_WITH_PORT));
+	m_interface->print ("Connecting to %1...\n", m_address.to_string (IP_WITH_PORT));
 	Bytestream packet;
 	packet.write_byte (CLRC_BEGINCONNECTION);
 	packet.write_byte (RCON_PROTOCOL_VERSION);
@@ -258,10 +253,9 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::send_password() -> void
+void RCONSession::send_password()
 {
-	print ("Authenticating...\n");
+	m_interface->print ("Authenticating...\n");
 	Bytestream packet;
 	packet.write_byte (CLRC_PASSWORD);
 	packet.write_string ((m_salt + m_password).md5());
@@ -271,16 +265,14 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::set_password (const String& password) -> void
+void RCONSession::set_password (const String& password)
 {
 	m_password = password;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::bump_last_ping() -> void
+void RCONSession::bump_last_ping()
 {
 	time_t now;
 	time (&now);
@@ -289,17 +281,7 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-STATIC METHOD
-RCONSession::get_session() -> RCONSession*
-{
-	static RCONSession session;
-	return &session;
-}
-
-// -------------------------------------------------------------------------------------------------
-//
-METHOD
-RCONSession::is_active() const -> bool
+bool RCONSession::is_active() const
 {
 	return state() != RCON_DISCONNECTED;
 }
@@ -307,8 +289,7 @@
 // -------------------------------------------------------------------------------------------------
 // Returns true if the message was successfully sent.
 //
-METHOD
-RCONSession::send_command (const String& message) -> bool
+bool RCONSession::send_command (const String& message)
 {
 	if (m_state != RCON_CONNECTED or message.is_empty())
 		return false;
@@ -323,40 +304,35 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::state() const -> RCONSessionState
+RCONSessionState RCONSession::state() const
 {
 	return m_state;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::address() const -> const IPAddress&
+const IPAddress& RCONSession::address() const
 {
 	return m_address;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::num_admins() const -> int
+int RCONSession::num_admins() const
 {
 	return m_numAdmins;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::level() const -> const String&
+const String& RCONSession::level() const
 {
 	return m_level;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-METHOD
-RCONSession::request_tab_complete (const String& part) -> void
+void RCONSession::request_tab_complete (const String& part)
 {
 	if (m_serverProtocol >= 4)
 	{
@@ -368,5 +344,5 @@
 		m_lastTabComplete = part;
 	}
 	else
-		print ("Server protocol is %1, cannot tab-complete\n", m_serverProtocol);
-}
+		m_interface->print ("Server protocol is %1, cannot tab-complete\n", m_serverProtocol);
+}
\ No newline at end of file
--- a/sources/network/rconsession.h	Fri May 15 18:36:22 2015 +0300
+++ b/sources/network/rconsession.h	Fri May 15 20:03:35 2015 +0300
@@ -91,28 +91,27 @@
 class RCONSession
 {
 public:
+	RCONSession (class Interface* iface);
 	~RCONSession();
 
-	METHOD address() const -> const IPAddress&;
-	METHOD connect (IPAddress address) -> void;
-	METHOD disconnect() -> void;
-	METHOD handle_packet (Bytestream& packet, const IPAddress& from) -> void;
-	METHOD process_server_updates (Bytestream& packet) -> void;
-	METHOD num_admins() const -> int;
-	METHOD send (const Bytestream& packet) -> void;
-	METHOD send_hello() -> void;
-	METHOD send_password() -> void;
-	METHOD set_password (const String& password) -> void;
-	METHOD socket() -> UDPSocket*;
-	METHOD tick() -> void;
-	METHOD bump_last_ping() -> void;
-	METHOD send_command (const String& message) -> bool;
-	METHOD state() const -> RCONSessionState;
-	METHOD level() const -> const String&;
-	METHOD is_active() const -> bool;
-	METHOD request_tab_complete (const String& part) -> void;
-
-	static METHOD get_session() -> RCONSession*;
+	const IPAddress& address() const;
+	void connect (IPAddress address);
+	void disconnect();
+	void handle_packet (Bytestream& packet, const IPAddress& from);
+	void process_server_updates (Bytestream& packet);
+	int num_admins() const;
+	void send (const Bytestream& packet);
+	void send_hello();
+	void send_password();
+	void set_password (const String& password);
+	UDPSocket* socket();
+	void tick();
+	void bump_last_ping();
+	bool send_command (const String& message);
+	RCONSessionState state() const;
+	const String& level() const;
+	bool is_active() const;
+	void request_tab_complete (const String& part);
 
 private:
 	RCONSession();
@@ -128,4 +127,5 @@
 	int m_numAdmins;
 	String m_level;
 	String m_lastTabComplete;
+	class Interface* m_interface;
 };

mercurial