Browse Source

removal of GNU readline in favor of own library

Kajetan Johannes Hammerle 5 months ago
parent
commit
cf6104b775

+ 3 - 0
.gitmodules

@@ -4,3 +4,6 @@
 [submodule "enet"]
 	path = enet
 	url = https://github.com/zpl-c/enet.git
+[submodule "raw-terminal"]
+	path = raw-terminal
+	url = git@git.hammerle.me:kjhammerle/raw-terminal.git

+ 3 - 7
meson.build

@@ -14,9 +14,8 @@ sourcesServer = ['server/Main.cpp',
     'server/network/Server.cpp',
     'server/network/Client.cpp',
     'server/GameServer.cpp',
-    'server/commands/ServerCommands.cpp',
-    'server/commands/CommandManager.cpp',
-    'server/commands/ConsoleEditor.cpp']
+    'server/commands/ServerState.cpp',
+    'server/commands/CommandManager.cpp']
 
 sourcesClient = ['client/Main.cpp',
     'gaming-core/utils/Size.cpp',
@@ -56,9 +55,6 @@ sourcesClient = ['client/Main.cpp',
 
 sourcesTest = ['tests/Main.cpp']
 
-c_compiler = meson.get_compiler('cpp')
-readline = c_compiler.find_library('readline', required: true)
-
 threadDep = dependency('threads')
 glewDep = dependency('glew')
 glfwDep = dependency('glfw3')
@@ -68,7 +64,7 @@ args = ['-Wall', '-Wextra', '-pedantic', '-Werror']
 
 executable('game_server', 
     sources: sourcesCommon + sourcesServer,
-    dependencies : [threadDep, readline],
+    dependencies : [threadDep],
     include_directories : include_directories('gaming-core'),
     cpp_args: args)
     

+ 1 - 0
raw-terminal

@@ -0,0 +1 @@
+Subproject commit 5d832b3daba5f53794dcb8d28a6459bd7f135b9d

+ 16 - 6
server/GameServer.cpp

@@ -2,20 +2,26 @@
 
 #include "server/commands/CommandTypes.h"
 #include "server/GameServer.h"
-#include "server/commands/ConsoleEditor.h"
 #include "server/commands/CommandManager.h"
 
-GameServer::GameServer(const Clock& tps) : tps(tps) {
+GameServer::GameServer() : reader(0, "> ") {
 }
 
 void GameServer::tick() {
+    tps.update();
+    handleCommands();
 }
 
-void GameServer::handleCommands(ServerCommands& serverCommands) {
-    RawCommand rawCommand;
-    while(ConsoleEditor::readCommand(rawCommand)) {
-        commandManager.execute(serverCommands, rawCommand);
+void GameServer::handleCommands() {
+    if(!reader.canRead()) {
+        return;
     }
+    const char* s = reader.readLine();
+    if(s == nullptr) {
+        return;
+    }
+    RawCommand rawCommand(s);
+    commandManager.execute(state, rawCommand);
 }
 
 void GameServer::onFullServerClientConnect(Client& client) {
@@ -40,4 +46,8 @@ void GameServer::onClientPackage(Client& client, Packet& packet) {
 void GameServer::onClientDisconnect(Client& client) {
     (void) client;
     std::cout << "disconnected\n";
+}
+
+bool GameServer::isRunning() const {
+    return state.running;
 }

+ 11 - 5
server/GameServer.h

@@ -1,27 +1,33 @@
 #ifndef GAMESERVER_H
 #define GAMESERVER_H
 
-#include "server/commands/ServerCommands.h"
+#include "server/commands/ServerState.h"
 #include "server/network/Client.h"
 #include "common/network/Packet.h"
 #include "gaming-core/utils/Clock.h"
 #include "commands/CommandManager.h"
+#include "raw-terminal/RawReader.h"
 
 class GameServer final {
+    ServerState state; 
+    Clock tps;
+    RawReader<256, 10> reader;
+    CommandManager commandManager;
+
 public:
-    GameServer(const Clock& tps);
+    GameServer();
 
     void tick();
-    void handleCommands(ServerCommands& serverCommands);
 
     void onFullServerClientConnect(Client& client);
     void onClientConnect(Client& client);
     void onClientPackage(Client& client, Packet& packet);
     void onClientDisconnect(Client& client);
+    
+    bool isRunning() const;
 
 private:
-    const Clock& tps;
-    CommandManager commandManager;
+    void handleCommands();
 };
 
 #endif

+ 3 - 11
server/Main.cpp

@@ -1,32 +1,24 @@
 #include "server/network/Server.h"
 #include "gaming-core/utils/Clock.h"
 #include "server/GameServer.h"
-#include "commands/ConsoleEditor.h"
-
 
 int main() {
     Server server(11196);
     if(server.hasError()) {
         return 0;
     }
-
-    Clock tps;
-    GameServer gameServer(tps);
-    ServerCommands serverCommands;
+    
+    GameServer gameServer;
     
     Clock clock;
     constexpr Clock::Nanos NANOS_PER_TICK = 50000000;
     Clock::Nanos lag = 0;
-    while(serverCommands.isRunning()) {
+    while(gameServer.isRunning()) {
         lag += clock.update();
         while(lag >= NANOS_PER_TICK) {
             lag -= NANOS_PER_TICK;
-            tps.update();
-            ConsoleEditor::clearPrintLine();
             server.consumeEvents(gameServer);
-            gameServer.handleCommands(serverCommands);
             gameServer.tick();
-            ConsoleEditor::printLine();
         }
         Clock::Nanos waitNanos = NANOS_PER_TICK - lag;
         if(waitNanos > 300000) {

+ 5 - 5
server/commands/CommandManager.cpp

@@ -2,18 +2,18 @@
 
 #include "server/commands/CommandManager.h"
 
-static void commandTest(ServerCommands&, const CommandArguments& args) {
+static void commandTest(ServerState&, const CommandArguments& args) {
     std::cout << "test command" << std::endl;
     for(int i = 0; i < args.getLength(); i++) {
         std::cout << " - " << args[i] << std::endl;
     }
 }
 
-static void commandStop(ServerCommands& sc, const CommandArguments&) {
-    sc.stop();
+static void commandStop(ServerState& sc, const CommandArguments&) {
+    sc.running = false;
 }
 
-static void commandEmpty(ServerCommands&, const CommandArguments&) {
+static void commandEmpty(ServerState&, const CommandArguments&) {
 }
 
 CommandManager::CommandManager() {
@@ -21,7 +21,7 @@ CommandManager::CommandManager() {
     commands.add("stop", commandStop);
 }
 
-void CommandManager::execute(ServerCommands& sc, const RawCommand& rawCommand) {
+void CommandManager::execute(ServerState& sc, const RawCommand& rawCommand) {
     CommandArguments args(rawCommand);
     if(args.getLength() == 0) {
         std::cout << "Invalid command syntax: '" << rawCommand << "'\n";

+ 3 - 3
server/commands/CommandManager.h

@@ -1,7 +1,7 @@
 #ifndef COMMANDMANAGER_H
 #define COMMANDMANAGER_H
 
-#include "server/commands/ServerCommands.h"
+#include "server/commands/ServerState.h"
 #include "server/commands/CommandTypes.h"
 #include "gaming-core/utils/HashMap.h"
 
@@ -9,10 +9,10 @@ class CommandManager {
 public:
     CommandManager();
 
-    void execute(ServerCommands& sc, const RawCommand& rawCommand);
+    void execute(ServerState& sc, const RawCommand& rawCommand);
     
 private:
-    typedef void (*Command) (ServerCommands&, const CommandArguments&);
+    typedef void (*Command) (ServerState&, const CommandArguments&);
 
     HashMap<CommandName, Command, 16> commands;
 };

+ 0 - 75
server/commands/ConsoleEditor.cpp

@@ -1,75 +0,0 @@
-#include <atomic>
-#include <thread>
-#include <mutex>
-
-#include <readline/readline.h>
-#include <readline/history.h>
-#include <poll.h>
-#include <unistd.h>
-
-#include "server/commands/ConsoleEditor.h"
-#include "gaming-core/utils/RingBuffer.h"
-
-#include <iostream>
-
-struct Setup {
-    std::atomic_bool running;
-    std::mutex queueMutex;
-    RingBuffer<char*, 8> queue;
-    std::thread readThread;
-
-    static Setup instance;
-
-    Setup() : running(true), readThread(&Setup::loop, this) {
-        rl_bind_key('\t', rl_insert);
-    }
-
-    ~Setup() {
-        running = false;
-        readThread.join();
-        rl_callback_handler_remove();
-        rl_clear_visible_line();
-    }
-
-    static void onLineRead(char* line) {
-        std::lock_guard<std::mutex> lg(instance.queueMutex);
-        add_history(line);
-        instance.queue.write(line);
-    }
-
-    void loop() {
-        rl_callback_handler_install("> ", onLineRead);
-        rl_set_keyboard_input_timeout(1);
-        while(running) {
-            struct pollfd fds;
-            fds.fd = STDIN_FILENO;
-            fds.events = POLLIN;
-            fds.revents = 0;
-            int result = poll(&fds, 1, 1);
-            if(result > 0) {
-                rl_callback_read_char();
-            }
-        }
-    }
-};
-
-Setup Setup::instance;
-
-void ConsoleEditor::clearPrintLine() {
-    rl_clear_visible_line();
-}
-
-void ConsoleEditor::printLine() {
-    rl_forced_update_display();
-}
-
-bool ConsoleEditor::readCommand(RawCommand& buffer) {
-    std::lock_guard<std::mutex> lg(Setup::instance.queueMutex);
-    if(Setup::instance.queue.canRead()) {
-        char* data = Setup::instance.queue.read();
-        buffer.clear().append(static_cast<const char*>(data));
-        free(data);
-        return true;
-    }
-    return false;
-}

+ 0 - 12
server/commands/ConsoleEditor.h

@@ -1,12 +0,0 @@
-#ifndef COMMANDEDITOR_H
-#define COMMANDEDITOR_H
-
-#include "server/commands/CommandTypes.h"
-
-namespace ConsoleEditor {
-    void clearPrintLine();
-    void printLine();
-    bool readCommand(RawCommand& buffer);
-}
-
-#endif

+ 0 - 12
server/commands/ServerCommands.cpp

@@ -1,12 +0,0 @@
-#include "server/commands/ServerCommands.h"
-
-ServerCommands::ServerCommands() : running(true) {
-}
-
-bool ServerCommands::isRunning() const {
-    return running;
-}
-
-void ServerCommands::stop() {
-    running = false;
-}

+ 0 - 17
server/commands/ServerCommands.h

@@ -1,17 +0,0 @@
-#ifndef SERVERCOMMANDS_H
-#define SERVERCOMMANDS_H
-
-#include <atomic>
-
-class ServerCommands final {
-public:
-    ServerCommands();
-
-    bool isRunning() const;
-    void stop();
-
-private:
-    std::atomic_bool running;
-};
-
-#endif

+ 4 - 0
server/commands/ServerState.cpp

@@ -0,0 +1,4 @@
+#include "server/commands/ServerState.h"
+
+ServerState::ServerState() : running(true) {
+}

+ 10 - 0
server/commands/ServerState.h

@@ -0,0 +1,10 @@
+#ifndef SERVERSTATE_H
+#define SERVERSTATE_H
+
+struct ServerState final {
+    bool running;
+    
+    ServerState();
+};
+
+#endif