CONSOLE: new module console
parent
2ef6d7b386
commit
88360b34a4
|
@ -196,6 +196,9 @@ find_host_program(GIT_EXECUTABLE NAMES ${GIT_BINARY} git)
|
|||
find_host_program(HG_EXECUTABLE NAMES ${HG_BINARY} hg)
|
||||
check_include_files("uuid/uuid.h" HAVE_UUID_H)
|
||||
|
||||
set(CURSES_NEED_NCURSES True)
|
||||
find_package(Curses)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# These includes are needed to let the include for IMPLICIT_DEPENDS for shaders work
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#cmakedefine HAVE_POSTGRES 1
|
||||
#cmakedefine HAVE_UUID_H 1
|
||||
#cmakedefine HAVE_SYS_TIME_H 1
|
||||
#cmakedefine CURSES_HAVE_NCURSES_H 1
|
||||
|
||||
#cmakedefine OPENCL_LIBRARY "@OPENCL_LIBRARY@"
|
||||
#cmakedefine BASE_URL "@BASE_URL@"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# files will not get copied
|
||||
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(console)
|
||||
add_subdirectory(http)
|
||||
add_subdirectory(commonlua)
|
||||
add_subdirectory(mail)
|
||||
|
|
|
@ -60,7 +60,7 @@ set(FILES
|
|||
)
|
||||
|
||||
set(LIB backend)
|
||||
engine_add_module(TARGET ${LIB} SRCS ${SRCS} FILES ${FILES} DEPENDENCIES eventmgr poi ai stock shared http)
|
||||
engine_add_module(TARGET ${LIB} SRCS ${SRCS} FILES ${FILES} DEPENDENCIES eventmgr poi ai stock shared http console)
|
||||
generate_db_models(${LIB} ${CMAKE_CURRENT_SOURCE_DIR}/tables.tbl BackendModels.h)
|
||||
|
||||
set(TEST_FILES
|
||||
|
|
|
@ -333,10 +333,6 @@ bool ServerLoop::init() {
|
|||
uv_signal_start(_signal, signalCallback, SIGHUP);
|
||||
uv_signal_start(_signal, signalCallback, SIGINT);
|
||||
|
||||
if (!_input.init(_loop)) {
|
||||
Log::warn("Could not init console input");
|
||||
}
|
||||
|
||||
// init the network last...
|
||||
if (!_network->init()) {
|
||||
Log::error("Failed to init the network");
|
||||
|
@ -361,7 +357,6 @@ void ServerLoop::shutdown() {
|
|||
_dbHandler->shutdown();
|
||||
_metricMgr->shutdown();
|
||||
_volumeCache->shutdown();
|
||||
_input.shutdown();
|
||||
_network->shutdown();
|
||||
_httpServer->shutdown();
|
||||
if (_loop != nullptr) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "core/EventBus.h"
|
||||
#include "core/Trace.h"
|
||||
#include "core/Input.h"
|
||||
#include "console/Input.h"
|
||||
#include "core/EventBus.h"
|
||||
#include "core/IComponent.h"
|
||||
#include "network/ServerNetwork.h"
|
||||
|
@ -38,7 +38,6 @@ private:
|
|||
eventmgr::EventMgrPtr _eventMgr;
|
||||
persistence::DBHandlerPtr _dbHandler;
|
||||
stock::StockDataProviderPtr _stockDataProvider;
|
||||
core::Input _input;
|
||||
MetricMgrPtr _metricMgr;
|
||||
io::FilesystemPtr _filesystem;
|
||||
persistence::PersistenceMgrPtr _persistenceMgr;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
set(SRCS
|
||||
Input.cpp Input.h
|
||||
CursesConsole.cpp CursesConsole.h
|
||||
CursesApp.cpp CursesApp.h
|
||||
)
|
||||
set(LIB console)
|
||||
|
||||
set(LIBS core util)
|
||||
|
||||
if (CURSES_FOUND)
|
||||
list(APPEND LIBS ${CURSES_LIBRARIES})
|
||||
endif()
|
||||
|
||||
engine_add_module(TARGET ${LIB} SRCS ${SRCS} DEPENDENCIES ${LIBS})
|
||||
|
||||
if (CURSES_FOUND)
|
||||
target_include_directories(${LIB} PRIVATE ${CURSES_INCLUDE_DIRS})
|
||||
endif()
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#include "CursesApp.h"
|
||||
|
||||
namespace console {
|
||||
|
||||
CursesApp::CursesApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, size_t threadPoolSize) :
|
||||
Super(metric, filesystem, eventBus, timeProvider, threadPoolSize) {
|
||||
}
|
||||
|
||||
CursesApp::~CursesApp() {
|
||||
}
|
||||
|
||||
core::AppState CursesApp::onConstruct() {
|
||||
const core::AppState state = Super::onConstruct();
|
||||
_console.construct();
|
||||
return state;
|
||||
}
|
||||
|
||||
core::AppState CursesApp::onInit() {
|
||||
const core::AppState state = Super::onInit();
|
||||
if (!_console.init()) {
|
||||
return core::AppState::InitFailure;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
core::AppState CursesApp::onCleanup() {
|
||||
const core::AppState state = Super::onCleanup();
|
||||
_console.shutdown();
|
||||
return state;
|
||||
}
|
||||
|
||||
core::AppState CursesApp::onRunning() {
|
||||
const core::AppState state = Super::onRunning();
|
||||
_console.update(_deltaFrameMillis);
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "CursesConsole.h"
|
||||
|
||||
namespace console {
|
||||
|
||||
class CursesApp : public core::CommandlineApp {
|
||||
private:
|
||||
using Super = core::CommandlineApp;
|
||||
|
||||
CursesConsole _console;
|
||||
public:
|
||||
CursesApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, size_t threadPoolSize = 1);
|
||||
virtual ~CursesApp();
|
||||
|
||||
core::AppState onConstruct() override;
|
||||
core::AppState onInit() override;
|
||||
core::AppState onCleanup() override;
|
||||
core::AppState onRunning() override;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#include "CursesConsole.h"
|
||||
#include "core/App.h"
|
||||
#include <SDL_stdinc.h>
|
||||
|
||||
#include "engine-config.h"
|
||||
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
#include <ncurses.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
namespace console {
|
||||
|
||||
CursesConsole::CursesConsole() :
|
||||
Super() {
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
_useOriginalLogFunction = false;
|
||||
#endif
|
||||
_consoleMarginLeft = 1;
|
||||
_consoleMarginLeftBehindPrompt = 1;
|
||||
_consoleActive = true;
|
||||
}
|
||||
|
||||
void CursesConsole::update(uint32_t deltaTime) {
|
||||
Super::update(deltaTime);
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
int key = getch();
|
||||
while (key != ERR) {
|
||||
if (key == KEY_ENTER || key == '\n') {
|
||||
executeCommandLine();
|
||||
} else if (key == KEY_CTAB || key == '\t') {
|
||||
autoComplete();
|
||||
} else if (key == KEY_RESIZE) {
|
||||
clear();
|
||||
refresh();
|
||||
} else if (key == KEY_BACKSPACE || key == 8 || key == 127) {
|
||||
cursorDelete();
|
||||
} else if (key == KEY_LEFT) {
|
||||
cursorLeft();
|
||||
} else if (key == KEY_PPAGE) {
|
||||
scrollPageUp();
|
||||
} else if (key == KEY_NPAGE) {
|
||||
scrollPageDown();
|
||||
} else if (key == KEY_HOME) {
|
||||
_cursorPos = 0;
|
||||
} else if (key == KEY_RIGHT) {
|
||||
cursorRight();
|
||||
} else if (key == KEY_END) {
|
||||
_cursorPos = _commandLine.size();
|
||||
} else if (key == KEY_UP) {
|
||||
cursorUp();
|
||||
} else if (key == KEY_DC) {
|
||||
cursorDelete(false);
|
||||
} else if (key == KEY_IC) {
|
||||
_overwrite ^= true;
|
||||
} else if (key == KEY_DOWN) {
|
||||
cursorDown();
|
||||
} else if (key >= 32 && key < 127) {
|
||||
const char buf[] = { (char)key, '\0' };
|
||||
insertText(buf);
|
||||
}
|
||||
key = getch();
|
||||
}
|
||||
#endif
|
||||
const math::Rect<int> rect(0, 0, COLS - 1, LINES - 1);
|
||||
render(rect, (long)deltaTime);
|
||||
}
|
||||
|
||||
void CursesConsole::drawString(int x, int y, const glm::ivec4& color, const char* str, int len) {
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
mvaddnstr(y, x, str, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CursesConsole::lineHeight() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
glm::ivec2 CursesConsole::stringSize(const char* s, int length) {
|
||||
return glm::ivec2(core_min(length, (int)strlen(s)), lineHeight());
|
||||
}
|
||||
|
||||
void CursesConsole::afterRender(const math::Rect<int> &rect) {
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
clrtoeol();
|
||||
refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CursesConsole::beforeRender(const math::Rect<int> &) {
|
||||
}
|
||||
|
||||
bool CursesConsole::init() {
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
// Start curses mode
|
||||
initscr();
|
||||
// We get F1, F2 etc..
|
||||
keypad(stdscr, TRUE);
|
||||
// Don't echo() while we do getch
|
||||
noecho();
|
||||
// non-blocking input
|
||||
nodelay(stdscr, TRUE);
|
||||
// enable the cursor
|
||||
curs_set(0);
|
||||
|
||||
if (has_colors()) {
|
||||
start_color();
|
||||
use_default_colors();
|
||||
init_pair(1, COLOR_RED, -1);
|
||||
init_pair(2, COLOR_GREEN, -1);
|
||||
init_pair(3, COLOR_YELLOW, -1);
|
||||
init_pair(4, COLOR_BLUE, -1);
|
||||
init_pair(5, COLOR_CYAN, -1);
|
||||
init_pair(6, COLOR_MAGENTA, -1);
|
||||
init_pair(7, -1, -1);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void CursesConsole::shutdown() {
|
||||
#ifdef CURSES_HAVE_NCURSES_H
|
||||
refresh();
|
||||
endwin();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/Console.h"
|
||||
|
||||
namespace console {
|
||||
|
||||
class CursesConsole : public util::Console {
|
||||
private:
|
||||
using Super = util::Console;
|
||||
protected:
|
||||
void drawString(int x, int y, const glm::ivec4& color, const char* str, int len) override;
|
||||
int lineHeight() override;
|
||||
glm::ivec2 stringSize(const char* s, int length) override;
|
||||
void afterRender(const math::Rect<int> &rect) override;
|
||||
void beforeRender(const math::Rect<int> &rect) override;
|
||||
public:
|
||||
CursesConsole();
|
||||
virtual ~CursesConsole() {}
|
||||
|
||||
bool init() override;
|
||||
void update(uint32_t deltaTime);
|
||||
void shutdown() override;
|
||||
};
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
#include "core/command/CommandHandler.h"
|
||||
#include <string.h>
|
||||
|
||||
namespace core {
|
||||
namespace console {
|
||||
|
||||
bool Input::init(uv_loop_t* loop) {
|
||||
_tty.data = this;
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <uv.h>
|
||||
|
||||
namespace core {
|
||||
namespace console {
|
||||
|
||||
/**
|
||||
* @brief Non-blocking console input reading e.g. for dedicated server command line
|
|
@ -32,14 +32,13 @@ set(SRCS
|
|||
Color.cpp Color.h
|
||||
Common.h Common.cpp
|
||||
Concurrency.h Concurrency.cpp
|
||||
ConsoleApp.h ConsoleApp.cpp
|
||||
CommandlineApp.h CommandlineApp.cpp
|
||||
Enum.h
|
||||
EventBus.cpp EventBus.h
|
||||
GameConfig.h
|
||||
GLM.cpp GLM.h
|
||||
Hash.h
|
||||
IComponent.h
|
||||
Input.cpp Input.h
|
||||
Log.cpp Log.h
|
||||
MD5.cpp MD5.h
|
||||
PoolAllocator.h
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
#include "ConsoleApp.h"
|
||||
#include "CommandlineApp.h"
|
||||
#include "core/Var.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
ConsoleApp::ConsoleApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, size_t threadPoolSize) :
|
||||
CommandlineApp::CommandlineApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, size_t threadPoolSize) :
|
||||
Super(metric, filesystem, eventBus, timeProvider, threadPoolSize) {
|
||||
}
|
||||
|
||||
ConsoleApp::~ConsoleApp() {
|
||||
CommandlineApp::~CommandlineApp() {
|
||||
}
|
||||
|
||||
AppState ConsoleApp::onConstruct() {
|
||||
AppState CommandlineApp::onConstruct() {
|
||||
const core::AppState state = Super::onConstruct();
|
||||
|
||||
registerArg("--trace").setDescription("Change log level to trace");
|
|
@ -4,18 +4,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "App.h"
|
||||
#include "core/App.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class ConsoleApp : public App {
|
||||
class CommandlineApp : public core::App {
|
||||
private:
|
||||
using Super = core::App;
|
||||
public:
|
||||
ConsoleApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, size_t threadPoolSize = 1);
|
||||
virtual ~ConsoleApp();
|
||||
CommandlineApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, size_t threadPoolSize = 1);
|
||||
virtual ~CommandlineApp();
|
||||
|
||||
virtual AppState onConstruct() override;
|
||||
virtual core::AppState onConstruct() override;
|
||||
};
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "core/io/Filesystem.h"
|
||||
#include "core/EventBus.h"
|
||||
#include "core/TimeProvider.h"
|
||||
|
@ -14,14 +14,14 @@ namespace core {
|
|||
|
||||
class AbstractBenchmark : public benchmark::Fixture {
|
||||
private:
|
||||
class BenchmarkApp: public core::ConsoleApp {
|
||||
class BenchmarkApp: public core::CommandlineApp {
|
||||
friend class AbstractBenchmark;
|
||||
protected:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
AbstractBenchmark* _benchmark = nullptr;
|
||||
public:
|
||||
BenchmarkApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, AbstractBenchmark* benchmark);
|
||||
~BenchmarkApp();
|
||||
virtual ~BenchmarkApp();
|
||||
|
||||
virtual core::AppState onInit() override;
|
||||
virtual core::AppState onCleanup() override;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "core/collection/Map.h"
|
||||
#include "core/EventBus.h"
|
||||
#include "core/io/Filesystem.h"
|
||||
|
@ -81,18 +81,18 @@ inline ::std::ostream& operator<<(::std::ostream& os, const glm::tvec1<T, P>& ve
|
|||
|
||||
class AbstractTest: public testing::Test {
|
||||
private:
|
||||
class TestApp: public core::ConsoleApp {
|
||||
class TestApp: public core::CommandlineApp {
|
||||
friend class AbstractTest;
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
protected:
|
||||
AbstractTest* _test = nullptr;
|
||||
public:
|
||||
TestApp(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider, AbstractTest* test);
|
||||
~TestApp();
|
||||
|
||||
AppState onInit() override;
|
||||
AppState onCleanup() override;
|
||||
core::AppState onInit() override;
|
||||
core::AppState onCleanup() override;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
namespace util {
|
||||
|
||||
namespace {
|
||||
static const char* historyFilename = "history";
|
||||
static const std::string consolePrompt = "> ";
|
||||
static const std::string consoleCursor = ".";
|
||||
static const int consoleMarginLeft = 5;
|
||||
static const int consoleMarginLeftBehindPrompt = 13;
|
||||
static const char colorMark = '^';
|
||||
|
||||
static const glm::ivec4 colors[MAX_COLORS] = {
|
||||
glm::ivec4(255, 255, 255, 255),
|
||||
|
@ -47,24 +41,6 @@ static const ConsoleColor priorityColors[SDL_NUM_LOG_PRIORITIES] = {
|
|||
static_assert(SDL_arraysize(priorityColors) == SDL_NUM_LOG_PRIORITIES, "Priority count doesn't match");
|
||||
}
|
||||
|
||||
std::string getColor(ConsoleColor color) {
|
||||
core_assert(color >= 0 && color <= (int)SDL_arraysize(colors));
|
||||
std::string s;
|
||||
s += colorMark;
|
||||
s += std::to_string((int)color);
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline bool isColor(const char *cstr) {
|
||||
static const char maxColor = MAX_COLORS + '0';
|
||||
return cstr[0] == colorMark && cstr[1] >= '0' && cstr[1] <= maxColor;
|
||||
}
|
||||
|
||||
static inline void skipColor(const char **cstr) {
|
||||
static_assert((int)MAX_COLORS < 10, "max colors must not exceed one ascii char for encoding");
|
||||
*cstr += 2;
|
||||
}
|
||||
|
||||
Console::Console() :
|
||||
_mainThread(std::this_thread::get_id()) {
|
||||
SDL_LogGetOutputFunction(&_logFunction, &_logUserData);
|
||||
|
@ -75,6 +51,24 @@ Console::~Console() {
|
|||
SDL_LogSetOutputFunction(_logFunction, _logUserData);
|
||||
}
|
||||
|
||||
std::string Console::getColor(ConsoleColor color) {
|
||||
core_assert(color >= 0 && color <= (int)SDL_arraysize(colors));
|
||||
std::string s;
|
||||
s += _colorMark;
|
||||
s += std::to_string((int)color);
|
||||
return s;
|
||||
}
|
||||
|
||||
bool Console::isColor(const char *cstr) {
|
||||
static const char maxColor = MAX_COLORS + '0';
|
||||
return cstr[0] == _colorMark && cstr[1] >= '0' && cstr[1] <= maxColor;
|
||||
}
|
||||
|
||||
void Console::skipColor(const char **cstr) {
|
||||
static_assert((int)MAX_COLORS < 10, "max colors must not exceed one ascii char for encoding");
|
||||
*cstr += 2;
|
||||
}
|
||||
|
||||
void Console::construct() {
|
||||
_autoEnable = core::Var::get("ui_autoconsole", "false", "Activate console on output");
|
||||
core::Command::registerCommand("toggleconsole", [&] (const core::CmdArgs& args) { toggle(); }).setHelp("Toggle the in-game console");
|
||||
|
@ -83,7 +77,7 @@ void Console::construct() {
|
|||
|
||||
bool Console::init() {
|
||||
const io::FilesystemPtr& fs = io::filesystem();
|
||||
const std::string& content = fs->load("%s", historyFilename);
|
||||
const std::string& content = fs->load("%s", _historyFilename);
|
||||
core::string::splitString(content, _history, "\n");
|
||||
_historyPos = _history.size();
|
||||
Log::info("Loaded %i history entries", _historyPos);
|
||||
|
@ -99,7 +93,7 @@ void Console::shutdown() {
|
|||
}
|
||||
|
||||
const io::FilesystemPtr& fs = io::filesystem();
|
||||
if (!fs->write(historyFilename, content)) {
|
||||
if (!fs->write(_historyFilename, content)) {
|
||||
Log::warn("Failed to write the history");
|
||||
} else {
|
||||
Log::debug("Wrote the history");
|
||||
|
@ -131,7 +125,7 @@ bool Console::onKeyPress(int32_t key, int16_t modifier) {
|
|||
} else if (key == SDLK_e) {
|
||||
_cursorPos = _commandLine.size();
|
||||
} else if (key == SDLK_c) {
|
||||
_messages.push_back(consolePrompt + _commandLine);
|
||||
_messages.push_back(_consolePrompt + _commandLine);
|
||||
clearCommandLine();
|
||||
} else if (key == SDLK_d) {
|
||||
toggle();
|
||||
|
@ -212,7 +206,7 @@ bool Console::onKeyPress(int32_t key, int16_t modifier) {
|
|||
}
|
||||
|
||||
void Console::executeCommandLine() {
|
||||
_messages.push_back(consolePrompt + _commandLine);
|
||||
_messages.push_back(_consolePrompt + _commandLine);
|
||||
_scrollPos = 0;
|
||||
if (_commandLine.empty()) {
|
||||
return;
|
||||
|
@ -426,7 +420,7 @@ void Console::autoComplete() {
|
|||
_commandLine.insert(cmdEraseIndex, matches.front());
|
||||
}
|
||||
} else {
|
||||
_messages.push_back(consolePrompt + _commandLine);
|
||||
_messages.push_back(_consolePrompt + _commandLine);
|
||||
std::sort(begin(matches), end(matches), [](const std::string& v1, const std::string& v2) {
|
||||
return v1 < v2;
|
||||
});
|
||||
|
@ -544,7 +538,9 @@ void Console::addLogLine(int category, SDL_LogPriority priority, const char *mes
|
|||
if (hasColor) {
|
||||
skipColor(&message);
|
||||
}
|
||||
_logFunction(_logUserData, category, priority, message);
|
||||
if (_useOriginalLogFunction) {
|
||||
_logFunction(_logUserData, category, priority, message);
|
||||
}
|
||||
}
|
||||
|
||||
bool Console::toggle() {
|
||||
|
@ -609,6 +605,7 @@ void Console::render(const math::Rect<int> &rect, long deltaFrame) {
|
|||
const int lineH = lineHeight();
|
||||
_maxLines = (rect.getMaxZ() - rect.getMinZ()) / lineH;
|
||||
if (_maxLines <= 0) {
|
||||
afterRender(rect);
|
||||
return;
|
||||
}
|
||||
const int maxY = _messages.size() * lineH;
|
||||
|
@ -617,19 +614,19 @@ void Console::render(const math::Rect<int> &rect, long deltaFrame) {
|
|||
MessagesIter i = _messages.rbegin();
|
||||
std::advance(i, _scrollPos);
|
||||
for (int y = startY; i != _messages.rend(); ++i) {
|
||||
if (y < 0) {
|
||||
if (y < rect.getMinZ()) {
|
||||
break;
|
||||
}
|
||||
const glm::ivec2& size = stringSize(i->c_str(), i->length());
|
||||
y -= size.y;
|
||||
drawString(consoleMarginLeft, y, *i, i->length());
|
||||
drawString(_consoleMarginLeft, y, *i, i->length());
|
||||
}
|
||||
|
||||
drawString(consoleMarginLeft, startY, consolePrompt, consolePrompt.length());
|
||||
drawString(consoleMarginLeft + consoleMarginLeftBehindPrompt, startY, _commandLine, _commandLine.length());
|
||||
drawString(_consoleMarginLeft, startY, _consolePrompt, _consolePrompt.length());
|
||||
drawString(_consoleMarginLeft + _consoleMarginLeftBehindPrompt, startY, _commandLine, _commandLine.length());
|
||||
if (_cursorBlink) {
|
||||
const glm::ivec2& l = stringSize(_commandLine.c_str(), _cursorPos);
|
||||
drawString(consoleMarginLeft + consoleMarginLeftBehindPrompt + l.x, startY, consoleCursor, consoleCursor.length());
|
||||
drawString(_consoleMarginLeft + _consoleMarginLeftBehindPrompt + l.x, startY, _consoleCursor, _consoleCursor.length());
|
||||
}
|
||||
|
||||
afterRender(rect);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include "core/Var.h"
|
||||
#include "core/Assert.h"
|
||||
#include "core/IComponent.h"
|
||||
#include "math/Rect.h"
|
||||
#include "core/collection/ConcurrentQueue.h"
|
||||
|
@ -28,6 +29,20 @@ protected:
|
|||
typedef Messages::const_reverse_iterator MessagesIter;
|
||||
Messages _messages;
|
||||
|
||||
int _consoleMarginLeft = 5;
|
||||
int _consoleMarginLeftBehindPrompt = 13;
|
||||
|
||||
const char* _historyFilename = "history";
|
||||
std::string _consolePrompt = "> ";
|
||||
std::string _consoleCursor = ".";
|
||||
char _colorMark = '^';
|
||||
|
||||
std::string getColor(ConsoleColor color);
|
||||
|
||||
bool isColor(const char *cstr);
|
||||
|
||||
void skipColor(const char **cstr);
|
||||
|
||||
/**
|
||||
* @brief Data structure to store a log entry call from a different thread.
|
||||
*/
|
||||
|
@ -85,6 +100,7 @@ protected:
|
|||
// commandline character will get overwritten if this is true
|
||||
bool _overwrite = false;
|
||||
bool _cursorBlink = false;
|
||||
bool _useOriginalLogFunction = true;
|
||||
int _frame = 0;
|
||||
int _cursorPos = 0;
|
||||
int _scrollPos = 0;
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "console/CursesApp.h"
|
||||
#include "backend/loop/ServerLoop.h"
|
||||
#include "core/TimeProvider.h"
|
||||
#include "http/HttpServer.h"
|
||||
|
||||
class Server: public core::ConsoleApp {
|
||||
class Server: public console::CursesApp {
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = console::CursesApp;
|
||||
backend::ServerLoopPtr _serverLoop;
|
||||
public:
|
||||
Server(const metric::MetricPtr& metric, const backend::ServerLoopPtr& serverLoop,
|
||||
|
|
|
@ -3,4 +3,4 @@ set(SRCS
|
|||
TestHttpServer.h TestHttpServer.cpp
|
||||
)
|
||||
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} NOINSTALL)
|
||||
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES core http)
|
||||
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES core console http)
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "http/HttpServer.h"
|
||||
#include "core/Input.h"
|
||||
#include "console/Input.h"
|
||||
#include <uv.h>
|
||||
|
||||
/**
|
||||
|
@ -14,11 +14,11 @@
|
|||
*
|
||||
* See e.g. https://github.com/zardus/preeny and https://lolware.net/2015/04/28/nginx-fuzzing.html
|
||||
*/
|
||||
class TestHttpServer: public core::ConsoleApp {
|
||||
class TestHttpServer: public core::CommandlineApp {
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
http::HttpServer _server;
|
||||
core::Input _input;
|
||||
console::Input _input;
|
||||
uv_loop_t *_loop = nullptr;
|
||||
core::VarPtr _exitAfterRequest;
|
||||
int _remainingFrames = 0;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "Types.h"
|
||||
#include <simplecpp.h>
|
||||
#include <vector>
|
||||
|
@ -25,9 +25,9 @@
|
|||
* @ingroup Tools
|
||||
* @ingroup Compute
|
||||
*/
|
||||
class ComputeShaderTool: public core::ConsoleApp {
|
||||
class ComputeShaderTool: public core::CommandlineApp {
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
protected:
|
||||
std::string _namespaceSrc;
|
||||
std::string _sourceDirectory;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "core/Tokenizer.h"
|
||||
#include "Table.h"
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
|||
*
|
||||
* @ingroup Tools
|
||||
*/
|
||||
class DatabaseTool: public core::ConsoleApp {
|
||||
class DatabaseTool: public core::CommandlineApp {
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
protected:
|
||||
std::string _tableFile;
|
||||
std::string _targetFile;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "Types.h"
|
||||
|
||||
/**
|
||||
|
@ -12,9 +12,9 @@
|
|||
*
|
||||
* @ingroup Tools
|
||||
*/
|
||||
class ShaderTool: public core::ConsoleApp {
|
||||
class ShaderTool: public core::CommandlineApp {
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
protected:
|
||||
ShaderStruct _shaderStruct;
|
||||
std::string _namespaceSrc;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/ConsoleApp.h"
|
||||
#include "core/CommandlineApp.h"
|
||||
#include "ui/turbobadger/TurboBadger.h"
|
||||
#include "ui/turbobadger/UIDummies.h"
|
||||
|
||||
|
@ -13,9 +13,9 @@
|
|||
*
|
||||
* @ingroup Tools
|
||||
*/
|
||||
class UITool: public core::ConsoleApp {
|
||||
class UITool: public core::CommandlineApp {
|
||||
private:
|
||||
using Super = core::ConsoleApp;
|
||||
using Super = core::CommandlineApp;
|
||||
DummyRenderer _renderer;
|
||||
tb::TBWidget _root;
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue