add a poll based EventManager and use it for ncurse client update
This commit is contained in:
parent
d5dc5dff7f
commit
ab47b72dc8
45
src/event_manager.cc
Normal file
45
src/event_manager.cc
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include "event_manager.hh"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
void EventManager::watch(int fd, EventHandler handler)
|
||||||
|
{
|
||||||
|
auto event = std::find_if(m_events.begin(), m_events.end(),
|
||||||
|
[&](const pollfd& pfd) { return pfd.fd == fd; });
|
||||||
|
if (event != m_events.end())
|
||||||
|
throw runtime_error("fd already watched");
|
||||||
|
|
||||||
|
m_events.push_back(pollfd{ fd, POLLIN | POLLPRI, 0 });
|
||||||
|
m_handlers.push_back(std::move(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventManager::unwatch(int fd)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_events.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_events[i].fd == fd)
|
||||||
|
{
|
||||||
|
m_events.erase(m_events.begin() + i);
|
||||||
|
m_handlers.erase(m_handlers.begin() + i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventManager::handle_next_events()
|
||||||
|
{
|
||||||
|
int res = poll(m_events.data(), m_events.size(), -1);
|
||||||
|
if (res > 0)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_events.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_events[i].revents & POLLIN)
|
||||||
|
m_handlers[i](m_events[i].fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
src/event_manager.hh
Normal file
29
src/event_manager.hh
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef event_manager_hh_INCLUDED
|
||||||
|
#define event_manager_hh_INCLUDED
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
#include "utils.hh"
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
using EventHandler = std::function<void (int fd)>;
|
||||||
|
|
||||||
|
class EventManager : public Singleton<EventManager>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void watch(int fd, EventHandler handler);
|
||||||
|
void unwatch(int fd);
|
||||||
|
|
||||||
|
void handle_next_events();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<pollfd> m_events;
|
||||||
|
std::vector<EventHandler> m_handlers;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // event_manager_hh_INCLUDED
|
||||||
|
|
55
src/main.cc
55
src/main.cc
|
@ -14,6 +14,7 @@
|
||||||
#include "filter_registry.hh"
|
#include "filter_registry.hh"
|
||||||
#include "hook_manager.hh"
|
#include "hook_manager.hh"
|
||||||
#include "option_manager.hh"
|
#include "option_manager.hh"
|
||||||
|
#include "event_manager.hh"
|
||||||
#include "context.hh"
|
#include "context.hh"
|
||||||
#include "ncurses.hh"
|
#include "ncurses.hh"
|
||||||
#include "regex.hh"
|
#include "regex.hh"
|
||||||
|
@ -442,6 +443,32 @@ std::unordered_map<Key, std::function<void (Context& context)>> keymap =
|
||||||
|
|
||||||
void run_unit_tests();
|
void run_unit_tests();
|
||||||
|
|
||||||
|
void manage_next_keypress(Context& context)
|
||||||
|
{
|
||||||
|
static int count = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Key key = context.client().get_key();
|
||||||
|
if (key.modifiers == Key::Modifiers::None and isdigit(key.key))
|
||||||
|
count = count * 10 + key.key - '0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto it = keymap.find(key);
|
||||||
|
if (it != keymap.end())
|
||||||
|
{
|
||||||
|
context.numeric_param(count);
|
||||||
|
it->second(context);
|
||||||
|
context.draw_ifn();
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Kakoune::runtime_error& error)
|
||||||
|
{
|
||||||
|
context.print_status(error.description());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
GlobalOptionManager option_manager;
|
GlobalOptionManager option_manager;
|
||||||
|
@ -452,6 +479,7 @@ int main(int argc, char* argv[])
|
||||||
RegisterManager register_manager;
|
RegisterManager register_manager;
|
||||||
HighlighterRegistry highlighter_registry;
|
HighlighterRegistry highlighter_registry;
|
||||||
FilterRegistry filter_registry;
|
FilterRegistry filter_registry;
|
||||||
|
EventManager event_manager;
|
||||||
|
|
||||||
run_unit_tests();
|
run_unit_tests();
|
||||||
|
|
||||||
|
@ -507,32 +535,11 @@ int main(int argc, char* argv[])
|
||||||
context.change_editor(*buffer->get_or_create_window());
|
context.change_editor(*buffer->get_or_create_window());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event_manager.watch(0, [&](int) { manage_next_keypress(context); });
|
||||||
|
|
||||||
context.draw_ifn();
|
context.draw_ifn();
|
||||||
int count = 0;
|
|
||||||
while(not quit_requested)
|
while(not quit_requested)
|
||||||
{
|
event_manager.handle_next_events();
|
||||||
try
|
|
||||||
{
|
|
||||||
Key key = context.client().get_key();
|
|
||||||
if (key.modifiers == Key::Modifiers::None and isdigit(key.key))
|
|
||||||
count = count * 10 + key.key - '0';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto it = keymap.find(key);
|
|
||||||
if (it != keymap.end())
|
|
||||||
{
|
|
||||||
context.numeric_param(count);
|
|
||||||
it->second(context);
|
|
||||||
context.draw_ifn();
|
|
||||||
}
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Kakoune::runtime_error& error)
|
|
||||||
{
|
|
||||||
context.print_status(error.description());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Kakoune::exception& error)
|
catch (Kakoune::exception& error)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user