diff options
author | bunnei <bunneidev@gmail.com> | 2015-07-12 05:56:59 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2015-07-12 05:56:59 +0200 |
commit | f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80 (patch) | |
tree | 8756cd27489dcb424103e443836b6ea8dba3fccd /src/core/hle/applets/applet.cpp | |
parent | Merge pull request #912 from yuriks/process-loading (diff) | |
parent | Applets: Reworked how the Applet update event is handled. (diff) | |
download | yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.tar yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.tar.gz yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.tar.bz2 yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.tar.lz yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.tar.xz yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.tar.zst yuzu-f4e1d8ea36fc3f8309234b8a4a8c9f659b171c80.zip |
Diffstat (limited to 'src/core/hle/applets/applet.cpp')
-rw-r--r-- | src/core/hle/applets/applet.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp new file mode 100644 index 000000000..4dcce729a --- /dev/null +++ b/src/core/hle/applets/applet.cpp @@ -0,0 +1,94 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/assert.h" +#include "common/logging/log.h" + +#include "core/core_timing.h" +#include "core/hle/applets/applet.h" +#include "core/hle/applets/swkbd.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// Specializes std::hash for AppletId, so that we can use it in std::unordered_map. +// Workaround for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 +namespace std { + template <> + struct hash<Service::APT::AppletId> { + typedef Service::APT::AppletId argument_type; + typedef std::size_t result_type; + + result_type operator()(const argument_type& id_code) const { + typedef std::underlying_type<argument_type>::type Type; + return std::hash<Type>()(static_cast<Type>(id_code)); + } + }; +} + +namespace HLE { +namespace Applets { + +static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets; +static u32 applet_update_event = -1; ///< The CoreTiming event identifier for the Applet update callback. +/// The interval at which the Applet update callback will be called, 16.6ms +static const u64 applet_update_interval_us = 16666; + +ResultCode Applet::Create(Service::APT::AppletId id) { + switch (id) { + case Service::APT::AppletId::SoftwareKeyboard1: + case Service::APT::AppletId::SoftwareKeyboard2: + applets[id] = std::make_shared<SoftwareKeyboard>(id); + break; + default: + // TODO(Subv): Find the right error code + return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent); + } + + return RESULT_SUCCESS; +} + +std::shared_ptr<Applet> Applet::Get(Service::APT::AppletId id) { + auto itr = applets.find(id); + if (itr != applets.end()) + return itr->second; + return nullptr; +} + +/// Handles updating the current Applet every time it's called. +static void AppletUpdateEvent(u64 applet_id, int cycles_late) { + Service::APT::AppletId id = static_cast<Service::APT::AppletId>(applet_id); + std::shared_ptr<Applet> applet = Applet::Get(id); + ASSERT_MSG(applet != nullptr, "Applet doesn't exist! applet_id=%08X", id); + + applet->Update(); + + // If the applet is still running after the last update, reschedule the event + if (applet->IsRunning()) { + CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us) - cycles_late, + applet_update_event, applet_id); + } else { + // Otherwise the applet has terminated, in which case we should clean it up + applets[id] = nullptr; + } +} + +ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) { + ResultCode result = StartImpl(parameter); + if (result.IsError()) + return result; + // Schedule the update event + CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id)); + return result; +} + +void Init() { + // Register the applet update callback + applet_update_event = CoreTiming::RegisterEvent("HLE Applet Update Event", AppletUpdateEvent); +} + +void Shutdown() { +} + +} +} // namespace |