Add a ClientManager for managing client lifetimes
This commit is contained in:
parent
bc7dfec44c
commit
1ea4b3998a
24
src/client_manager.cc
Normal file
24
src/client_manager.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "client_manager.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
void ClientManager::add_client(Client&& client)
|
||||
{
|
||||
m_clients.emplace_back(std::move(client));
|
||||
}
|
||||
|
||||
void ClientManager::remove_client_by_context(Context& context)
|
||||
{
|
||||
for (auto it = m_clients.begin(); it != m_clients.end(); ++it)
|
||||
{
|
||||
if (it->context.get() == &context)
|
||||
{
|
||||
m_clients.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
42
src/client_manager.hh
Normal file
42
src/client_manager.hh
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef client_manager_hh_INCLUDED
|
||||
#define client_manager_hh_INCLUDED
|
||||
|
||||
#include "context.hh"
|
||||
#include "input_handler.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
struct Client
|
||||
{
|
||||
std::unique_ptr<UserInterface> ui;
|
||||
std::unique_ptr<InputHandler> input_handler;
|
||||
std::unique_ptr<Context> 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&&) = default;
|
||||
};
|
||||
|
||||
struct client_removed{};
|
||||
|
||||
class ClientManager : public Singleton<ClientManager>
|
||||
{
|
||||
public:
|
||||
void add_client(Client&& client);
|
||||
void remove_client_by_context(Context& context);
|
||||
|
||||
bool empty() const { return m_clients.empty(); }
|
||||
size_t count() const { return m_clients.size(); }
|
||||
private:
|
||||
std::vector<Client> m_clients;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // client_manager_hh_INCLUDED
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
#include "shell_manager.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "color_registry.hh"
|
||||
#include "client_manager.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -334,7 +335,7 @@ void quit(const CommandParameters& params, Context& context)
|
|||
if (params.size() != 0)
|
||||
throw wrong_argument_count();
|
||||
|
||||
if (not force)
|
||||
if (not force and ClientManager::instance().count() == 1)
|
||||
{
|
||||
std::vector<String> names;
|
||||
for (auto& buffer : BufferManager::instance())
|
||||
|
@ -355,7 +356,8 @@ void quit(const CommandParameters& params, Context& context)
|
|||
throw runtime_error(message);
|
||||
}
|
||||
}
|
||||
quit_requested = true;
|
||||
ClientManager::instance().remove_client_by_context(context);
|
||||
throw client_removed{};
|
||||
}
|
||||
|
||||
template<bool force>
|
||||
|
|
54
src/main.cc
54
src/main.cc
|
@ -21,6 +21,7 @@
|
|||
#include "file.hh"
|
||||
#include "color_registry.hh"
|
||||
#include "remote.hh"
|
||||
#include "client_manager.hh"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
|
@ -38,8 +39,6 @@ using namespace std::placeholders;
|
|||
namespace Kakoune
|
||||
{
|
||||
|
||||
bool quit_requested = false;
|
||||
|
||||
template<InsertMode mode>
|
||||
void do_insert(Context& context)
|
||||
{
|
||||
|
@ -494,21 +493,7 @@ void register_registers()
|
|||
}
|
||||
}
|
||||
|
||||
struct Client
|
||||
{
|
||||
std::unique_ptr<UserInterface> ui;
|
||||
std::unique_ptr<InputHandler> input_handler;
|
||||
std::unique_ptr<Context> context;
|
||||
|
||||
Client(UserInterface* ui, Window& window)
|
||||
: ui(ui),
|
||||
input_handler(new InputHandler{}),
|
||||
context(new Context(*input_handler, window, *ui)) {}
|
||||
|
||||
Client() {}
|
||||
};
|
||||
|
||||
Client create_local_client(const String& file)
|
||||
void create_local_client(const String& file)
|
||||
{
|
||||
Buffer* buffer = nullptr;
|
||||
UserInterface* ui = new NCursesUI{};
|
||||
|
@ -537,14 +522,16 @@ Client create_local_client(const String& file)
|
|||
{
|
||||
ui->print_status(error.description(), -1);
|
||||
}
|
||||
catch (Kakoune::client_removed&)
|
||||
{
|
||||
EventManager::instance().unwatch(0);
|
||||
}
|
||||
});
|
||||
|
||||
context->draw_ifn();
|
||||
return client;
|
||||
ClientManager::instance().add_client(std::move(client));
|
||||
}
|
||||
|
||||
std::vector<Client> clients;
|
||||
|
||||
struct Server
|
||||
{
|
||||
Server()
|
||||
|
@ -583,8 +570,13 @@ struct Server
|
|||
{
|
||||
ui->print_status(error.description(), -1);
|
||||
}
|
||||
catch (Kakoune::client_removed&)
|
||||
{
|
||||
EventManager::instance().unwatch(sock);
|
||||
close(sock);
|
||||
}
|
||||
});
|
||||
clients.push_back(std::move(client));
|
||||
ClientManager::instance().add_client(std::move(client));
|
||||
};
|
||||
EventManager::instance().watch(m_listen_sock, accepter);
|
||||
}
|
||||
|
@ -647,9 +639,16 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (argc == 3 and String("-c") == argv[1])
|
||||
{
|
||||
std::unique_ptr<RemoteClient> client(connect_to(argv[2]));
|
||||
while(not quit_requested)
|
||||
event_manager.handle_next_events();
|
||||
try
|
||||
{
|
||||
std::unique_ptr<RemoteClient> client(connect_to(argv[2]));
|
||||
while (true)
|
||||
event_manager.handle_next_events();
|
||||
}
|
||||
catch (peer_disconnected&)
|
||||
{
|
||||
puts("disconnected");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -662,6 +661,7 @@ int main(int argc, char* argv[])
|
|||
HighlighterRegistry highlighter_registry;
|
||||
FilterRegistry filter_registry;
|
||||
ColorRegistry color_registry;
|
||||
ClientManager client_manager;
|
||||
|
||||
run_unit_tests();
|
||||
|
||||
|
@ -677,7 +677,6 @@ int main(int argc, char* argv[])
|
|||
|
||||
Server server;
|
||||
|
||||
Client local_client;
|
||||
try
|
||||
{
|
||||
Context initialisation_context;
|
||||
|
@ -688,9 +687,10 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
write_debug("error while parsing kakrc: " + error.description());
|
||||
}
|
||||
local_client = create_local_client(argc > 1 ? argv[1] : "");
|
||||
|
||||
while(not quit_requested)
|
||||
create_local_client(argc > 1 ? argv[1] : "");
|
||||
|
||||
while (not client_manager.empty())
|
||||
event_manager.handle_next_events();
|
||||
}
|
||||
catch (Kakoune::exception& error)
|
||||
|
|
|
@ -108,6 +108,8 @@ template<>
|
|||
String read<String>(int socket)
|
||||
{
|
||||
ByteCount length = read<ByteCount>(socket);
|
||||
if (length == 0)
|
||||
return String{};
|
||||
char buffer[2048];
|
||||
assert(length < 2048);
|
||||
read(socket, buffer, (int)length);
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
namespace Kakoune
|
||||
{
|
||||
|
||||
struct peer_disconnected : public runtime_error
|
||||
{
|
||||
peer_disconnected() : runtime_error("peer disconnected") {}
|
||||
};
|
||||
struct peer_disconnected {};
|
||||
|
||||
class RemoteUI : public UserInterface
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user