ConsoleEditor.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include <atomic>
  2. #include <thread>
  3. #include <mutex>
  4. #include <readline/readline.h>
  5. #include <readline/history.h>
  6. #include <poll.h>
  7. #include <unistd.h>
  8. #include "server/commands/ConsoleEditor.h"
  9. #include "gaming-core/utils/RingBuffer.h"
  10. #include <iostream>
  11. struct Setup {
  12. std::atomic_bool running;
  13. std::mutex queueMutex;
  14. RingBuffer<char*, 8> queue;
  15. std::thread readThread;
  16. static Setup instance;
  17. Setup() : running(true), readThread(&Setup::loop, this) {
  18. rl_bind_key('\t', rl_insert);
  19. }
  20. ~Setup() {
  21. running = false;
  22. readThread.join();
  23. rl_callback_handler_remove();
  24. rl_clear_visible_line();
  25. }
  26. static void onLineRead(char* line) {
  27. std::lock_guard<std::mutex> lg(instance.queueMutex);
  28. add_history(line);
  29. instance.queue.write(line);
  30. }
  31. void loop() {
  32. rl_callback_handler_install("> ", onLineRead);
  33. rl_set_keyboard_input_timeout(1);
  34. while(running) {
  35. struct pollfd fds;
  36. fds.fd = STDIN_FILENO;
  37. fds.events = POLLIN;
  38. fds.revents = 0;
  39. int result = poll(&fds, 1, 1);
  40. if(result > 0) {
  41. rl_callback_read_char();
  42. }
  43. }
  44. }
  45. };
  46. Setup Setup::instance;
  47. void ConsoleEditor::clearPrintLine() {
  48. rl_clear_visible_line();
  49. }
  50. void ConsoleEditor::printLine() {
  51. rl_forced_update_display();
  52. }
  53. bool ConsoleEditor::readCommand(RawCommand& buffer) {
  54. std::lock_guard<std::mutex> lg(Setup::instance.queueMutex);
  55. if(Setup::instance.queue.canRead()) {
  56. char* data = Setup::instance.queue.read();
  57. buffer.clear().append(static_cast<const char*>(data));
  58. free(data);
  59. return true;
  60. }
  61. return false;
  62. }