From 7ca186fe93143c0e91c89f1a3d2c1aeb15626be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Mar 2017 10:31:58 +0100 Subject: [PATCH] Initial work on StorageFolderBrowser --- UWP/StorageFileLoader.cpp | 2 +- UWP/StorageFolderBrowser.cpp | 101 +++++++++++++++++++++++++++++++++++ UWP/StorageFolderBrowser.h | 70 ++++++++++++++++++++++++ UWP/UWP.vcxproj | 2 + UWP/UWP.vcxproj.filters | 2 + 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 UWP/StorageFolderBrowser.cpp create mode 100644 UWP/StorageFolderBrowser.h diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index 11a9fcb930..9e90b8b2ef 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -10,7 +10,7 @@ using namespace Concurrency; using namespace Windows::Storage; using namespace Windows::Storage::Streams; -std::mutex initMutex; +static std::mutex initMutex; StorageFileLoader::StorageFileLoader(Windows::Storage::StorageFile ^file) { file_ = file; diff --git a/UWP/StorageFolderBrowser.cpp b/UWP/StorageFolderBrowser.cpp new file mode 100644 index 0000000000..e5c6149d4c --- /dev/null +++ b/UWP/StorageFolderBrowser.cpp @@ -0,0 +1,101 @@ +#include "pch.h" +#include "ppltasks.h" + +#include "base/logging.h" +#include "thread/threadutil.h" + +#include "StorageFolderBrowser.h" +#include "UWPUtil.h" + +using namespace Concurrency; +using namespace Windows::Storage; +using namespace Windows::Storage::Streams; + +static std::mutex initMutex; + +StorageFolderBrowser::StorageFolderBrowser(Windows::Storage::StorageFolder ^folder) : folder_(folder) { + thread_.reset(new std::thread([this]() { this->threadfunc(); })); + + path_ = FromPlatformString(folder->Path); + displayName_ = FromPlatformString(folder->DisplayName); +} + +void StorageFolderBrowser::threadfunc() { + setCurrentThreadName("StorageFileLoader"); + + initMutex.lock(); + + /* + auto opentask = create_task(folder_->GetItemsAsync()->OpenReadAsync()).then([this](IRandomAccessStreamWithContentType ^stream) { + stream_ = stream; + active_ = true; + }); + + try { + opentask.wait(); + } + catch (const std::exception& e) { + operationFailed_ = true; + // TODO: What do we do? + const char *what = e.what(); + ILOG("%s", what); + } + catch (Platform::COMException ^e) { + + } + + auto sizetask = create_task(file_->GetBasicPropertiesAsync()).then([this](Windows::Storage::FileProperties::BasicProperties ^props) { + size_ = props->Size; + }); + try { + sizetask.wait(); + } + catch (const std::exception& e) { + const char *what = e.what(); + ILOG("%s", what); + } + catch (Platform::COMException ^e) { + std::string what = FromPlatformString(e->ToString()); + ILOG("%s", what.c_str()); + } + */ + initMutex.unlock(); + + std::unique_lock lock(mutex_); + while (active_) { + if (!operationRequested_) { + cond_.wait(lock); + } + if (operationRequested_) { + switch (operation_.type) { + case OpType::LIST_DIRECTORY: { + + /* + Streams::Buffer ^buf = ref new Streams::Buffer(operation_.size); + operationFailed_ = false; + stream_->Seek(operation_.offset); + auto task = create_task(stream_->ReadAsync(buf, operation_.size, Streams::InputStreamOptions::None)); + Streams::IBuffer ^output = nullptr; + try { + task.wait(); + output = task.get(); + } + catch (const std::exception& e) { + operationFailed_ = true; + const char *what = e.what(); + ILOG("%s", what); + } + operationRequested_ = false; + std::unique_lock lock(mutexResponse_); + response_.buffer = output; + responseAvailable_ = true; + condResponse_.notify_one(); + break;*/ + } + default: + operationRequested_ = false; + break; + } + } + } +} diff --git a/UWP/StorageFolderBrowser.h b/UWP/StorageFolderBrowser.h new file mode 100644 index 0000000000..d5da640fa4 --- /dev/null +++ b/UWP/StorageFolderBrowser.h @@ -0,0 +1,70 @@ +#pragma once +#pragma once + +#include "pch.h" + +#include +#include +#include +#include +#include + +#include "Common/CommonTypes.h" +#include "Core/Loaders.h" + +// This thing is a terrible abomination that wraps asynchronous file access behind a synchronous interface, +// completely defeating MS' design goals for StorageFile. But hey, you gotta do what you gotta do. +// This opens a stream attached to the passed-in file. Multiple of these can be created against one StorageFile. + +class StorageFolderBrowser { +public: + StorageFolderBrowser(Windows::Storage::StorageFolder ^folder); + ~StorageFolderBrowser(); + + std::string Path() const { + return path_; + } + + std::string DisplayName() const { + return displayName_; + } + + +private: + void threadfunc(); + + enum class OpType { + NONE, + LIST_DIRECTORY, + CHANGE_FOLDER, + }; + + struct Operation { + OpType type; + }; + + struct Response { + }; + + std::string path_; + std::string displayName_; + + bool active_ = false; + std::unique_ptr thread_; + + Windows::Storage::StorageFolder ^folder_; + + bool operationRequested_ = false; + Operation operation_{ OpType::NONE }; + std::condition_variable cond_; + std::mutex mutex_; + + bool operationFailed_ = false; + + bool responseAvailable_ = false; + Response response_; + std::condition_variable condResponse_; + std::mutex mutexResponse_; + + int64_t seekPos_ = 0; +}; diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 1eb7303395..72d62dc1cc 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -377,6 +377,7 @@ copy AssetsGold\*.* Assets /Y + @@ -410,6 +411,7 @@ copy AssetsGold\*.* Assets /Y Create + diff --git a/UWP/UWP.vcxproj.filters b/UWP/UWP.vcxproj.filters index b5bea942d5..18938e7ad7 100644 --- a/UWP/UWP.vcxproj.filters +++ b/UWP/UWP.vcxproj.filters @@ -49,6 +49,7 @@ + @@ -61,6 +62,7 @@ +