Add FileSystem & LocalStorage

This commit is contained in:
Nomango 2019-10-11 21:12:29 +08:00
parent cbcfc231c6
commit 6d266d7e2d
25 changed files with 329 additions and 322 deletions

View File

@ -77,7 +77,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
@ -95,7 +95,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>

View File

@ -79,7 +79,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
@ -97,7 +97,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>

View File

@ -4,7 +4,7 @@
<ClInclude Include="..\..\src\kiwano-network\kiwano-network.h" />
<ClInclude Include="..\..\src\kiwano-network\src\HttpClient.h" />
<ClInclude Include="..\..\src\kiwano-network\src\HttpRequest.h" />
<ClInclude Include="..\..\src\kiwano-network\src\HttpResponse.h" />
<ClInclude Include="..\..\src\kiwano-network\src\HttpResponse.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano-network\src\HttpClient.cpp" />
@ -75,7 +75,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
@ -93,7 +93,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>

View File

@ -13,7 +13,7 @@
<ClInclude Include="..\..\src\kiwano-network\src\HttpRequest.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano-network\src\HttpResponse.h">
<ClInclude Include="..\..\src\kiwano-network\src\HttpResponse.hpp">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>

View File

@ -86,9 +86,8 @@
<ClInclude Include="..\..\src\kiwano\renderer\win32\TextRenderer.h" />
<ClInclude Include="..\..\src\kiwano\ui\Button.h" />
<ClInclude Include="..\..\src\kiwano\ui\Menu.h" />
<ClInclude Include="..\..\src\kiwano\utils\DataUtil.h" />
<ClInclude Include="..\..\src\kiwano\utils\FileUtil.h" />
<ClInclude Include="..\..\src\kiwano\utils\Path.h" />
<ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h" />
<ClInclude Include="..\..\src\kiwano\utils\FileSystem.h" />
<ClInclude Include="..\..\src\kiwano\utils\ResourceCache.h" />
</ItemGroup>
<ItemGroup>
@ -146,9 +145,8 @@
<ClCompile Include="..\..\src\kiwano\renderer\win32\TextRenderer.cpp" />
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp" />
<ClCompile Include="..\..\src\kiwano\ui\Menu.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\DataUtil.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\FileUtil.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\Path.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\FileSystem.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\ResourceCache.cpp" />
</ItemGroup>
<ItemGroup Label="ProjectConfigurations">
@ -215,7 +213,7 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -233,7 +231,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>../../src;../../src/3rd-party;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../src;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@ -102,9 +102,6 @@
<ClInclude Include="..\..\src\kiwano\platform\modules.h">
<Filter>platform</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\utils\Path.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\config.h" />
<ClInclude Include="..\..\src\kiwano\macros.h" />
<ClInclude Include="..\..\src\kiwano\math\Vec2.hpp">
@ -117,9 +114,6 @@
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\kiwano.h" />
<ClInclude Include="..\..\src\kiwano\utils\DataUtil.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\base\Timer.h">
<Filter>base</Filter>
</ClInclude>
@ -129,9 +123,6 @@
<ClInclude Include="..\..\src\kiwano\base\AsyncTask.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\utils\FileUtil.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\GifSprite.h">
<Filter>2d</Filter>
</ClInclude>
@ -297,6 +288,12 @@
<ClInclude Include="..\..\src\kiwano\base\win32\helper.h">
<Filter>base\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\utils\FileSystem.h">
<Filter>utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp">
@ -338,15 +335,9 @@
<ClCompile Include="..\..\src\kiwano\platform\modules.cpp">
<Filter>platform</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\utils\Path.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\base\Input.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\utils\DataUtil.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\base\Timer.cpp">
<Filter>base</Filter>
</ClCompile>
@ -356,9 +347,6 @@
<ClCompile Include="..\..\src\kiwano\base\AsyncTask.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\utils\FileUtil.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\GifSprite.cpp">
<Filter>2d</Filter>
</ClCompile>
@ -473,5 +461,11 @@
<ClCompile Include="..\..\src\kiwano\base\Component.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\utils\FileSystem.cpp">
<Filter>utils</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#include <kiwano/base/Logger.h>
#include <kiwano/utils/FileUtil.h>
#include <kiwano/utils/FileSystem.h>
#include "Sound.h"
#include "AudioEngine.h"
@ -54,7 +54,7 @@ namespace kiwano
bool Sound::Load(String const& file_path)
{
if (!FileUtil::ExistsFile(file_path))
if (!FileSystem::GetInstance()->IsFileExists(file_path))
{
KGE_WARNING_LOG(L"Media file '%s' not found", file_path.c_str());
return false;
@ -65,7 +65,9 @@ namespace kiwano
Close();
}
HRESULT hr = transcoder_.LoadMediaFile(file_path);
String full_path = FileSystem::GetInstance()->GetFullPathForFile(file_path);
HRESULT hr = transcoder_.LoadMediaFile(full_path);
if (FAILED(hr))
{

View File

@ -24,4 +24,4 @@
#include "src/ImGuiModule.h"
// ImGui
#include <imgui/imgui.h>
#include <3rd-party/imgui/imgui.h>

View File

@ -1,7 +1,7 @@
// dear imgui: Renderer for Kiwano (DirectX10)
#pragma once
#include <imgui/imgui.h>
#include <3rd-party/imgui/imgui.h>
struct ID3D10Device;

View File

@ -1,7 +1,7 @@
// dear imgui: Renderer for Kiwano (DirectX11)
#pragma once
#include <imgui/imgui.h>
#include <3rd-party/imgui/imgui.h>
struct ID3D11Device;
struct ID3D11DeviceContext;

View File

@ -21,5 +21,5 @@
#pragma once
#include "src/HttpRequest.h"
#include "src/HttpResponse.h"
#include "src/HttpResponse.hpp"
#include "src/HttpClient.h"

View File

@ -22,12 +22,12 @@
#include <codecvt>
#include "HttpRequest.h"
#include "HttpResponse.h"
#include "HttpResponse.hpp"
#include "HttpClient.h"
#include <kiwano/base/Logger.h>
#include <kiwano/platform/Application.h>
#include <curl/curl.h> // CURL
#include <3rd-party/curl/curl.h> // CURL
namespace
{

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/core/Function.hpp>
#include <kiwano/core/function.hpp>
#include <kiwano/core/basic_json.hpp>
#include <kiwano/base/ObjectBase.h>
#include <kiwano/base/SmartPtr.hpp>

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#include "../Logger.h"
#include <StackWalker/StackWalker.h>
#include <3rd-party/StackWalker/StackWalker.h>
namespace kiwano
{

View File

@ -135,9 +135,8 @@
// utils
//
#include "utils/Path.h"
#include "utils/DataUtil.h"
#include "utils/FileUtil.h"
#include "utils/FileSystem.h"
#include "utils/LocalStorage.h"
#include "utils/ResourceCache.h"

View File

@ -21,7 +21,7 @@
#include "Renderer.h"
#include "../base/win32/helper.h"
#include "../base/Window.h"
#include "../utils/FileUtil.h"
#include "../utils/FileSystem.h"
namespace kiwano
{
@ -247,7 +247,7 @@ namespace kiwano
hr = E_UNEXPECTED;
}
if (!FileUtil::ExistsFile(file_path))
if (!FileSystem::GetInstance()->IsFileExists(file_path))
{
KGE_WARNING_LOG(L"Texture file '%s' not found!", file_path.c_str());
hr = E_FAIL;
@ -255,8 +255,10 @@ namespace kiwano
if (SUCCEEDED(hr))
{
String full_path = FileSystem::GetInstance()->GetFullPathForFile(file_path);
ComPtr<IWICBitmapDecoder> decoder;
hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, file_path);
hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path);
if (SUCCEEDED(hr))
{
@ -363,7 +365,7 @@ namespace kiwano
hr = E_UNEXPECTED;
}
if (!FileUtil::ExistsFile(file_path))
if (!FileSystem::GetInstance()->IsFileExists(file_path))
{
KGE_WARNING_LOG(L"Gif texture file '%s' not found!", file_path.c_str());
hr = E_FAIL;
@ -371,8 +373,10 @@ namespace kiwano
if (SUCCEEDED(hr))
{
String full_path = FileSystem::GetInstance()->GetFullPathForFile(file_path);
ComPtr<IWICBitmapDecoder> decoder;
hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, file_path);
hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path);
if (SUCCEEDED(hr))
{
@ -586,15 +590,19 @@ namespace kiwano
hr = E_UNEXPECTED;
}
Vector<String> full_paths(file_paths);
if (SUCCEEDED(hr))
{
for (const auto& file_path : file_paths)
for (auto& file_path : full_paths)
{
if (!FileUtil::ExistsFile(file_path))
if (!FileSystem::GetInstance()->IsFileExists(file_path))
{
KGE_WARNING_LOG(L"Font file '%s' not found!", file_path.c_str());
hr = E_FAIL;
}
file_path = FileSystem::GetInstance()->GetFullPathForFile(file_path);
}
}
@ -603,7 +611,7 @@ namespace kiwano
LPVOID collection_key = nullptr;
std::uint32_t collection_key_size = 0;
hr = font_collection_loader_->AddFilePaths(file_paths, &collection_key, &collection_key_size);
hr = font_collection_loader_->AddFilePaths(full_paths, &collection_key, &collection_key_size);
if (SUCCEEDED(hr))
{

View File

@ -0,0 +1,208 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "FileSystem.h"
#include "../platform/modules.h"
namespace kiwano
{
namespace
{
inline String ConvertPathFormat(String const& path)
{
// C:\a\b\c.txt => C:/a/b/c.txt
size_t len = path.length();
String result = path;
for (size_t i = 0; i < len; i++)
{
if (result[i] == L'\\')
{
result[i] = L'/';
}
}
return result;
}
inline bool IsFileExists(String const& path)
{
DWORD dwAttrib = ::GetFileAttributesW(path.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
}
FileSystem::FileSystem()
{
}
FileSystem::~FileSystem()
{
}
void FileSystem::AddSearchPath(String const& path)
{
String search_path = ConvertPathFormat(path);
if (!search_path.empty() && search_path[search_path.length() - 1] != L'/')
{
search_path += L"/";
}
search_paths_.push_back(search_path);
}
void FileSystem::SetSearchPaths(Vector<String> const& paths)
{
search_paths_ = paths;
for (auto& path : search_paths_)
{
path = ConvertPathFormat(path);
if (!path.empty() && path[path.length() - 1] != L'/')
{
path += L"/";
}
}
}
String FileSystem::GetFullPathForFile(String const& file) const
{
if (file.empty())
{
return L"";
}
if (IsAbsolutePath(file))
{
return file;
}
// Search file path cache
auto cache_iter = file_lookup_cache_.find(file);
if (cache_iter != file_lookup_cache_.end())
{
return cache_iter->second;
}
String dict_path;
// Search file path dictionary
auto iter = file_lookup_dict_.find(file);
if (iter != file_lookup_dict_.end())
{
dict_path = iter->second;
}
else
{
dict_path = ConvertPathFormat(file);
}
if (kiwano::IsFileExists(dict_path))
{
file_lookup_cache_.emplace(file, dict_path);
return dict_path;
}
for (const auto& search_path : search_paths_)
{
String full_path = search_path + dict_path;
if (kiwano::IsFileExists(full_path))
{
file_lookup_cache_.emplace(file, full_path); // Save to cache
return full_path;
}
}
// File not found
return L"";
}
void FileSystem::AddFileLookupRule(String const& key, String const& file_path)
{
file_lookup_dict_.emplace(key, ConvertPathFormat(file_path));
}
void FileSystem::SetFileLookupDictionary(UnorderedMap<String, String> const& dict)
{
file_lookup_cache_.clear();
file_lookup_dict_ = dict;
}
bool FileSystem::IsFileExists(String const& file_path) const
{
if (IsAbsolutePath(file_path))
{
return kiwano::IsFileExists(file_path);
}
else
{
String full_path = GetFullPathForFile(file_path);
return !full_path.empty();
}
}
bool FileSystem::IsAbsolutePath(String const& path) const
{
// like "C:\some.file"
return path.length() > 2 && ((std::isalpha(path[0]) && path[1] == L':') || (path[0] == L'/' && path[1] == L'/'));
}
bool FileSystem::RemoveFile(String const& file_path) const
{
if (::DeleteFileW(file_path.c_str()))
return true;
return false;
}
bool FileSystem::ExtractResourceToFile(Resource const& res, String const& dest_file_name) const
{
HANDLE file_handle = ::CreateFileW(
dest_file_name.c_str(),
GENERIC_WRITE,
NULL,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
Resource::Data data = res.GetData();
if (data)
{
DWORD written_bytes = 0;
::WriteFile(file_handle, data.buffer, data.size, &written_bytes, NULL);
::CloseHandle(file_handle);
return true;
}
else
{
::CloseHandle(file_handle);
::DeleteFile(dest_file_name.c_str());
}
return false;
}
}

View File

@ -19,28 +19,55 @@
// THE SOFTWARE.
#pragma once
#include "../macros.h"
#include "../base/Resource.h"
namespace kiwano
{
// 文件
class KGE_API FileUtil
class KGE_API FileSystem
: public Singleton<FileSystem>
{
public:
// 删除文件
static bool Delete(String const& file_path);
KGE_DECLARE_SINGLETON(FileSystem);
// 释放二进制资源到临时文件目录
static bool Extract(
Resource const& res, /* 资源 */
String const& dest_file_name /* 目标文件名 */
);
public:
// 添加文件搜索路径
void AddSearchPath(String const& path);
// 设置文件搜索路径
void SetSearchPaths(Vector<String> const& paths);
// 获取文件的完整路径
String GetFullPathForFile(String const& file) const;
// 添加文件路径查找字典规则
void AddFileLookupRule(String const& key, String const& file_path);
// 设置文件路径查找字典
void SetFileLookupDictionary(UnorderedMap<String, String> const& dict);
// 文件是否存在
static bool ExistsFile(String const& file_path);
bool IsFileExists(String const& file_path) const;
// 文件夹是否存在
static bool ExistsDirectory(String const& dir_path);
// 判断路径是否是绝对路径
bool IsAbsolutePath(String const& path) const;
// 删除文件
bool RemoveFile(String const& file_path) const;
// 释放二进制资源到临时文件目录
bool ExtractResourceToFile(
Resource const& res, /* 资源 */
String const& dest_file_name /* 目标文件名 */
) const;
private:
FileSystem();
~FileSystem();
private:
Vector<String> search_paths_;
UnorderedMap<String, String> file_lookup_dict_;
mutable UnorderedMap<String, String> file_lookup_cache_;
};
}

View File

@ -1,81 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "FileUtil.h"
#include "../platform/modules.h"
namespace kiwano
{
bool FileUtil::Delete(String const& file_path)
{
if (::DeleteFile(file_path.c_str()))
return true;
return false;
}
bool FileUtil::Extract(Resource const& res, String const& dest_file_name)
{
HANDLE file_handle = ::CreateFile(
dest_file_name.c_str(),
GENERIC_WRITE,
NULL,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY,
NULL
);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
Resource::Data data = res.GetData();
if (data)
{
DWORD written_bytes = 0;
::WriteFile(file_handle, data.buffer, data.size, &written_bytes, NULL);
::CloseHandle(file_handle);
return true;
}
else
{
::CloseHandle(file_handle);
::DeleteFile(dest_file_name.c_str());
}
return false;
}
bool FileUtil::ExistsFile(String const& file_path)
{
DWORD dwAttrib = ::GetFileAttributesW(file_path.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
bool FileUtil::ExistsDirectory(String const& dir_path)
{
DWORD dwAttrib = ::GetFileAttributesW(dir_path.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
}

View File

@ -18,27 +18,27 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "DataUtil.h"
#include "LocalStorage.h"
namespace kiwano
{
DataUtil::DataUtil(String const & file_path, String const & field)
LocalStorage::LocalStorage(String const & file_path, String const & field)
{
SetFilePath(file_path);
SetFieldName(field);
}
void DataUtil::SetFilePath(String const & file_path)
void LocalStorage::SetFilePath(String const & file_path)
{
file_path_ = file_path;
}
void DataUtil::SetFieldName(String const & field_name)
void LocalStorage::SetFieldName(String const & field_name)
{
field_name_ = field_name;
}
bool DataUtil::Exists(String const& key) const
bool LocalStorage::Exists(String const& key) const
{
wchar_t temp[256] = { 0 };
::GetPrivateProfileStringW(
@ -52,7 +52,7 @@ namespace kiwano
return temp[0] == L'\0';
}
bool DataUtil::SaveInt(String const& key, int val) const
bool LocalStorage::SaveInt(String const& key, int val) const
{
BOOL ret = ::WritePrivateProfileStringW(
field_name_.c_str(),
@ -63,7 +63,7 @@ namespace kiwano
return ret == TRUE;
}
bool DataUtil::SaveFloat(String const& key, float val) const
bool LocalStorage::SaveFloat(String const& key, float val) const
{
BOOL ret = ::WritePrivateProfileStringW(
field_name_.c_str(),
@ -74,7 +74,7 @@ namespace kiwano
return ret == TRUE;
}
bool DataUtil::SaveDouble(String const& key, double val) const
bool LocalStorage::SaveDouble(String const& key, double val) const
{
BOOL ret = ::WritePrivateProfileStringW(
field_name_.c_str(),
@ -85,7 +85,7 @@ namespace kiwano
return ret == TRUE;
}
bool DataUtil::SaveBool(String const& key, bool val) const
bool LocalStorage::SaveBool(String const& key, bool val) const
{
BOOL ret = ::WritePrivateProfileStringW(
field_name_.c_str(),
@ -96,7 +96,7 @@ namespace kiwano
return ret == TRUE;
}
bool DataUtil::SaveString(String const& key, String const& val) const
bool LocalStorage::SaveString(String const& key, String const& val) const
{
BOOL ret = ::WritePrivateProfileStringW(
field_name_.c_str(),
@ -107,7 +107,7 @@ namespace kiwano
return ret == TRUE;
}
int DataUtil::GetInt(String const & key, int default_value) const
int LocalStorage::GetInt(String const & key, int default_value) const
{
return ::GetPrivateProfileIntW(
field_name_.c_str(),
@ -117,7 +117,7 @@ namespace kiwano
);
}
float DataUtil::GetFloat(String const & key, float default_value) const
float LocalStorage::GetFloat(String const & key, float default_value) const
{
wchar_t temp[32] = { 0 };
String default_str = String::parse(default_value);
@ -125,7 +125,7 @@ namespace kiwano
return std::stof(temp);
}
double DataUtil::GetDouble(String const & key, double default_value) const
double LocalStorage::GetDouble(String const & key, double default_value) const
{
wchar_t temp[32] = { 0 };
String default_str = String::parse(default_value);
@ -133,7 +133,7 @@ namespace kiwano
return std::stod(temp);
}
bool DataUtil::GetBool(String const & key, bool default_value) const
bool LocalStorage::GetBool(String const & key, bool default_value) const
{
int nValue = ::GetPrivateProfileIntW(
field_name_.c_str(),
@ -143,7 +143,7 @@ namespace kiwano
return nValue == TRUE;
}
String DataUtil::GetString(String const & key, String const & default_value) const
String LocalStorage::GetString(String const & key, String const & default_value) const
{
wchar_t temp[256] = { 0 };
::GetPrivateProfileStringW(
@ -156,4 +156,4 @@ namespace kiwano
);
return temp;
}
}
}

View File

@ -25,19 +25,19 @@
namespace kiwano
{
//
// 数据存取工具 (.ini 格式)
// 一个 DataUtil 对象表示一个数据储存实体, 用于存取简单格式 (bool | int | float | double | String) 的数据
// 本地数据存取工具
// LocalStorage 用于在本地存取数据, 支持的数据类型包括 (bool | int | float | double | String)
// 数据都采用 key-value (键-值) 的方式存取
// 例如, 保存一份游戏最高分, 以便下次进行游戏时读取:
// DataUtil data; // 创建数据对象
// data.SaveInt(L"best score", 20); // 保存最高分 20
// int best = data.GetInt(L"best score"); // 读取之前储存的最高分
// LocalStorage data; // 创建数据对象
// data.SaveInt(L"best-score", 20); // 保存最高分 20
// int best = data.GetInt(L"best-score"); // 读取之前储存的最高分
//
class KGE_API DataUtil
class KGE_API LocalStorage
{
public:
DataUtil(
LocalStorage(
String const& file_path = L"./data.ini", // 文件路径
String const& field = L"defalut" // 字段名
);

View File

@ -1,108 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "Path.h"
#include "../platform/modules.h"
#pragma warning (push)
#pragma warning (disable:4091) // ignore warning 4091 (on winSDK 8.1)
#include <shlobj.h>
#pragma warning (pop)
namespace kiwano
{
namespace
{
// 创建指定文件夹
bool CreateFolder(String const& dir_path)
{
if (dir_path.empty() || dir_path.size() >= MAX_PATH)
return false;
wchar_t tmp_dir_path[MAX_PATH] = { 0 };
std::size_t length = dir_path.length();
for (std::size_t i = 0; i < length; ++i)
{
tmp_dir_path[i] = dir_path.at(i);
if (tmp_dir_path[i] == L'\\' || tmp_dir_path[i] == L'/' || i == (length - 1))
{
if (::_waccess(tmp_dir_path, 0) != 0)
{
if (::_wmkdir(tmp_dir_path) != 0)
{
return false;
}
}
}
}
return true;
}
}
String const& Path::GetTemporaryPath()
{
static String temp_path;
if (temp_path.empty())
{
// 设置临时文件保存路径
wchar_t path[_MAX_PATH];
if (0 != ::GetTempPath(_MAX_PATH, path))
{
temp_path.append(path).append(L"\\KiwanoGameTemp\\");
if (!modules::Shlwapi::Get().PathFileExistsW(temp_path.c_str()) && !CreateFolder(temp_path))
{
temp_path = L"";
}
}
}
return temp_path;
}
String const& Path::GetLocalAppDataPath()
{
static String local_app_data_path;
if (local_app_data_path.empty())
{
// 获取 AppData/Local 文件夹的路径
wchar_t path[MAX_PATH] = { 0 };
::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
local_app_data_path = path;
}
return local_app_data_path;
}
String const& Path::GetExeFilePath()
{
static String exe_file_path;
if (exe_file_path.empty())
{
TCHAR path[_MAX_PATH] = { 0 };
if (::GetModuleFileName(nullptr, path, _MAX_PATH) != 0)
{
exe_file_path = path;
}
}
return exe_file_path;
}
}

View File

@ -1,40 +0,0 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include "../macros.h"
#include "../core/core.h"
namespace kiwano
{
// 路径
class KGE_API Path
{
public:
// 获取临时文件目录
static String const& GetTemporaryPath();
// 获取 LocalAppData 目录
static String const& GetLocalAppDataPath();
// 获取当前程序的运行路径
static String const& GetExeFilePath();
};
}

View File

@ -23,7 +23,7 @@
#include "../base/Resource.h"
#include "../2d/include-forwards.h"
#include "../renderer/GifImage.h"
#include <tinyxml2/tinyxml2.h>
#include <3rd-party/tinyxml2/tinyxml2.h>
namespace kiwano
{