Skip to content

Commit

Permalink
AsyncUserInput: add interface UserInputHandler
Browse files Browse the repository at this point in the history
To remove global variables eventually.
  • Loading branch information
MaxKellermann committed Sep 5, 2024
1 parent 321c391 commit 930b846
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 60 deletions.
35 changes: 26 additions & 9 deletions src/AsyncUserInput.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@

#include "config.h"
#include "AsyncUserInput.hxx"
#include "UserInputHandler.hxx"
#include "Command.hxx"
#include "Bindings.hxx"
#include "GlobalBindings.hxx"
#include "ncmpc.hxx"
#include "ui/Point.hxx"

// TODO remove this kludge
static AsyncUserInput *global_async_user_input;

static constexpr bool
ignore_key(int key) noexcept
{
Expand Down Expand Up @@ -41,7 +45,10 @@ AsyncUserInput::OnSocketReady(unsigned) noexcept
#endif

begin_input_event();
do_mouse_event({event.x, event.y}, event.bstate);

if (!handler.OnMouse({event.x, event.y}, event.bstate))
return;

end_input_event();

return;
Expand All @@ -54,28 +61,38 @@ AsyncUserInput::OnSocketReady(unsigned) noexcept

begin_input_event();

if (!do_input_event(stdin_event.GetEventLoop(), cmd))
if (!handler.OnCommand(cmd))
return;

end_input_event();
return;
}

AsyncUserInput::AsyncUserInput(EventLoop &event_loop, WINDOW &_w) noexcept
AsyncUserInput::AsyncUserInput(EventLoop &event_loop, WINDOW &_w,
UserInputHandler &_handler) noexcept
:stdin_event(event_loop, BIND_THIS_METHOD(OnSocketReady),
FileDescriptor{STDIN_FILENO}),
w(_w)
w(_w),
handler(_handler)
{
stdin_event.ScheduleRead();

// TODO remove this kludge
global_async_user_input = this;
}

void
keyboard_unread(EventLoop &event_loop, int key) noexcept
inline void
AsyncUserInput::InjectKey(int key) noexcept
{
if (ignore_key(key))
return;

Command cmd = translate_key(key);
if (cmd != Command::NONE)
do_input_event(event_loop, cmd);
if (Command cmd = translate_key(key); cmd != Command::NONE)
handler.OnCommand(cmd);
}

void
keyboard_unread(int key) noexcept
{
global_async_user_input->InjectKey(key);
}
17 changes: 11 additions & 6 deletions src/AsyncUserInput.hxx
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project

#ifndef ASYNC_USER_INPUT_HXX
#define ASYNC_USER_INPUT_HXX
#pragma once

#include "event/PipeEvent.hxx"

#include <curses.h>

class UserInputHandler;

class AsyncUserInput {
PipeEvent stdin_event;

WINDOW &w;

UserInputHandler &handler;

public:
AsyncUserInput(EventLoop &event_loop, WINDOW &_w) noexcept;
AsyncUserInput(EventLoop &event_loop, WINDOW &_w,
UserInputHandler &_handler) noexcept;

// TODO remove this kludge
void InjectKey(int key) noexcept;

private:
void OnSocketReady(unsigned flags) noexcept;
};

void
keyboard_unread(EventLoop &event_loop, int key) noexcept;

#endif
keyboard_unread(int key) noexcept;
4 changes: 2 additions & 2 deletions src/Instance.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ Instance::Instance()
#endif
screen_manager(event_loop),
#ifdef ENABLE_LIRC
lirc_input(event_loop),
lirc_input(event_loop, *this),
#endif
user_input(event_loop, *screen_manager.main_window.w)
user_input(event_loop, *screen_manager.main_window.w, *this)
{
screen_manager.Init(&client);

Expand Down
12 changes: 8 additions & 4 deletions src/Instance.hxx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project

#ifndef NCMPC_INSTANCE_HXX
#define NCMPC_INSTANCE_HXX
#pragma once

#include "config.h"
#include "AsyncUserInput.hxx"
#include "UserInputHandler.hxx"
#include "mpdclient.hxx"
#include "DelayedSeek.hxx"
#include "screen.hxx"
Expand All @@ -20,7 +20,7 @@
/**
* A singleton holding global instance variables.
*/
class Instance {
class Instance final : UserInputHandler {
EventLoop event_loop;

struct mpdclient client;
Expand Down Expand Up @@ -117,6 +117,10 @@ private:
#ifndef NCMPC_MINI
void OnCheckKeyBindings() noexcept;
#endif
};

// virtual methods from AsyncUserInputHandler
bool OnCommand(Command cmd) noexcept override;
#ifdef HAVE_GETMOUSE
bool OnMouse(Point p, mmask_t bstate) noexcept override;
#endif
};
16 changes: 8 additions & 8 deletions src/Main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -206,39 +206,39 @@ void end_input_event() noexcept
}

