/* * Copyright (c) 2019-2020 Atmosphère-NX * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include #include #include #include namespace ams::pgl { namespace impl { class EventObserverInterface { NON_COPYABLE(EventObserverInterface); NON_MOVEABLE(EventObserverInterface); public: constexpr EventObserverInterface() = default; virtual ~EventObserverInterface() { /* ... */ } virtual Result GetSystemEvent(os::SystemEventType *out) = 0; virtual Result GetProcessEventInfo(pm::ProcessEventInfo *out) = 0; }; class EventObserverByCmif final : public EventObserverInterface { NON_COPYABLE(EventObserverByCmif); NON_MOVEABLE(EventObserverByCmif); private: ams::sf::SharedPointer m_cmif_interface; public: explicit EventObserverByCmif(ams::sf::SharedPointer intf) : m_cmif_interface(intf) { /* ... */ } public: virtual Result GetSystemEvent(os::SystemEventType *out) override { ams::sf::CopyHandle handle; R_TRY(m_cmif_interface->GetProcessEventHandle(std::addressof(handle))); os::AttachSystemEvent(out, handle.GetValue(), true, svc::InvalidHandle, false, os::EventClearMode_AutoClear); return ResultSuccess(); } virtual Result GetProcessEventInfo(pm::ProcessEventInfo *out) override { return m_cmif_interface->GetProcessEventInfo(out); } }; template requires tipc::IsIEventObserver class EventObserverByTipc final : public EventObserverInterface { NON_COPYABLE(EventObserverByTipc); NON_MOVEABLE(EventObserverByTipc); private: T m_tipc_interface; public: template explicit EventObserverByTipc(Args &&... args) : m_tipc_interface(std::forward(args)...) { /* ... */ } public: virtual Result GetSystemEvent(os::SystemEventType *out) override { ams::tipc::CopyHandle handle; R_TRY(m_tipc_interface.GetProcessEventHandle(std::addressof(handle))); os::AttachSystemEvent(out, handle.GetValue(), true, svc::InvalidHandle, false, os::EventClearMode_AutoClear); return ResultSuccess(); } virtual Result GetProcessEventInfo(pm::ProcessEventInfo *out) override { return m_tipc_interface.GetProcessEventInfo(ams::tipc::Out(out)); } }; } class EventObserver { NON_COPYABLE(EventObserver); private: struct Deleter { void operator()(impl::EventObserverInterface *); }; public: using UniquePtr = std::unique_ptr; private: UniquePtr m_impl; public: EventObserver() { /* ... */ } explicit EventObserver(UniquePtr impl) : m_impl(std::move(impl)) { /* ... */ } EventObserver(EventObserver &&rhs) { m_impl = std::move(rhs.m_impl); } EventObserver &operator=(EventObserver &&rhs) { EventObserver(std::move(rhs)).Swap(*this); return *this; } void Swap(EventObserver &rhs) { std::swap(m_impl, rhs.m_impl); } public: Result GetSystemEvent(os::SystemEventType *out) { return m_impl->GetSystemEvent(out); } Result GetProcessEventInfo(pm::ProcessEventInfo *out) { return m_impl->GetProcessEventInfo(out); } }; }