From 5ce7dd300317d720c8c43219c0a595239095d9cf Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Tue, 5 Nov 2024 23:56:44 -0500 Subject: [PATCH] external event loop --- CMakeLists.txt | 2 +- src/lib/fcitx-utils/CMakeLists.txt | 20 ++-- src/lib/fcitx-utils/event_impl.h | 29 ++++++ src/lib/fcitx-utils/event_stub.cpp | 154 +++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 src/lib/fcitx-utils/event_impl.h create mode 100644 src/lib/fcitx-utils/event_stub.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index aa90bad4a..a57c39a2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,7 @@ if (NOT TARGET Systemd::Systemd) if (NOT LIBUV_TARGET) if (NOT (TARGET PkgConfig::LibUV)) - pkg_check_modules(LibUV REQUIRED IMPORTED_TARGET "libuv") + pkg_check_modules(LibUV IMPORTED_TARGET "libuv") endif() set(LIBUV_TARGET PkgConfig::LibUV) endif() diff --git a/src/lib/fcitx-utils/CMakeLists.txt b/src/lib/fcitx-utils/CMakeLists.txt index dd67e07db..15ad8c8a4 100644 --- a/src/lib/fcitx-utils/CMakeLists.txt +++ b/src/lib/fcitx-utils/CMakeLists.txt @@ -27,14 +27,16 @@ if (ENABLE_DBUS) endif() endif() -if (NOT TARGET Systemd::Systemd) +if (TARGET Systemd::Systemd) set(FCITX_UTILS_SOURCES ${FCITX_UTILS_SOURCES} - event_libuv.cpp) -else() + event_sdevent.cpp) +elseif (TARGET ${LIBUV_TARGET}) set(FCITX_UTILS_SOURCES ${FCITX_UTILS_SOURCES} - event_sdevent.cpp) + event_libuv.cpp) +else() + list(APPEND FCITX_UTILS_SOURCES event_stub.cpp) endif() set(FCITX_UTILS_SOURCES @@ -104,6 +106,10 @@ set(FCITX_UTILS_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/fcitxutils_export.h ) +if (NOT TARGET Systemd::Systemd AND NOT TARGET ${LIBUV_TARGET}) + list(APPEND FCITX_UTILS_HEADERS event_impl.h) +endif() + set(FCITX_UTILS_DBUS_HEADERS dbus/message.h dbus/objectvtable.h @@ -134,13 +140,13 @@ if(LIBKVM_FOUND) target_link_libraries(Fcitx5Utils PRIVATE LibKVM::LibKVM) endif() -if (NOT TARGET Systemd::Systemd) +if (TARGET Systemd::Systemd) + target_link_libraries(Fcitx5Utils PRIVATE Systemd::Systemd) +elseif (TARGET ${LIBUV_TARGET}) target_link_libraries(Fcitx5Utils PRIVATE ${LIBUV_TARGET}) if (ENABLE_DBUS) target_link_libraries(Fcitx5Utils PRIVATE PkgConfig::DBus) endif() -else() - target_link_libraries(Fcitx5Utils PRIVATE Systemd::Systemd) endif() configure_file(Fcitx5Utils.pc.in ${CMAKE_CURRENT_BINARY_DIR}/Fcitx5Utils.pc @ONLY) diff --git a/src/lib/fcitx-utils/event_impl.h b/src/lib/fcitx-utils/event_impl.h new file mode 100644 index 000000000..ce86ddc01 --- /dev/null +++ b/src/lib/fcitx-utils/event_impl.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2024 Qijia Liu + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + */ +#ifndef _FCITX_UTILS_EVENT_IMPL_H_ +#define _FCITX_UTILS_EVENT_IMPL_H_ + +#include +namespace fcitx { +class FCITXUTILS_EXPORT EventLoopImpl { +public: + EventLoopImpl() = default; + virtual ~EventLoopImpl() = default; + virtual std::unique_ptr + addIOEvent(int fd, IOEventFlags flags, IOCallback callback); + virtual std::unique_ptr + addTimeEvent(clockid_t clock, uint64_t usec, uint64_t accuracy, + TimeCallback callback); + virtual std::unique_ptr addExitEvent(EventCallback callback); + virtual std::unique_ptr addDeferEvent(EventCallback callback); + virtual std::unique_ptr addPostEvent(EventCallback callback); +}; + +FCITXUTILS_EXPORT void setEventLoopImpl(std::unique_ptr factory); +} // namespace fcitx + +#endif // _FCITX_UTILS_EVENT_H_ diff --git a/src/lib/fcitx-utils/event_stub.cpp b/src/lib/fcitx-utils/event_stub.cpp new file mode 100644 index 000000000..84e828700 --- /dev/null +++ b/src/lib/fcitx-utils/event_stub.cpp @@ -0,0 +1,154 @@ +/* + * SPDX-FileCopyrightText: 2024 Qijia Liu + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + */ +#include "fcitx-utils/event.h" +#include "fcitx-utils/log.h" +#include "event_impl.h" + +namespace fcitx { + +template +struct StubEventSourceBase : public Interface { +public: + ~StubEventSourceBase() override {} + + bool isEnabled() const override { return false; } + + void setEnabled(bool enabled) override { FCITX_UNUSED(enabled); } + + bool isOneShot() const override { return false; } + + void setOneShot() override {} +}; + +struct StubEventSource : public StubEventSourceBase { + StubEventSource() {} +}; + +struct StubEventSourceIO : public StubEventSourceBase { + StubEventSourceIO() {} + + int fd() const override { return 0; } + + void setFd(int fd) override { FCITX_UNUSED(fd); } + + IOEventFlags events() const override { return IOEventFlag::In; } + + void setEvents(IOEventFlags flags) override { FCITX_UNUSED(flags); } + + IOEventFlags revents() const override { return IOEventFlag::In; } +}; + +struct StubEventSourceTime : public StubEventSourceBase { + StubEventSourceTime() {} + + uint64_t time() const override { return 0; } + + void setTime(uint64_t time) override { FCITX_UNUSED(time); } + + uint64_t accuracy() const override { return 0; } + + void setAccuracy(uint64_t time) override { FCITX_UNUSED(time); } + + clockid_t clock() const override { return 0; } +}; + +static std::shared_ptr eventLoopImpl = nullptr; + +void setEventLoopImpl(std::unique_ptr impl) { + eventLoopImpl = std::move(impl); +} + +class EventLoopPrivate { +public: + EventLoopPrivate() { + if (!eventLoopImpl) { + FCITX_WARN() << "Using stub event loop implementation."; + eventLoopImpl = std::make_shared(); + } + impl_ = eventLoopImpl; + } + ~EventLoopPrivate() {} + + std::shared_ptr impl_; +}; + +EventLoop::EventLoop() : d_ptr(std::make_unique()) {} + +EventLoop::~EventLoop() = default; + +const char *EventLoop::impl() { return "stub"; } + +void *EventLoop::nativeHandle() { return nullptr; } + +bool EventLoop::exec() { return true; } + +void EventLoop::exit() {} + +std::unique_ptr EventLoop::addIOEvent(int fd, IOEventFlags flags, + IOCallback callback) { + FCITX_D(); + return d->impl_->addIOEvent(fd, flags, std::move(callback)); +} + +std::unique_ptr +EventLoop::addTimeEvent(clockid_t clock, uint64_t usec, uint64_t accuracy, + TimeCallback callback) { + FCITX_D(); + return d->impl_->addTimeEvent(clock, usec, accuracy, std::move(callback)); +} + +std::unique_ptr EventLoop::addExitEvent(EventCallback callback) { + FCITX_D(); + return d->impl_->addExitEvent(std::move(callback)); +} + +std::unique_ptr EventLoop::addDeferEvent(EventCallback callback) { + FCITX_D(); + return d->impl_->addDeferEvent(std::move(callback)); +} + +std::unique_ptr EventLoop::addPostEvent(EventCallback callback) { + FCITX_D(); + return d->impl_->addPostEvent(std::move(callback)); +} + +std::unique_ptr +EventLoopImpl::addIOEvent(int fd, IOEventFlags flags, IOCallback callback) { + FCITX_UNUSED(fd); + FCITX_UNUSED(flags); + FCITX_UNUSED(callback); + return std::make_unique(); +} + +std::unique_ptr +EventLoopImpl::addTimeEvent(clockid_t clock, uint64_t usec, uint64_t accuracy, + TimeCallback callback) { + FCITX_UNUSED(clock); + FCITX_UNUSED(usec); + FCITX_UNUSED(accuracy); + FCITX_UNUSED(callback); + return std::make_unique(); +} + +std::unique_ptr +EventLoopImpl::addExitEvent(EventCallback callback) { + FCITX_UNUSED(callback); + return std::make_unique(); +} + +std::unique_ptr +EventLoopImpl::addDeferEvent(EventCallback callback) { + FCITX_UNUSED(callback); + return std::make_unique(); +} + +std::unique_ptr +EventLoopImpl::addPostEvent(EventCallback callback) { + FCITX_UNUSED(callback); + return std::make_unique(); +} +} // namespace fcitx