mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Thread pooled & fslib update.
This commit is contained in:
parent
30a607a9e1
commit
3c54474e5b
|
|
@ -1 +1 @@
|
|||
Subproject commit 995054e0d28ca9d4bf5134b10493ecebb51a7ab9
|
||||
Subproject commit 382c7d490a68e4897fdc7d1ba37ac6e49cd6ac0e
|
||||
|
|
@ -61,17 +61,18 @@ class BackupMenuState final : public BaseState
|
|||
int index{};
|
||||
};
|
||||
|
||||
struct DataStruct
|
||||
struct DataStruct : sys::Task::DataStruct
|
||||
{
|
||||
data::User *user{};
|
||||
data::TitleInfo *titleInfo{};
|
||||
fslib::Path path{}; // This and
|
||||
std::string remoteName{}; // and this and
|
||||
remote::Item *remoteItem{}; // this are set when needed.
|
||||
BackupMenuState *spawningState{};
|
||||
bool killTask = false; // Some tasks use other tasks instead of repeating code.
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// This makes some things elsewhere easier to type.
|
||||
using TaskData = std::shared_ptr<BackupMenuState::DataStruct>;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -28,27 +28,26 @@ namespace
|
|||
/// @tparam TaskType The type of task spawned on confirmation. Ex: Task, ProgressTask
|
||||
/// @tparam StateType The state type spawned on confirmation. Ex: TaskState, ProgressState
|
||||
/// @tparam StructType The type of struct passed to the state on confirmation.
|
||||
template <typename TaskType, typename StateType, typename StructType>
|
||||
template <typename TaskType, typename StateType>
|
||||
class ConfirmState final : public BaseState
|
||||
{
|
||||
public:
|
||||
/// @brief All functions passed to this state need to follow this signature: void function(<TaskType> *,
|
||||
/// std::shared_ptr<<StructType>>)
|
||||
using TaskFunction = void (*)(TaskType *, std::shared_ptr<StructType>);
|
||||
|
||||
/// @brief Constructor for new ConfirmState.
|
||||
/// @param query The string displayed.
|
||||
/// @param holdRequired Whether or not confirmation requires holding A for three seconds.
|
||||
/// @param function Function executed on confirmation.
|
||||
/// @param dataStruct shared_ptr<StructType> that is passed to function. I tried templating this and it was a nightmare.
|
||||
ConfirmState(std::string_view query, bool holdRequired, TaskFunction function, std::shared_ptr<StructType> dataStruct)
|
||||
ConfirmState(std::string_view query,
|
||||
bool holdRequired,
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
: BaseState(false)
|
||||
, m_query(query)
|
||||
, m_yesText(strings::get_by_name(strings::names::YES_NO_OK, 0))
|
||||
, m_noText(strings::get_by_name(strings::names::YES_NO_OK, 1))
|
||||
, m_holdRequired(holdRequired)
|
||||
, m_function(function)
|
||||
, m_dataStruct(dataStruct)
|
||||
, m_taskData(taskData)
|
||||
{
|
||||
ConfirmState::initialize_static_members();
|
||||
ConfirmState::center_no();
|
||||
|
|
@ -59,20 +58,20 @@ class ConfirmState final : public BaseState
|
|||
/// @brief Returns a new ConfirmState. See constructor.
|
||||
static inline std::shared_ptr<ConfirmState> create(std::string_view query,
|
||||
bool holdRequired,
|
||||
TaskFunction function,
|
||||
std::shared_ptr<StructType> dataStruct)
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
return std::make_shared<ConfirmState>(query, holdRequired, function, dataStruct);
|
||||
return std::make_shared<ConfirmState>(query, holdRequired, function, taskData);
|
||||
}
|
||||
|
||||
/// @brief Creates and returns a new ConfirmState and pushes it.
|
||||
static inline std::shared_ptr<ConfirmState> create_and_push(std::string_view query,
|
||||
bool holdRequired,
|
||||
TaskFunction function,
|
||||
std::shared_ptr<StructType> dataStruct)
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
// I'm gonna use a sneaky trick here. This shouldn't do this because it's confusing.
|
||||
auto newState = create(query, holdRequired, function, dataStruct);
|
||||
auto newState = create(query, holdRequired, function, taskData);
|
||||
StateManager::push_state(newState);
|
||||
return newState;
|
||||
}
|
||||
|
|
@ -80,10 +79,10 @@ class ConfirmState final : public BaseState
|
|||
/// @brief Same as above but with a fade transition pushed in between.
|
||||
static std::shared_ptr<ConfirmState> create_push_fade(std::string_view query,
|
||||
bool holdRequired,
|
||||
TaskFunction function,
|
||||
std::shared_ptr<StructType> dataStruct)
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
auto newState = ConfirmState::create(query, holdRequired, function, dataStruct);
|
||||
auto newState = ConfirmState::create(query, holdRequired, function, taskData);
|
||||
FadeState::create_and_push(colors::DIM_BACKGROUND, 0x00, 0x88, newState);
|
||||
return newState;
|
||||
}
|
||||
|
|
@ -151,10 +150,10 @@ class ConfirmState final : public BaseState
|
|||
int m_stage{};
|
||||
|
||||
/// @brief Function to execute if action is confirmed.
|
||||
const TaskFunction m_function{};
|
||||
const sys::threadpool::JobFunction m_function{};
|
||||
|
||||
/// @brief Pointer to data struct passed to ^
|
||||
const std::shared_ptr<StructType> m_dataStruct{};
|
||||
const sys::Task::TaskData m_taskData{};
|
||||
|
||||
static inline std::shared_ptr<ui::DialogBox> sm_dialog{};
|
||||
|
||||
|
|
@ -188,8 +187,8 @@ class ConfirmState final : public BaseState
|
|||
|
||||
void confirmed()
|
||||
{
|
||||
auto newState = std::make_shared<StateType>(m_function, m_dataStruct);
|
||||
StateManager::push_state(newState);
|
||||
// auto newState = std::make_shared<StateType>(m_function, m_taskData);
|
||||
auto newState = StateType::create_and_push(m_function, m_taskData);
|
||||
BaseState::deactivate();
|
||||
}
|
||||
|
||||
|
|
@ -229,3 +228,6 @@ class ConfirmState final : public BaseState
|
|||
ConfirmState::center_yes();
|
||||
}
|
||||
};
|
||||
|
||||
using ConfirmTask = ConfirmState<sys::Task, TaskState>;
|
||||
using ConfirmProgress = ConfirmState<sys::ProgressTask, ProgressState>;
|
||||
|
|
@ -14,35 +14,25 @@ class DataLoadingState final : public BaseTask
|
|||
/// @brief This is a definition for functions that are called at destruction.
|
||||
using DestructFunction = std::function<void()>;
|
||||
|
||||
template <typename... Args>
|
||||
DataLoadingState(data::DataContext &context,
|
||||
DestructFunction destructFunction,
|
||||
void (*function)(sys::Task *, Args...),
|
||||
Args... args)
|
||||
: BaseTask()
|
||||
, m_context(context)
|
||||
, m_destructFunction(destructFunction)
|
||||
{
|
||||
DataLoadingState::initialize_static_members();
|
||||
m_task = std::make_unique<sys::Task>(function, std::forward<Args>(args)...);
|
||||
}
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData);
|
||||
|
||||
template <typename... Args>
|
||||
static inline std::shared_ptr<DataLoadingState> create(data::DataContext &context,
|
||||
DestructFunction destructFunction,
|
||||
void (*function)(sys::Task *, Args...),
|
||||
Args... args)
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
return std::make_shared<DataLoadingState>(context, destructFunction, function, std::forward<Args>(args)...);
|
||||
return std::make_shared<DataLoadingState>(context, destructFunction, function, taskData);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static inline std::shared_ptr<DataLoadingState> create_and_push(data::DataContext &context,
|
||||
DestructFunction destructFunction,
|
||||
void (*function)(sys::Task *, Args...),
|
||||
Args... args)
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
auto newState = DataLoadingState::create(context, destructFunction, function, std::forward<Args>(args)...);
|
||||
auto newState = DataLoadingState::create(context, destructFunction, function, taskData);
|
||||
StateManager::push_state(newState);
|
||||
return newState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "appstates/BaseState.hpp"
|
||||
#include "appstates/FileModeState.hpp"
|
||||
#include "fslib.hpp"
|
||||
#include "sys/sys.hpp"
|
||||
#include "ui/ui.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
|
@ -41,7 +42,7 @@ class FileOptionState final : public BaseState
|
|||
void update_destination();
|
||||
|
||||
// clang-format off
|
||||
struct DataStruct
|
||||
struct DataStruct : sys::Task::DataStruct
|
||||
{
|
||||
fslib::Path sourcePath{};
|
||||
fslib::Path destPath{};
|
||||
|
|
@ -50,9 +51,6 @@ class FileOptionState final : public BaseState
|
|||
};
|
||||
// clang-format on
|
||||
|
||||
/// @brief This makes some other stuff easier to read and type.
|
||||
using TaskData = std::shared_ptr<FileOptionState::DataStruct>;
|
||||
|
||||
private:
|
||||
/// @brief Pointer to spawning FileMode state.
|
||||
FileModeState *m_spawningState{};
|
||||
|
|
|
|||
|
|
@ -42,14 +42,12 @@ class MainMenuState final : public BaseState
|
|||
static void refresh_view_states();
|
||||
|
||||
// clang-format off
|
||||
struct DataStruct
|
||||
struct DataStruct : sys::Task::DataStruct
|
||||
{
|
||||
data::UserList userList;
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
using TaskData = std::shared_ptr<MainMenuState::DataStruct>;
|
||||
|
||||
private:
|
||||
/// @brief Render target this state renders to.
|
||||
sdl::SharedTexture m_renderTarget{};
|
||||
|
|
@ -70,7 +68,7 @@ class MainMenuState final : public BaseState
|
|||
std::shared_ptr<ui::ControlGuide> m_controlGuide{};
|
||||
|
||||
/// @brief This is the data struct passed to tasks.
|
||||
MainMenuState::TaskData m_dataStruct{};
|
||||
std::shared_ptr<MainMenuState::DataStruct> m_dataStruct{};
|
||||
|
||||
/// @brief Records the size of the sm_users vector.
|
||||
static inline int sm_userCount{};
|
||||
|
|
|
|||
|
|
@ -14,30 +14,19 @@ class ProgressState final : public BaseTask
|
|||
{
|
||||
public:
|
||||
/// @brief Constructs a new ProgressState.
|
||||
/// @param function Function for the task to run.
|
||||
/// @param args Variadic arguments to be forwarded to the function passed.
|
||||
/// @note All functions passed to this must follow this signature: void function(sys::ProgressTask *, <arguments>)
|
||||
template <typename... Args>
|
||||
ProgressState(void (*function)(sys::ProgressTask *, Args...), Args... args)
|
||||
: BaseTask()
|
||||
{
|
||||
ProgressState::initialize_static_members();
|
||||
m_task = std::make_unique<sys::ProgressTask>(function, std::forward<Args>(args)...);
|
||||
}
|
||||
ProgressState(sys::threadpool::JobFunction function, sys::Task::TaskData taskData);
|
||||
|
||||
/// @brief Creates and returns a new progress state.
|
||||
template <typename... Args>
|
||||
static inline std::shared_ptr<ProgressState> create(void (*function)(sys::ProgressTask *, Args...), Args... args)
|
||||
/// @brief Creates and returns a new ProgressState
|
||||
static inline std::shared_ptr<ProgressState> create(sys::threadpool::JobFunction function, sys::Task::TaskData taskData)
|
||||
{
|
||||
return std::make_shared<ProgressState>(function, std::forward<Args>(args)...);
|
||||
return std::make_shared<ProgressState>(function, taskData);
|
||||
}
|
||||
|
||||
/// @brief Creates, pushes, then returns a new ProgressState.
|
||||
template <typename... Args>
|
||||
static inline std::shared_ptr<ProgressState> create_and_push(void (*function)(sys::ProgressTask *, Args...),
|
||||
Args... args)
|
||||
static inline std::shared_ptr<ProgressState> create_and_push(sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
auto newState = ProgressState::create(function, std::forward<Args>(args)...);
|
||||
auto newState = ProgressState::create(function, taskData);
|
||||
StateManager::push_state(newState);
|
||||
return newState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,15 @@ class SaveCreateState final : public BaseState
|
|||
/// @brief This signals so data and the view can be refreshed on the next update() to avoid threading shenanigans.
|
||||
void refresh_required();
|
||||
|
||||
// clang-format off
|
||||
struct DataStruct : sys::Task::DataStruct
|
||||
{
|
||||
data::User *user{};
|
||||
data::TitleInfo *titleInfo{};
|
||||
SaveCreateState *spawningState{};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
/// @brief Pointer to target user.
|
||||
data::User *m_user{};
|
||||
|
|
@ -56,6 +65,9 @@ class SaveCreateState final : public BaseState
|
|||
/// @brief Whether or not a refresh is required on the next update() call.
|
||||
std::atomic<bool> m_refreshRequired{};
|
||||
|
||||
/// @brief Data struct passed to the task.
|
||||
std::shared_ptr<SaveCreateState::DataStruct> m_dataStruct{};
|
||||
|
||||
/// @brief Shared slide panel all instances use. There's no point in allocating a new one every time.
|
||||
static inline std::unique_ptr<ui::SlideOutPanel> sm_slidePanel{};
|
||||
|
||||
|
|
@ -68,6 +80,9 @@ class SaveCreateState final : public BaseState
|
|||
/// @brief Pushes the titles to the menu
|
||||
void initialize_menu();
|
||||
|
||||
/// @brief Assigns the user and title info.
|
||||
void initialize_data_struct();
|
||||
|
||||
/// @brief Launches the save creation task.
|
||||
void create_save_data_for();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,29 +9,20 @@
|
|||
class TaskState final : public BaseTask
|
||||
{
|
||||
public:
|
||||
/// @brief Constructs and spawns a new TaskState.
|
||||
/// @param function Function to run in the thread.
|
||||
/// @param args Variadic templated arguments to forward.
|
||||
/// @note All functions passed must follow this signature: void function(sys::Task *, <arguments>)
|
||||
template <typename... Args>
|
||||
TaskState(void (*function)(sys::Task *, Args...), Args... args)
|
||||
: BaseTask()
|
||||
/// @brief Constructs a new TaskState.
|
||||
TaskState(sys::threadpool::JobFunction function, sys::Task::TaskData taskData);
|
||||
|
||||
/// @brief Constructs and returns a TaskState.
|
||||
static inline std::shared_ptr<TaskState> create(sys::threadpool::JobFunction function, sys::Task::TaskData taskData)
|
||||
{
|
||||
m_task = std::make_unique<sys::Task>(function, std::forward<Args>(args)...);
|
||||
return std::make_shared<TaskState>(function, taskData);
|
||||
}
|
||||
|
||||
/// @brief Creates and returns a new TaskState.
|
||||
template <typename... Args>
|
||||
static inline std::shared_ptr<TaskState> create(void (*function)(sys::Task *, Args...), Args... args)
|
||||
/// @brief Constructs, pushes, then returns a new TaskState.
|
||||
static inline std::shared_ptr<TaskState> create_and_push(sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
{
|
||||
return std::make_shared<TaskState>(function, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// @brief Creates, pushes, then returns and new TaskState.
|
||||
template <typename... Args>
|
||||
static inline std::shared_ptr<TaskState> create_and_push(void (*function)(sys::Task *, Args...), Args... args)
|
||||
{
|
||||
auto newState = TaskState::create(function, std::forward<Args>(args)...);
|
||||
auto newState = TaskState::create(function, taskData);
|
||||
StateManager::push_state(newState);
|
||||
return newState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class TitleOptionState final : public BaseState
|
|||
void refresh_required();
|
||||
|
||||
// clang-format off
|
||||
struct DataStruct
|
||||
struct DataStruct : sys::Task::DataStruct
|
||||
{
|
||||
data::User *user{};
|
||||
data::TitleInfo *titleInfo{};
|
||||
|
|
@ -58,8 +58,6 @@ class TitleOptionState final : public BaseState
|
|||
};
|
||||
// clang-format on
|
||||
|
||||
using TaskData = std::shared_ptr<TitleOptionState::DataStruct>;
|
||||
|
||||
private:
|
||||
/// @brief This is just in case the option should only apply to the current user.
|
||||
data::User *m_user{};
|
||||
|
|
|
|||
|
|
@ -44,15 +44,13 @@ class UserOptionState final : public BaseState
|
|||
void refresh_required();
|
||||
|
||||
// clang-format off
|
||||
struct DataStruct
|
||||
struct DataStruct : sys::Task::DataStruct
|
||||
{
|
||||
data::User *user{};
|
||||
UserOptionState *spawningState{};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
using TaskData = std::shared_ptr<UserOptionState::DataStruct>;
|
||||
|
||||
private:
|
||||
/// @brief Pointer to the target user.
|
||||
data::User *m_user{};
|
||||
|
|
|
|||
|
|
@ -2,14 +2,17 @@
|
|||
#include "fslib.hpp"
|
||||
#include "sys/sys.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace curl
|
||||
{
|
||||
inline constexpr size_t SHARED_BUFFER_SIZE = 0x500000;
|
||||
|
||||
// clang-format off
|
||||
struct DownloadStruct
|
||||
struct DownloadStruct : sys::threadpool::DataStruct
|
||||
{
|
||||
/// @brief Buffer mutex.
|
||||
std::mutex lock{};
|
||||
|
|
@ -18,7 +21,10 @@ namespace curl
|
|||
std::condition_variable condition{};
|
||||
|
||||
/// @brief Shared buffer that is read into.
|
||||
std::vector<sys::byte> sharedBuffer{};
|
||||
std::array<sys::byte, SHARED_BUFFER_SIZE> sharedBuffer{};
|
||||
|
||||
/// @brief Current offset in the shared buffer.
|
||||
size_t sharedOffset{};
|
||||
|
||||
/// @brief Bool to signal when the buffer is ready/empty.
|
||||
bool bufferReady{};
|
||||
|
|
@ -36,4 +42,15 @@ namespace curl
|
|||
int64_t fileSize{};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static inline std::shared_ptr<curl::DownloadStruct> create_download_struct(fslib::File &dest,
|
||||
sys::ProgressTask *task,
|
||||
int64_t fileSize)
|
||||
{
|
||||
auto downloadStruct = std::make_shared<curl::DownloadStruct>();
|
||||
downloadStruct->dest = &dest;
|
||||
downloadStruct->task = task;
|
||||
downloadStruct->offset = fileSize;
|
||||
return downloadStruct;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace curl
|
|||
|
||||
/// @brief Function used to download files threaded.
|
||||
/// @param download Struct shared by both threads.
|
||||
void download_write_thread_function(curl::DownloadStruct &download);
|
||||
void download_write_thread_function(sys::threadpool::JobData jobData);
|
||||
|
||||
/// @brief Gets the value of a header from an array of headers.
|
||||
/// @param array Array of headers to search.
|
||||
|
|
|
|||
|
|
@ -1,26 +1,16 @@
|
|||
#pragma once
|
||||
#include "sys/Task.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace sys
|
||||
{
|
||||
/// @brief Derived class of Task that has methods for tracking progress.
|
||||
class ProgressTask final : public sys::Task
|
||||
{
|
||||
public:
|
||||
/// @brief Contstructs a new ProgressTask
|
||||
/// @param function Function for thread to execute.
|
||||
/// @param args Arguments to forward to the thread function.
|
||||
/// @note All functions passed to this must follow this signature: void function(sys::ProgressTask *,
|
||||
//<arguments>)
|
||||
template <typename... Args>
|
||||
ProgressTask(void (*function)(sys::ProgressTask *, Args...), Args... args)
|
||||
{
|
||||
m_thread = std::thread(function, this, std::forward<Args>(args)...);
|
||||
m_isRunning.store(true);
|
||||
}
|
||||
/// @brief Creates a Progress task.
|
||||
/// @param function
|
||||
/// @param taskData
|
||||
ProgressTask(sys::threadpool::JobFunction function, sys::ProgressTask::TaskData taskData);
|
||||
|
||||
/// @brief Resets the progress and sets a new goal.
|
||||
/// @param goal The goal we all strive for.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#pragma once
|
||||
#include "sys/threadpool.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
// This macro helps keep things a bit easier to read and cuts down on repetition.
|
||||
#define TASK_FINISH_RETURN(x) \
|
||||
|
|
@ -16,18 +17,21 @@ namespace sys
|
|||
class Task
|
||||
{
|
||||
public:
|
||||
/// @brief Default constructor.
|
||||
Task() = default;
|
||||
|
||||
template <typename... Args>
|
||||
Task(void (*function)(sys::Task *, Args...), Args... args)
|
||||
// clang-format off
|
||||
struct DataStruct : sys::threadpool::DataStruct
|
||||
{
|
||||
m_thread = std::thread(function, this, std::forward<Args>(args)...);
|
||||
m_isRunning.store(true);
|
||||
}
|
||||
sys::Task *task{};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/// @brief Required destructor.
|
||||
virtual ~Task();
|
||||
/// @brief This makes some things easier to type and read in other places.
|
||||
using TaskData = std::shared_ptr<Task::DataStruct>;
|
||||
|
||||
/// @brief Default constructor.
|
||||
Task();
|
||||
|
||||
/// @brief Starts a new task.
|
||||
Task(sys::threadpool::JobFunction function, sys::Task::TaskData taskData);
|
||||
|
||||
/// @brief Returns if the thread has signaled it's finished running.
|
||||
/// @return True if the thread is still running. False if it isn't.
|
||||
|
|
@ -40,6 +44,9 @@ namespace sys
|
|||
/// @brief Sets the task/threads current status string. Thread safe.
|
||||
void set_status(std::string_view status);
|
||||
|
||||
/// @brief Moves the status string instead of creating a copy.
|
||||
void set_status(std::string &status);
|
||||
|
||||
/// @brief Returns the status string. Thread safe.
|
||||
/// @return Copy of the status string.
|
||||
std::string get_status() noexcept;
|
||||
|
|
@ -48,9 +55,6 @@ namespace sys
|
|||
// Whether task is still running.
|
||||
std::atomic<bool> m_isRunning{};
|
||||
|
||||
// Thread
|
||||
std::thread m_thread{};
|
||||
|
||||
private:
|
||||
// Status string the thread can set that the main thread can display.
|
||||
std::string m_status{};
|
||||
|
|
|
|||
|
|
@ -7,34 +7,24 @@
|
|||
namespace tasks::backup
|
||||
{
|
||||
/// @brief Task/thread function executed when a new backup is created.
|
||||
void create_new_backup_local(sys::ProgressTask *task,
|
||||
data::User *user,
|
||||
data::TitleInfo *titleInfo,
|
||||
fslib::Path target,
|
||||
BackupMenuState *spawningState,
|
||||
bool killTask = true);
|
||||
void create_new_backup_remote(sys::ProgressTask *task,
|
||||
data::User *user,
|
||||
data::TitleInfo *titleInfo,
|
||||
std::string remoteName,
|
||||
BackupMenuState *spawningState,
|
||||
bool killTask = true);
|
||||
void create_new_backup_local(sys::threadpool::JobData taskData);
|
||||
void create_new_backup_remote(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Overwrites a pre-existing backup.
|
||||
void overwrite_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
|
||||
void overwrite_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
|
||||
void overwrite_backup_local(sys::threadpool::JobData taskData);
|
||||
void overwrite_backup_remote(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Restores a backup
|
||||
void restore_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
|
||||
void restore_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
|
||||
void restore_backup_local(sys::threadpool::JobData taskData);
|
||||
void restore_backup_remote(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Deletes a backup
|
||||
void delete_backup_local(sys::Task *task, BackupMenuState::TaskData taskData);
|
||||
void delete_backup_remote(sys::Task *task, BackupMenuState::TaskData taskData);
|
||||
void delete_backup_local(sys::threadpool::JobData taskData);
|
||||
void delete_backup_remote(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Uploads a backup
|
||||
void upload_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
|
||||
void upload_backup(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Patches a pre-existing backup on the remote storage.
|
||||
void patch_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
|
||||
void patch_backup(sys::threadpool::JobData taskData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
namespace tasks::fileoptions
|
||||
{
|
||||
/// @brief Copies the source to destination passed through taskData.
|
||||
void copy_source_to_destination(sys::ProgressTask *task, FileOptionState::TaskData taskData);
|
||||
void copy_source_to_destination(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Deletes the source path passed through taskData
|
||||
void delete_target(sys::Task *task, FileOptionState::TaskData taskData);
|
||||
void delete_target(sys::threadpool::JobData taskData);
|
||||
}
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
|
||||
namespace tasks::mainmenu
|
||||
{
|
||||
void backup_all_for_all_local(sys::ProgressTask *task, MainMenuState::TaskData taskData);
|
||||
void backup_all_for_all_remote(sys::ProgressTask *task, MainMenuState::TaskData taskData);
|
||||
void backup_all_for_all_local(sys::threadpool::JobData taskData);
|
||||
void backup_all_for_all_remote(sys::threadpool::JobData taskData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@
|
|||
|
||||
namespace tasks::savecreate
|
||||
{
|
||||
void create_save_data_for(sys::Task *task, data::User *user, data::TitleInfo *titleInfo, SaveCreateState *spawningState);
|
||||
void create_save_data_for(sys::threadpool::JobData taskData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,20 +6,20 @@
|
|||
namespace tasks::titleoptions
|
||||
{
|
||||
/// @brief Adds a title to the blacklist. Needs to be task formatted to work with confirmations.
|
||||
void blacklist_title(sys::Task *task, TitleOptionState::TaskData taskData);
|
||||
void blacklist_title(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Wipes deletes all local backups for the current title.
|
||||
void delete_all_local_backups_for_title(sys::Task *task, TitleOptionState::TaskData taskData);
|
||||
void delete_all_local_backups_for_title(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Deletes all backups found on the remote storage service.
|
||||
void delete_all_remote_backups_for_title(sys::Task *task, TitleOptionState::TaskData taskData);
|
||||
void delete_all_remote_backups_for_title(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Resets save data for the current title.
|
||||
void reset_save_data(sys::Task *task, TitleOptionState::TaskData taskData);
|
||||
void reset_save_data(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Deletes the save data from the system the same way Data Management does.
|
||||
void delete_save_data_from_system(sys::Task *task, TitleOptionState::TaskData taskData);
|
||||
void delete_save_data_from_system(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief Extends the save container for the current save info.
|
||||
void extend_save_data(sys::Task *task, TitleOptionState::TaskData taskData);
|
||||
void extend_save_data(sys::threadpool::JobData taskData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
namespace tasks::useroptions
|
||||
{
|
||||
void backup_all_for_user_local(sys::ProgressTask *task, UserOptionState::TaskData taskData);
|
||||
void backup_all_for_user_remote(sys::ProgressTask *task, UserOptionState::TaskData taskData);
|
||||
void create_all_save_data_for_user(sys::Task *task, UserOptionState::TaskData taskData);
|
||||
void delete_all_save_data_for_user(sys::Task *task, UserOptionState::TaskData taskData);
|
||||
void backup_all_for_user_local(sys::threadpool::JobData taskData);
|
||||
void backup_all_for_user_remote(sys::threadpool::JobData taskData);
|
||||
void create_all_save_data_for_user(sys::threadpool::JobData taskData);
|
||||
void delete_all_save_data_for_user(sys::threadpool::JobData taskData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,10 +41,13 @@ namespace ui
|
|||
/// @param hasFocus Whether or not the calling state has focus.
|
||||
void render(sdl::SharedTexture &target, bool hasFocus) override;
|
||||
|
||||
/// @brief Adds and option to the menu.
|
||||
/// @brief Adds an option to the menu.
|
||||
/// @param newOption Option to add to menu.
|
||||
void add_option(std::string_view newOption);
|
||||
|
||||
/// @brief Adds an option to the menu. Moves the string instead of creating a new one.
|
||||
void add_option(std::string &newOption);
|
||||
|
||||
/// @brief Allows updating and editing the option.
|
||||
/// @param newOption Option to change text to.
|
||||
void edit_option(int index, std::string_view newOption);
|
||||
|
|
@ -71,7 +74,7 @@ namespace ui
|
|||
bool is_empty() const noexcept;
|
||||
|
||||
/// @brief Resets the menu and returns it to an empty, default state.
|
||||
void reset();
|
||||
void reset(bool full = true);
|
||||
|
||||
protected:
|
||||
/// @brief X coordinate menu is rendered to.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ namespace ui
|
|||
/// @brief PopMessage constructor.
|
||||
PopMessage(int ticks, std::string_view message);
|
||||
|
||||
/// @brief Same as above. Moves string instead of copying.
|
||||
PopMessage(int ticks, std::string &message);
|
||||
|
||||
/// @brief Updates the width, target, and typing.
|
||||
void update(double targetY);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ namespace ui
|
|||
/// @brief Pushes a new message to the queue for processing.
|
||||
static void push_message(int displayTicks, std::string_view message);
|
||||
|
||||
/// @brief Move version of above.
|
||||
static void push_message(int displayTicks, std::string &message);
|
||||
|
||||
/// @brief The default duration of ticks for messages to be shown.
|
||||
static constexpr int DEFAULT_TICKS = 2500;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ JKSV::JKSV()
|
|||
|
||||
// This needs the config init'd or read to work.
|
||||
JKSV::create_directories();
|
||||
|
||||
sys::threadpool::initialize();
|
||||
|
||||
data::launch_initialization(false, finish_initialization);
|
||||
|
|
@ -105,6 +104,7 @@ JKSV::~JKSV()
|
|||
sdl::exit();
|
||||
|
||||
appletSetCpuBoostMode(ApmCpuBoostMode_Normal);
|
||||
appletUnlockExit();
|
||||
}
|
||||
|
||||
bool JKSV::is_running() const noexcept { return m_isRunning && appletMainLoop(); }
|
||||
|
|
@ -170,6 +170,7 @@ bool JKSV::initialize_services()
|
|||
serviceInit = serviceInit && initialize_service(setsysInitialize, "SetSys");
|
||||
serviceInit = serviceInit && initialize_service(socketInitialize, "Socket", &SOCKET_INIT_CONFIG);
|
||||
serviceInit = serviceInit && initialize_service(nifmInitialize, "NIFM", NifmServiceType_User);
|
||||
serviceInit = serviceInit && initialize_service(appletLockExit, "AppletLockExit");
|
||||
return serviceInit;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,6 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
// These make some things cleaner and easier to type.
|
||||
using TaskConfirm = ConfirmState<sys::Task, TaskState, BackupMenuState::DataStruct>;
|
||||
using ProgressConfirm = ConfirmState<sys::ProgressTask, ProgressState, BackupMenuState::DataStruct>;
|
||||
} // namespace
|
||||
|
||||
BackupMenuState::BackupMenuState(data::User *user, data::TitleInfo *titleInfo)
|
||||
: m_user(user)
|
||||
, m_titleInfo(titleInfo)
|
||||
|
|
@ -238,23 +231,21 @@ void BackupMenuState::name_and_create_backup()
|
|||
const bool named = autoNamed || keyboard::get_input(SwkbdType_QWERTY, name, keyboardHeader, name, SIZE_NAME_LENGTH);
|
||||
if (!named) { return; }
|
||||
|
||||
const bool hasZipExt = std::strstr(name, STRING_ZIP_EXT); // This might not be the best check.
|
||||
m_dataStruct->killTask = true; // Need to make sure these kill the task.
|
||||
const bool hasZipExt = std::strstr(name, STRING_ZIP_EXT); // This might not be the best check.
|
||||
if (autoUpload && remote)
|
||||
{
|
||||
if (!hasZipExt) { std::strncat(name, STRING_ZIP_EXT, SIZE_NAME_LENGTH); }
|
||||
ProgressState::create_and_push(tasks::backup::create_new_backup_remote,
|
||||
m_user,
|
||||
m_titleInfo,
|
||||
std::string{name},
|
||||
this,
|
||||
true);
|
||||
|
||||
ProgressState::create_and_push(tasks::backup::create_new_backup_remote, m_dataStruct);
|
||||
}
|
||||
else
|
||||
{
|
||||
fslib::Path target{m_directoryPath / name};
|
||||
if (!hasZipExt && (autoUpload || exportZip)) { target += STRING_ZIP_EXT; } // We're going to append zip either way.
|
||||
|
||||
ProgressState::create_and_push(tasks::backup::create_new_backup_local, m_user, m_titleInfo, target, this, true);
|
||||
m_dataStruct->path = std::move(target);
|
||||
ProgressState::create_and_push(tasks::backup::create_new_backup_local, m_dataStruct);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,14 +261,16 @@ void BackupMenuState::confirm_overwrite()
|
|||
m_dataStruct->remoteItem = m_remoteListing.at(entry.index);
|
||||
const char *itemName = m_dataStruct->remoteItem->get_name().data();
|
||||
const std::string query = stringutil::get_formatted_string(confirmTemplate, itemName);
|
||||
ProgressConfirm::create_push_fade(query, holdRequired, tasks::backup::overwrite_backup_remote, m_dataStruct);
|
||||
|
||||
ConfirmProgress::create_push_fade(query, holdRequired, tasks::backup::overwrite_backup_remote, m_dataStruct);
|
||||
}
|
||||
else if (entry.type == MenuEntryType::Local)
|
||||
{
|
||||
m_dataStruct->path = m_directoryPath / m_directoryListing[entry.index];
|
||||
const char *targetName = m_directoryListing[entry.index].get_filename();
|
||||
const std::string query = stringutil::get_formatted_string(confirmTemplate, targetName);
|
||||
ProgressConfirm::create_push_fade(query, holdRequired, tasks::backup::overwrite_backup_local, m_dataStruct);
|
||||
|
||||
ConfirmProgress::create_push_fade(query, holdRequired, tasks::backup::overwrite_backup_local, m_dataStruct);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +310,7 @@ void BackupMenuState::confirm_restore()
|
|||
const char *targetName = m_directoryListing[entry.index].get_filename();
|
||||
const std::string query = stringutil::get_formatted_string(confirmTemplate, targetName);
|
||||
|
||||
ProgressConfirm::create_push_fade(query, holdRequired, tasks::backup::restore_backup_local, m_dataStruct);
|
||||
ConfirmProgress::create_push_fade(query, holdRequired, tasks::backup::restore_backup_local, m_dataStruct);
|
||||
}
|
||||
else if (entry.type == MenuEntryType::Remote)
|
||||
{
|
||||
|
|
@ -326,7 +319,7 @@ void BackupMenuState::confirm_restore()
|
|||
m_dataStruct->remoteItem = target;
|
||||
m_dataStruct->path = m_directoryPath + "//"; // To-do: This is a workaround.
|
||||
|
||||
ProgressConfirm::create_push_fade(query, holdRequired, tasks::backup::restore_backup_remote, m_dataStruct);
|
||||
ConfirmProgress::create_push_fade(query, holdRequired, tasks::backup::restore_backup_remote, m_dataStruct);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -337,14 +330,13 @@ void BackupMenuState::confirm_delete()
|
|||
const bool holdRequired = config::get_by_key(config::keys::HOLD_FOR_DELETION);
|
||||
const char *confirmTemplate = strings::get_by_name(strings::names::BACKUPMENU_CONFS, 2);
|
||||
|
||||
std::shared_ptr<TaskConfirm> confirm{};
|
||||
if (entry.type == MenuEntryType::Local)
|
||||
{
|
||||
m_dataStruct->path = m_directoryPath / m_directoryListing[entry.index];
|
||||
const char *targetName = m_directoryListing[entry.index].get_filename();
|
||||
const std::string query = stringutil::get_formatted_string(confirmTemplate, targetName);
|
||||
|
||||
TaskConfirm::create_and_push(query, holdRequired, tasks::backup::delete_backup_local, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, holdRequired, tasks::backup::delete_backup_local, m_dataStruct);
|
||||
}
|
||||
else if (entry.type == MenuEntryType::Remote)
|
||||
{
|
||||
|
|
@ -352,7 +344,7 @@ void BackupMenuState::confirm_delete()
|
|||
const char *itemName = m_dataStruct->remoteItem->get_name().data();
|
||||
const std::string query = stringutil::get_formatted_string(confirmTemplate, itemName);
|
||||
|
||||
TaskConfirm::create_and_push(query, holdRequired, tasks::backup::delete_backup_remote, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, holdRequired, tasks::backup::delete_backup_remote, m_dataStruct);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +378,7 @@ void BackupMenuState::upload_backup()
|
|||
const bool holdRequired = config::get_by_key(config::keys::HOLD_FOR_OVERWRITE);
|
||||
m_dataStruct->remoteItem = remoteItem;
|
||||
|
||||
ProgressConfirm::create_and_push(query, holdRequired, tasks::backup::patch_backup, m_dataStruct);
|
||||
ConfirmProgress::create_push_fade(query, holdRequired, tasks::backup::patch_backup, m_dataStruct);
|
||||
}
|
||||
else { ProgressState::create_and_push(tasks::backup::upload_backup, m_dataStruct); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void BlacklistEditState::update()
|
|||
sm_slidePanel->update(hasFocus);
|
||||
|
||||
if (aPressed) { BlacklistEditState::remove_from_blacklist(); }
|
||||
else if (bPressed) { sm_slidePanel->close(); }
|
||||
else if (bPressed || m_blacklist.empty()) { sm_slidePanel->close(); }
|
||||
else if (sm_slidePanel->is_closed()) { BlacklistEditState::deactivate_state(); }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,18 @@ namespace
|
|||
constexpr int SCREEN_CENTER = 640;
|
||||
}
|
||||
|
||||
DataLoadingState::DataLoadingState(data::DataContext &context,
|
||||
DestructFunction destructFunction,
|
||||
sys::threadpool::JobFunction function,
|
||||
sys::Task::TaskData taskData)
|
||||
: BaseTask()
|
||||
, m_context(context)
|
||||
, m_destructFunction(destructFunction)
|
||||
{
|
||||
DataLoadingState::initialize_static_members();
|
||||
m_task = std::make_unique<sys::Task>(function, taskData);
|
||||
}
|
||||
|
||||
void DataLoadingState::update()
|
||||
{
|
||||
BaseTask::update_loading_glyph();
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void ExtrasMenuState::render()
|
|||
|
||||
void ExtrasMenuState::initialize_menu()
|
||||
{
|
||||
if (!m_extrasMenu) { m_extrasMenu = ui::Menu::create(32, 8, 1000, 24, 555); }
|
||||
if (!m_extrasMenu) { m_extrasMenu = ui::Menu::create(32, 10, 1000, 23, 555); }
|
||||
|
||||
for (int i = 0; const char *option = strings::get_by_name(strings::names::EXTRASMENU_MENU, i); i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ void FileModeState::initialize_paths()
|
|||
|
||||
void FileModeState::initialize_menus()
|
||||
{
|
||||
m_dirMenuA = ui::Menu::create(8, 8, 594, 22, 538);
|
||||
m_dirMenuB = ui::Menu::create(626, 8, 594, 22, 538);
|
||||
m_dirMenuA = ui::Menu::create(8, 5, 594, 20, 538);
|
||||
m_dirMenuB = ui::Menu::create(626, 5, 594, 20, 538);
|
||||
|
||||
FileModeState::initialize_directory_menu(m_pathA, m_dirA, *m_dirMenuA.get());
|
||||
FileModeState::initialize_directory_menu(m_pathB, m_dirB, *m_dirMenuB.get());
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@ namespace
|
|||
PROPERTIES,
|
||||
CLOSE
|
||||
};
|
||||
|
||||
// These make things easier to read and type.
|
||||
using TaskConfirm = ConfirmState<sys::Task, TaskState, FileOptionState::DataStruct>;
|
||||
using ProgressConfirm = ConfirmState<sys::ProgressTask, ProgressState, FileOptionState::DataStruct>;
|
||||
}
|
||||
|
||||
// Defined at bottom.
|
||||
|
|
@ -183,7 +179,7 @@ void FileOptionState::copy_target()
|
|||
if (!entry.is_directory())
|
||||
{
|
||||
const char *errorFormat = strings::get_by_name(strings::names::FILEOPTION_POPS, 4);
|
||||
const std::string pop = stringutil::get_formatted_string(errorFormat, entry.get_filename());
|
||||
std::string pop = stringutil::get_formatted_string(errorFormat, entry.get_filename());
|
||||
ui::PopMessageManager::push_message(popTicks, pop);
|
||||
return;
|
||||
}
|
||||
|
|
@ -202,7 +198,7 @@ void FileOptionState::copy_target()
|
|||
const char *copyFormat = strings::get_by_name(strings::names::FILEOPTION_CONFS, 0);
|
||||
const std::string query = stringutil::get_formatted_string(copyFormat, sourceString.c_str(), destString.c_str());
|
||||
|
||||
ProgressConfirm::create_push_fade(query, false, tasks::fileoptions::copy_source_to_destination, m_dataStruct);
|
||||
ConfirmProgress::create_push_fade(query, false, tasks::fileoptions::copy_source_to_destination, m_dataStruct);
|
||||
}
|
||||
|
||||
void FileOptionState::delete_target()
|
||||
|
|
@ -233,7 +229,7 @@ void FileOptionState::delete_target()
|
|||
m_dataStruct->sourcePath = std::move(fullTarget);
|
||||
m_dataStruct->journalSize = m_spawningState->m_journalSize;
|
||||
|
||||
TaskConfirm::create_push_fade(query, holdRequired, tasks::fileoptions::delete_target, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, holdRequired, tasks::fileoptions::delete_target, m_dataStruct);
|
||||
}
|
||||
|
||||
void FileOptionState::rename_target()
|
||||
|
|
@ -278,7 +274,7 @@ void FileOptionState::rename_target()
|
|||
if (dirError && fileError && commitError)
|
||||
{
|
||||
const char *popFormat = strings::get_by_name(strings::names::FILEOPTION_POPS, 2);
|
||||
const std::string pop = stringutil::get_formatted_string(popFormat, filename);
|
||||
std::string pop = stringutil::get_formatted_string(popFormat, filename);
|
||||
ui::PopMessageManager::push_message(popTicks, pop);
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +308,7 @@ void FileOptionState::create_directory()
|
|||
if (createError || (commitRequired && commitError))
|
||||
{
|
||||
const char *popFormat = strings::get_by_name(strings::names::FILEOPTION_POPS, 3);
|
||||
const std::string pop = stringutil::get_formatted_string(popFormat, nameBuffer);
|
||||
std::string pop = stringutil::get_formatted_string(popFormat, nameBuffer);
|
||||
ui::PopMessageManager::push_message(popTicks, pop);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@
|
|||
#include "tasks/mainmenu.hpp"
|
||||
#include "ui/PopMessageManager.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using ProgressConfirm = ConfirmState<sys::ProgressTask, ProgressState, MainMenuState::DataStruct>;
|
||||
}
|
||||
|
||||
MainMenuState::MainMenuState()
|
||||
: m_renderTarget(sdl::TextureManager::load("mainMenuTarget", 200, 555, SDL_TEXTUREACCESS_TARGET))
|
||||
, m_background(sdl::TextureManager::load("mainBackground", "romfs:/Textures/MenuBackground.png"))
|
||||
|
|
@ -138,8 +133,8 @@ void MainMenuState::push_target_state()
|
|||
const int titleCount = user->get_total_data_entries();
|
||||
if (titleCount <= 0)
|
||||
{
|
||||
const char *nickname = user->get_nickname();
|
||||
const std::string popError = stringutil::get_formatted_string(popNoSaveFormat, nickname);
|
||||
const char *nickname = user->get_nickname();
|
||||
std::string popError = stringutil::get_formatted_string(popNoSaveFormat, nickname);
|
||||
ui::PopMessageManager::push_message(popTicks, popError);
|
||||
return;
|
||||
}
|
||||
|
|
@ -166,7 +161,7 @@ void MainMenuState::backup_all_for_all()
|
|||
const char *query = strings::get_by_name(strings::names::MAINMENU_CONFS, 0);
|
||||
if (remote && autoUpload)
|
||||
{
|
||||
ProgressConfirm::create_and_push(query, true, tasks::mainmenu::backup_all_for_all_remote, m_dataStruct);
|
||||
ConfirmProgress::create_push_fade(query, true, tasks::mainmenu::backup_all_for_all_remote, m_dataStruct);
|
||||
}
|
||||
else { ProgressConfirm::create_and_push(query, true, tasks::mainmenu::backup_all_for_all_local, m_dataStruct); }
|
||||
else { ConfirmProgress::create_push_fade(query, true, tasks::mainmenu::backup_all_for_all_local, m_dataStruct); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ namespace
|
|||
constexpr double SIZE_BAR_WIDTH = 656.0f;
|
||||
}
|
||||
|
||||
ProgressState::ProgressState(sys::threadpool::JobFunction function, sys::Task::TaskData taskData)
|
||||
{
|
||||
initialize_static_members();
|
||||
m_task = std::make_unique<sys::ProgressTask>(function, taskData);
|
||||
}
|
||||
|
||||
void ProgressState::update()
|
||||
{
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(m_task.get());
|
||||
|
|
@ -53,8 +59,10 @@ void ProgressState::render()
|
|||
sdl::render_line(sdl::Texture::Null, 280, 454, 999, 454, colors::DIV_COLOR);
|
||||
sdl::render_rect_fill(sdl::Texture::Null, COORD_BAR_X, COORD_BAR_Y, barWidth, 32, colors::BLACK);
|
||||
sdl::render_rect_fill(sdl::Texture::Null, COORD_BAR_X, COORD_BAR_Y, m_progressBarWidth, 32, colors::GREEN);
|
||||
|
||||
sm_barEdges->render_part(sdl::Texture::Null, COORD_BAR_X, COORD_BAR_Y, 0, 0, 16, 32);
|
||||
sm_barEdges->render_part(sdl::Texture::Null, RIGHT_EDGE_X, COORD_BAR_Y, 16, 0, 16, 32);
|
||||
|
||||
sdl::text::render(sdl::Texture::Null,
|
||||
m_percentageX,
|
||||
COORD_TEXT_Y,
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ static bool compare_info(data::TitleInfo *infoA, data::TitleInfo *infoB);
|
|||
SaveCreateState::SaveCreateState(data::User *user, TitleSelectCommon *titleSelect)
|
||||
: m_user(user)
|
||||
, m_titleSelect(titleSelect)
|
||||
, m_saveMenu(ui::Menu::create(8, 8, 624, 22, 720))
|
||||
, m_saveMenu(ui::Menu::create(8, 8, 624, 23, 720))
|
||||
, m_dataStruct(std::make_shared<SaveCreateState::DataStruct>())
|
||||
{
|
||||
SaveCreateState::initialize_static_members();
|
||||
SaveCreateState::initialize_title_info_vector();
|
||||
SaveCreateState::initialize_menu();
|
||||
SaveCreateState::initialize_data_struct();
|
||||
}
|
||||
|
||||
void SaveCreateState::update()
|
||||
|
|
@ -87,13 +89,19 @@ void SaveCreateState::initialize_menu()
|
|||
sm_slidePanel->push_new_element(m_saveMenu);
|
||||
}
|
||||
|
||||
void SaveCreateState::initialize_data_struct()
|
||||
{
|
||||
m_dataStruct->user = m_user;
|
||||
m_dataStruct->spawningState = this;
|
||||
}
|
||||
|
||||
void SaveCreateState::create_save_data_for()
|
||||
{
|
||||
const int selected = m_saveMenu->get_selected();
|
||||
data::TitleInfo *titleInfo = m_titleInfoVector[selected];
|
||||
auto createTask = TaskState::create(tasks::savecreate::create_save_data_for, m_user, titleInfo, this);
|
||||
m_dataStruct->titleInfo = titleInfo;
|
||||
|
||||
StateManager::push_state(createTask);
|
||||
TaskState::create_and_push(tasks::savecreate::create_save_data_for, m_dataStruct);
|
||||
}
|
||||
|
||||
void SaveCreateState::deactivate_state()
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace
|
|||
} // namespace
|
||||
|
||||
SettingsState::SettingsState()
|
||||
: m_settingsMenu(ui::Menu::create(32, 8, 1000, 24, 555))
|
||||
: m_settingsMenu(ui::Menu::create(32, 10, 1000, 23, 555))
|
||||
, m_controlGuide(ui::ControlGuide::create(strings::get_by_name(strings::names::CONTROL_GUIDES, 3)))
|
||||
, m_renderTarget(sdl::TextureManager::load(SECONDARY_TARGET, 1080, 555, SDL_TEXTUREACCESS_TARGET))
|
||||
{
|
||||
|
|
@ -179,7 +179,7 @@ void SettingsState::change_working_directory()
|
|||
}
|
||||
|
||||
const std::string newPathString = newPath.string();
|
||||
const std::string popMessage = stringutil::get_formatted_string(popSuccessFormat, newPathString.c_str());
|
||||
std::string popMessage = stringutil::get_formatted_string(popSuccessFormat, newPathString.c_str());
|
||||
ui::PopMessageManager::push_message(popTicks, popMessage);
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ void SettingsState::toggle_options()
|
|||
case CYCLE_SCALING: SettingsState::cycle_anim_scaling(); break;
|
||||
default: config::toggle_by_key(CONFIG_KEY_ARRAY[selected]); break;
|
||||
}
|
||||
config::save();
|
||||
|
||||
SettingsState::update_menu_options();
|
||||
}
|
||||
|
||||
|
|
@ -227,6 +227,7 @@ void SettingsState::cycle_zip_level()
|
|||
{
|
||||
uint8_t zipLevel = config::get_by_key(config::keys::ZIP_COMPRESSION_LEVEL);
|
||||
if (++zipLevel % 10 == 0) { zipLevel = 0; }
|
||||
|
||||
config::set_by_key(config::keys::ZIP_COMPRESSION_LEVEL, zipLevel);
|
||||
}
|
||||
|
||||
|
|
@ -239,12 +240,14 @@ void SettingsState::cycle_sort_type()
|
|||
data::UserList users{};
|
||||
data::get_users(users);
|
||||
for (data::User *user : users) { user->sort_data(); }
|
||||
|
||||
MainMenuState::refresh_view_states();
|
||||
}
|
||||
|
||||
void SettingsState::toggle_jksm_mode()
|
||||
{
|
||||
config::toggle_by_key(config::keys::JKSM_TEXT_MODE);
|
||||
|
||||
MainMenuState::initialize_view_states();
|
||||
}
|
||||
|
||||
|
|
@ -262,17 +265,20 @@ void SettingsState::cycle_anim_scaling()
|
|||
{
|
||||
double scaling = config::get_animation_scaling();
|
||||
if ((scaling += 0.25f) > 4.0f) { scaling = 1.0f; }
|
||||
|
||||
config::set_animation_scaling(scaling);
|
||||
}
|
||||
|
||||
const char *SettingsState::get_status_text(uint8_t value)
|
||||
{
|
||||
if (value > 1) { return nullptr; }
|
||||
|
||||
return m_onOff[value];
|
||||
}
|
||||
|
||||
const char *SettingsState::get_sort_type_text(uint8_t value)
|
||||
{
|
||||
if (value > 2) { return nullptr; }
|
||||
|
||||
return m_sortTypes[value];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,15 @@
|
|||
#include "strings/strings.hpp"
|
||||
#include "ui/PopMessageManager.hpp"
|
||||
|
||||
TaskState::TaskState(sys::threadpool::JobFunction function, sys::Task::TaskData taskData)
|
||||
{
|
||||
m_task = std::make_unique<sys::Task>(function, taskData);
|
||||
}
|
||||
|
||||
void TaskState::update()
|
||||
{
|
||||
BaseTask::update_loading_glyph();
|
||||
BaseTask::pop_on_plus();
|
||||
BaseTask::update_loading_glyph();
|
||||
if (!m_task->is_running()) { TaskState::deactivate_state(); }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace
|
|||
TextTitleSelectState::TextTitleSelectState(data::User *user)
|
||||
: TitleSelectCommon()
|
||||
, m_user(user)
|
||||
, m_titleSelectMenu(ui::Menu::create(32, 8, 1000, 22, 555))
|
||||
, m_titleSelectMenu(ui::Menu::create(32, 10, 1000, 23, 555))
|
||||
, m_renderTarget(sdl::TextureManager::load(SECONDARY_TARGET, 1080, 555, SDL_TEXTUREACCESS_TARGET))
|
||||
{
|
||||
TextTitleSelectState::refresh();
|
||||
|
|
@ -61,7 +61,7 @@ void TextTitleSelectState::refresh()
|
|||
{
|
||||
static constexpr const char *STRING_HEART = "^\uE017^ ";
|
||||
|
||||
m_titleSelectMenu->reset();
|
||||
m_titleSelectMenu->reset(false);
|
||||
|
||||
const size_t totalEntries = m_user->get_total_data_entries();
|
||||
for (size_t i = 0; i < totalEntries; i++)
|
||||
|
|
@ -118,7 +118,7 @@ void TextTitleSelectState::add_remove_favorite()
|
|||
const uint64_t appIDAt = m_user->get_application_id_at(i);
|
||||
if (appIDAt == applicationID) { break; }
|
||||
}
|
||||
m_titleSelectMenu->set_selected(i);
|
||||
|
||||
MainMenuState::refresh_view_states();
|
||||
m_titleSelectMenu->set_selected(i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ namespace
|
|||
EXTEND_CONTAINER,
|
||||
EXPORT_SVI
|
||||
};
|
||||
|
||||
using TaskConfirm = ConfirmState<sys::Task, TaskState, TitleOptionState::DataStruct>;
|
||||
using ProgressConfirm = ConfirmState<sys::ProgressTask, ProgressState, TitleOptionState::DataStruct>;
|
||||
} // namespace
|
||||
|
||||
TitleOptionState::TitleOptionState(data::User *user, data::TitleInfo *titleInfo, TitleSelectCommon *titleSelect)
|
||||
|
|
@ -144,7 +141,7 @@ void TitleOptionState::add_to_blacklist()
|
|||
const char *confirmFormat = strings::get_by_name(strings::names::TITLEOPTION_CONFS, 0);
|
||||
const std::string query = stringutil::get_formatted_string(confirmFormat, title);
|
||||
|
||||
TaskConfirm::create_and_push(query, false, tasks::titleoptions::blacklist_title, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, false, tasks::titleoptions::blacklist_title, m_dataStruct);
|
||||
}
|
||||
|
||||
void TitleOptionState::change_output_directory()
|
||||
|
|
@ -193,7 +190,7 @@ void TitleOptionState::change_output_directory()
|
|||
config::add_custom_path(applicationID, pathBuffer.data());
|
||||
|
||||
const char *popSuccessFormat = strings::get_by_name(strings::names::TITLEOPTION_POPS, 8);
|
||||
const std::string popSuccess = stringutil::get_formatted_string(popSuccessFormat, pathBuffer.data());
|
||||
std::string popSuccess = stringutil::get_formatted_string(popSuccessFormat, pathBuffer.data());
|
||||
ui::PopMessageManager::push_message(popTicks, popSuccess);
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +221,7 @@ void TitleOptionState::delete_all_local_backups()
|
|||
const char *confirmFormat = strings::get_by_name(strings::names::TITLEOPTION_CONFS, 1);
|
||||
const std::string query = stringutil::get_formatted_string(confirmFormat, title);
|
||||
|
||||
TaskConfirm::create_and_push(query, true, tasks::titleoptions::delete_all_local_backups_for_title, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, true, tasks::titleoptions::delete_all_local_backups_for_title, m_dataStruct);
|
||||
}
|
||||
|
||||
void TitleOptionState::delete_all_remote_backups()
|
||||
|
|
@ -233,7 +230,7 @@ void TitleOptionState::delete_all_remote_backups()
|
|||
const char *confirmFormat = strings::get_by_name(strings::names::TITLEOPTION_CONFS, 1);
|
||||
const std::string query = stringutil::get_formatted_string(confirmFormat, title);
|
||||
|
||||
TaskConfirm::create_and_push(query, true, tasks::titleoptions::delete_all_remote_backups_for_title, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, true, tasks::titleoptions::delete_all_remote_backups_for_title, m_dataStruct);
|
||||
}
|
||||
|
||||
void TitleOptionState::reset_save_data()
|
||||
|
|
@ -255,7 +252,7 @@ void TitleOptionState::reset_save_data()
|
|||
const char *confirmFormat = strings::get_by_name(strings::names::TITLEOPTION_CONFS, 2);
|
||||
const std::string query = stringutil::get_formatted_string(confirmFormat, title);
|
||||
|
||||
TaskConfirm::create_and_push(query, true, tasks::titleoptions::reset_save_data, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, true, tasks::titleoptions::reset_save_data, m_dataStruct);
|
||||
}
|
||||
|
||||
void TitleOptionState::delete_save_from_system()
|
||||
|
|
@ -278,7 +275,7 @@ void TitleOptionState::delete_save_from_system()
|
|||
const char *confirmFormat = strings::get_by_name(strings::names::TITLEOPTION_CONFS, 3);
|
||||
const std::string query = stringutil::get_formatted_string(confirmFormat, nickname, title);
|
||||
|
||||
TaskConfirm::create_and_push(query, true, tasks::titleoptions::delete_save_data_from_system, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, true, tasks::titleoptions::delete_save_data_from_system, m_dataStruct);
|
||||
}
|
||||
|
||||
void TitleOptionState::extend_save_container()
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@ namespace
|
|||
CREATE_ALL_SAVE,
|
||||
DELETE_ALL_SAVE
|
||||
};
|
||||
|
||||
// These make things easier to type later.
|
||||
using TaskConfirm = ConfirmState<sys::Task, TaskState, UserOptionState::DataStruct>;
|
||||
using ProgressConfirm = ConfirmState<sys::ProgressTask, ProgressState, UserOptionState::DataStruct>;
|
||||
} // namespace
|
||||
|
||||
UserOptionState::UserOptionState(data::User *user, TitleSelectCommon *titleSelect)
|
||||
|
|
@ -128,9 +124,9 @@ void UserOptionState::backup_all()
|
|||
const std::string query = stringutil::get_formatted_string(confirmFormat, nickname);
|
||||
if (remote && autoUpload)
|
||||
{
|
||||
ProgressConfirm::create_and_push(query, true, tasks::useroptions::backup_all_for_user_remote, m_dataStruct);
|
||||
ConfirmProgress::create_push_fade(query, true, tasks::useroptions::backup_all_for_user_remote, m_dataStruct);
|
||||
}
|
||||
else { ProgressConfirm::create_and_push(query, true, tasks::useroptions::backup_all_for_user_local, m_dataStruct); }
|
||||
else { ConfirmProgress::create_push_fade(query, true, tasks::useroptions::backup_all_for_user_local, m_dataStruct); }
|
||||
}
|
||||
|
||||
void UserOptionState::create_save_create()
|
||||
|
|
@ -149,7 +145,7 @@ void UserOptionState::create_all_save_data()
|
|||
const char *nickname = m_user->get_nickname();
|
||||
|
||||
const std::string query = stringutil::get_formatted_string(confirmFormat, nickname);
|
||||
TaskConfirm::create_and_push(query, true, tasks::useroptions::create_all_save_data_for_user, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(query, true, tasks::useroptions::create_all_save_data_for_user, m_dataStruct);
|
||||
}
|
||||
|
||||
void UserOptionState::delete_all_save_data()
|
||||
|
|
@ -160,7 +156,7 @@ void UserOptionState::delete_all_save_data()
|
|||
const char *confirmFormat = strings::get_by_name(strings::names::USEROPTION_CONFS, 2);
|
||||
const char *nickname = m_user->get_nickname();
|
||||
const std::string queryString = stringutil::get_formatted_string(confirmFormat, nickname);
|
||||
TaskConfirm::create_and_push(queryString, true, tasks::useroptions::delete_all_save_data_for_user, m_dataStruct);
|
||||
ConfirmTask::create_push_fade(queryString, true, tasks::useroptions::delete_all_save_data_for_user, m_dataStruct);
|
||||
}
|
||||
|
||||
void UserOptionState::deactivate_state()
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ void config::ConfigContext::reset()
|
|||
m_configMap[config::keys::SHOW_SYSTEM_USER.data()] = 0;
|
||||
m_configMap[config::keys::ENABLE_TRASH_BIN.data()] = 0;
|
||||
m_animationScaling = DEFAULT_SCALING;
|
||||
|
||||
ConfigContext::save();
|
||||
}
|
||||
|
||||
bool config::ConfigContext::load()
|
||||
|
|
@ -110,7 +108,6 @@ void config::ConfigContext::add_favorite(uint64_t applicationID)
|
|||
const auto findFav = ConfigContext::find_application_id(m_favorites, applicationID);
|
||||
if (findFav != m_favorites.end()) { return; }
|
||||
m_favorites.push_back(applicationID);
|
||||
ConfigContext::save_config_file();
|
||||
}
|
||||
|
||||
void config::ConfigContext::remove_favorite(uint64_t applicationID) noexcept
|
||||
|
|
@ -118,7 +115,6 @@ void config::ConfigContext::remove_favorite(uint64_t applicationID) noexcept
|
|||
const auto findFav = ConfigContext::find_application_id(m_favorites, applicationID);
|
||||
if (findFav == m_favorites.end()) { return; }
|
||||
m_favorites.erase(findFav);
|
||||
ConfigContext::save_config_file();
|
||||
}
|
||||
|
||||
bool config::ConfigContext::is_favorite(uint64_t applicationID) const noexcept
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ bool config::set_working_directory(const fslib::Path &path) noexcept
|
|||
const bool pathSet = s_context.set_working_directory(path);
|
||||
if (!pathSet) { return false; }
|
||||
|
||||
s_context.save();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +45,6 @@ void config::add_remove_favorite(uint64_t applicationID)
|
|||
const bool favorite = s_context.is_favorite(applicationID);
|
||||
if (favorite) { s_context.remove_favorite(applicationID); }
|
||||
else { s_context.add_favorite(applicationID); }
|
||||
s_context.save();
|
||||
}
|
||||
|
||||
bool config::is_favorite(uint64_t applicationID) noexcept { return s_context.is_favorite(applicationID); }
|
||||
|
|
@ -56,7 +54,6 @@ void config::add_remove_blacklist(uint64_t applicationID)
|
|||
const bool blacklisted = s_context.is_blacklisted(applicationID);
|
||||
if (blacklisted) { s_context.remove_from_blacklist(applicationID); }
|
||||
else { s_context.add_to_blacklist(applicationID); }
|
||||
s_context.save();
|
||||
}
|
||||
|
||||
void config::get_blacklisted_titles(std::vector<uint64_t> &listOut) { s_context.get_blacklist(listOut); }
|
||||
|
|
|
|||
|
|
@ -67,13 +67,14 @@ size_t curl::write_data_to_file(const char *buffer, size_t size, size_t count, f
|
|||
|
||||
size_t curl::download_file_threaded(const char *buffer, size_t size, size_t count, curl::DownloadStruct *download)
|
||||
{
|
||||
std::mutex &lock = download->lock;
|
||||
std::condition_variable &condition = download->condition;
|
||||
std::vector<sys::byte> &sharedBuffer = download->sharedBuffer;
|
||||
bool &bufferReady = download->bufferReady;
|
||||
sys::ProgressTask *task = download->task;
|
||||
size_t &offset = download->offset;
|
||||
int64_t &fileSize = download->fileSize;
|
||||
std::mutex &lock = download->lock;
|
||||
std::condition_variable &condition = download->condition;
|
||||
auto &sharedBuffer = download->sharedBuffer;
|
||||
size_t &sharedOffset = download->sharedOffset;
|
||||
bool &bufferReady = download->bufferReady;
|
||||
sys::ProgressTask *task = download->task;
|
||||
size_t &offset = download->offset;
|
||||
int64_t &fileSize = download->fileSize;
|
||||
|
||||
const size_t downloadSize = size * count;
|
||||
const std::span<const sys::byte> bufferSpan{reinterpret_cast<const sys::byte *>(buffer), downloadSize};
|
||||
|
|
@ -81,11 +82,12 @@ size_t curl::download_file_threaded(const char *buffer, size_t size, size_t coun
|
|||
{
|
||||
std::unique_lock<std::mutex> bufferLock(lock);
|
||||
condition.wait(bufferLock, [&]() { return bufferReady == false; });
|
||||
sharedBuffer.append_range(bufferSpan);
|
||||
|
||||
const size_t sharedSize = sharedBuffer.size();
|
||||
std::copy(bufferSpan.begin(), bufferSpan.end(), &sharedBuffer[sharedOffset]);
|
||||
sharedOffset += downloadSize;
|
||||
|
||||
const int64_t nextOffset = offset + downloadSize;
|
||||
if (sharedSize >= SIZE_DOWNLOAD_THRESHOLD || nextOffset >= fileSize)
|
||||
if (sharedOffset >= SIZE_DOWNLOAD_THRESHOLD || nextOffset >= fileSize)
|
||||
{
|
||||
bufferReady = true;
|
||||
condition.notify_one();
|
||||
|
|
@ -99,14 +101,17 @@ size_t curl::download_file_threaded(const char *buffer, size_t size, size_t coun
|
|||
return downloadSize;
|
||||
}
|
||||
|
||||
void curl::download_write_thread_function(curl::DownloadStruct &download)
|
||||
void curl::download_write_thread_function(sys::threadpool::JobData jobData)
|
||||
{
|
||||
std::mutex &lock = download.lock;
|
||||
std::condition_variable &condition = download.condition;
|
||||
std::vector<sys::byte> &sharedBuffer = download.sharedBuffer;
|
||||
bool &bufferReady = download.bufferReady;
|
||||
fslib::File *dest = download.dest;
|
||||
size_t fileSize = download.fileSize;
|
||||
auto castData = std::static_pointer_cast<curl::DownloadStruct>(jobData);
|
||||
|
||||
std::mutex &lock = castData->lock;
|
||||
std::condition_variable &condition = castData->condition;
|
||||
auto &sharedBuffer = castData->sharedBuffer;
|
||||
size_t &sharedOffset = castData->sharedOffset;
|
||||
bool &bufferReady = castData->bufferReady;
|
||||
fslib::File &dest = *castData->dest;
|
||||
size_t fileSize = castData->fileSize;
|
||||
|
||||
auto localBuffer = std::make_unique<sys::byte[]>(SIZE_DOWNLOAD_THRESHOLD + 0x100000); // Gonna give this some room.
|
||||
|
||||
|
|
@ -117,14 +122,15 @@ void curl::download_write_thread_function(curl::DownloadStruct &download)
|
|||
std::unique_lock<std::mutex> bufferLock(lock);
|
||||
condition.wait(bufferLock, [&]() { return bufferReady == true; });
|
||||
|
||||
bufferSize = sharedBuffer.size();
|
||||
std::memcpy(localBuffer.get(), sharedBuffer.data(), bufferSize);
|
||||
// Copy and reset the offset.
|
||||
bufferSize = sharedOffset;
|
||||
std::copy(sharedBuffer.begin(), sharedBuffer.begin() + sharedOffset, localBuffer.get());
|
||||
sharedOffset = 0;
|
||||
|
||||
sharedBuffer.clear();
|
||||
bufferReady = false;
|
||||
condition.notify_one();
|
||||
}
|
||||
dest->write(localBuffer.get(), bufferSize);
|
||||
dest.write(localBuffer.get(), bufferSize);
|
||||
i += bufferSize;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ void data::DataContext::load_user_save_info(sys::Task *task)
|
|||
{
|
||||
std::lock_guard userGuard{m_userMutex};
|
||||
{
|
||||
const char *nickname = user.get_nickname();
|
||||
const std::string status = stringutil::get_formatted_string(statusLoadingUserInfo, nickname);
|
||||
const char *nickname = user.get_nickname();
|
||||
std::string status = stringutil::get_formatted_string(statusLoadingUserInfo, nickname);
|
||||
task->set_status(status);
|
||||
}
|
||||
user.load_user_data();
|
||||
|
|
@ -108,7 +108,7 @@ void data::DataContext::load_application_records(sys::Task *task)
|
|||
if (DataContext::title_is_loaded(record.application_id)) { continue; }
|
||||
|
||||
{
|
||||
const std::string status = stringutil::get_formatted_string(statusLoadingRecords, record.application_id);
|
||||
std::string status = stringutil::get_formatted_string(statusLoadingRecords, record.application_id);
|
||||
task->set_status(status);
|
||||
}
|
||||
DataContext::load_title(record.application_id);
|
||||
|
|
@ -171,7 +171,8 @@ void data::DataContext::import_svi_files(sys::Task *task)
|
|||
|
||||
task->set_status(statusLoadingSvi);
|
||||
|
||||
auto controlData = std::make_unique<NsApplicationControlData>();
|
||||
// auto controlData = std::make_unique<NsApplicationControlData>();
|
||||
NsApplicationControlData controlData{};
|
||||
for (const fslib::DirectoryEntry &entry : sviDir)
|
||||
{
|
||||
const fslib::Path target{sviPath / entry};
|
||||
|
|
@ -186,11 +187,11 @@ void data::DataContext::import_svi_files(sys::Task *task)
|
|||
const bool exists = DataContext::title_is_loaded(applicationID);
|
||||
if (!magicRead || magic != fs::SAVE_META_MAGIC || !idRead || exists) { continue; }
|
||||
|
||||
const bool dataRead = sviFile.read(controlData.get(), SIZE_CTRL_DATA) == SIZE_CTRL_DATA;
|
||||
const bool dataRead = sviFile.read(&controlData, SIZE_CTRL_DATA) == SIZE_CTRL_DATA;
|
||||
if (!dataRead) { continue; }
|
||||
|
||||
std::scoped_lock multiGuard{m_iconQueueMutex, m_titleMutex};
|
||||
m_titleInfo.try_emplace(applicationID, applicationID, *controlData);
|
||||
m_titleInfo.try_emplace(applicationID, applicationID, controlData);
|
||||
m_iconQueue.push_back(&m_titleInfo.at(applicationID));
|
||||
}
|
||||
}
|
||||
|
|
@ -213,9 +214,9 @@ bool data::DataContext::read_cache(sys::Task *task)
|
|||
const char *statusLoadingCache = strings::get_by_name(strings::names::DATA_LOADING_STATUS, 4);
|
||||
task->set_status(statusLoadingCache);
|
||||
|
||||
auto controlData = std::make_unique<NsApplicationControlData>();
|
||||
NsApplicationControlData controlData{};
|
||||
do {
|
||||
const bool dataRead = cacheZip.read(controlData.get(), SIZE_CTRL_DATA) == SIZE_CTRL_DATA;
|
||||
const bool dataRead = cacheZip.read(&controlData, SIZE_CTRL_DATA) == SIZE_CTRL_DATA;
|
||||
if (!dataRead) { continue; }
|
||||
|
||||
std::string_view filename{cacheZip.get_filename()};
|
||||
|
|
@ -227,7 +228,7 @@ bool data::DataContext::read_cache(sys::Task *task)
|
|||
|
||||
std::scoped_lock multiGuard{m_iconQueueMutex, m_titleMutex};
|
||||
|
||||
m_titleInfo.try_emplace(applicationID, applicationID, *controlData);
|
||||
m_titleInfo.try_emplace(applicationID, applicationID, controlData);
|
||||
m_iconQueue.push_back(&m_titleInfo.at(applicationID));
|
||||
} while (cacheZip.next_file());
|
||||
m_cacheIsValid = true;
|
||||
|
|
|
|||
|
|
@ -10,15 +10,26 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
// clang-format off
|
||||
// This seems stupid, but it's the only way, really.
|
||||
struct StateDataStruct : sys::Task::DataStruct
|
||||
{
|
||||
bool clearCache{};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
data::DataContext s_context{};
|
||||
} // namespace
|
||||
|
||||
/// @brief The main routine for the task to load data.
|
||||
static void data_initialize_task(sys::Task *task, bool clearCache);
|
||||
static void data_initialize_task(sys::threadpool::JobData taskData);
|
||||
|
||||
void data::launch_initialization(bool clearCache, std::function<void()> onDestruction)
|
||||
{
|
||||
auto loadingState = DataLoadingState::create(s_context, onDestruction, data_initialize_task, clearCache);
|
||||
auto taskData = std::make_shared<StateDataStruct>();
|
||||
taskData->clearCache = clearCache;
|
||||
|
||||
auto loadingState = DataLoadingState::create(s_context, onDestruction, data_initialize_task, taskData);
|
||||
StateManager::push_state(loadingState);
|
||||
}
|
||||
|
||||
|
|
@ -40,8 +51,12 @@ void data::get_title_info_by_type(FsSaveDataType saveType, data::TitleInfoList &
|
|||
s_context.get_title_info_list_by_type(saveType, listOut);
|
||||
}
|
||||
|
||||
static void data_initialize_task(sys::Task *task, bool clearCache)
|
||||
static void data_initialize_task(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<StateDataStruct>(taskData);
|
||||
sys::Task *task = castData->task;
|
||||
const bool clearCache = castData->clearCache;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
const char *statusFinalizing = strings::get_by_name(strings::names::DATA_LOADING_STATUS, 6);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "error.hpp"
|
||||
#include "fs/SaveMetaData.hpp"
|
||||
#include "fslib.hpp"
|
||||
#include "logging/logger.hpp"
|
||||
#include "strings/strings.hpp"
|
||||
#include "stringutil.hpp"
|
||||
#include "sys/sys.hpp"
|
||||
|
|
@ -16,9 +17,9 @@
|
|||
namespace
|
||||
{
|
||||
// Size of buffer shared between threads.
|
||||
// constexpr size_t FILE_BUFFER_SIZE = 0x600000;
|
||||
constexpr size_t SIZE_FILE_BUFFER = 0x600000;
|
||||
// This one is just for testing something.
|
||||
constexpr size_t SIZE_FILE_BUFFER = 0x200000;
|
||||
// constexpr size_t SIZE_FILE_BUFFER = 0x200000;
|
||||
} // namespace
|
||||
|
||||
// clang-format off
|
||||
|
|
@ -75,7 +76,7 @@ void fs::copy_file(const fslib::Path &source, const fslib::Path &destination, sy
|
|||
if (task)
|
||||
{
|
||||
const std::string sourceString = source.string();
|
||||
const std::string status = stringutil::get_formatted_string(statusTemplate, sourceString.c_str());
|
||||
std::string status = stringutil::get_formatted_string(statusTemplate, sourceString.c_str());
|
||||
task->set_status(status);
|
||||
task->reset(static_cast<double>(sourceSize));
|
||||
}
|
||||
|
|
@ -110,6 +111,7 @@ void fs::copy_file(const fslib::Path &source, const fslib::Path &destination, sy
|
|||
}
|
||||
// This should be checked. Not sure how yet...
|
||||
destFile.write(localBuffer.get(), localRead);
|
||||
|
||||
i += localRead;
|
||||
if (task) { task->update_current(static_cast<double>(i)); }
|
||||
}
|
||||
|
|
@ -132,7 +134,7 @@ void fs::copy_file_commit(const fslib::Path &source,
|
|||
if (task)
|
||||
{
|
||||
const std::string sourceString = source.string();
|
||||
const std::string status = stringutil::get_formatted_string(copyingStatus, sourceString.c_str());
|
||||
std::string status = stringutil::get_formatted_string(copyingStatus, sourceString.c_str());
|
||||
task->set_status(status);
|
||||
task->reset(static_cast<double>(sourceSize));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ void fs::copy_directory_to_zip(const fslib::Path &source, fs::MiniZip &dest, sys
|
|||
|
||||
if (task)
|
||||
{
|
||||
const std::string status = stringutil::get_formatted_string(ioStatus, sourceString.c_str());
|
||||
std::string status = stringutil::get_formatted_string(ioStatus, sourceString.c_str());
|
||||
task->set_status(status);
|
||||
task->reset(static_cast<double>(fileSize));
|
||||
}
|
||||
|
|
@ -216,7 +216,7 @@ void fs::copy_zip_to_directory(fs::MiniUnzip &unzip, const fslib::Path &dest, in
|
|||
|
||||
if (task)
|
||||
{
|
||||
const std::string status = stringutil::get_formatted_string(statusTemplate, fullDest.get_filename());
|
||||
std::string status = stringutil::get_formatted_string(statusTemplate, fullDest.get_filename());
|
||||
task->set_status(status);
|
||||
task->reset(static_cast<double>(fileSize));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ void logger::log(const char *format, ...) noexcept
|
|||
{
|
||||
static std::mutex logLock{};
|
||||
|
||||
std::array<char, VA_BUFFER_SIZE> vaBuffer{};
|
||||
std::array<char, VA_BUFFER_SIZE> vaBuffer = {0};
|
||||
std::va_list vaList{};
|
||||
va_start(vaList, format);
|
||||
vsnprintf(vaBuffer.data(), VA_BUFFER_SIZE, format, vaList);
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ bool remote::GoogleDrive::download_file(const remote::Item *file, const fslib::P
|
|||
if (!GoogleDrive::token_is_valid() && !GoogleDrive::refresh_token()) { return false; }
|
||||
|
||||
const int64_t itemSize = file->get_size();
|
||||
fslib::File destFile{destination, FsOpenMode_Create | FsOpenMode_Write, itemSize};
|
||||
fslib::File destFile{destination, FsOpenMode_Create | FsOpenMode_Write};
|
||||
if (!destFile)
|
||||
{
|
||||
logger::log("Error downloading file: local file could not be opened for writing!");
|
||||
|
|
@ -307,16 +307,19 @@ bool remote::GoogleDrive::download_file(const remote::Item *file, const fslib::P
|
|||
remote::URL url{URL_DRIVE_FILE_API};
|
||||
url.append_path(file->get_id()).append_parameter("alt", "media");
|
||||
|
||||
curl::DownloadStruct download{.dest = &destFile, .task = task, .fileSize = itemSize};
|
||||
auto download = std::make_shared<curl::DownloadStruct>();
|
||||
download->dest = &destFile;
|
||||
download->task = task;
|
||||
download->fileSize = itemSize;
|
||||
|
||||
curl::prepare_get(m_curl);
|
||||
curl::set_option(m_curl, CURLOPT_HTTPHEADER, header.get());
|
||||
curl::set_option(m_curl, CURLOPT_URL, url.get());
|
||||
curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::download_file_threaded);
|
||||
curl::set_option(m_curl, CURLOPT_WRITEDATA, &download);
|
||||
curl::set_option(m_curl, CURLOPT_WRITEDATA, download.get());
|
||||
|
||||
std::thread writeThread(curl::download_write_thread_function, std::ref(download));
|
||||
sys::threadpool::push_job(curl::download_write_thread_function, download);
|
||||
if (!curl::perform(m_curl)) { return false; }
|
||||
writeThread.join();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,21 +202,23 @@ bool remote::WebDav::download_file(const remote::Item *item, const fslib::Path &
|
|||
remote::URL url{m_origin};
|
||||
url.append_path(item->get_id());
|
||||
|
||||
curl::DownloadStruct download{.dest = &destFile, .task = task, .fileSize = itemSize};
|
||||
auto download = std::make_shared<curl::DownloadStruct>();
|
||||
download->dest = &destFile;
|
||||
download->task = task;
|
||||
download->fileSize = itemSize;
|
||||
|
||||
curl::reset_handle(m_curl);
|
||||
WebDav::append_credentials();
|
||||
curl::set_option(m_curl, CURLOPT_HTTPGET, 1L);
|
||||
curl::set_option(m_curl, CURLOPT_URL, url.get());
|
||||
curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::download_file_threaded);
|
||||
curl::set_option(m_curl, CURLOPT_WRITEDATA, &download);
|
||||
|
||||
std::thread writeThread{curl::download_write_thread_function, std::ref(download)};
|
||||
if (!curl::perform(m_curl)) { return false; }
|
||||
curl::set_option(m_curl, CURLOPT_WRITEDATA, download.get());
|
||||
|
||||
// Copied from gd.cpp implementation.
|
||||
// TODO: Not sure how a thread helps if this parent waits here.
|
||||
// TODO: Read and understand what's actually happening before making comments on other's choices.
|
||||
writeThread.join();
|
||||
sys::threadpool::push_job(curl::download_write_thread_function, download);
|
||||
if (!curl::perform(m_curl)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,19 @@ namespace
|
|||
|
||||
/// @brief This is the single (for now) instance of a storage class.
|
||||
std::unique_ptr<remote::Storage> s_storage{};
|
||||
|
||||
// clang-format off
|
||||
struct DriveStruct : sys::Task::DataStruct
|
||||
{
|
||||
remote::GoogleDrive *drive{};
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
} // namespace
|
||||
|
||||
// Declarations here. Definitions at bottom.
|
||||
/// @brief This is the thread function that handles logging into Google.
|
||||
static void drive_sign_in(sys::Task *task, remote::GoogleDrive *drive);
|
||||
static void drive_sign_in(sys::threadpool::JobData taskData);
|
||||
|
||||
/// @brief This creates (if needed) the JKSV folder for Google Drive and sets it as the root.
|
||||
/// @param drive Pointer to the drive instance..
|
||||
|
|
@ -56,7 +64,10 @@ void remote::initialize_google_drive()
|
|||
remote::GoogleDrive *drive = static_cast<remote::GoogleDrive *>(s_storage.get());
|
||||
if (drive->sign_in_required())
|
||||
{
|
||||
TaskState::create_and_push(drive_sign_in, drive);
|
||||
auto driveStruct = std::make_shared<DriveStruct>();
|
||||
driveStruct->drive = drive;
|
||||
|
||||
TaskState::create_and_push(drive_sign_in, driveStruct);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -92,10 +103,15 @@ remote::Storage *remote::get_remote_storage() noexcept
|
|||
return s_storage.get();
|
||||
}
|
||||
|
||||
static void drive_sign_in(sys::Task *task, remote::GoogleDrive *drive)
|
||||
static void drive_sign_in(sys::threadpool::JobData taskData)
|
||||
{
|
||||
static constexpr const char *STRING_ERROR_SIGNING_IN = "Error signing into Google Drive: %s";
|
||||
|
||||
auto castData = std::static_pointer_cast<DriveStruct>(taskData);
|
||||
|
||||
sys::Task *task = castData->task;
|
||||
remote::GoogleDrive *drive = castData->drive;
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
std::string message{}, deviceCode{};
|
||||
std::time_t expiration{};
|
||||
|
|
@ -106,7 +122,7 @@ static void drive_sign_in(sys::Task *task, remote::GoogleDrive *drive)
|
|||
TASK_FINISH_RETURN(task);
|
||||
}
|
||||
|
||||
task->set_status(message.c_str());
|
||||
task->set_status(message);
|
||||
|
||||
while (std::time(NULL) < expiration && !drive->poll_sign_in(deviceCode))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ bool stringutil::sanitize_string_for_path(const char *stringIn, char *stringOut,
|
|||
continue;
|
||||
}
|
||||
|
||||
const bool asciiCheck = codepoint < 0x0 || codepoint >= 0x7E;
|
||||
const bool asciiCheck = codepoint < 0x1E || codepoint >= 0x7E;
|
||||
if (asciiCheck) { return false; }
|
||||
|
||||
const bool isForbidden = std::find(FORBIDDEN_PATH_CHARACTERS.begin(), FORBIDDEN_PATH_CHARACTERS.end(), codepoint) !=
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
#include "sys/ProgressTask.hpp"
|
||||
|
||||
#include "logging/logger.hpp"
|
||||
|
||||
sys::ProgressTask::ProgressTask(sys::threadpool::JobFunction function, sys::ProgressTask::TaskData taskData)
|
||||
: Task()
|
||||
{
|
||||
taskData->task = this;
|
||||
threadpool::push_job(function, taskData);
|
||||
}
|
||||
|
||||
void sys::ProgressTask::reset(double goal) noexcept
|
||||
{
|
||||
m_current = 0;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,15 @@
|
|||
|
||||
#include "logging/logger.hpp"
|
||||
|
||||
sys::Task::~Task() { m_thread.join(); }
|
||||
sys::Task::Task()
|
||||
: m_isRunning(true) {};
|
||||
|
||||
sys::Task::Task(sys::threadpool::JobFunction function, sys::Task::TaskData taskData)
|
||||
: Task()
|
||||
{
|
||||
taskData->task = this;
|
||||
sys::threadpool::push_job(function, taskData);
|
||||
}
|
||||
|
||||
bool sys::Task::is_running() const noexcept { return m_isRunning; }
|
||||
|
||||
|
|
@ -14,6 +22,12 @@ void sys::Task::set_status(std::string_view status)
|
|||
m_status = status;
|
||||
}
|
||||
|
||||
void sys::Task::set_status(std::string &status)
|
||||
{
|
||||
std::lock_guard statusGuard{m_statusLock};
|
||||
m_status = std::move(status);
|
||||
}
|
||||
|
||||
std::string sys::Task::get_status() noexcept
|
||||
{
|
||||
std::lock_guard statusGuard{m_statusLock};
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void sys::threadpool::initialize()
|
|||
for (size_t i = 0; i < COUNT_THREADS; i++)
|
||||
{
|
||||
// NOTE: If pool size increases, i + 1 isn't going to work anymore.
|
||||
error::libnx(threadCreate(&s_threads[i], thread_pool_function, nullptr, nullptr, SIZE_THREAD_STACK, 0x2B, i + 1));
|
||||
error::libnx(threadCreate(&s_threads[i], thread_pool_function, nullptr, nullptr, SIZE_THREAD_STACK, 0x2C, i + 1));
|
||||
error::libnx(threadStart(&s_threads[i]));
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ void sys::threadpool::push_job(sys::threadpool::JobFunction function, sys::threa
|
|||
{
|
||||
std::lock_guard jobGuard{s_jobMutex};
|
||||
s_jobQueue.push(std::make_pair(function, data));
|
||||
s_jobCondition.notify_all();
|
||||
s_jobCondition.notify_one();
|
||||
}
|
||||
|
||||
static void thread_pool_function(void *)
|
||||
|
|
|
|||
|
|
@ -26,13 +26,30 @@ static void write_meta_file(const fslib::Path &target, const FsSaveDataInfo *sav
|
|||
static void write_meta_zip(fs::MiniZip &zip, const FsSaveDataInfo *saveInfo);
|
||||
static fs::ScopedSaveMount create_scoped_mount(const FsSaveDataInfo *saveInfo);
|
||||
|
||||
void tasks::backup::create_new_backup_local(sys::ProgressTask *task,
|
||||
data::User *user,
|
||||
data::TitleInfo *titleInfo,
|
||||
fslib::Path target,
|
||||
BackupMenuState *spawningState,
|
||||
bool killTask)
|
||||
void tasks::backup::create_new_backup_local(sys::threadpool::JobData taskData)
|
||||
{
|
||||
logger::log("create_new_backup_local");
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
logger::log("static_pointer_cast");
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
logger::log("task");
|
||||
|
||||
data::User *user = castData->user;
|
||||
logger::log("user");
|
||||
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
logger::log("titleInfo");
|
||||
|
||||
const fslib::Path &target = castData->path;
|
||||
logger::log("path");
|
||||
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
logger::log("spawningState");
|
||||
|
||||
const bool killTask = castData->killTask;
|
||||
logger::log("casts & references");
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
|
|
@ -67,13 +84,17 @@ void tasks::backup::create_new_backup_local(sys::ProgressTask *task,
|
|||
if (killTask) { task->complete(); }
|
||||
}
|
||||
|
||||
void tasks::backup::create_new_backup_remote(sys::ProgressTask *task,
|
||||
data::User *user,
|
||||
data::TitleInfo *titleInfo,
|
||||
std::string remoteName,
|
||||
BackupMenuState *spawningState,
|
||||
bool killTask)
|
||||
void tasks::backup::create_new_backup_remote(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
const std::string &remoteName = castData->remoteName;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
const bool &killTask = castData->killTask;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
|
|
@ -103,7 +124,7 @@ void tasks::backup::create_new_backup_remote(sys::ProgressTask *task,
|
|||
|
||||
{
|
||||
const char *uploadFormat = strings::get_by_name(strings::names::IO_STATUSES, 5);
|
||||
const std::string status = stringutil::get_formatted_string(uploadFormat, remoteName.data());
|
||||
std::string status = stringutil::get_formatted_string(uploadFormat, remoteName.data());
|
||||
task->set_status(status);
|
||||
}
|
||||
const bool uploaded = remote->upload_file(tempPath, remoteName, task);
|
||||
|
|
@ -118,14 +139,17 @@ void tasks::backup::create_new_backup_remote(sys::ProgressTask *task,
|
|||
if (killTask) { task->complete(); }
|
||||
}
|
||||
|
||||
void tasks::backup::overwrite_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::overwrite_backup_local(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
const fslib::Path &target = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
const fslib::Path &target = castData->path;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
|
|
@ -138,17 +162,23 @@ void tasks::backup::overwrite_backup_local(sys::ProgressTask *task, BackupMenuSt
|
|||
ui::PopMessageManager::push_message(popTicks, popErrorDeleting);
|
||||
TASK_FINISH_RETURN(task);
|
||||
}
|
||||
tasks::backup::create_new_backup_local(task, user, titleInfo, target, spawningState);
|
||||
|
||||
castData->killTask = true;
|
||||
tasks::backup::create_new_backup_local(castData);
|
||||
}
|
||||
|
||||
void tasks::backup::overwrite_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::overwrite_backup_remote(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
remote::Item *target = taskData->remoteItem;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
remote::Item *target = castData->remoteItem;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(remote) || error::is_null(target)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const uint64_t applicationID = titleInfo->get_application_id();
|
||||
|
|
@ -171,7 +201,7 @@ void tasks::backup::overwrite_backup_remote(sys::ProgressTask *task, BackupMenuS
|
|||
{
|
||||
const char *targetName = target->get_name().data();
|
||||
const char *statusFormat = strings::get_by_name(strings::names::IO_STATUSES, 5);
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, targetName);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, targetName);
|
||||
task->set_status(status);
|
||||
}
|
||||
remote->patch_file(target, tempPath, task);
|
||||
|
|
@ -186,14 +216,17 @@ void tasks::backup::overwrite_backup_remote(sys::ProgressTask *task, BackupMenuS
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::restore_backup_local(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
const fslib::Path &target = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
const fslib::Path &target = castData->path;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const uint64_t applicationID = titleInfo->get_application_id();
|
||||
|
|
@ -211,7 +244,7 @@ void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuStat
|
|||
const bool hasZipExt = std::strstr(targetString.c_str(), STRING_ZIP_EXT);
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
if (autoBackup) { auto_backup(task, taskData); }
|
||||
if (autoBackup) { auto_backup(task, castData); }
|
||||
|
||||
{
|
||||
auto scopedMount = create_scoped_mount(saveInfo);
|
||||
|
|
@ -229,13 +262,13 @@ void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuStat
|
|||
TASK_FINISH_RETURN(task);
|
||||
}
|
||||
|
||||
read_and_process_meta(unzip, taskData, task);
|
||||
read_and_process_meta(unzip, castData, task);
|
||||
auto scopedMount = create_scoped_mount(saveInfo);
|
||||
fs::copy_zip_to_directory(unzip, fs::DEFAULT_SAVE_ROOT, journalSize, task);
|
||||
}
|
||||
else if (isDir)
|
||||
{
|
||||
read_and_process_meta(target, taskData, task);
|
||||
read_and_process_meta(target, castData, task);
|
||||
auto scopedMount = create_scoped_mount(saveInfo);
|
||||
fs::copy_directory_commit(target, fs::DEFAULT_SAVE_ROOT, journalSize, task);
|
||||
}
|
||||
|
|
@ -250,14 +283,18 @@ void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuStat
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::backup::restore_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::restore_backup_remote(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const bool autoBackup = config::get_by_key(config::keys::AUTO_BACKUP_ON_RESTORE);
|
||||
|
|
@ -265,7 +302,7 @@ void tasks::backup::restore_backup_remote(sys::ProgressTask *task, BackupMenuSta
|
|||
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
|
||||
if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
if (autoBackup) { auto_backup(task, taskData); }
|
||||
if (autoBackup) { auto_backup(task, castData); }
|
||||
|
||||
{
|
||||
auto scopedMount = create_scoped_mount(saveInfo);
|
||||
|
|
@ -274,12 +311,12 @@ void tasks::backup::restore_backup_remote(sys::ProgressTask *task, BackupMenuSta
|
|||
}
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
remote::Item *target = taskData->remoteItem;
|
||||
remote::Item *target = castData->remoteItem;
|
||||
const fslib::Path tempPath{PATH_JKSV_TEMP};
|
||||
{
|
||||
const char *name = target->get_name().data();
|
||||
const char *downloadingFormat = strings::get_by_name(strings::names::IO_STATUSES, 4);
|
||||
const std::string status = stringutil::get_formatted_string(downloadingFormat, name);
|
||||
std::string status = stringutil::get_formatted_string(downloadingFormat, name);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +348,7 @@ void tasks::backup::restore_backup_remote(sys::ProgressTask *task, BackupMenuSta
|
|||
}
|
||||
}
|
||||
|
||||
read_and_process_meta(backup, taskData, task);
|
||||
read_and_process_meta(backup, castData, task);
|
||||
{
|
||||
FsSaveDataExtraData extraData{};
|
||||
const bool readExtra = fs::read_save_extra_data(saveInfo, extraData);
|
||||
|
|
@ -333,19 +370,23 @@ void tasks::backup::restore_backup_remote(sys::ProgressTask *task, BackupMenuSta
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::backup::delete_backup_local(sys::Task *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::delete_backup_local(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::Task *task = castData->task;
|
||||
const fslib::Path &path = castData->path;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
const fslib::Path &path = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
if (error::is_null(spawningState)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
{
|
||||
const std::string pathString = path.string();
|
||||
const char *statusFormat = strings::get_by_name(strings::names::IO_STATUSES, 3);
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, pathString.c_str());
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, pathString.c_str());
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -374,13 +415,17 @@ void tasks::backup::delete_backup_local(sys::Task *task, BackupMenuState::TaskDa
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::backup::delete_backup_remote(sys::Task *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::delete_backup_remote(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::Task *task = castData->task;
|
||||
remote::Item *target = castData->remoteItem;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
remote::Item *target = taskData->remoteItem;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(target) || error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
|
|
@ -402,19 +447,23 @@ void tasks::backup::delete_backup_remote(sys::Task *task, BackupMenuState::TaskD
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::backup::upload_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::upload_backup(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
const fslib::Path &path = castData->path;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
const fslib::Path &path = taskData->path;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
{
|
||||
const char *filename = path.get_filename();
|
||||
const char *statusFormat = strings::get_by_name(strings::names::IO_STATUSES, 5);
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, filename);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, filename);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -424,20 +473,23 @@ void tasks::backup::upload_backup(sys::ProgressTask *task, BackupMenuState::Task
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::backup::patch_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
|
||||
void tasks::backup::patch_backup(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<BackupMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
const fslib::Path &path = castData->path;
|
||||
remote::Item *remoteItem = castData->remoteItem;
|
||||
BackupMenuState *spawningState = castData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
const fslib::Path &path = taskData->path;
|
||||
remote::Item *remoteItem = taskData->remoteItem;
|
||||
BackupMenuState *spawningState = taskData->spawningState;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
{
|
||||
const char *filename = path.get_filename();
|
||||
const char *statusFormat = strings::get_by_name(strings::names::IO_STATUSES, 5);
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, filename);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, filename);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -474,10 +526,8 @@ static void auto_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskD
|
|||
std::string backupName = stringutil::get_formatted_string("AUTO - %s - %s", safeNickname, dateString.c_str());
|
||||
if (zip) { backupName += STRING_ZIP_EXT; }
|
||||
|
||||
if (autoUpload && remote)
|
||||
{
|
||||
tasks::backup::create_new_backup_remote(task, user, titleInfo, backupName, spawningState, false);
|
||||
}
|
||||
taskData->killTask = false;
|
||||
if (autoUpload && remote) { tasks::backup::create_new_backup_remote(taskData); }
|
||||
else
|
||||
{
|
||||
// We're going to get the target dir from the path passed.
|
||||
|
|
@ -485,7 +535,7 @@ static void auto_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskD
|
|||
if (lastSlash == target.NOT_FOUND) { return; }
|
||||
|
||||
fslib::Path autoTarget{target.sub_path(lastSlash) / backupName};
|
||||
tasks::backup::create_new_backup_local(task, user, titleInfo, autoTarget, spawningState, false);
|
||||
tasks::backup::create_new_backup_local(taskData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,18 +4,23 @@
|
|||
#include "error.hpp"
|
||||
#include "fs/fs.hpp"
|
||||
#include "fslib.hpp"
|
||||
#include "logging/logger.hpp"
|
||||
#include "strings/strings.hpp"
|
||||
#include "stringutil.hpp"
|
||||
|
||||
void tasks::fileoptions::copy_source_to_destination(sys::ProgressTask *task, FileOptionState::TaskData taskData)
|
||||
void tasks::fileoptions::copy_source_to_destination(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
auto castData = std::static_pointer_cast<FileOptionState::DataStruct>(taskData);
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
const fslib::Path &source = taskData->sourcePath;
|
||||
const fslib::Path &dest = taskData->destPath;
|
||||
const int64_t journalSpace = taskData->journalSize;
|
||||
FileOptionState *spawningState = taskData->spawningState;
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
const fslib::Path &source = castData->sourcePath;
|
||||
const fslib::Path &dest = castData->destPath;
|
||||
const int64_t journalSpace = castData->journalSize;
|
||||
FileOptionState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
const bool sourceIsDir = fslib::directory_exists(source);
|
||||
bool destError = false;
|
||||
|
|
@ -33,7 +38,7 @@ void tasks::fileoptions::copy_source_to_destination(sys::ProgressTask *task, Fil
|
|||
if (destError)
|
||||
{
|
||||
const char *errorFormat = strings::get_by_name(strings::names::FILEOPTION_POPS, 0);
|
||||
const std::string pop = stringutil::get_formatted_string(errorFormat, source.get_filename());
|
||||
std::string pop = stringutil::get_formatted_string(errorFormat, source.get_filename());
|
||||
ui::PopMessageManager::push_message(popTicks, pop);
|
||||
TASK_FINISH_RETURN(task);
|
||||
}
|
||||
|
|
@ -49,8 +54,15 @@ void tasks::fileoptions::copy_source_to_destination(sys::ProgressTask *task, Fil
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::fileoptions::delete_target(sys::Task *task, FileOptionState::TaskData taskData)
|
||||
void tasks::fileoptions::delete_target(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<FileOptionState::DataStruct>(taskData);
|
||||
|
||||
sys::Task *task = castData->task;
|
||||
const fslib::Path &target = castData->sourcePath;
|
||||
const int64_t journalSpace = castData->journalSize;
|
||||
FileOptionState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
// Gonna borrow this. No point in duplicating it.
|
||||
|
|
@ -58,13 +70,9 @@ void tasks::fileoptions::delete_target(sys::Task *task, FileOptionState::TaskDat
|
|||
const char *deletingFormat = strings::get_by_name(strings::names::IO_STATUSES, 3);
|
||||
const char *errorFormat = strings::get_by_name(strings::names::FILEOPTION_POPS, 1);
|
||||
|
||||
const fslib::Path &target = taskData->sourcePath;
|
||||
const int64_t journalSpace = taskData->journalSize;
|
||||
FileOptionState *spawningState = taskData->spawningState;
|
||||
|
||||
{
|
||||
const char *filename = target.get_filename();
|
||||
const std::string status = stringutil::get_formatted_string(deletingFormat, filename);
|
||||
const char *filename = target.get_filename();
|
||||
std::string status = stringutil::get_formatted_string(deletingFormat, filename);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -77,16 +85,16 @@ void tasks::fileoptions::delete_target(sys::Task *task, FileOptionState::TaskDat
|
|||
|
||||
if (deleteError)
|
||||
{
|
||||
const char *filename = target.get_filename();
|
||||
const std::string pop = stringutil::get_formatted_string(errorFormat, filename);
|
||||
const char *filename = target.get_filename();
|
||||
std::string pop = stringutil::get_formatted_string(errorFormat, filename);
|
||||
ui::PopMessageManager::push_message(popTicks, pop);
|
||||
}
|
||||
|
||||
const bool commitError = needsCommit && error::fslib(fslib::commit_data_to_file_system(target.get_device_name()));
|
||||
if (commitError)
|
||||
{
|
||||
const char *filename = target.get_filename();
|
||||
const std::string pop = stringutil::get_formatted_string(errorFormat, filename);
|
||||
const char *filename = target.get_filename();
|
||||
std::string pop = stringutil::get_formatted_string(errorFormat, filename);
|
||||
ui::PopMessageManager::push_message(popTicks, pop);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,24 @@
|
|||
#include "stringutil.hpp"
|
||||
#include "tasks/backup.hpp"
|
||||
|
||||
void tasks::mainmenu::backup_all_for_all_local(sys::ProgressTask *task, MainMenuState::TaskData taskData)
|
||||
void tasks::mainmenu::backup_all_for_all_local(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<MainMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::UserList &userList = castData->userList;
|
||||
const bool exportZip = config::get_by_key(config::keys::EXPORT_TO_ZIP);
|
||||
data::UserList &userList = taskData->userList;
|
||||
|
||||
// This is to pass and use the already written backup function.
|
||||
auto backupStruct = std::make_shared<BackupMenuState::DataStruct>();
|
||||
backupStruct->task = castData->task;
|
||||
backupStruct->killTask = false; // Just to be sure.
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
for (data::User *user : userList)
|
||||
{
|
||||
backupStruct->user = user;
|
||||
|
||||
const int64_t titleCount = user->get_total_data_entries();
|
||||
for (int64_t i = 0; i < titleCount; i++)
|
||||
{
|
||||
|
|
@ -34,6 +43,7 @@ void tasks::mainmenu::backup_all_for_all_local(sys::ProgressTask *task, MainMenu
|
|||
data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID);
|
||||
if (error::is_null(titleInfo)) { continue; }
|
||||
|
||||
backupStruct->titleInfo = titleInfo;
|
||||
const fslib::Path workDir{config::get_working_directory()};
|
||||
const fslib::Path targetDir{workDir / titleInfo->get_path_safe_title()};
|
||||
const bool exists = fslib::directory_exists(targetDir);
|
||||
|
|
@ -42,7 +52,7 @@ void tasks::mainmenu::backup_all_for_all_local(sys::ProgressTask *task, MainMenu
|
|||
|
||||
const char *pathSafe = user->get_path_safe_nickname();
|
||||
const std::string dateString = stringutil::get_date_string();
|
||||
std::string name = stringutil::get_formatted_string("%s - %s", pathSafe, dateString.c_str());
|
||||
const std::string name = stringutil::get_formatted_string("%s - %s", pathSafe, dateString.c_str());
|
||||
fslib::Path finalTarget{targetDir / name};
|
||||
if (exportZip) { finalTarget += ".zip"; }
|
||||
else
|
||||
|
|
@ -51,23 +61,32 @@ void tasks::mainmenu::backup_all_for_all_local(sys::ProgressTask *task, MainMenu
|
|||
if (createError) { continue; }
|
||||
}
|
||||
|
||||
tasks::backup::create_new_backup_local(task, user, titleInfo, finalTarget, nullptr, false);
|
||||
backupStruct->path = std::move(finalTarget);
|
||||
tasks::backup::create_new_backup_local(backupStruct);
|
||||
}
|
||||
}
|
||||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::mainmenu::backup_all_for_all_remote(sys::ProgressTask *task, MainMenuState::TaskData taskData)
|
||||
void tasks::mainmenu::backup_all_for_all_remote(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<MainMenuState::DataStruct>(taskData);
|
||||
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
if (error::is_null(task)) { return; }
|
||||
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const data::UserList &userList = taskData->userList;
|
||||
auto backupStruct = std::make_shared<BackupMenuState::DataStruct>();
|
||||
backupStruct->task = task;
|
||||
backupStruct->killTask = false;
|
||||
|
||||
const data::UserList &userList = castData->userList;
|
||||
for (data::User *user : userList)
|
||||
{
|
||||
if (user->get_account_save_type() == FsSaveDataType_System) { continue; }
|
||||
backupStruct->user = user;
|
||||
|
||||
const int64_t titleCount = user->get_total_data_entries();
|
||||
for (int64_t i = 0; i < titleCount; i++)
|
||||
|
|
@ -84,6 +103,7 @@ void tasks::mainmenu::backup_all_for_all_remote(sys::ProgressTask *task, MainMen
|
|||
data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID);
|
||||
if (error::is_null(titleInfo)) { continue; }
|
||||
|
||||
backupStruct->titleInfo = titleInfo;
|
||||
const std::string_view remoteTitle =
|
||||
remote->supports_utf8() ? titleInfo->get_title() : titleInfo->get_path_safe_title();
|
||||
const bool exists = remote->directory_exists(remoteTitle);
|
||||
|
|
@ -95,9 +115,10 @@ void tasks::mainmenu::backup_all_for_all_remote(sys::ProgressTask *task, MainMen
|
|||
|
||||
const char *pathSafe = user->get_path_safe_nickname();
|
||||
const std::string dateString = stringutil::get_date_string();
|
||||
const std::string remoteName = stringutil::get_formatted_string("%s - %s.zip", pathSafe, dateString.c_str());
|
||||
std::string remoteName = stringutil::get_formatted_string("%s - %s.zip", pathSafe, dateString.c_str());
|
||||
backupStruct->remoteName = std::move(remoteName);
|
||||
|
||||
tasks::backup::create_new_backup_remote(task, user, titleInfo, remoteName, nullptr, false);
|
||||
tasks::backup::create_new_backup_remote(backupStruct);
|
||||
remote->return_to_root();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,15 @@
|
|||
#include "stringutil.hpp"
|
||||
#include "ui/PopMessageManager.hpp"
|
||||
|
||||
void tasks::savecreate::create_save_data_for(sys::Task *task,
|
||||
data::User *user,
|
||||
data::TitleInfo *titleInfo,
|
||||
SaveCreateState *spawningState)
|
||||
void tasks::savecreate::create_save_data_for(sys::threadpool::JobData taskData)
|
||||
{
|
||||
auto castData = std::static_pointer_cast<SaveCreateState::DataStruct>(taskData);
|
||||
|
||||
sys::Task *task = castData->task;
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
SaveCreateState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task) || error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState)) { return; }
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
|
|
@ -20,7 +24,7 @@ void tasks::savecreate::create_save_data_for(sys::Task *task,
|
|||
const char *title = titleInfo->get_title();
|
||||
|
||||
{
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +32,7 @@ void tasks::savecreate::create_save_data_for(sys::Task *task,
|
|||
if (!saveCreated) { ui::PopMessageManager::push_message(popTicks, popFailed); }
|
||||
else
|
||||
{
|
||||
const std::string popMessage = stringutil::get_formatted_string(popSuccess, title);
|
||||
std::string popMessage = stringutil::get_formatted_string(popSuccess, title);
|
||||
ui::PopMessageManager::push_message(popTicks, popMessage);
|
||||
spawningState->refresh_required();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
void tasks::titleoptions::blacklist_title(sys::Task *task, TitleOptionState::TaskData taskData)
|
||||
void tasks::titleoptions::blacklist_title(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<TitleOptionState::DataStruct>(taskData);
|
||||
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
TitleOptionState *spawningState = taskData->spawningState;
|
||||
sys::Task *task = castData->task;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
TitleOptionState *spawningState = castData->spawningState;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(titleInfo) || error::is_null(spawningState))
|
||||
{
|
||||
task->complete();
|
||||
|
|
@ -39,11 +42,14 @@ void tasks::titleoptions::blacklist_title(sys::Task *task, TitleOptionState::Tas
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::titleoptions::delete_all_local_backups_for_title(sys::Task *task, TitleOptionState::TaskData taskData)
|
||||
void tasks::titleoptions::delete_all_local_backups_for_title(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<TitleOptionState::DataStruct>(taskData);
|
||||
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
sys::Task *task = castData->task;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
|
|
@ -53,7 +59,7 @@ void tasks::titleoptions::delete_all_local_backups_for_title(sys::Task *task, Ti
|
|||
{
|
||||
const char *title = titleInfo->get_title();
|
||||
const char *statusFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 0);
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -66,20 +72,23 @@ void tasks::titleoptions::delete_all_local_backups_for_title(sys::Task *task, Ti
|
|||
if (deleteFailed) { ui::PopMessageManager::push_message(popTicks, popFailure); }
|
||||
else
|
||||
{
|
||||
const char *title = titleInfo->get_title();
|
||||
const std::string popMessage = stringutil::get_formatted_string(popSuccess, title);
|
||||
const char *title = titleInfo->get_title();
|
||||
std::string popMessage = stringutil::get_formatted_string(popSuccess, title);
|
||||
ui::PopMessageManager::push_message(popTicks, popMessage);
|
||||
}
|
||||
|
||||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::titleoptions::delete_all_remote_backups_for_title(sys::Task *task, TitleOptionState::TaskData taskData)
|
||||
void tasks::titleoptions::delete_all_remote_backups_for_title(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<TitleOptionState::DataStruct>(taskData);
|
||||
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
sys::Task *task = castData->task;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(titleInfo) || error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const char *title = titleInfo->get_title();
|
||||
|
|
@ -95,7 +104,7 @@ void tasks::titleoptions::delete_all_remote_backups_for_title(sys::Task *task, T
|
|||
|
||||
{
|
||||
const char *statusFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 0);
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -110,17 +119,19 @@ void tasks::titleoptions::delete_all_remote_backups_for_title(sys::Task *task, T
|
|||
|
||||
remote->return_to_root();
|
||||
|
||||
const std::string popMessage = stringutil::get_formatted_string(popSuccess, title);
|
||||
std::string popMessage = stringutil::get_formatted_string(popSuccess, title);
|
||||
ui::PopMessageManager::push_message(popTicks, popMessage);
|
||||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::titleoptions::reset_save_data(sys::Task *task, TitleOptionState::TaskData taskData)
|
||||
void tasks::titleoptions::reset_save_data(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<TitleOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
sys::Task *task = castData->task;
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const uint64_t applicationID = titleInfo->get_application_id();
|
||||
|
|
@ -134,7 +145,7 @@ void tasks::titleoptions::reset_save_data(sys::Task *task, TitleOptionState::Tas
|
|||
{
|
||||
const char *statusFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 1);
|
||||
const char *title = titleInfo->get_title();
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -149,14 +160,16 @@ void tasks::titleoptions::reset_save_data(sys::Task *task, TitleOptionState::Tas
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::titleoptions::delete_save_data_from_system(sys::Task *task, TitleOptionState::TaskData taskData)
|
||||
void tasks::titleoptions::delete_save_data_from_system(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<TitleOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
TitleSelectCommon *titleSelect = taskData->titleSelect;
|
||||
TitleOptionState *spawningState = taskData->spawningState;
|
||||
sys::Task *task = castData->task;
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
TitleSelectCommon *titleSelect = castData->titleSelect;
|
||||
TitleOptionState *spawningState = castData->spawningState;
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(titleSelect) || error::is_null(spawningState))
|
||||
{
|
||||
TASK_FINISH_RETURN(task);
|
||||
|
|
@ -171,7 +184,7 @@ void tasks::titleoptions::delete_save_data_from_system(sys::Task *task, TitleOpt
|
|||
const char *statusFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 2);
|
||||
const char *nickname = user->get_nickname();
|
||||
const char *title = titleInfo->get_title();
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, nickname, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, nickname, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
@ -180,12 +193,7 @@ void tasks::titleoptions::delete_save_data_from_system(sys::Task *task, TitleOpt
|
|||
{
|
||||
const char *popError = strings::get_by_name(strings::names::SAVECREATE_POPS, 2);
|
||||
ui::PopMessageManager::push_message(popTicks, popError);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *title = titleInfo->get_title();
|
||||
const char *popSuccessFormat = strings::get_by_name(strings::names::SAVECREATE_POPS, 0);
|
||||
const std::string popMessage = stringutil::get_formatted_string(popSuccessFormat, title);
|
||||
return;
|
||||
}
|
||||
|
||||
user->erase_save_info_by_id(applicationID);
|
||||
|
|
@ -194,14 +202,16 @@ void tasks::titleoptions::delete_save_data_from_system(sys::Task *task, TitleOpt
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::titleoptions::extend_save_data(sys::Task *task, TitleOptionState::TaskData taskData)
|
||||
void tasks::titleoptions::extend_save_data(sys::threadpool::JobData taskData)
|
||||
{
|
||||
static constexpr int SIZE_MB = 0x100000;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<TitleOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
data::TitleInfo *titleInfo = taskData->titleInfo;
|
||||
sys::Task *task = castData->task;
|
||||
data::User *user = castData->user;
|
||||
data::TitleInfo *titleInfo = castData->titleInfo;
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
|
|
@ -224,7 +234,7 @@ void tasks::titleoptions::extend_save_data(sys::Task *task, TitleOptionState::Ta
|
|||
const char *nickname = user->get_nickname();
|
||||
const char *title = titleInfo->get_title();
|
||||
const char *extendingFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 3);
|
||||
const std::string status = stringutil::get_formatted_string(extendingFormat, nickname, title);
|
||||
std::string status = stringutil::get_formatted_string(extendingFormat, nickname, title);
|
||||
|
||||
task->set_status(status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,21 @@
|
|||
#include "tasks/backup.hpp"
|
||||
#include "ui/ui.hpp"
|
||||
|
||||
void tasks::useroptions::backup_all_for_user_local(sys::ProgressTask *task, UserOptionState::TaskData taskData)
|
||||
void tasks::useroptions::backup_all_for_user_local(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<UserOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
auto backupStruct = std::make_shared<BackupMenuState::DataStruct>();
|
||||
backupStruct->task = task;
|
||||
backupStruct->user = user;
|
||||
backupStruct->killTask = false;
|
||||
|
||||
const fslib::Path workDir{config::get_working_directory()};
|
||||
const bool exportToZip = config::get_by_key(config::keys::EXPORT_TO_ZIP);
|
||||
const int titleCount = user->get_total_data_entries();
|
||||
|
|
@ -31,6 +39,7 @@ void tasks::useroptions::backup_all_for_user_local(sys::ProgressTask *task, User
|
|||
|
||||
data::TitleInfo *titleInfo = data::get_title_info_by_id(saveInfo->application_id);
|
||||
if (error::is_null(titleInfo)) { continue; }
|
||||
backupStruct->titleInfo = titleInfo;
|
||||
|
||||
const fslib::Path targetDir{workDir / titleInfo->get_path_safe_title()};
|
||||
const bool targetExists = fslib::directory_exists(targetDir);
|
||||
|
|
@ -48,19 +57,27 @@ void tasks::useroptions::backup_all_for_user_local(sys::ProgressTask *task, User
|
|||
if (createError) { continue; }
|
||||
}
|
||||
|
||||
tasks::backup::create_new_backup_local(task, user, titleInfo, finalTarget, nullptr, false);
|
||||
backupStruct->path = std::move(finalTarget);
|
||||
tasks::backup::create_new_backup_local(backupStruct);
|
||||
}
|
||||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::useroptions::backup_all_for_user_remote(sys::ProgressTask *task, UserOptionState::TaskData taskData)
|
||||
void tasks::useroptions::backup_all_for_user_remote(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<UserOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(castData->task);
|
||||
data::User *user = castData->user;
|
||||
remote::Storage *remote = remote::get_remote_storage();
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(remote)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
auto backupStruct = std::make_shared<BackupMenuState::DataStruct>();
|
||||
backupStruct->task = task;
|
||||
backupStruct->user = user;
|
||||
backupStruct->killTask = false;
|
||||
|
||||
const int titleCount = user->get_total_data_entries();
|
||||
for (int i = 0; i < titleCount; i++)
|
||||
{
|
||||
|
|
@ -75,6 +92,7 @@ void tasks::useroptions::backup_all_for_user_remote(sys::ProgressTask *task, Use
|
|||
data::TitleInfo *titleInfo = data::get_title_info_by_id(saveInfo->application_id);
|
||||
if (error::is_null(saveInfo)) { continue; }
|
||||
|
||||
backupStruct->titleInfo = titleInfo;
|
||||
const std::string_view remoteTitle =
|
||||
remote->supports_utf8() ? titleInfo->get_title() : titleInfo->get_path_safe_title();
|
||||
const bool dirExists = remote->directory_exists(remoteTitle);
|
||||
|
|
@ -85,21 +103,23 @@ void tasks::useroptions::backup_all_for_user_remote(sys::ProgressTask *task, Use
|
|||
remote->change_directory(target);
|
||||
|
||||
const std::string dateString = stringutil::get_date_string();
|
||||
const std::string remoteName =
|
||||
stringutil::get_formatted_string("%s - %s.zip", user->get_nickname(), dateString.c_str());
|
||||
tasks::backup::create_new_backup_remote(task, user, titleInfo, remoteName, nullptr, false);
|
||||
|
||||
backupStruct->remoteName = stringutil::get_formatted_string("%s - %s.zip", user->get_nickname(), dateString.c_str());
|
||||
tasks::backup::create_new_backup_remote(backupStruct);
|
||||
|
||||
remote->return_to_root();
|
||||
}
|
||||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::useroptions::create_all_save_data_for_user(sys::Task *task, UserOptionState::TaskData taskData)
|
||||
void tasks::useroptions::create_all_save_data_for_user(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<UserOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
UserOptionState *spawningState = taskData->spawningState;
|
||||
sys::Task *task = castData->task;
|
||||
data::User *user = castData->user;
|
||||
UserOptionState *spawningState = castData->spawningState;
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); }
|
||||
|
||||
data::TitleInfoList infoList{};
|
||||
|
|
@ -116,14 +136,14 @@ void tasks::useroptions::create_all_save_data_for_user(sys::Task *task, UserOpti
|
|||
if (!hasSaveType) { continue; }
|
||||
|
||||
{
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
const bool saveCreated = fs::create_save_data_for(user, titleInfo);
|
||||
if (!saveCreated)
|
||||
{
|
||||
const std::string popMessage = stringutil::get_formatted_string(popFailure, title);
|
||||
std::string popMessage = stringutil::get_formatted_string(popFailure, title);
|
||||
ui::PopMessageManager::push_message(popTicks, popMessage);
|
||||
}
|
||||
}
|
||||
|
|
@ -132,14 +152,18 @@ void tasks::useroptions::create_all_save_data_for_user(sys::Task *task, UserOpti
|
|||
task->complete();
|
||||
}
|
||||
|
||||
void tasks::useroptions::delete_all_save_data_for_user(sys::Task *task, UserOptionState::TaskData taskData)
|
||||
void tasks::useroptions::delete_all_save_data_for_user(sys::threadpool::JobData taskData)
|
||||
{
|
||||
if (error::is_null(task)) { return; }
|
||||
auto castData = std::static_pointer_cast<UserOptionState::DataStruct>(taskData);
|
||||
|
||||
data::User *user = taskData->user;
|
||||
UserOptionState *spawningState = taskData->spawningState;
|
||||
if (error::is_null(user) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); }
|
||||
if (user->get_account_save_type() == FsSaveDataType_System) { TASK_FINISH_RETURN(task); }
|
||||
sys::Task *task = castData->task;
|
||||
data::User *user = castData->user;
|
||||
UserOptionState *spawningState = castData->spawningState;
|
||||
if (error::is_null(task)) { return; }
|
||||
if (error::is_null(user) || error::is_null(spawningState) || user->get_account_save_type() == FsSaveDataType_System)
|
||||
{
|
||||
TASK_FINISH_RETURN(task);
|
||||
}
|
||||
|
||||
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
|
||||
const char *statusFormat = strings::get_by_name(strings::names::USEROPTION_STATUS, 1);
|
||||
|
|
@ -156,7 +180,7 @@ void tasks::useroptions::delete_all_save_data_for_user(sys::Task *task, UserOpti
|
|||
{
|
||||
data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID);
|
||||
const char *title = titleInfo->get_title();
|
||||
const std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
std::string status = stringutil::get_formatted_string(statusFormat, title);
|
||||
task->set_status(status);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
ui::Menu::Menu(int x, int y, int width, int fontSize, int renderTargetHeight)
|
||||
: m_x(x)
|
||||
, m_y(y)
|
||||
, m_optionHeight(std::round(static_cast<double>(fontSize) * 1.8f))
|
||||
, m_optionHeight(std::floor(static_cast<double>(fontSize) * 1.8f))
|
||||
, m_optionTarget(
|
||||
sdl::TextureManager::load("MENU_" + std::to_string(sm_menuID++), width, m_optionHeight, SDL_TEXTUREACCESS_TARGET))
|
||||
, m_boundingBox(ui::BoundingBox::create(0, 0, width + 12, m_optionHeight + 12))
|
||||
|
|
@ -75,6 +75,12 @@ void ui::Menu::add_option(std::string_view newOption)
|
|||
m_options.push_back(newOption.data());
|
||||
}
|
||||
|
||||
void ui::Menu::add_option(std::string &newOption)
|
||||
{
|
||||
if (m_options.empty()) { m_optionScroll->set_text(newOption, false); }
|
||||
m_options.push_back(std::move(newOption));
|
||||
}
|
||||
|
||||
void ui::Menu::edit_option(int index, std::string_view newOption)
|
||||
{
|
||||
const int optionSize = m_options.size();
|
||||
|
|
@ -95,10 +101,14 @@ void ui::Menu::set_y(int y) noexcept { m_y = y; }
|
|||
|
||||
void ui::Menu::set_width(int width) noexcept { m_width = width; }
|
||||
|
||||
void ui::Menu::reset()
|
||||
void ui::Menu::reset(bool full)
|
||||
{
|
||||
m_selected = 0;
|
||||
m_y = m_originalY;
|
||||
if (full)
|
||||
{
|
||||
m_selected = 0;
|
||||
m_y = m_originalY;
|
||||
}
|
||||
|
||||
m_options.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,17 @@ ui::PopMessage::PopMessage(int ticks, std::string_view message)
|
|||
PopMessage::PERMA_HEIGHT,
|
||||
ui::DialogBox::Type::Light)) {};
|
||||
|
||||
ui::PopMessage::PopMessage(int ticks, std::string &message)
|
||||
: m_ticks(ticks)
|
||||
, m_message(std::move(message))
|
||||
, m_y(PopMessage::START_Y)
|
||||
, m_width(PopMessage::START_WIDTH)
|
||||
, m_dialog(ui::DialogBox::create(PopMessage::START_X,
|
||||
m_y - 6,
|
||||
PopMessage::START_WIDTH,
|
||||
PopMessage::PERMA_HEIGHT,
|
||||
ui::DialogBox::Type::Light)) {};
|
||||
|
||||
void ui::PopMessage::update(double targetY)
|
||||
{
|
||||
update_y(targetY);
|
||||
|
|
|
|||
|
|
@ -86,3 +86,26 @@ void ui::PopMessageManager::push_message(int displayTicks, std::string_view mess
|
|||
auto queuePair = std::make_pair(displayTicks, std::string{message});
|
||||
messageQueue.push_back(std::move(queuePair));
|
||||
}
|
||||
|
||||
void ui::PopMessageManager::push_message(int displayTicks, std::string &message)
|
||||
{
|
||||
PopMessageManager &manager = PopMessageManager::get_instance();
|
||||
std::mutex &queueMutex = manager.m_queueMutex;
|
||||
std::mutex &messageMutex = manager.m_messageMutex;
|
||||
auto &messageQueue = manager.m_messageQueue;
|
||||
auto &messages = manager.m_messages;
|
||||
|
||||
{
|
||||
std::lock_guard messageGuard{messageMutex};
|
||||
if (!messages.empty())
|
||||
{
|
||||
ui::PopMessage &back = messages.back();
|
||||
const std::string_view lastMessage = back.get_message();
|
||||
if (lastMessage == message) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
std::lock_guard queueGuard(queueMutex);
|
||||
auto queuePair = std::make_pair(displayTicks, std::move(message));
|
||||
messageQueue.push_back(std::move(queuePair));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user