From e791ac9a46095e0241181da89c35a7c702982c21 Mon Sep 17 00:00:00 2001 From: Hannes Schulze Date: Tue, 4 Feb 2025 19:25:03 +0100 Subject: clean up path logic a bit --- app/mac/scene.mm | 161 +++++++++++++++++++------------------------------------ 1 file changed, 55 insertions(+), 106 deletions(-) (limited to 'app/mac/scene.mm') diff --git a/app/mac/scene.mm b/app/mac/scene.mm index f8e3bb5..133fc18 100644 --- a/app/mac/scene.mm +++ b/app/mac/scene.mm @@ -6,6 +6,7 @@ #import "nes/app/file-browser.hh" #import "nes/common/display.hh" #import "nes/common/path-view.hh" +#import "nes/common/path-builder.hh" #import #import #import @@ -358,26 +359,14 @@ namespace class file_browser_impl final : public nes::app::file_browser { - std::vector components_; - std::vector component_views_; + nes::path_buffer<256> path_; DIR* it_{ nullptr }; nes::u32 it_pos_{ 0 }; public: explicit file_browser_impl() { - if (chdir("/") == -1) - { - perror("chdir"); - std::abort(); - } - - it_ = opendir("."); - if (!it_) - { - perror("opendir"); - std::abort(); - } + reopen_dir(); } ~file_browser_impl() override @@ -387,73 +376,77 @@ namespace auto get_path() const -> nes::path_view override { - return nes::path_view{ component_views_.data(), static_cast(component_views_.size()) }; - } - - auto read_item_count() -> nes::u32 override - { - while (read_next()) - ; - return it_pos_; + return path_.get_components(); } - auto read_items(nes::u32 offset, item* buffer, nes::u32 buffer_size) -> nes::u32 override + auto seek(nes::u32 const position) -> void override { - seek(offset); - auto count = nes::u32{ 0 }; - for (auto i = nes::u32{ 0 }; i < buffer_size; ++i) + if (it_pos_ > position) { - auto item = read_next(); - if (!item) { break; } - buffer[count++] = *item; + reopen_dir(); } - return count; + while (it_pos_ < position) + { + if (!read_next(nullptr)) { break; } + } } - auto navigate_up() -> void override + auto read_next(item* out_item) -> bool override { - if (components_.empty()) { return; } + if (!it_) { return false; } - components_.erase(components_.begin() + static_cast(components_.size() - 1)); - component_views_.erase(component_views_.begin() + static_cast(component_views_.size() - 1)); - auto path = std::string{}; - for (auto const component : get_path()) + while (true) { - path += "/"; - path += component; - } - path += "/"; + errno = 0; + auto entry = readdir(it_); + if (!entry) + { + if (errno) + { + perror("readdir"); + std::abort(); + } - if (chdir(path.c_str()) == -1) - { - perror("chdir"); - std::abort(); + return false; + } + + auto const name = std::string_view{ entry->d_name }; + if (name.length() > max_name_length) { continue; } + if (name[0] == '.') { continue; } + + auto type = item_type::directory; + if (entry->d_type == DT_DIR) { type = item_type::directory; } + else if (entry->d_type == DT_REG) { type = item_type::file; } + else { continue; } + + it_pos_ += 1; + if (out_item) { *out_item = item{ type, name }; } + return true; } + } + + auto navigate_up() -> void override + { + if (!path_.pop()) { return; } - reopen_dir(); + reopen_dir(); } auto navigate(std::string_view const item) -> void override { - auto item_copy = std::string{ item }; - if (chdir(item_copy.c_str()) == -1) - { - perror("chdir"); - std::abort(); - } + if (!path_.push(item)) { std::abort(); } - components_.emplace_back(std::move(item_copy)); - component_views_.clear(); - for (auto& str : components_) { component_views_.emplace_back(str); } - - reopen_dir(); + reopen_dir(); } auto load(std::string_view const item, nes::u8* buffer, nes::u32 const buffer_size) -> nes::u32 override { - auto item_copy = std::string{ item }; - auto const fd = open(item_copy.c_str(), O_RDONLY | O_NOCTTY | O_NDELAY | O_NONBLOCK); + auto file_path = path_; + if (!file_path.push(item)) { std::abort(); } + + auto const path = std::string{ file_path.get_path() }; + auto const fd = open(path.c_str(), O_RDONLY); if (fd == -1) { perror("open"); @@ -482,8 +475,10 @@ namespace private: auto reopen_dir() -> void { - closedir(it_); - it_ = opendir("."); + if (it_) { closedir(it_); } + + auto const path = std::string{ path_.get_path() }; + it_ = opendir(path.c_str()); if (!it_) { perror("opendir"); @@ -491,52 +486,6 @@ namespace } it_pos_ = 0; } - - auto seek(nes::u32 const position) -> void - { - if (it_pos_ > position) - { - reopen_dir(); - } - - while (it_pos_ < position) - { - if (!read_next()) { break; } - } - } - - auto read_next() -> std::optional - { - if (!it_) { return std::nullopt; } - - while (true) - { - errno = 0; - auto entry = readdir(it_); - if (!entry) - { - if (errno) - { - perror("readdir"); - std::abort(); - } - - return std::nullopt; - } - - auto const name = std::string_view{ entry->d_name }; - if (name.length() > max_name_length) { continue; } - if (name[0] == '.') { continue; } - - auto type = item_type::directory; - if (entry->d_type == DT_DIR) { type = item_type::directory; } - else if (entry->d_type == DT_REG) { type = item_type::file; } - else { continue; } - - it_pos_ += 1; - return item{ type, name }; - } - } }; } // namespace -- cgit v1.3.1