CommandEditor.cpp 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include <readline/readline.h>
  2. #include <readline/history.h>
  3. #include <poll.h>
  4. #include <unistd.h>
  5. #include "server/commands/CommandEditor.h"
  6. std::mutex CommandEditor::queueMutex;
  7. RingBuffer<String, 5> CommandEditor::queue;
  8. CommandEditor::CommandEditor() : running(true), readThread(&CommandEditor::loop, this) {
  9. rl_bind_key('\t', rl_insert);
  10. }
  11. CommandEditor::~CommandEditor() {
  12. running = false;
  13. readThread.join();
  14. rl_callback_handler_remove();
  15. rl_clear_visible_line();
  16. }
  17. void CommandEditor::preTick() const {
  18. rl_clear_visible_line();
  19. }
  20. void CommandEditor::postTick() const {
  21. rl_forced_update_display();
  22. }
  23. bool CommandEditor::hasCommand() const {
  24. return queue.canRead();
  25. }
  26. String CommandEditor::readCommand() {
  27. std::lock_guard<std::mutex> lg(queueMutex);
  28. return queue.read();
  29. }
  30. void CommandEditor::onLineRead(char* line) {
  31. std::lock_guard<std::mutex> lg(queueMutex);
  32. add_history(line);
  33. queue.write(line);
  34. free(line);
  35. }
  36. void CommandEditor::loop() {
  37. rl_callback_handler_install("> ", onLineRead);
  38. rl_set_keyboard_input_timeout(1);
  39. while(running) {
  40. struct pollfd fds;
  41. fds.fd = STDIN_FILENO;
  42. fds.events = POLLIN;
  43. fds.revents = 0;
  44. int result = poll(&fds, 1, 1);
  45. if(result > 0) {
  46. rl_callback_read_char();
  47. }
  48. }
  49. rl_callback_handler_remove();
  50. }