phase 5: transfer service

This commit is contained in:
2026-04-27 01:21:16 +03:00
parent b5c506cf03
commit 895fee6235
49 changed files with 905 additions and 838 deletions
-13
View File
@@ -1,13 +0,0 @@
#include <string>
#include <switch.h>
int transfer_files(size_t index, AccountUid uid);
bool isClientTransferDone();
bool isClientTransferCancelled();
bool isClientConnectionFailed();
bool isClientProgressKnown();
bool isClientWorkersIdle();
void cancelClientTransfer();
double getClientProgress();
std::string getClientStatusText();
std::string getClientFailReason();
@@ -1,16 +1,15 @@
#pragma once
#include <const.h>
#include "account.hpp"
#include "title.hpp"
#include "util.hpp"
#include <nxst/ui/const.h>
#include <nxst/domain/account.hpp>
#include <nxst/domain/title.hpp>
#include <nxst/domain/util.hpp>
#include <memory>
#include <switch.h>
#include "logger.hpp"
#include <nxst/infra/sys/logger.hpp>
typedef enum { SORT_ALPHA, SORT_LAST_PLAYED, SORT_PLAY_TIME, SORT_MODES_COUNT } sort_t;
inline float g_currentTime = 0;
inline AccountUid g_currentUId;
inline bool g_backupScrollEnabled = 0;
inline bool g_notificationLedAvailable = false;
inline bool g_shouldExitNetworkLoop = false;
@@ -1,21 +1,22 @@
#pragma once
#include <pu/Plutonium>
#include <users_layout.hpp>
#include <titles_layout.hpp>
namespace ui {
class MainApplication : public pu::ui::Application {
public:
using Application::Application;
PU_SMART_CTOR(MainApplication)
void OnLoad() override;
// Layout instance
UsersLayout::Ref usersLayout;
TitlesLayout::Ref titlesLayout;
};
#pragma once
#include <pu/Plutonium>
#include <nxst/service/transfer_service.hpp>
#include <nxst/ui/users_layout.hpp>
#include <nxst/ui/titles_layout.hpp>
namespace ui {
class MainApplication : public pu::ui::Application {
public:
using Application::Application;
PU_SMART_CTOR(MainApplication)
void OnLoad() override;
UsersLayout::Ref users_layout;
TitlesLayout::Ref titles_layout;
nxst::TransferService transfer;
};
}
@@ -25,9 +25,9 @@
*/
#pragma once
#include "account.hpp"
#include "filesystem.hpp"
#include "io.hpp"
#include <nxst/domain/account.hpp>
#include <nxst/infra/fs/filesystem.hpp>
#include <nxst/infra/fs/io.hpp>
#include <algorithm>
#include <stdlib.h>
#include <string>
@@ -25,9 +25,9 @@
*/
#pragma once
#include "account.hpp"
#include "common.hpp"
#include "io.hpp"
#include <nxst/domain/account.hpp>
#include <nxst/domain/common.hpp>
#include <nxst/infra/fs/io.hpp>
#include <switch.h>
#include <sys/stat.h>
@@ -25,7 +25,7 @@
*/
#pragma once
#include "account.hpp"
#include <nxst/domain/account.hpp>
#include <switch.h>
namespace FileSystem {
@@ -25,10 +25,10 @@
*/
#pragma once
#include "account.hpp"
#include "directory.hpp"
#include "title.hpp"
#include "util.hpp"
#include <nxst/domain/account.hpp>
#include <nxst/infra/fs/directory.hpp>
#include <nxst/domain/title.hpp>
#include <nxst/domain/util.hpp>
#include <dirent.h>
#include <switch.h>
#include <sys/stat.h>
@@ -0,0 +1 @@
#pragma once
@@ -0,0 +1 @@
#pragma once
+76
View File
@@ -0,0 +1,76 @@
#pragma once
#include <atomic>
#include <pthread.h>
#include <string>
#include <switch.h>
#include <nxst/domain/transfer_state.hpp>
namespace nxst {
class TransferService {
public:
int startSend(size_t title_index, AccountUid uid);
void cancelSend();
bool isSendDone() const { return sender_state.done.load(); }
bool isSendCancelled() const { return sender_state.cancelled.load(); }
bool isSendConnectionFailed() const { return sender_state.connection_failed.load(); }
bool isSendProgressKnown() const { return sender_state.bytes_total.load() > 0; }
bool isSendWorkersIdle() const { return !sender_active.load(); }
double sendProgress() const { return sender_state.progress(); }
std::string sendStatusText() const { return sender_state.getStatus(); }
std::string sendFailReason() const { return sender_state.fail_reason; }
int startReceive(size_t title_index, AccountUid uid, std::string title_name);
void cancelReceive();
bool isReceiveDone() const { return receiver_state.done.load(); }
bool isReceiveCancelled() const { return receiver_state.cancelled.load(); }
bool isReceiveWorkersIdle() const {
return !receiver_accept_active.load() && !receiver_broadcast_active.load();
}
double receiveProgress() const { return receiver_state.progress(); }
std::string receiveStatusText() const { return receiver_state.getStatus(); }
bool restoreSucceeded() const { return restore_ok; }
std::string restoreError() const { return restore_error; }
private:
// Sender
TransferState sender_state;
std::atomic<int> sender_udp_sock{-1};
std::atomic<int> sender_tcp_sock{-1};
std::atomic<bool> sender_active{false};
// Receiver
TransferState receiver_state;
std::atomic<int> receiver_client_sock{-1};
std::atomic<int> receiver_listen_sock{-1};
std::atomic<int> receiver_bcast_sock{-1};
std::atomic<bool> receiver_accept_active{false};
std::atomic<bool> receiver_broadcast_active{false};
pthread_t receiver_bcast_thread{};
// Stored at startReceive, read after network transfer completes
size_t restore_title_index{0};
AccountUid restore_uid{};
std::string restore_title_name;
bool restore_ok{false};
std::string restore_error;
// Sender thread
struct SenderArgs { TransferService* svc; size_t title_index; AccountUid uid; };
static void* senderEntry(void* arg);
void runSender(size_t title_index, AccountUid uid);
void failSend(const std::string& reason);
int findServer(char* out_ip);
// Receiver threads
struct AcceptArgs { TransferService* svc; int server_fd; };
static void* broadcastEntry(void* arg);
static void* acceptEntry(void* arg);
void runBroadcast();
void runAccept(int server_fd);
std::string replaceUsername(const std::string& file_path) const;
};
} // namespace nxst
@@ -1,6 +1,6 @@
#pragma once
#include <pu/Plutonium>
#include <theme.hpp>
#include <nxst/ui/theme.hpp>
namespace ui {
+1 -1
View File
@@ -1,6 +1,6 @@
#pragma once
#include <theme.hpp>
#include <nxst/ui/theme.hpp>
#define COLOR(hex) pu::ui::Color::FromHex(hex)
#define BACKGROUND_COLOR theme::color::BgBase
@@ -1,8 +1,8 @@
#pragma once
#include <pu/Plutonium>
#include <theme.hpp>
#include <ui/ui_context.hpp>
#include <account.hpp>
#include <nxst/ui/theme.hpp>
#include <nxst/ui/ui_context.hpp>
#include <nxst/domain/account.hpp>
namespace ui {
@@ -1,6 +1,6 @@
#pragma once
#include <pu/Plutonium>
#include <theme.hpp>
#include <nxst/ui/theme.hpp>
#include <vector>
#include <string>
@@ -1,12 +1,13 @@
#pragma once
#include <pu/Plutonium>
#include <const.h>
#include <title.hpp>
#include <account.hpp>
#include <nxst/ui/const.h>
#include <nxst/domain/title.hpp>
#include <nxst/domain/account.hpp>
#include <unordered_map>
#include <vector>
#include <memory>
#include <ui/header_bar.hpp>
#include <ui/hint_bar.hpp>
#include <nxst/ui/header_bar.hpp>
#include <nxst/ui/hint_bar.hpp>
namespace ui {
@@ -33,6 +34,7 @@ namespace ui {
pu::ui::elm::TextBlock::Ref emptyText;
pu::ui::elm::TextBlock::Ref emptySub;
AccountUid current_uid{};
TitlesFocus focus = TitlesFocus::List;
TitlesAction action = TitlesAction::Transfer;
int lockedListIndex = 0;
@@ -46,7 +48,7 @@ namespace ui {
public:
TitlesLayout();
void InitTitles();
void InitTitles(AccountUid uid);
void LockInput() { m_inputLocked = true; }
void UnlockInput() { m_inputLocked = false; }
@@ -1,7 +1,7 @@
#pragma once
#include <pu/Plutonium>
#include <theme.hpp>
#include <util.hpp>
#include <nxst/ui/theme.hpp>
#include <nxst/domain/util.hpp>
namespace ui {
@@ -2,7 +2,7 @@
#include <string>
#include <optional>
#include <switch.h>
#include <account.hpp>
#include <nxst/domain/account.hpp>
namespace ui {
struct UiContext {
@@ -1,7 +1,7 @@
#include <pu/Plutonium>
#include <const.h>
#include <ui/header_bar.hpp>
#include <ui/hint_bar.hpp>
#include <nxst/ui/const.h>
#include <nxst/ui/header_bar.hpp>
#include <nxst/ui/hint_bar.hpp>
#include <memory>
namespace ui {
-8
View File
@@ -1,8 +0,0 @@
#include <string>
int startSendingThread();
bool isServerTransferDone();
bool isServerTransferCancelled();
bool isServerWorkersIdle();
void cancelServerTransfer();
double getServerProgress();
std::string getServerStatusText();