diff --git a/src/client_manager.cc b/src/client_manager.cc index 6f30277da..2d65402b8 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -1,11 +1,33 @@ #include "client_manager.hh" +#include "event_manager.hh" + namespace Kakoune { -void ClientManager::add_client(Client&& client) +void ClientManager::create_client(std::unique_ptr&& ui, + Buffer& buffer, int event_fd) { - m_clients.emplace_back(std::move(client)); + m_clients.emplace_back(std::move(ui), *buffer.get_or_create_window()); + + InputHandler* input_handler = m_clients.back().input_handler.get(); + Context* context = m_clients.back().context.get(); + EventManager::instance().watch(event_fd, [=](int) { + try + { + input_handler->handle_available_inputs(*context); + } + catch (Kakoune::runtime_error& error) + { + context->print_status(error.description()); + } + catch (Kakoune::client_removed&) + { + EventManager::instance().unwatch(event_fd); + close(event_fd); + } + }); + context->draw_ifn(); } void ClientManager::remove_client_by_context(Context& context) diff --git a/src/client_manager.hh b/src/client_manager.hh index 99500d4fb..c43346cb7 100644 --- a/src/client_manager.hh +++ b/src/client_manager.hh @@ -7,41 +7,43 @@ namespace Kakoune { -struct Client -{ - std::unique_ptr ui; - std::unique_ptr input_handler; - std::unique_ptr context; - - Client(UserInterface* ui, Window& window) - : ui(ui), - input_handler(new InputHandler{}), - context(new Context(*input_handler, window, *ui)) {} - - Client(Client&&) = default; - Client& operator=(Client&& other) - { - // drop safe pointers first - context.reset(); - - ui = std::move(other.ui); - input_handler = std::move(other.input_handler); - context = std::move(other.context); - return *this; - } -}; - struct client_removed{}; class ClientManager : public Singleton { public: - void add_client(Client&& client); + void create_client(std::unique_ptr&& ui, + Buffer& buffer, int event_fd); void remove_client_by_context(Context& context); bool empty() const { return m_clients.empty(); } size_t count() const { return m_clients.size(); } + private: + struct Client + { + Client(std::unique_ptr&& ui, Window& window) + : user_interface(std::move(ui)), input_handler(new InputHandler{}), + context(new Context(*input_handler, window, *user_interface)) + {} + + Client(Client&&) = default; + Client& operator=(Client&& other) + { + // drop safe pointers first + context.reset(); + + user_interface = std::move(other.user_interface); + input_handler = std::move(other.input_handler); + context = std::move(other.context); + return *this; + } + + std::unique_ptr user_interface; + std::unique_ptr input_handler; + std::unique_ptr context; + }; + std::vector m_clients; }; diff --git a/src/main.cc b/src/main.cc index eb2ceedbf..95e0d30bb 100644 --- a/src/main.cc +++ b/src/main.cc @@ -509,27 +509,8 @@ void create_local_client(const String& file) else buffer = new Buffer("*scratch*", Buffer::Type::Scratch); - Client client{ui, *buffer->get_or_create_window()}; - - InputHandler* input_handler = client.input_handler.get(); - Context* context = client.context.get(); - EventManager::instance().watch(0, [=](int) { - try - { - input_handler->handle_available_inputs(*context); - } - catch (Kakoune::runtime_error& error) - { - ui->print_status(error.description(), -1); - } - catch (Kakoune::client_removed&) - { - EventManager::instance().unwatch(0); - } - }); - - context->draw_ifn(); - ClientManager::instance().add_client(std::move(client)); + ClientManager::instance().create_client( + std::unique_ptr{ui}, *buffer, 0); } struct Server @@ -558,25 +539,8 @@ struct Server auto& buffer = *BufferManager::instance().begin(); RemoteUI* ui = new RemoteUI{sock}; - Client client{ui, *buffer->get_or_create_window()}; - InputHandler* input_handler = client.input_handler.get(); - Context* context = client.context.get(); - EventManager::instance().watch(sock, [=](int) { - try - { - input_handler->handle_available_inputs(*context); - } - catch (Kakoune::runtime_error& error) - { - ui->print_status(error.description(), -1); - } - catch (Kakoune::client_removed&) - { - EventManager::instance().unwatch(sock); - close(sock); - } - }); - ClientManager::instance().add_client(std::move(client)); + ClientManager::instance().create_client( + std::unique_ptr{ui}, *buffer, sock); }; EventManager::instance().watch(m_listen_sock, accepter); }