- begin work on interface - input line works for the most part :)

Sat, 13 Dec 2014 07:36:00 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 13 Dec 2014 07:36:00 +0200
changeset 14
33b8f428bacb
parent 13
09dcaeaa216b
child 15
33da84af4bba

- begin work on interface - input line works for the most part :)

CMakeLists.txt file | annotate | diff | comparison | revisions
sources/basics.h file | annotate | diff | comparison | revisions
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/mystring.cpp file | annotate | diff | comparison | revisions
sources/mystring.h file | annotate | diff | comparison | revisions
sources/network/rconsession.cpp file | annotate | diff | comparison | revisions
sources/network/rconsession.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sat Dec 13 04:50:33 2014 +0200
+++ b/CMakeLists.txt	Sat Dec 13 07:36:00 2014 +0200
@@ -4,6 +4,7 @@
 set (SOURCE_FILES
 	sources/filesystem.cpp
 	sources/format.cpp
+	sources/interface.cpp
 	sources/main.cpp
 	sources/md5.cpp
 	sources/mystring.cpp
--- a/sources/basics.h	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/basics.h	Sat Dec 13 07:36:00 2014 +0200
@@ -31,6 +31,7 @@
 #pragma once
 #include <algorithm>
 #include <functional>
+#include <memory>
 
 #define FUNCTION auto
 #define STATIC
@@ -38,10 +39,18 @@
 #define MACRO_TO_STRING_2(A) #A
 #define MACRO_TO_STRING(A) MACRO_TO_STRING_2(A)
 
+class String;
+
 using std::swap;
 using std::min;
 using std::max;
 
+template<typename T>
+using SharedPointer = std::shared_ptr<T>;
+
+template<typename T>
+using WeakPointer = std::weak_ptr<T>;
+
 enum Color
 {
 	BLACK,
@@ -59,3 +68,5 @@
 
 template<typename Signature>
 using Function = std::function<Signature>;
+
+FUNCTION print_to_console (const String& a) -> void;
--- a/sources/format.h	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/format.h	Sat Dec 13 07:36:00 2014 +0200
@@ -185,7 +185,7 @@
 {
 	FILE* handle;
 
-	if ((handle = fopen (filename, "w+")))
+	if ((handle = fopen (filename, "a")))
 	{
 		print_to (handle, fmtstr, args...);
 		fclose (handle);
@@ -193,10 +193,10 @@
 }
 
 // -------------------------------------------------------------------------------------------------
-// Prints the formatting result to stdout
+// Prints the formatting result to the console
 //
 template<typename... argtypes>
 void print (const String& fmtstr, const argtypes&... args)
 {
-	print_to (stdout, fmtstr, args...);
+	print_to_console (format (fmtstr, args...);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/interface.cpp	Sat Dec 13 07:36:00 2014 +0200
@@ -0,0 +1,213 @@
+/*
+	Copyright 2014 Teemu Piippo
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions
+	are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. Neither the name of the copyright holder nor the names of its
+	   contributors may be used to endorse or promote products derived from
+	   this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+	PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+	OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <string.h>
+#include "interface.h"
+
+static String g_input;
+static int g_cursor = 0;
+static int g_pan = 0;
+static bool g_needRefresh = false;
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
+interface_sessions_width() -> int
+{
+	return COLS / 3;
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
+interface_render_titlebar() -> void
+{
+	String versionText = format (APPNAME " %1 (%2)",
+		full_version_string(), changeset_date_string());
+
+	if (versionText.length() <= COLS)
+		mvprintw (0, (COLS - versionText.length()) / 2, "%s", versionText.chars());
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
+interface_render_log_area() -> void
+{
+
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
+interface_render_input() -> void
+{
+	static char prompt[] = "> ";
+	int displaylength = COLS - strlen (prompt) - 1;
+	int y = LINES - 2;
+
+	// Ensure that the cursor is always in view, adjust panning if this is not the case
+	if (g_cursor > g_pan + displaylength)
+		g_pan = g_cursor - displaylength; // cursor went too far right
+	else if (g_cursor < g_pan)
+		g_pan = g_cursor; // cursor went past the pan value to the left
+
+	int start = g_pan;
+	int end = min<int> (g_input.length(), start + displaylength);
+	assert (g_cursor >= start and g_cursor <= end);
+	String displayTextBegin = g_input.mid (start, g_cursor);
+	String displayTextEnd = g_input.mid (g_cursor, end);
+
+	// Clear, but only as much as is necessary. I want to avoid clearing the entire line to save
+	// bandwidth over SSH connections. Perhaps needlessly? I'm paranoid.
+	int renderLength = strlen (prompt) + displayTextBegin.length() + displayTextEnd.length();
+	static int lastRenderLength = 0;
+
+	if (lastRenderLength > renderLength)
+		mvhline (y, renderLength, ' ', lastRenderLength - renderLength);
+
+	lastRenderLength = renderLength;
+
+	// Render the input line, with the part of the input string that's before the cursor written
+	// AFTER the part that comes afterwards. This is to ensure that the cursor is placed at the
+	// position where our cursor is. It looks nice like that. :)
+	mvprintw (y, 0, "%s", prompt);
+	mvprintw (y, strlen (prompt) + displayTextBegin.length(), "%s", displayTextEnd.chars());
+	mvprintw (y, strlen (prompt), "%s", displayTextBegin.chars());
+	g_needRefresh = true;
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
+interface_render_statusbar() -> void
+{
+
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
+interface_render_full() -> void
+{
+	interface_render_titlebar();
+	interface_render_log_area();
+	interface_render_statusbar();
+	interface_render_input();
+	g_needRefresh = true;
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+FUNCTION
+Interface::initialize() -> void
+{
+	::initscr();
+	::start_color();
+	::raw();
+	::keypad (stdscr, true);
+	::noecho();
+	::refresh();
+	::timeout (0);
+	interface_render_full();
+	refresh();
+	g_needRefresh = false;
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+FUNCTION
+Interface::handle_input() -> void
+{
+	int ch = ::getch();
+
+	if (ch == KEY_F(1))
+	{
+		endwin();
+		exit (EXIT_SUCCESS);
+	}
+	else if (ch >= 0x20 and ch <= 0x7E)
+	{
+		g_input.insert (g_cursor++, char (ch));
+		interface_render_input();
+		refresh();
+	}
+	else if (ch == KEY_LEFT)
+	{
+		if (g_cursor > 0)
+		{
+			g_cursor--;
+			interface_render_input();
+		}
+	}
+	else if (ch == KEY_RIGHT)
+	{
+		if (g_cursor < g_input.length())
+		{
+			g_cursor++;
+			interface_render_input();
+		}
+	}
+	else if (ch == KEY_HOME)
+	{
+		if (g_cursor != 0)
+		{
+			g_cursor = 0;
+			interface_render_input();
+		}
+	}
+	else if (ch == KEY_END)
+	{
+		if (g_cursor != g_input.length())
+		{
+			g_cursor = g_input.length();
+			interface_render_input();
+		}
+	}
+	else if (ch == KEY_BACKSPACE)
+	{
+		if (not g_input.is_empty() and g_cursor > 0)
+		{
+			g_input.remove_at (--g_cursor);
+			interface_render_input();
+		}
+	}
+
+	if (g_needRefresh)
+	{
+		refresh();
+		g_needRefresh = false;
+	}
+}
+
+FUNCTION print_to_console (const String& a) -> void
+{
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/interface.h	Sat Dec 13 07:36:00 2014 +0200
@@ -0,0 +1,38 @@
+/*
+	Copyright 2014 Teemu Piippo
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions
+	are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. Neither the name of the copyright holder nor the names of its
+	   contributors may be used to endorse or promote products derived from
+	   this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+	PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+	OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+#include "main.h"
+
+namespace Interface
+{
+	void initialize();
+	void handle_input();
+};
--- a/sources/main.cpp	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/main.cpp	Sat Dec 13 07:36:00 2014 +0200
@@ -33,13 +33,7 @@
 #include "main.h"
 #include "network/rconsession.h"
 #include "huffman/huffman.h"
-
-// -------------------------------------------------------------------------------------------------
-//
-FUNCTION handle_input() -> void
-{
-	int ch = getch();
-}
+#include "interface.h"
 
 // -------------------------------------------------------------------------------------------------
 //
@@ -47,20 +41,15 @@
 main (int argc, char* argv[]) -> int
 {
 	HUFFMAN_Construct();
+	Interface::initialize();
+
 	/*
-	::initscr();
-	::start_color();
-	::raw();
-	::keypad (stdscr, true);
-	::noecho();
-	::refresh();
-	::timeout (0);
-	*/
 	Vector<RCONSession*> rconsessions;
 	RCONSession* sess = new RCONSession;
 	sess->set_password ("testpassword");
 	sess->connect (IPAddress (localhost, 10666));
 	rconsessions << sess;
+	*/
 
 	for (;;)
 	{
@@ -70,29 +59,28 @@
 		timeout.tv_sec = 0;
 		timeout.tv_usec = 250000; // 0.25 seconds
 		FD_ZERO (&fdset);
-		//FD_SET (0, &fdset);
+		FD_SET (0, &fdset);
 
+		/*
 		for (RCONSession* session : rconsessions)
 		{
 			int fd = 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?
-			handle_input();
-		}
-		*/
+			Interface::handle_input();
 
+		/*
 		for (RCONSession* session : rconsessions)
 			session->tick();
+		*/
 	}
 
-	endwin();
 	return EXIT_SUCCESS;
 }
--- a/sources/mystring.cpp	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/mystring.cpp	Sat Dec 13 07:36:00 2014 +0200
@@ -63,7 +63,7 @@
 	for (char c : unwanted)
 	{
 		for (int pos = 0; (pos = copy.find (String (c))) != -1;)
-			copy.remove (pos--);
+			copy.remove_at (pos--);
 	}
 
 	return copy;
--- a/sources/mystring.h	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/mystring.h	Sat Dec 13 07:36:00 2014 +0200
@@ -83,8 +83,8 @@
 	inline METHOD modify_index (int& a) -> void;
 	       METHOD normalize (int (*filter)(int) = &std::isspace) -> void;
 	inline METHOD prepend (String a) -> void;
-	inline METHOD remove (int pos) -> void;
 	inline METHOD remove (int pos, int len) -> void;
+	inline METHOD remove_at (int pos) -> void;
 	inline METHOD remove_from_end (int len) -> void;
 	inline METHOD remove_from_start (int len) -> void;
 	       METHOD replace (const char* a, const char* b) -> void;
@@ -228,7 +228,7 @@
 // -------------------------------------------------------------------------------------------------
 
 inline METHOD
-String::remove (int pos) -> void
+String::remove_at (int pos) -> void
 {
 	m_string.erase (m_string.begin() + pos);
 }
--- a/sources/network/rconsession.cpp	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/network/rconsession.cpp	Sat Dec 13 07:36:00 2014 +0200
@@ -1,5 +1,7 @@
 #include "rconsession.h"
 
+static Vector<RCONSessionPointer> g_allSessions;
+
 // -------------------------------------------------------------------------------------------------
 //
 RCONSession::RCONSession() :
@@ -236,3 +238,11 @@
 	time (&now);
 	m_lastPing = now;
 }
+
+// -------------------------------------------------------------------------------------------------
+//
+STATIC METHOD
+RCONSession::all_sessions() -> const Vector<RCONSessionPointer>&
+{
+	return g_allSessions;
+}
--- a/sources/network/rconsession.h	Sat Dec 13 04:50:33 2014 +0200
+++ b/sources/network/rconsession.h	Sat Dec 13 07:36:00 2014 +0200
@@ -103,6 +103,8 @@
 	METHOD tick() -> void;
 	METHOD bump_last_ping() -> void;
 
+	static METHOD all_sessions() -> const Vector<SharedPointer<RCONSession>>&;
+
 private:
 	RCONSessionState m_state;
 	IPAddress m_address;
@@ -113,3 +115,5 @@
 	int m_serverProtocol;
 	String m_hostname;
 };
+
+using RCONSessionPointer = SharedPointer<RCONSession>;

mercurial