bool
do_input_event(EventLoop &event_loop, Command cmd) noexcept
Instance::OnCommand(Command cmd) noexcept
{
if (cmd == Command::QUIT) {
event_loop.Break();
return false;
}

try {
screen->OnCommand(global_instance->GetClient(),
global_instance->GetSeek(), cmd);
screen_manager.OnCommand(GetClient(), GetSeek(), cmd);
} catch (...) {
screen_status_error(std::current_exception());
return true;
}

if (cmd == Command::VOLUME_UP || cmd == Command::VOLUME_DOWN)
/* make sure we don't update the volume yet */
global_instance->DisableUpdateTimer();
DisableUpdateTimer();

return true;
}

#ifdef HAVE_GETMOUSE

void
do_mouse_event(Point p, mmask_t bstate) noexcept
bool
Instance::OnMouse(Point p, mmask_t bstate) noexcept
{
try {
screen->OnMouse(global_instance->GetClient(),
global_instance->GetSeek(), p, bstate);
screen_manager.OnMouse(GetClient(), GetSeek(), p, bstate);
} catch (...) {
screen_status_error(std::current_exception());
}

return true;
}

#endif
Expand Down
20 changes: 20 additions & 0 deletions src/UserInputHandler.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project

#pragma once

#include "config.h"

#include <curses.h>

enum class Command : unsigned;
struct Point;

class UserInputHandler {
public:
virtual bool OnCommand(Command cmd) noexcept = 0;

#ifdef HAVE_GETMOUSE
virtual bool OnMouse(Point p, mmask_t bstate) noexcept = 0;
#endif
};
9 changes: 6 additions & 3 deletions src/lirc.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright The Music Player Daemon Project

#include "lirc.hxx"
#include "UserInputHandler.hxx"
#include "ncmpc.hxx"
#include "Command.hxx"
#include "config.h"
Expand All @@ -18,16 +19,18 @@ LircInput::OnSocketReady(unsigned) noexcept
if (lirc_nextcode(&code) == 0) {
while (lirc_code2char(lc, code, &txt) == 0 && txt != nullptr) {
const auto cmd = get_key_command_from_name(txt);
if (!do_input_event(GetEventLoop(), cmd))
if (!handler.OnCommand(cmd))
return;
}
}

end_input_event();
}

LircInput::LircInput(EventLoop &_event_loop) noexcept
:event(_event_loop, BIND_THIS_METHOD(OnSocketReady))
LircInput::LircInput(EventLoop &_event_loop,
UserInputHandler &_handler) noexcept
:handler(_handler),
event(_event_loop, BIND_THIS_METHOD(OnSocketReady))
{
int lirc_socket = 0;

Expand Down
12 changes: 7 additions & 5 deletions src/lirc.hxx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project

#ifndef LIRC_H
#define LIRC_H
#pragma once

#include "event/SocketEvent.hxx"

class UserInputHandler;

class LircInput final {
struct lirc_config *lc = nullptr;

UserInputHandler &handler;

SocketEvent event;

public:
explicit LircInput(EventLoop &event_loop) noexcept;
LircInput(EventLoop &event_loop,
UserInputHandler &_handler) noexcept;
~LircInput();

auto &GetEventLoop() const noexcept {
Expand All @@ -22,5 +26,3 @@ public:
private:
void OnSocketReady(unsigned flags) noexcept;
};

#endif
23 changes: 1 addition & 22 deletions src/ncmpc.hxx
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project

#ifndef NCMPC_H
#define NCMPC_H
#pragma once

#ifdef HAVE_GETMOUSE
#include <curses.h>
#endif

enum class Command : unsigned;
struct Point;
class EventLoop;
class ScreenManager;
extern ScreenManager *screen;

Expand All @@ -19,16 +11,3 @@ begin_input_event() noexcept;

void
end_input_event() noexcept;

/**
* @return false if the application shall quit
*/
bool
do_input_event(EventLoop &event_loop, Command cmd) noexcept;

#ifdef HAVE_GETMOUSE
void
do_mouse_event(Point p, mmask_t bstate) noexcept;
#endif

#endif /* NCMPC_H */
2 changes: 1 addition & 1 deletion src/screen_find.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,5 @@ screen_jump(ScreenManager &screen, ListWindow &lw,
screen.findbuf = search_str;

/* ncmpc should get the command */
keyboard_unread(screen.GetEventLoop(), key);
keyboard_unread(key);
}

0 comments on commit 930b846

Please sign in to comment.