UCIEndpoint.cpp 3.7 KB

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