UI updates

- add import dialog
  this is more complex than I thought
- added scope exit
  grammar sugar
- main dialog is now linked to import dialog
- importer citra file path is fixed
- importer now reports maximum size
- file util is improved with GetDirectoryTreeSize
This commit is contained in:
zhupengfei
2019-08-28 23:02:30 +08:00
parent 7df0b63a1e
commit 8acfe9f304
13 changed files with 448 additions and 27 deletions
+1
View File
@@ -8,6 +8,7 @@ add_library(common STATIC
file_util.h
logging/log.h
misc.cpp
scope_exit.h
string_util.cpp
string_util.h
swap.h
+31
View File
@@ -367,6 +367,37 @@ u64 GetSize(FILE* f) {
return size;
}
u64 GetDirectoryTreeSize(const std::string& path, unsigned int recursion) {
if (!IsDirectory(path)) {
LOG_ERROR(Common_FileSystem, "failed {}: is a file", path);
return 0;
}
std::string real_path = path;
if (real_path.back() != '/' && real_path.back() != '\\') {
real_path += '/';
}
u64 total_size = 0;
const auto callback = [recursion, &total_size](u64* /*num_entries_out*/,
const std::string& directory,
const std::string& virtual_name) -> bool {
if (IsDirectory(directory + virtual_name)) {
if (recursion == 0) {
LOG_WARNING(Common_FileSystem, "directory tree too deep");
return true;
}
total_size += GetDirectoryTreeSize(directory + virtual_name, recursion - 1);
} else { // is a file
total_size += GetSize(directory + virtual_name);
}
return true;
};
return ForeachDirectoryEntry(nullptr, real_path, callback) ? total_size : 0;
}
bool CreateEmptyFile(const std::string& filename) {
LOG_TRACE(Common_Filesystem, "{}", filename);
+3
View File
@@ -59,6 +59,9 @@ u64 GetSize(const int fd);
// Overloaded GetSize, accepts FILE*
u64 GetSize(FILE* f);
// Returns the size of a directory tree
u64 GetDirectoryTreeSize(const std::string& path, unsigned int recursion = 256);
// Returns true if successful, or path already exists.
bool CreateDir(const std::string& filename);
+1 -1
View File
@@ -30,7 +30,7 @@ void PrintLog(std::FILE* f, const std::string& log_class, const std::string& lev
us / 1000000.0, real_class, level, file, line, func, args...);
fflush(stderr);
} catch (...) {
std::cerr << "FMT failed with exception" << std::endl;
std::cerr << "(unexpected) fmt failed with exception" << std::endl;
}
}
+44
View File
@@ -0,0 +1,44 @@
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <utility>
#include "common/common_funcs.h"
namespace detail {
template <typename Func>
struct ScopeExitHelper {
explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {}
~ScopeExitHelper() {
func();
}
Func func;
};
template <typename Func>
ScopeExitHelper<Func> ScopeExit(Func&& func) {
return ScopeExitHelper<Func>(std::forward<Func>(func));
}
} // namespace detail
/**
* This macro allows you to conveniently specify a block of code that will run on scope exit. Handy
* for doing ad-hoc clean-up tasks in a function with multiple returns.
*
* Example usage:
* \code
* const int saved_val = g_foo;
* g_foo = 55;
* SCOPE_EXIT({ g_foo = saved_val; });
*
* if (Bar()) {
* return 0;
* } else {
* return 20;
* }
* \endcode
*/
#define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body)