Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/consoleinterface.cc288
-rw-r--r--src/sys/consoleinterface.h150
-rw-r--r--src/sys/sys.cc32
-rw-r--r--src/sys/sys.h10
4 files changed, 280 insertions, 200 deletions
diff --git a/src/sys/consoleinterface.cc b/src/sys/consoleinterface.cc
index 073f34b..284a48d 100644
--- a/src/sys/consoleinterface.cc
+++ b/src/sys/consoleinterface.cc
@@ -6,187 +6,213 @@
#include "sys/consoleinterface.h"
-#include <iostream>
-
-#include <stdlib.h>
-
namespace sys
{
-ConsoleInterface *ConsoleInterface::consoleinterface_instance = 0;
-
-ConsoleInterface::ConsoleInterface()
-{
- consoleinterface_ansi = true;
- if (consoleinterface_instance) {
- std::cerr << "multiple sys::ConsoleInterface instances!" << std::endl;
- sys::quit(2);
- }
-
- consoleinterface_rcon = false;
-
- consoleinterface_instance = this;
- consoleinterface_text.clear();
- consoleinterface_buffer.clear();
-}
-
-ConsoleInterface::~ConsoleInterface()
-{
- consoleinterface_instance = 0;
-}
-
-ConsoleInterface *ConsoleInterface::instance()
-{
- return consoleinterface_instance;
-}
-
-std::ostream & ConsoleInterface::messagestream()
-{
- flush();
- return (consoleinterface_buffer << "^N");
-}
+const size_t DEFAULT_LOGSIZE = 2048;
-std::ostream & ConsoleInterface::warningstream()
-{
- flush();
- return (consoleinterface_buffer << "^W");
-}
+/* -- ANSI color code support -------------------------------------- */
-std::ostream & ConsoleInterface::errorstream()
-{
- flush();
- return (consoleinterface_buffer << "^R");
-}
+bool con_ansicolor = false;
-std::ostream & ConsoleInterface::debugstream()
+bool ansi()
{
- flush();
- return (consoleinterface_buffer << "^D");
+ return con_ansicolor;
}
-void ConsoleInterface::flush()
+void set_ansi(const bool ansi)
{
- if (rcon())
- return;
-
- char line[MAXCMDSIZE];
-
- while(consoleinterface_buffer.getline(line, MAXCMDSIZE-1)) {
- while (consoleinterface_text.size() >= MAXCONLINES) {
- consoleinterface_text.pop_front();
- }
- consoleinterface_text.push_back(std::string(line));
-
- // print to stdout
- print_ansi(line);
- std::cout << std::endl;
+ con_ansicolor = ansi;
+ if (con_ansicolor) {
+ // ANSI default color
+ std::cout << "\033[0;39m";
}
-
- consoleinterface_buffer.clear();
-}
-
-void ConsoleInterface::resize()
-{
}
-void ConsoleInterface::print_ansi(const char *line)
+void fallback_print(const std::string &text)
{
- if (consoleinterface_ansi)
- std::cout << "\033[0;39m";
-
- const char *c = line;
+ bool is_color_code = false;
+ int ansi_bold = 0;
+ int ansi_color = 39;
+
+ const char *c = text.c_str();
while (*c) {
+
+ if ((*c) == '\n') {
+ std::cout << std::endl;
+
+ } else if ((*c) == '^') {
- if ((*c == '^')) {
- bool is_code = true;
- int bold = 0;
- int color = 39;
-
+ is_color_code = true;
+ ansi_bold = 0;
+ ansi_color = 39;
+
switch (*(c+1)) {
case '0': // black
- color = 0;
- bold = 1;
- break;
- case '1': // red
- color = 31;
- break;
- case '2': // green
- color = 32;
- break;
- case '3': // yellow
- bold = 1;
- color = 33;
- break;
- case '4': // blue
- color = 34;
- break;
- case '5': // cyan
- color = 36;
- break;
- case '6': // magenta
- color = 35;
- break;
- case '7': // white is mapped to foreground color
- bold = 1;
- color = 39;
+ ansi_color = 0;
+ ansi_bold = 1;
break;
-
+ case '1': // red
+ ansi_color = 31;
+ break;
+ case '2': // green
+ ansi_color = 32;
+ break;
+ case '3': // yellow
+ ansi_color = 1;
+ ansi_color = 33;
+ break;
+ case '4': // blue
+ ansi_color = 34;
+ break;
+ case '5': // cyan
+ ansi_color = 36;
+ break;
+ case '6': // magenta
+ ansi_color = 35;
+ break;
+ case '7': // white is mapped to foreground color
+ ansi_bold = 1;
+ ansi_color = 39;
+ break;
+
case 'N': // normal
- bold = 0;
- color = 39;
+ ansi_bold = 0;
+ ansi_color = 39;
break;
case 'B': // bold
- bold = 1;
- color = 39;
+ ansi_bold = 1;
+ ansi_color = 39;
break;
case 'D': // debug
- bold = 0;
- color = 39;
+ ansi_bold = 0;
+ ansi_color = 39;
break;
case 'R': // error
- bold = 0;
- color = 31;
+ ansi_bold = 0;
+ ansi_color = 31;
break;
case 'W': // warning
- bold = 1;
- color = 33;
+ ansi_bold = 1;
+ ansi_color = 33;
break;
case 'F': // fancy
- bold = 0;
- color = 32;
+ ansi_bold = 0;
+ ansi_color = 32;
break;
default:
- is_code = false;
+ is_color_code = false;
}
- if (is_code) {
+
+ if (is_color_code) {
+ if (con_ansicolor)
+ std::cout << "\033[" << ansi_bold << ";" << ansi_color << "m";
c++;
- if (consoleinterface_ansi)
- std::cout << "\033[" << bold << ";" << color << "m";
- } else
+ } else {
std::cout << *c;
+ }
+
} else {
std::cout << *c;
}
+
c++;
}
+}
- if (consoleinterface_ansi)
- std::cout << "\033[0;39m";
+/* -- ConsoleBuffer ------------------------------------------------ */
+
+int ConsoleBuffer::overflow(int c)
+{
+ if (c == Traits::eof())
+ return Traits::not_eof(c);
+
+ if (c == '\n') {
+ if (ConsoleInterface::instance()) {
+ ConsoleInterface::instance()->event_text(con_buffer);
+ } else {
+ fallback_print(con_buffer);
+ std::cout << std::endl;
+ }
+ con_buffer.clear();
+ } else {
+ con_buffer += c;
+ }
+ return c;
}
-void ConsoleInterface::set_ansi(bool enable)
+/* -- ConsoleStream ------------------------------------------------ */
+
+ConsoleStream con_out;
+
+ConsoleStream::ConsoleStream() : std::basic_ostream<char, Traits>(&con_buffer)
{
- consoleinterface_ansi = enable;
+ clear();
}
-void ConsoleInterface::set_rcon(bool enable)
+ConsoleStream::~ConsoleStream()
{
- if (enable) {
- flush();
+ if (con_ansicolor) {
+ // ANSI default color
+ std::cout << "\033[0;39m" << std::endl;
}
+}
+
+/* -- Console ------------------------------------------------------ */
+
+ConsoleInterface *ConsoleInterface::consoleinterface_instance = 0;
+
+ConsoleInterface::ConsoleInterface()
+{
+ if (consoleinterface_instance) {
+ std::cerr << "multiple sys::ConsoleInterface instances!" << std::endl;
+ sys::quit(2);
+ }
+
+ consoleinterface_rcon = false;
+ consoleinterface_instance = this;
+ consoleinterface_logsize = DEFAULT_LOGSIZE;
+}
+
+ConsoleInterface::~ConsoleInterface()
+{
+ consoleinterface_instance = 0;
+}
+
+ConsoleInterface *ConsoleInterface::instance()
+{
+ return consoleinterface_instance;
+}
+
+void ConsoleInterface::set_rcon(bool enable)
+{
consoleinterface_rcon = enable;
}
-} // namespace sys
+void ConsoleInterface::set_logsize(const size_t logsize)
+{
+ consoleinterface_logsize = logsize < 16 ? 16 : logsize;
+}
+void ConsoleInterface::event_text(const std::string & text)
+{
+ if (rcon()) {
+ consoleinterface_rconbuf.push_back(text);
+ } else {
+ while (consoleinterface_log.size() >= consoleinterface_logsize) {
+ consoleinterface_log.pop_front();
+ }
+
+ consoleinterface_log.push_back(std::string(text));
+ print(text);
+ }
+}
+
+void ConsoleInterface::print(const std::string & text)
+{
+ fallback_print(text);
+ std::cout << std::endl;
+}
+
+} // namespace sys
diff --git a/src/sys/consoleinterface.h b/src/sys/consoleinterface.h
index 5411cb6..3a7d3ed 100644
--- a/src/sys/consoleinterface.h
+++ b/src/sys/consoleinterface.h
@@ -8,89 +8,141 @@
#define __INCLUDED_SYS_CONSOLEINTERFACE_H__
#include <iostream>
+#include <string>
+#include <streambuf>
+#include <ostream>
#include <sstream>
#include <deque>
#include "sys/sys.h"
-/// global define to send a message to the system console
-#define con_print sys::ConsoleInterface::instance()->messagestream()
-/// global define to send a warning message to the system console
-#define con_warn sys::ConsoleInterface::instance()->warningstream()
-/// global define to send an error message to the system console
-#define con_error sys::ConsoleInterface::instance()->errorstream()
-
-#ifdef HAVE_DEBUG_MESSAGES
-/// global define to send a debug message to the system console
-#define con_debug sys::ConsoleInterface::instance()->debugstream()
-#else
-#define con_debug if (0) *(std::ostream*)(0)
-#endif
namespace sys
{
-const size_t MAXCONLINES = 2048;
+/// true if ANSI colors are enabled
+bool ansi();
-/// interface for the client and server Console classes
-class ConsoleInterface
-{
-public:
- /// default constructor
- ConsoleInterface();
+/// enable or disable ANSI colors
+void set_ansi(bool enable = true);
- /// default destructor
- virtual ~ConsoleInterface();
-
- /// stream to send normal messages to
- std::ostream & messagestream();
+/* -- ConsoleBuffer ------------------------------------------------ */
- /// stream to send warning messages to
- std::ostream & warningstream();
+typedef std::char_traits<char> Traits;
- /// stream to send error messages to
- std::ostream & errorstream();
+/// buffer back-end for console output
+class ConsoleBuffer : public std::basic_streambuf<char, Traits >
+{
+public:
+ const std::string & str() const
+ {
+ return con_buffer;
+ }
+
+protected:
+ /// stream overflow
+ virtual int overflow(int c = Traits::eof());
+
+private:
+ std::string con_buffer;
+};
- /// stream to send debug messages to
- std::ostream & debugstream();
- /// flush buffered messages
- virtual void flush();
+/* -- ConsoleStream ------------------------------------------------ */
- /// resize the console (ncurses stub)
- virtual void resize();
+/// provides global streams for console output
+class ConsoleStream : public std::basic_ostream<char, Traits >
+{
+public:
+ ConsoleStream();
+ ~ConsoleStream();
+
+ inline ConsoleBuffer & buf()
+ {
+ return con_buffer;
+ }
+
+private:
+ ConsoleBuffer con_buffer;
+};
- /// return the console inputbuffer
- inline std::stringstream & buffer() { return consoleinterface_buffer; }
+/// global console output stream
+extern ConsoleStream con_out;
- inline bool rcon() { return consoleinterface_rcon; }
- inline bool ansi() { return consoleinterface_ansi; }
+/* -- Console ------------------------------------------------------ */
- /// enable or disable ANSI escape sequences
- void set_ansi(bool enable = true);
+/// interface for the client and server Console classes
+class ConsoleInterface
+{
+public:
+ /// default constructor
+ ConsoleInterface();
+
+ /// default destructor
+ virtual ~ConsoleInterface();
+
+ /// set maximal number of lines in the log
+ void set_logsize(const size_t logsize);
+
+ /// return rcon state
+ inline bool rcon()
+ {
+ return consoleinterface_rcon;
+ }
+
/// enable or disable rcon
void set_rcon(bool enable = true);
-
+
+ typedef std::deque<std::string> Text;
+
+ inline Text & rconbuf()
+ {
+ return consoleinterface_rconbuf;
+ }
+
+ inline Text & log()
+ {
+ return consoleinterface_log;
+ }
+
/// a pointer to the current console instance
static ConsoleInterface *instance();
-
+
+ /// incoming text event handler
+ void event_text(const std::string & text);
+
+ /// ncurses resize event
+ virtual void resize()
+ {};
+
protected:
- std::deque<std::string> consoleinterface_text;
- std::stringstream consoleinterface_buffer;
+ /// print one line of text
+ virtual void print(const std::string & text);
- /// print a string to stdout with ansi color codes
- void print_ansi(const char *line);
-
private:
/// console singleton
static ConsoleInterface *consoleinterface_instance;
- bool consoleinterface_ansi;
+
bool consoleinterface_rcon;
+ Text consoleinterface_rconbuf;
+
+ Text consoleinterface_log;
+ size_t consoleinterface_logsize;
};
} // namespace sys
+#define con_print sys::con_out << "^N"
+#define con_warn sys::con_out << "^W"
+#define con_error sys::con_out << "^R"
+#ifdef HAVE_DEBUG_MESSAGES
+#define con_debug sys::con_out << "^D"
+#else
+#define con_debug if (0) *(std::ostream*)(0)
+#endif
+
+
#endif // __INCLUDED_SYS_CONSOLEINTERFACE_H__
diff --git a/src/sys/sys.cc b/src/sys/sys.cc
index db2be4d..59ed11d 100644
--- a/src/sys/sys.cc
+++ b/src/sys/sys.cc
@@ -29,18 +29,19 @@
#include "sys/sys.h"
-namespace sys {
+namespace sys
+{
-bool isdirectory(std::string const &path)
+bool isdirectory(const std::string &path)
{
#ifdef _WIN32
struct ::_stat path_stat;
memset(&path_stat, 0, sizeof(struct ::_stat));
-
+
if (::_stat(path.c_str(), &path_stat) != 0) {
return false;
}
-
+
if (path_stat.st_mode & _S_IFDIR) {
return true;
}
@@ -48,11 +49,11 @@ bool isdirectory(std::string const &path)
#else
struct stat path_stat;
memset(&path_stat, 0, sizeof(path_stat));
-
+
if (stat(path.c_str(), &path_stat) != 0) {
return false;
}
-
+
if (path_stat.st_mode & S_IFDIR) {
return true;
}
@@ -61,7 +62,7 @@ bool isdirectory(std::string const &path)
#endif
}
-void mkdir(std::string const &path)
+void mkdir(const std::string &path)
{
#ifdef _WIN32
std::string p(path);
@@ -69,7 +70,7 @@ void mkdir(std::string const &path)
if (p[i] == '/') p[i] = '\\';
if (p.size() && (p[p.size()-1] == '\\'))
p.erase(p.size() -1, 1);
-
+
if (_mkdir(p.c_str()) != 0) {
con_warn << "Could not create directory '" << p << "'" << std::endl;
}
@@ -83,23 +84,23 @@ void signal(int signum, signalfunc handler)
{
#ifndef _WIN32
struct sigaction sa;
-
+
sa.sa_sigaction = 0;
memset(&sa.sa_mask, 0 ,sizeof(sigset_t));
sa.sa_flags = 0;
sa.sa_handler = handler;
-
+
::sigaction(signum, &sa, 0);
#endif
}
-unsigned long time()
+unsigned long time()
{
#ifndef _WIN32
struct ::tm localtime;
time_t epochtime = ::time(0);
::localtime_r(&epochtime, &localtime);
- return ((unsigned long) (localtime.tm_sec + localtime.tm_min*60 + localtime.tm_hour*3600));
+ return ((unsigned long)(localtime.tm_sec + localtime.tm_min*60 + localtime.tm_hour*3600));
#else
return 0;
#endif
@@ -108,13 +109,14 @@ unsigned long time()
void sleep(float seconds)
{
#ifndef _WIN32
- ::usleep((useconds_t) (seconds * 1000000.0f) );
+ ::usleep((useconds_t)(seconds * 1000000.0f));
#else
- Sleep((DWORD) (seconds*1000.0f));
+ Sleep((DWORD)(seconds*1000.0f));
#endif
}
-void quit(int status) {
+void quit(int status)
+{
::exit(status);
}
diff --git a/src/sys/sys.h b/src/sys/sys.h
index 66040f0..81eba94 100644
--- a/src/sys/sys.h
+++ b/src/sys/sys.h
@@ -19,18 +19,18 @@
*/
namespace sys
{
-typedef void (* signalfunc)(int signum);
+typedef void(* signalfunc)(int signum);
-/// check if a path exists and if it is a directory
-bool isdirectory(std::string const &path);
+/// returns true if a path exists and it is a directory
+bool isdirectory(const std::string &path);
/// create a directory
-void mkdir(std::string const &path);
+void mkdir(const std::string &path);
/// intercept OS signals
void signal(int signum, signalfunc handler);
-/**
+/**
* @brief operation system exit() application
* @param status return value
*/