// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include #include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/result.h" #include "core/hle/service/service.h" namespace Kernel { class ClientPort; class ClientSession; class KernelCore; class ServerPort; class SessionRequestHandler; } // namespace Kernel namespace Service::SM { class Controller; /// Interface to "sm:" service class SM final : public ServiceFramework { public: explicit SM(std::shared_ptr service_manager, Kernel::KernelCore& kernel); ~SM() override; private: void Initialize(Kernel::HLERequestContext& ctx); void GetService(Kernel::HLERequestContext& ctx); void RegisterService(Kernel::HLERequestContext& ctx); void UnregisterService(Kernel::HLERequestContext& ctx); std::shared_ptr service_manager; Kernel::KernelCore& kernel; }; class ServiceManager { public: static void InstallInterfaces(std::shared_ptr self, Kernel::KernelCore& kernel); ServiceManager(); ~ServiceManager(); ResultVal> RegisterService(std::string name, unsigned int max_sessions); ResultCode UnregisterService(const std::string& name); ResultVal> GetServicePort(const std::string& name); ResultVal> ConnectToService(const std::string& name); template std::shared_ptr GetService(const std::string& service_name) const { static_assert(std::is_base_of_v, "Not a base of ServiceFrameworkBase"); auto service = registered_services.find(service_name); if (service == registered_services.end()) { LOG_DEBUG(Service, "Can't find service: {}", service_name); return nullptr; } auto port = service->second->GetServerPort(); if (port == nullptr) { return nullptr; } return std::static_pointer_cast(port->GetHLEHandler()); } void InvokeControlRequest(Kernel::HLERequestContext& context); private: std::weak_ptr sm_interface; std::unique_ptr controller_interface; /// Map of registered services, retrieved using GetServicePort or ConnectToService. std::unordered_map> registered_services; }; } // namespace Service::SM