mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-12 23:16:40 +00:00
sprofile: implement OpenProfileUpdateObserver
This commit is contained in:
parent
bd240b23d8
commit
75d5e2aef0
11 changed files with 396 additions and 3 deletions
|
@ -86,6 +86,9 @@ namespace ams::sprofile::srv {
|
||||||
/* Create the profile manager. */
|
/* Create the profile manager. */
|
||||||
util::ConstructAt(g_profile_manager, SaveDataInfo);
|
util::ConstructAt(g_profile_manager, SaveDataInfo);
|
||||||
|
|
||||||
|
/* Process profile manager savedata. */
|
||||||
|
util::GetReference(g_profile_manager).InitializeSaveData();
|
||||||
|
|
||||||
/* Create the service objects. */
|
/* Create the service objects. */
|
||||||
util::ConstructAt(g_bg_service_object, std::addressof(g_sf_memory_resource), util::GetPointer(g_profile_manager));
|
util::ConstructAt(g_bg_service_object, std::addressof(g_sf_memory_resource), util::GetPointer(g_profile_manager));
|
||||||
util::ConstructAt(g_sp_service_object, std::addressof(g_sf_memory_resource), util::GetPointer(g_profile_manager));
|
util::ConstructAt(g_sp_service_object, std::addressof(g_sf_memory_resource), util::GetPointer(g_profile_manager));
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_profile_manager.hpp"
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
Result WriteFile(const char *path, const void *src, size_t size) {
|
||||||
|
/* Create the file. */
|
||||||
|
R_TRY_CATCH(fs::CreateFile(path, size)) {
|
||||||
|
R_CATCH(fs::ResultPathAlreadyExists) { /* It's okay if the file already exists. */ }
|
||||||
|
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||||
|
|
||||||
|
/* Open the file. */
|
||||||
|
fs::FileHandle file;
|
||||||
|
R_ABORT_UNLESS(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Write));
|
||||||
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
/* Set the file size. */
|
||||||
|
R_ABORT_UNLESS(fs::SetFileSize(file, size));
|
||||||
|
|
||||||
|
/* Write the file. */
|
||||||
|
return fs::WriteFile(file, 0, src, size, fs::WriteOption::Flush);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
Result ReadFile(const char *path, void *dst, size_t size, s64 offset);
|
||||||
|
Result WriteFile(const char *path, const void *src, size_t size);
|
||||||
|
Result MoveFile(const char *dst_path, const char *src_path);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_profile_manager.hpp"
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Result CreateSaveData(const ProfileManager::SaveDataInfo &save_data_info) {
|
||||||
|
R_TRY_CATCH(fs::CreateSystemSaveData(save_data_info.id, save_data_info.size, save_data_info.journal_size, save_data_info.flags)) {
|
||||||
|
R_CATCH(fs::ResultPathAlreadyExists) { /* Nintendo accepts already-existing savedata here. */ }
|
||||||
|
} R_END_TRY_CATCH;
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileManager::ProfileManager(const SaveDataInfo &save_data_info)
|
||||||
|
: m_general_mutex(), m_fs_mutex(), m_save_data_info(save_data_info), m_save_file_mounted(false),
|
||||||
|
m_update_observer_manager()
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfileManager::InitializeSaveData() {
|
||||||
|
/* Acquire locks. */
|
||||||
|
std::scoped_lock lk1(m_general_mutex);
|
||||||
|
std::scoped_lock lk2(m_fs_mutex);
|
||||||
|
|
||||||
|
/* Ensure the savedata exists. */
|
||||||
|
if (R_SUCCEEDED(CreateSaveData(m_save_data_info))) {
|
||||||
|
m_save_file_mounted = R_SUCCEEDED(fs::MountSystemSaveData(m_save_data_info.mount_name, m_save_data_info.id));
|
||||||
|
|
||||||
|
/* TODO: Remove this after implementation, as it's for debugging. */
|
||||||
|
R_ABORT_UNLESS(fs::MountSdCard("sprof-dbg"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_profile_update_observer_impl.hpp"
|
||||||
|
|
||||||
namespace ams::sprofile::srv {
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
@ -28,19 +29,21 @@ namespace ams::sprofile::srv {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
class UpdateObserverManager;
|
|
||||||
private:
|
private:
|
||||||
os::SdkMutex m_general_mutex;
|
os::SdkMutex m_general_mutex;
|
||||||
os::SdkMutex m_fs_mutex;
|
os::SdkMutex m_fs_mutex;
|
||||||
SaveDataInfo m_save_data_info;
|
SaveDataInfo m_save_data_info;
|
||||||
|
bool m_save_file_mounted;
|
||||||
/* TODO: util::optional<ProfileImporter> m_profile_importer; */
|
/* TODO: util::optional<ProfileImporter> m_profile_importer; */
|
||||||
/* TODO: util::optional<ProfileMetadata> m_profile_metadata; */
|
/* TODO: util::optional<ProfileMetadata> m_profile_metadata; */
|
||||||
/* TODO: util::optional<ServiceProfile> m_service_profile; */
|
/* TODO: util::optional<ServiceProfile> m_service_profile; */
|
||||||
UpdateObserverManager *m_update_observer_manager;
|
ProfileUpdateObserverManager m_update_observer_manager;
|
||||||
public:
|
public:
|
||||||
ProfileManager(const SaveDataInfo &save_data_info);
|
ProfileManager(const SaveDataInfo &save_data_info);
|
||||||
public:
|
public:
|
||||||
/* TODO */
|
void InitializeSaveData();
|
||||||
|
|
||||||
|
ProfileUpdateObserverManager &GetUpdateObserverManager() { return m_update_observer_manager; }
|
||||||
private:
|
private:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_profile_manager.hpp"
|
||||||
|
#include "sprofile_srv_profile_update_observer_impl.hpp"
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class AutoUnregisterObserver : public ProfileUpdateObserverImpl {
|
||||||
|
public:
|
||||||
|
static constexpr auto MaxProfiles = 4;
|
||||||
|
private:
|
||||||
|
Identifier m_profiles[MaxProfiles];
|
||||||
|
int m_profile_count;
|
||||||
|
os::SdkMutex m_mutex;
|
||||||
|
ProfileUpdateObserverManager *m_manager;
|
||||||
|
public:
|
||||||
|
AutoUnregisterObserver(ProfileUpdateObserverManager *manager) : m_profile_count(0), m_mutex(), m_manager(manager) { /* ... */ }
|
||||||
|
virtual ~AutoUnregisterObserver() { m_manager->CloseObserver(this); }
|
||||||
|
public:
|
||||||
|
Result Listen(Identifier profile) {
|
||||||
|
/* Lock ourselves. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Check if we can listen. */
|
||||||
|
R_UNLESS(m_profile_count < MaxProfiles, sprofile::ResultMaxListeners());
|
||||||
|
|
||||||
|
/* Check if we're already listening. */
|
||||||
|
for (auto i = 0; i < m_profile_count; ++i) {
|
||||||
|
R_UNLESS(m_profiles[i] != profile, sprofile::ResultAlreadyListening());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the profile. */
|
||||||
|
m_profiles[m_profile_count++] = profile;
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Unlisten(Identifier profile) {
|
||||||
|
/* Check that we're listening. */
|
||||||
|
for (auto i = 0; i < m_profile_count; ++i) {
|
||||||
|
if (m_profiles[i] == profile) {
|
||||||
|
m_profiles[i] = m_profiles[--m_profile_count];
|
||||||
|
AMS_ABORT_UNLESS(m_profile_count >= 0);
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprofile::ResultNotListening();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetEventHandle(sf::OutCopyHandle out) {
|
||||||
|
out.SetValue(this->GetEvent().GetReadableHandle());
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sprofile::IsIProfileUpdateObserver<AutoUnregisterObserver>);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProfileUpdateObserverManager::OpenObserver(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileUpdateObserver>> &out, MemoryResource *memory_resource) {
|
||||||
|
/* Lock ourselves. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Check that we can allocate. */
|
||||||
|
R_UNLESS(m_observer_count < MaxObservers, sprofile::ResultMaxObservers());
|
||||||
|
|
||||||
|
/* Allocate an object. */
|
||||||
|
auto obj = sf::ObjectFactory<sf::MemoryResourceAllocationPolicy>::CreateSharedEmplaced<IProfileUpdateObserver, AutoUnregisterObserver>(memory_resource, this);
|
||||||
|
R_UNLESS(obj != nullptr, sprofile::ResultAllocationFailed());
|
||||||
|
|
||||||
|
/* Register the observer. */
|
||||||
|
m_observers[m_observer_count++] = std::addressof(obj.GetImpl());
|
||||||
|
|
||||||
|
/* Return the object. */
|
||||||
|
*out = std::move(obj);
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfileUpdateObserverManager::CloseObserver(ProfileUpdateObserverImpl *observer) {
|
||||||
|
/* Lock ourselves. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Find the observer. */
|
||||||
|
int index = -1;
|
||||||
|
for (auto i = 0; i < m_observer_count; ++i) {
|
||||||
|
if (m_observers[i] == observer) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AMS_ABORT_UNLESS(index != -1);
|
||||||
|
|
||||||
|
/* Remove from our list. */
|
||||||
|
m_observers[index] = m_observers[--m_observer_count];
|
||||||
|
|
||||||
|
/* Sanity check. */
|
||||||
|
AMS_ABORT_UNLESS(m_observer_count >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_i_profile_update_observer.hpp"
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
class ProfileUpdateObserverImpl {
|
||||||
|
private:
|
||||||
|
os::SystemEvent m_event;
|
||||||
|
public:
|
||||||
|
ProfileUpdateObserverImpl() : m_event(os::EventClearMode_ManualClear, true) { /* ... */ }
|
||||||
|
virtual ~ProfileUpdateObserverImpl() { /* ... */ }
|
||||||
|
public:
|
||||||
|
os::SystemEvent &GetEvent() { return m_event; }
|
||||||
|
const os::SystemEvent &GetEvent() const { return m_event; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProfileUpdateObserverManager {
|
||||||
|
public:
|
||||||
|
static constexpr auto MaxObservers = 10;
|
||||||
|
private:
|
||||||
|
ProfileUpdateObserverImpl *m_observers[MaxObservers];
|
||||||
|
int m_observer_count;
|
||||||
|
os::SdkMutex m_mutex;
|
||||||
|
public:
|
||||||
|
ProfileUpdateObserverManager() : m_observer_count(0), m_mutex() { /* ... */ }
|
||||||
|
public:
|
||||||
|
Result OpenObserver(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileUpdateObserver>> &out, MemoryResource *memory_resource);
|
||||||
|
void CloseObserver(ProfileUpdateObserverImpl *observer);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_profile_manager.hpp"
|
||||||
|
#include "sprofile_srv_service_for_bg_agent.hpp"
|
||||||
|
#include "sprofile_srv_fs_utils.hpp"
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
Result ServiceForBgAgent::OpenProfileImporter(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileImporter>> out) {
|
||||||
|
AMS_ABORT("TODO: OpenProfileImporter");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ServiceForBgAgent::ReadMetadata(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, const sf::InBuffer &meta) {
|
||||||
|
WriteFile("sprof-dbg:/sprof/meta.bin", meta.GetPointer(), meta.GetSize());
|
||||||
|
AMS_ABORT("TODO: ReadMetadata");
|
||||||
|
}
|
||||||
|
Result ServiceForBgAgent::IsUpdateNeeded(sf::Out<bool> out, Identifier revision_key) {
|
||||||
|
WriteFile("sprof-dbg:/sprof/revision_key.bin", std::addressof(revision_key), sizeof(revision_key));
|
||||||
|
AMS_ABORT("TODO: IsUpdateNeeded");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ServiceForBgAgent::Reset() {
|
||||||
|
AMS_ABORT("TODO: Reset");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "sprofile_srv_profile_manager.hpp"
|
||||||
|
#include "sprofile_srv_service_for_system_process.hpp"
|
||||||
|
|
||||||
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
|
Result ServiceForSystemProcess::OpenProfileReader(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileReader>> out) {
|
||||||
|
/* TODO */
|
||||||
|
AMS_ABORT("TODO: OpenProfileReader");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ServiceForSystemProcess::OpenProfileUpdateObserver(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileUpdateObserver>> out) {
|
||||||
|
return m_profile_manager->GetUpdateObserverManager().OpenObserver(out, m_memory_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ServiceForSystemProcess::OpenProfileControllerForDebug(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileControllerForDebug>> out) {
|
||||||
|
/* TODO */
|
||||||
|
AMS_ABORT("TODO: OpenProfileControllerForDebug");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -64,6 +64,7 @@
|
||||||
#include <vapours/results/sm_results.hpp>
|
#include <vapours/results/sm_results.hpp>
|
||||||
#include <vapours/results/socket_results.hpp>
|
#include <vapours/results/socket_results.hpp>
|
||||||
#include <vapours/results/spl_results.hpp>
|
#include <vapours/results/spl_results.hpp>
|
||||||
|
#include <vapours/results/sprofile_results.hpp>
|
||||||
#include <vapours/results/svc_results.hpp>
|
#include <vapours/results/svc_results.hpp>
|
||||||
#include <vapours/results/time_results.hpp>
|
#include <vapours/results/time_results.hpp>
|
||||||
#include <vapours/results/tipc_results.hpp>
|
#include <vapours/results/tipc_results.hpp>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours/results/results_common.hpp>
|
||||||
|
|
||||||
|
namespace ams::sprofile {
|
||||||
|
|
||||||
|
R_DEFINE_NAMESPACE_RESULT_MODULE(246);
|
||||||
|
|
||||||
|
R_DEFINE_ERROR_RESULT(AllocationFailed, 401);
|
||||||
|
|
||||||
|
R_DEFINE_ERROR_RESULT(MaxListeners, 620);
|
||||||
|
R_DEFINE_ERROR_RESULT(AlreadyListening, 621);
|
||||||
|
R_DEFINE_ERROR_RESULT(NotListening, 622);
|
||||||
|
R_DEFINE_ERROR_RESULT(MaxObservers, 623);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue