Files
sphaira/sphaira/include/ui/menus/install_stream_menu_base.hpp

66 lines
1.6 KiB
C++

#pragma once
#include "ui/menus/menu_base.hpp"
#include "yati/source/stream.hpp"
namespace sphaira::ui::menu::stream {
enum class State {
// not connected.
None,
// just connected, starts the transfer.
Connected,
// set whilst transfer is in progress.
Progress,
// set when the transfer is finished.
Done,
// failed to connect.
Failed,
};
using OnInstallStart = std::function<bool(const char* path)>;
using OnInstallWrite = std::function<bool(const void* buf, size_t size)>;
using OnInstallClose = std::function<void()>;
struct Stream final : yati::source::Stream {
Stream(const fs::FsPath& path, std::stop_token token);
Result ReadChunk(void* buf, s64 size, u64* bytes_read) override;
bool Push(const void* buf, s64 size);
void Disable();
auto& GetPath() const { return m_path; }
private:
fs::FsPath m_path{};
std::stop_token m_token{};
std::vector<u8> m_buffer{};
CondVar m_can_read{};
CondVar m_can_write{};
public:
Mutex m_mutex{};
std::atomic_bool m_active{};
};
struct Menu : MenuBase {
Menu(const std::string& title, u32 flags);
virtual ~Menu();
virtual void Update(Controller* controller, TouchInfo* touch);
virtual void Draw(NVGcontext* vg, Theme* theme);
virtual void OnDisableInstallMode() = 0;
protected:
bool OnInstallStart(const char* path);
bool OnInstallWrite(const void* buf, size_t size);
void OnInstallClose();
private:
std::unique_ptr<Stream> m_source{};
Thread m_thread{};
Mutex m_mutex{};
State m_state{State::None};
};
} // namespace sphaira::ui::menu::stream