UCIEndpoint.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "UCIEndpoint.h"
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/Debug.h>
  9. #include <AK/DeprecatedString.h>
  10. #include <LibCore/EventLoop.h>
  11. namespace Chess::UCI {
  12. Endpoint::Endpoint(NonnullRefPtr<Core::IODevice> in, NonnullRefPtr<Core::IODevice> out)
  13. : m_in(in)
  14. , m_out(out)
  15. , m_in_notifier(Core::Notifier::construct(in->fd(), Core::Notifier::Read))
  16. {
  17. set_in_notifier();
  18. }
  19. void Endpoint::send_command(Command const& command)
  20. {
  21. dbgln_if(UCI_DEBUG, "{} Sent UCI Command: {}", class_name(), DeprecatedString(command.to_deprecated_string().characters(), Chomp));
  22. m_out->write(command.to_deprecated_string());
  23. }
  24. void Endpoint::event(Core::Event& event)
  25. {
  26. switch (static_cast<Command::Type>(event.type())) {
  27. case Command::Type::UCI:
  28. return handle_uci();
  29. case Command::Type::Debug:
  30. return handle_debug(static_cast<DebugCommand const&>(event));
  31. case Command::Type::IsReady:
  32. return handle_uci();
  33. case Command::Type::SetOption:
  34. return handle_setoption(static_cast<SetOptionCommand const&>(event));
  35. case Command::Type::Position:
  36. return handle_position(static_cast<PositionCommand const&>(event));
  37. case Command::Type::Go:
  38. return handle_go(static_cast<GoCommand const&>(event));
  39. case Command::Type::Stop:
  40. return handle_stop();
  41. case Command::Type::Id:
  42. return handle_id(static_cast<IdCommand const&>(event));
  43. case Command::Type::UCIOk:
  44. return handle_uciok();
  45. case Command::Type::ReadyOk:
  46. return handle_readyok();
  47. case Command::Type::BestMove:
  48. return handle_bestmove(static_cast<BestMoveCommand const&>(event));
  49. case Command::Type::Info:
  50. return handle_info(static_cast<InfoCommand const&>(event));
  51. default:
  52. break;
  53. }
  54. }
  55. void Endpoint::set_in_notifier()
  56. {
  57. m_in_notifier = Core::Notifier::construct(m_in->fd(), Core::Notifier::Read);
  58. m_in_notifier->on_ready_to_read = [this] {
  59. while (m_in->can_read_line())
  60. Core::EventLoop::current().post_event(*this, read_command());
  61. };
  62. }
  63. NonnullOwnPtr<Command> Endpoint::read_command()
  64. {
  65. DeprecatedString line(ReadonlyBytes(m_in->read_line(4096).bytes()), Chomp);
  66. dbgln_if(UCI_DEBUG, "{} Received UCI Command: {}", class_name(), line);
  67. if (line == "uci") {
  68. return make<UCICommand>(UCICommand::from_string(line));
  69. } else if (line.starts_with("debug"sv)) {
  70. return make<DebugCommand>(DebugCommand::from_string(line));
  71. } else if (line.starts_with("isready"sv)) {
  72. return make<IsReadyCommand>(IsReadyCommand::from_string(line));
  73. } else if (line.starts_with("setoption"sv)) {
  74. return make<SetOptionCommand>(SetOptionCommand::from_string(line));
  75. } else if (line.starts_with("position"sv)) {
  76. return make<PositionCommand>(PositionCommand::from_string(line));
  77. } else if (line.starts_with("go"sv)) {
  78. return make<GoCommand>(GoCommand::from_string(line));
  79. } else if (line.starts_with("stop"sv)) {
  80. return make<StopCommand>(StopCommand::from_string(line));
  81. } else if (line.starts_with("id"sv)) {
  82. return make<IdCommand>(IdCommand::from_string(line));
  83. } else if (line.starts_with("uciok"sv)) {
  84. return make<UCIOkCommand>(UCIOkCommand::from_string(line));
  85. } else if (line.starts_with("readyok"sv)) {
  86. return make<ReadyOkCommand>(ReadyOkCommand::from_string(line));
  87. } else if (line.starts_with("bestmove"sv)) {
  88. return make<BestMoveCommand>(BestMoveCommand::from_string(line));
  89. } else if (line.starts_with("info"sv)) {
  90. return make<InfoCommand>(InfoCommand::from_string(line));
  91. }
  92. dbgln("command line: {}", line);
  93. VERIFY_NOT_REACHED();
  94. }
  95. };