filebrowser/picker: backport changes in totalsms (optimise zip peek, remove unused vars and code, optimise folder count, fix missed extension parse).

This commit is contained in:
ITotalJustice
2025-08-03 03:26:24 +01:00
parent a3780bdcea
commit 4300c9ee1b
8 changed files with 250 additions and 156 deletions

View File

@@ -537,6 +537,9 @@ enum class SphairaResult : Result {
ZipOpenNewFileInZip,
ZipWriteInFileInZip,
MmzBadLocalHeaderSig,
MmzBadLocalHeaderRead,
FileBrowserFailedUpload,
FileBrowserDirNotDaybreak,
@@ -685,6 +688,8 @@ enum : Result {
MAKE_SPHAIRA_RESULT_ENUM(ZipOpen2_64),
MAKE_SPHAIRA_RESULT_ENUM(ZipOpenNewFileInZip),
MAKE_SPHAIRA_RESULT_ENUM(ZipWriteInFileInZip),
MAKE_SPHAIRA_RESULT_ENUM(MmzBadLocalHeaderSig),
MAKE_SPHAIRA_RESULT_ENUM(MmzBadLocalHeaderRead),
MAKE_SPHAIRA_RESULT_ENUM(FileBrowserFailedUpload),
MAKE_SPHAIRA_RESULT_ENUM(FileBrowserDirNotDaybreak),
MAKE_SPHAIRA_RESULT_ENUM(AppstoreFailedZipDownload),

View File

@@ -4,6 +4,7 @@
#include <vector>
#include <span>
#include <switch.h>
#include "fs.hpp"
namespace sphaira::mz {
@@ -20,5 +21,12 @@ struct MzSpan {
void FileFuncMem(MzMem* mem, zlib_filefunc64_def* funcs);
void FileFuncSpan(MzSpan* span, zlib_filefunc64_def* funcs);
void FileFuncStdio(zlib_filefunc64_def* funcs);
void FileFuncNative(zlib_filefunc64_def* funcs);
// minizip takes 18ms to open a zip and 4ms to parse the first file entry.
// this results in a dropped frame.
// this version simply reads the local header + file name in 2 reads,
// which takes 1-2ms.
Result PeekFirstFileName(fs::Fs* fs, const fs::FsPath& path, fs::FsPath& name);
} // namespace sphaira::mz

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ui/menus/filebrowser.hpp"
#include "ui/menus/menu_base.hpp"
#include "ui/scrolling_text.hpp"
#include "ui/list.hpp"
@@ -17,13 +18,6 @@ enum FsEntryFlag {
FsEntryFlag_Assoc = 1 << 1,
};
enum class FsType {
Sd,
ImageNand,
ImageSd,
Stdio,
};
enum SortType {
SortType_Size,
SortType_Alphabetical,
@@ -34,77 +28,10 @@ enum OrderType {
OrderType_Ascending,
};
struct FsEntry {
fs::FsPath name{};
fs::FsPath root{};
FsType type{};
u32 flags{FsEntryFlag_None};
auto IsReadOnly() const -> bool {
return flags & FsEntryFlag_ReadOnly;
}
auto IsAssoc() const -> bool {
return flags & FsEntryFlag_Assoc;
}
auto IsSame(const FsEntry& e) const {
return root == e.root && type == e.type;
}
};
// roughly 1kib in size per entry
struct FileEntry : FsDirectoryEntry {
std::string extension{}; // if any
std::string internal_name{}; // if any
std::string internal_extension{}; // if any
s64 file_count{-1}; // number of files in a folder, non-recursive
s64 dir_count{-1}; // number folders in a folder, non-recursive
FsTimeStampRaw time_stamp{};
bool checked_extension{}; // did we already search for an ext?
bool checked_internal_extension{}; // did we already search for an ext?
auto IsFile() const -> bool {
return type == FsDirEntryType_File;
}
auto IsDir() const -> bool {
return !IsFile();
}
auto IsHidden() const -> bool {
return name[0] == '.';
}
auto GetName() const -> std::string {
return name;
}
auto GetExtension() const -> std::string {
return extension;
}
auto GetInternalName() const -> std::string {
if (!internal_name.empty()) {
return internal_name;
}
return GetName();
}
auto GetInternalExtension() const -> std::string {
if (!internal_extension.empty()) {
return internal_extension;
}
return GetExtension();
}
};
struct LastFile {
fs::FsPath name{};
s64 index{};
float offset{};
s64 entries_count{};
};
using FsType = filebrowser::FsType;
using FsEntry = filebrowser::FsEntry;
using FileEntry = filebrowser::FileEntry;
using LastFile = filebrowser::LastFile;
using Callback = std::function<bool(const fs::FsPath& path)>;

View File

@@ -7,7 +7,6 @@
#include "fs.hpp"
#include "option.hpp"
#include "hasher.hpp"
// #include <optional>
#include <span>
namespace sphaira::ui::menu::filebrowser {
@@ -97,6 +96,11 @@ struct FileEntry : FsDirectoryEntry {
}
auto GetExtension() const -> std::string {
if (!checked_extension) {
if (auto ext = std::strrchr(name, '.')) {
return ext+1;
}
}
return extension;
}
@@ -396,14 +400,6 @@ private:
std::vector<FileAssocEntry> m_assoc_entries{};
SelectedStash m_selected{};
// this keeps track of the highlighted file before opening a folder
// if the user presses B to go back to the previous dir
// this vector is popped, then, that entry is checked if it still exists
// if it does, the index becomes that file.
std::vector<LastFile> m_previous_highlighted_file{};
s64 m_index{};
s64 m_selected_count{};
option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_Alphabetical};
option::OptionLong m_order{INI_SECTION, "order", OrderType::OrderType_Descending};
option::OptionBool m_show_hidden{INI_SECTION, "show_hidden", false};
@@ -412,7 +408,6 @@ private:
option::OptionBool m_ignore_read_only{INI_SECTION, "ignore_read_only", false};
bool m_loaded_assoc_entries{};
bool m_is_update_folder{};
bool m_split_screen{};
};