Change default char code

This commit is contained in:
Nomango 2020-02-10 13:47:00 +08:00
parent b763064b3d
commit 1e93eddb88
40 changed files with 23314 additions and 458 deletions

View File

@ -93,11 +93,11 @@ struct json_lexer
break; break;
case 't': case 't':
return scan_literal(L"true", token_type::LITERAL_TRUE); return scan_literal("true", token_type::LITERAL_TRUE);
case 'f': case 'f':
return scan_literal(L"false", token_type::LITERAL_FALSE); return scan_literal("false", token_type::LITERAL_FALSE);
case 'n': case 'n':
return scan_literal(L"null", token_type::LITERAL_NULL); return scan_literal("null", token_type::LITERAL_NULL);
case '\"': case '\"':
return scan_string(); return scan_string();

View File

@ -18,6 +18,7 @@ class vector
public: public:
using value_type = _Ty; using value_type = _Ty;
using size_type = size_t; using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = value_type&; using reference = value_type&;
using const_reference = const value_type&; using const_reference = const value_type&;
using iterator = value_type*; using iterator = value_type*;
@ -70,6 +71,7 @@ public:
inline bool empty() const { return size_ == 0; } inline bool empty() const { return size_ == 0; }
inline size_type size() const { return size_; } inline size_type size() const { return size_; }
inline size_type size_in_bytes() const { return size_ * ((size_type)sizeof(_Ty)); } inline size_type size_in_bytes() const { return size_ * ((size_type)sizeof(_Ty)); }
inline size_type max_size() const { return std::numeric_limits<difference_type>::max(); }
inline size_type capacity() const { return capacity_; } inline size_type capacity() const { return capacity_; }
inline reference operator[](size_type off) { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; } inline reference operator[](size_type off) { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; }
inline const_reference operator[](size_type off) const { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; } inline const_reference operator[](size_type off) const { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; }

22875
src/3rd-party/nlohmann/json.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@
#define HEADER_PUGICONFIG_HPP #define HEADER_PUGICONFIG_HPP
// Uncomment this to enable wchar_t mode // Uncomment this to enable wchar_t mode
#define PUGIXML_WCHAR_MODE // #define PUGIXML_WCHAR_MODE
// Uncomment this to enable compact mode // Uncomment this to enable compact mode
// #define PUGIXML_COMPACT // #define PUGIXML_COMPACT

View File

@ -37,7 +37,7 @@ AudioEngine::~AudioEngine() {}
void AudioEngine::SetupComponent() void AudioEngine::SetupComponent()
{ {
KGE_SYS_LOG(L"Creating audio resources"); KGE_SYS_LOG("Creating audio resources");
HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL); HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
@ -56,7 +56,7 @@ void AudioEngine::SetupComponent()
void AudioEngine::DestroyComponent() void AudioEngine::DestroyComponent()
{ {
KGE_SYS_LOG(L"Destroying audio resources"); KGE_SYS_LOG("Destroying audio resources");
if (mastering_voice_) if (mastering_voice_)
{ {

View File

@ -65,7 +65,7 @@ bool Sound::Load(String const& file_path)
{ {
if (!FileSystem::GetInstance().IsFileExists(file_path)) if (!FileSystem::GetInstance().IsFileExists(file_path))
{ {
KGE_WARN(L"Media file '%s' not found", file_path.c_str()); KGE_WARN("Media file '%s' not found", file_path.c_str());
return false; return false;
} }
@ -79,7 +79,7 @@ bool Sound::Load(String const& file_path)
HRESULT hr = transcoder_.LoadMediaFile(full_path); HRESULT hr = transcoder_.LoadMediaFile(full_path);
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_ERROR(L"Load media file failed with HRESULT of %08X", hr); KGE_ERROR("Load media file failed with HRESULT of %08X", hr);
return false; return false;
} }
@ -103,7 +103,7 @@ bool Sound::Load(Resource const& res)
HRESULT hr = transcoder_.LoadMediaResource(res); HRESULT hr = transcoder_.LoadMediaResource(res);
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_ERROR(L"Load media resource failed with HRESULT of %08X", hr); KGE_ERROR("Load media resource failed with HRESULT of %08X", hr);
return false; return false;
} }
@ -126,7 +126,7 @@ void Sound::Play(int loop_count)
{ {
if (!opened_) if (!opened_)
{ {
KGE_ERROR(L"Sound must be opened first!"); KGE_ERROR("Sound must be opened first!");
return; return;
} }
@ -157,7 +157,7 @@ void Sound::Play(int loop_count)
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_ERROR(L"Submitting source buffer failed with HRESULT of %08X", hr); KGE_ERROR("Submitting source buffer failed with HRESULT of %08X", hr);
} }
playing_ = SUCCEEDED(hr); playing_ = SUCCEEDED(hr);

View File

@ -76,7 +76,7 @@ HRESULT Transcoder::LoadMediaFile(String const& file_path)
ComPtr<IMFSourceReader> reader; ComPtr<IMFSourceReader> reader;
hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromURL(file_path.c_str(), nullptr, &reader); hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromURL(MultiByteToWide(file_path).c_str(), nullptr, &reader);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -105,7 +105,7 @@ HRESULT Transcoder::LoadMediaResource(Resource const& res)
if (stream == nullptr) if (stream == nullptr)
{ {
KGE_ERROR(L"SHCreateMemStream failed"); KGE_ERROR("SHCreateMemStream failed");
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
@ -198,7 +198,7 @@ HRESULT Transcoder::ReadSource(IMFSourceReader* reader)
if (data == nullptr) if (data == nullptr)
{ {
KGE_ERROR(L"Low memory"); KGE_ERROR("Low memory");
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
} }
else else

View File

@ -51,7 +51,7 @@ XAudio2::XAudio2()
} }
else else
{ {
KGE_ERROR(L"Load xaudio2.dll failed"); KGE_ERROR("Load xaudio2.dll failed");
throw std::runtime_error("Load xaudio2.dll failed"); throw std::runtime_error("Load xaudio2.dll failed");
} }
} }
@ -79,7 +79,7 @@ MediaFoundation::MediaFoundation()
} }
else else
{ {
KGE_ERROR(L"Load Mfplat.dll failed"); KGE_ERROR("Load Mfplat.dll failed");
throw std::runtime_error("Load Mfplat.dll failed"); throw std::runtime_error("Load Mfplat.dll failed");
} }
@ -92,7 +92,7 @@ MediaFoundation::MediaFoundation()
} }
else else
{ {
KGE_ERROR(L"Load Mfreadwrite.dll failed"); KGE_ERROR("Load Mfreadwrite.dll failed");
throw std::runtime_error("Load Mfreadwrite.dll failed"); throw std::runtime_error("Load Mfreadwrite.dll failed");
} }
} }

View File

@ -18,7 +18,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <codecvt>
#include <thread> #include <thread>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/platform/Application.h> #include <kiwano/platform/Application.h>
@ -34,8 +33,8 @@ using namespace kiwano::network;
uint32_t write_data(void* buffer, uint32_t size, uint32_t nmemb, void* userp) uint32_t write_data(void* buffer, uint32_t size, uint32_t nmemb, void* userp)
{ {
ByteString* recv_buffer = (ByteString*)userp; String* recv_buffer = (String*)userp;
uint32_t total = size * nmemb; uint32_t total = size * nmemb;
// add data to the end of recv_buffer // add data to the end of recv_buffer
// write data maybe called more than once in a single request // write data maybe called more than once in a single request
@ -44,40 +43,6 @@ uint32_t write_data(void* buffer, uint32_t size, uint32_t nmemb, void* userp)
return total; return total;
} }
ByteString convert_to_utf8(String const& str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
ByteString result;
try
{
result = utf8_conv.to_bytes(str.c_str());
}
catch (std::range_error&)
{
// bad conversion
result = WideToMultiByte(str);
}
return result;
}
String convert_from_utf8(ByteString const& str)
{
oc::string_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
String result;
try
{
result = utf8_conv.from_bytes(str);
}
catch (std::range_error&)
{
// bad conversion
result = MultiByteToWide(str);
}
return result;
}
class Curl class Curl
{ {
public: public:
@ -102,8 +67,8 @@ public:
} }
} }
bool Init(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, ByteString* response_data, bool Init(HttpClient* client, Vector<String> const& headers, String const& url, String* response_data,
ByteString* response_header, char* error_buffer) String* response_header, char* error_buffer)
{ {
if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer))
return false; return false;
@ -112,7 +77,7 @@ public:
if (!SetOption(CURLOPT_CONNECTTIMEOUT, client->GetTimeoutForConnect())) if (!SetOption(CURLOPT_CONNECTTIMEOUT, client->GetTimeoutForConnect()))
return false; return false;
const auto ssl_ca_file = wide_to_string(client->GetSSLVerification()); const String& ssl_ca_file = client->GetSSLVerification();
if (ssl_ca_file.empty()) if (ssl_ca_file.empty())
{ {
if (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L)) if (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L))
@ -167,8 +132,8 @@ public:
} }
public: public:
static inline bool GetRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, static inline bool GetRequest(HttpClient* client, Vector<String> const& headers, String const& url,
long* response_code, ByteString* response_data, ByteString* response_header, long* response_code, String* response_data, String* response_header,
char* error_buffer) char* error_buffer)
{ {
Curl curl; Curl curl;
@ -176,9 +141,9 @@ public:
&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.Perform(response_code); && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.Perform(response_code);
} }
static inline bool PostRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, static inline bool PostRequest(HttpClient* client, Vector<String> const& headers, String const& url,
ByteString const& request_data, long* response_code, ByteString* response_data, String const& request_data, long* response_code, String* response_data,
ByteString* response_header, char* error_buffer) String* response_header, char* error_buffer)
{ {
Curl curl; Curl curl;
return curl.Init(client, headers, url, response_data, response_header, error_buffer) return curl.Init(client, headers, url, response_data, response_header, error_buffer)
@ -186,9 +151,9 @@ public:
&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code); && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code);
} }
static inline bool PutRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, static inline bool PutRequest(HttpClient* client, Vector<String> const& headers, String const& url,
ByteString const& request_data, long* response_code, ByteString* response_data, String const& request_data, long* response_code, String* response_data,
ByteString* response_header, char* error_buffer) String* response_header, char* error_buffer)
{ {
Curl curl; Curl curl;
return curl.Init(client, headers, url, response_data, response_header, error_buffer) return curl.Init(client, headers, url, response_data, response_header, error_buffer)
@ -197,8 +162,8 @@ public:
&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code); && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code);
} }
static inline bool DeleteRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, static inline bool DeleteRequest(HttpClient* client, Vector<String> const& headers, String const& url,
long* response_code, ByteString* response_data, ByteString* response_header, long* response_code, String* response_data, String* response_header,
char* error_buffer) char* error_buffer)
{ {
Curl curl; Curl curl;
@ -276,20 +241,19 @@ void HttpClient::NetworkThread()
void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response) void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response)
{ {
bool ok = false; bool ok = false;
long response_code = 0; long response_code = 0;
char error_message[256] = { 0 }; char error_message[256] = { 0 };
ByteString response_header; String response_header;
ByteString response_data; String response_data;
String url = request->GetUrl();
String data = request->GetData();
ByteString url = convert_to_utf8(request->GetUrl()); Vector<String> headers;
ByteString data = convert_to_utf8(request->GetData());
Vector<ByteString> headers;
headers.reserve(request->GetHeaders().size()); headers.reserve(request->GetHeaders().size());
for (const auto& pair : request->GetHeaders()) for (const auto& pair : request->GetHeaders())
{ {
headers.push_back(wide_to_string(pair.first) + ":" + wide_to_string(pair.second)); headers.push_back(pair.first + ":" + pair.second);
} }
switch (request->GetType()) switch (request->GetType())
@ -309,17 +273,17 @@ void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response)
ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message);
break; break;
default: default:
KGE_ERROR(L"HttpClient: unknown request type, only GET, POST, PUT or DELETE is supported"); KGE_ERROR("HttpClient: unknown request type, only GET, POST, PUT or DELETE is supported");
return; return;
} }
response->SetResponseCode(response_code); response->SetResponseCode(response_code);
response->SetHeader(MultiByteToWide(response_header)); response->SetHeader(response_header);
response->SetData(convert_from_utf8(response_data)); response->SetData(response_data);
if (!ok) if (!ok)
{ {
response->SetSucceed(false); response->SetSucceed(false);
response->SetError(MultiByteToWide(error_message)); response->SetError(error_message);
} }
else else
{ {

View File

@ -66,7 +66,7 @@ HttpRequestPtr HttpRequest::Create(String const& url, HttpType type, Json const&
void HttpRequest::SetJsonData(Json const& json) void HttpRequest::SetJsonData(Json const& json)
{ {
SetHeader(L"Content-Type", L"application/json;charset=UTF-8"); SetHeader("Content-Type", "application/json;charset=UTF-8");
data_ = json.dump(); data_ = json.dump();
} }

View File

@ -513,7 +513,7 @@ void Actor::AddChild(Actor* child, int zorder)
{ {
if (parent == child) if (parent == child)
{ {
KGE_ERROR(L"A actor cannot be its own parent"); KGE_ERROR("A actor cannot be its own parent");
return; return;
} }
} }

View File

@ -34,7 +34,7 @@ class comma_numpunct : public std::numpunct<wchar_t>
private: private:
virtual wchar_t do_thousands_sep() const override virtual wchar_t do_thousands_sep() const override
{ {
return L','; return ',';
} }
virtual std::string do_grouping() const override virtual std::string do_grouping() const override
@ -46,7 +46,7 @@ private:
DebugActor::DebugActor() DebugActor::DebugActor()
{ {
SetName(L"kiwano-debug-actor"); SetName("kiwano-debug-actor");
SetPosition(Point{ 10, 10 }); SetPosition(Point{ 10, 10 });
SetResponsible(true); SetResponsible(true);
SetCascadeOpacityEnabled(true); SetCascadeOpacityEnabled(true);
@ -60,7 +60,7 @@ DebugActor::DebugActor()
fill_brush->SetColor(Color::White); fill_brush->SetColor(Color::White);
TextStyle style; TextStyle style;
style.font_family = L"Arial"; style.font_family = "Arial";
style.font_size = 16.f; style.font_size = 16.f;
style.font_weight = FontWeight::Normal; style.font_weight = FontWeight::Normal;
style.line_spacing = 20.f; style.line_spacing = 20.f;

View File

@ -43,12 +43,12 @@ Stage::~Stage() {}
void Stage::OnEnter() void Stage::OnEnter()
{ {
KGE_SYS_LOG(L"Stage entered"); KGE_SYS_LOG("Stage entered");
} }
void Stage::OnExit() void Stage::OnExit()
{ {
KGE_SYS_LOG(L"Stage exited"); KGE_SYS_LOG("Stage exited");
} }
void Stage::RenderBorder(RenderContext& ctx) void Stage::RenderBorder(RenderContext& ctx)

View File

@ -175,7 +175,7 @@ public:
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
virtual ActionPtr Reverse() const override virtual ActionPtr Reverse() const override
{ {
KGE_ERROR(L"Reverse() not supported in ActionMoveTo"); KGE_ERROR("Reverse() not supported in ActionMoveTo");
return nullptr; return nullptr;
} }
@ -243,7 +243,7 @@ public:
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
virtual ActionPtr Reverse() const override virtual ActionPtr Reverse() const override
{ {
KGE_ERROR(L"Reverse() not supported in ActionJumpTo"); KGE_ERROR("Reverse() not supported in ActionJumpTo");
return nullptr; return nullptr;
} }
@ -308,7 +308,7 @@ public:
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
virtual ActionPtr Reverse() const override virtual ActionPtr Reverse() const override
{ {
KGE_ERROR(L"Reverse() not supported in ActionScaleTo"); KGE_ERROR("Reverse() not supported in ActionScaleTo");
return nullptr; return nullptr;
} }
@ -340,7 +340,7 @@ public:
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
virtual ActionPtr Reverse() const override virtual ActionPtr Reverse() const override
{ {
KGE_ERROR(L"Reverse() not supported in ActionFadeTo"); KGE_ERROR("Reverse() not supported in ActionFadeTo");
return nullptr; return nullptr;
} }
@ -429,7 +429,7 @@ public:
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
virtual ActionPtr Reverse() const override virtual ActionPtr Reverse() const override
{ {
KGE_ERROR(L"Reverse() not supported in ActionRotateTo"); KGE_ERROR("Reverse() not supported in ActionRotateTo");
return nullptr; return nullptr;
} }
@ -465,7 +465,7 @@ public:
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override ActionPtr Reverse() const override
{ {
KGE_ERROR(L"Reverse() not supported in ActionCustom"); KGE_ERROR("Reverse() not supported in ActionCustom");
return nullptr; return nullptr;
} }

View File

@ -9,9 +9,9 @@
//#define KGE_ASSERT(EXPR) __noop // Disable asserts //#define KGE_ASSERT(EXPR) __noop // Disable asserts
//---- Define debug-output handler. Defaults to calling kiwano::logs::Messageln()/Warningln()/Errorln() //---- Define debug-output handler. Defaults to calling kiwano::logs::Messageln()/Warningln()/Errorln()
//#define KGE_SYS_LOG(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__) //#define KGE_SYS_LOG(FORMAT, ...) wprintf(FORMAT "\n", __VA_ARGS__)
//#define KGE_WARN(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__) //#define KGE_WARN(FORMAT, ...) wprintf(FORMAT "\n", __VA_ARGS__)
//#define KGE_ERROR(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__) //#define KGE_ERROR(FORMAT, ...) wprintf(FORMAT "\n", __VA_ARGS__)
//---- Define attributes of all API symbols declarations for DLL //---- Define attributes of all API symbols declarations for DLL
//#define KGE_USE_DLL //#define KGE_USE_DLL

View File

@ -19,9 +19,6 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <3rd-party/OuterC/oc/oc.h>
#include <kiwano/core/Singleton.h>
#include <kiwano/macros.h>
#include <list> #include <list>
#include <map> #include <map>
#include <queue> #include <queue>
@ -30,25 +27,42 @@
#include <stack> #include <stack>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <kiwano/macros.h>
#include <kiwano/core/Singleton.h>
#include <3rd-party/OuterC/oc/oc.h>
#include <3rd-party/nlohmann/json.hpp>
namespace kiwano namespace kiwano
{ {
/// \~chinese
/// @brief 字符串容器
using String = oc::wstring;
/// \~chinese /// \~chinese
/// @brief 窄字符串容器 /// @brief 输入流
using ByteString = oc::string; using InputStream = std::istream;
/// \~chinese
/// @brief 输出流
using OutputStream = std::ostream;
/// \~chinese
/// @brief 字符串容器
using String = oc::string;
/// \~chinese
/// @brief 宽字符串容器
using WideString = oc::wstring;
/// \~chinese /// \~chinese
/// @brief 字符串流 /// @brief 字符串流
using StringStream = std::wstringstream; using StringStream = std::stringstream;
/// \~chinese
/// @brief 宽字符串流
using WideStringStream = std::wstringstream;
/// \~chinese /// \~chinese
/// @brief 线性数组容器 /// @brief 线性数组容器
template <typename _Ty, typename... _Args> template <typename _Ty, typename... _Args>
using Vector = oc::vector<_Ty, _Args...>; using Vector = std::vector<_Ty, _Args...>;
/// \~chinese /// \~chinese
/// @brief 链表容器 /// @brief 链表容器
@ -99,10 +113,6 @@ using Function = oc::function<_FuncTy>;
/// @brief 单值容器 /// @brief 单值容器
using Any = oc::any; using Any = oc::any;
/// \~chinese
/// @brief JSON对象容器
using Json = oc::basic_json<Map, Vector, String, int, double, bool, std::allocator>;
/// \~chinese /// \~chinese
/// @brief 侵入式链表容器 /// @brief 侵入式链表容器
template <typename _Ty> template <typename _Ty>
@ -118,6 +128,10 @@ using IntrusiveListItem = oc::intrusive_list_item<_Ty>;
template <typename _Ty, typename _RefProxyTy> template <typename _Ty, typename _RefProxyTy>
using IntrusivePtr = oc::intrusive_ptr<_Ty, _RefProxyTy>; using IntrusivePtr = oc::intrusive_ptr<_Ty, _RefProxyTy>;
/// \~chinese
/// @brief JSON对象容器
using Json = nlohmann::basic_json<Map, Vector, String>;
/// \~chinese /// \~chinese
/// @brief 不可拷贝对象 /// @brief 不可拷贝对象
using Noncopyable = oc::noncopyable; using Noncopyable = oc::noncopyable;
@ -138,13 +152,14 @@ inline Function<_Ret(_Args...)> Closure(_Uty* ptr, _Ret (_Ty::*func)(_Args...) c
return oc::closure(ptr, func); return oc::closure(ptr, func);
} }
inline ByteString WideToMultiByte(const String& str) inline String WideToMultiByte(const WideString& str)
{ {
return oc::wide_to_string(str); return oc::wide_to_string(str);
} }
inline String MultiByteToWide(const ByteString& str) inline WideString MultiByteToWide(const String& str)
{ {
return oc::string_to_wide(str); return oc::string_to_wide(str);
} }
} // namespace kiwano } // namespace kiwano

View File

@ -40,12 +40,6 @@ Library::~Library()
} }
bool Library::Load(String const& lib) bool Library::Load(String const& lib)
{
instance_ = ::LoadLibraryW(lib.c_str());
return IsValid();
}
bool Library::Load(ByteString const& lib)
{ {
instance_ = ::LoadLibraryA(lib.c_str()); instance_ = ::LoadLibraryA(lib.c_str());
return IsValid(); return IsValid();
@ -65,7 +59,7 @@ void Library::Free()
} }
} }
FARPROC Library::GetProcess(ByteString const& proc_name) FARPROC Library::GetProcess(String const& proc_name)
{ {
KGE_ASSERT(instance_ != nullptr); KGE_ASSERT(instance_ != nullptr);

View File

@ -20,7 +20,6 @@
#pragma once #pragma once
#include <kiwano/core/Common.h> #include <kiwano/core/Common.h>
#include <kiwano/macros.h>
namespace kiwano namespace kiwano
{ {
@ -47,11 +46,6 @@ public:
/// @param lib DLL文件路径 /// @param lib DLL文件路径
bool Load(String const& lib); bool Load(String const& lib);
/// \~chinese
/// @brief 加载DLL
/// @param lib DLL文件路径
bool Load(ByteString const& lib);
/// \~chinese /// \~chinese
/// @brief 是否有效 /// @brief 是否有效
bool IsValid() const; bool IsValid() const;
@ -63,13 +57,13 @@ public:
/// \~chinese /// \~chinese
/// @brief 检索指定的DLL中的输出库函数地址 /// @brief 检索指定的DLL中的输出库函数地址
/// @param proc_name 函数名 /// @param proc_name 函数名
FARPROC GetProcess(ByteString const& proc_name); FARPROC GetProcess(String const& proc_name);
/// \~chinese /// \~chinese
/// @brief 检索指定的DLL中的输出库函数地址 /// @brief 检索指定的DLL中的输出库函数地址
/// @param proc_name 函数名 /// @param proc_name 函数名
template <typename _Proc> template <typename _Proc>
inline _Proc GetProcess(ByteString const& proc_name) inline _Proc GetProcess(String const& proc_name)
{ {
return reinterpret_cast<_Proc>(GetProcess(proc_name)); return reinterpret_cast<_Proc>(GetProcess(proc_name));
} }

View File

@ -141,7 +141,7 @@ const WORD reset = white;
} // namespace console_colors } // namespace console_colors
#define DECLARE_HANDLE_COLOR(NAME, HANDLE_NAME, COLOR) \ #define DECLARE_HANDLE_COLOR(NAME, HANDLE_NAME, COLOR) \
inline std::wostream&(NAME)(std::wostream & _out) \ inline OutputStream&(NAME)(OutputStream & _out) \
{ \ { \
::SetConsoleTextAttribute(::GetStdHandle(HANDLE_NAME), console_colors::##COLOR); \ ::SetConsoleTextAttribute(::GetStdHandle(HANDLE_NAME), console_colors::##COLOR); \
return _out; \ return _out; \
@ -175,8 +175,8 @@ Logger::Logger()
: enabled_(true) : enabled_(true)
, default_stdout_color_(0) , default_stdout_color_(0)
, default_stderr_color_(0) , default_stderr_color_(0)
, output_stream_(std::wcout.rdbuf()) , output_stream_(std::cout.rdbuf())
, error_stream_(std::wcerr.rdbuf()) , error_stream_(std::cerr.rdbuf())
{ {
ResetOutputStream(); ResetOutputStream();
} }
@ -186,7 +186,7 @@ Logger::~Logger()
FreeAllocatedConsole(); FreeAllocatedConsole();
} }
void Logger::Printf(Level level, const wchar_t* format, ...) void Logger::Printf(Level level, const char* format, ...)
{ {
if (!enabled_) if (!enabled_)
return; return;
@ -200,11 +200,11 @@ void Logger::Printf(Level level, const wchar_t* format, ...)
va_list args = nullptr; va_list args = nullptr;
va_start(args, format); va_start(args, format);
static wchar_t temp_buffer[1024 * 3 + 1]; static char temp_buffer[1024 * 3 + 1];
const auto len = ::_vscwprintf(format, args) + 1; const auto len = ::_vscprintf(format, args) + 1;
::_vsnwprintf_s(temp_buffer, len, len, format, args); ::_vsnprintf_s(temp_buffer, len, len, format, args);
sstream << ' ' << temp_buffer << L"\r\n"; sstream << ' ' << temp_buffer << "\r\n";
va_end(args); va_end(args);
} }
@ -219,16 +219,16 @@ void Logger::Prepare(Level level, StringStream& sstream)
switch (level) switch (level)
{ {
case Level::Info: case Level::Info:
prefix = L"[INFO] "; prefix = "[INFO] ";
break; break;
case Level::System: case Level::System:
prefix = L"[SYSTEM] "; prefix = "[SYSTEM] ";
break; break;
case Level::Warning: case Level::Warning:
prefix = L"[WARN] "; prefix = "[WARN] ";
break; break;
case Level::Error: case Level::Error:
prefix = L"[ERROR] "; prefix = "[ERROR] ";
break; break;
} }
@ -236,11 +236,13 @@ void Logger::Prepare(Level level, StringStream& sstream)
time_t unix = std::time(nullptr); time_t unix = std::time(nullptr);
std::tm tmbuf; std::tm tmbuf;
localtime_s(&tmbuf, &unix); localtime_s(&tmbuf, &unix);
sstream << prefix << std::put_time(&tmbuf, L"%H:%M:%S "); sstream << prefix << std::put_time(&tmbuf, "%H:%M:%S ");
} }
void Logger::Output(Level level, StringStream& sstream) void Logger::Output(Level level, StringStream& sstream)
{ {
using ConsoleColor = Function<OutputStream&(OutputStream&)>;
OutputStream* ostream = nullptr; OutputStream* ostream = nullptr;
ConsoleColor color = nullptr; ConsoleColor color = nullptr;
@ -269,7 +271,7 @@ void Logger::Output(Level level, StringStream& sstream)
{ {
auto output = sstream.str(); auto output = sstream.str();
color(*ostream) << output << std::flush; color(*ostream) << output << std::flush;
::OutputDebugStringW(output.c_str()); ::OutputDebugStringA(output.c_str());
ResetConsoleColor(); ResetConsoleColor();
} }
@ -297,20 +299,20 @@ void Logger::ResetOutputStream()
// replace the C++ global locale with the user-preferred locale // replace the C++ global locale with the user-preferred locale
(void)std::locale::global(std::locale("")); (void)std::locale::global(std::locale(""));
(void)std::wcout.imbue(std::locale()); (void)std::cout.imbue(std::locale());
(void)std::wcerr.imbue(std::locale()); (void)std::cerr.imbue(std::locale());
RedirectOutputStreamBuffer(std::wcout.rdbuf()); RedirectOutputStreamBuffer(std::cout.rdbuf());
RedirectErrorStreamBuffer(std::wcerr.rdbuf()); RedirectErrorStreamBuffer(std::cerr.rdbuf());
} }
} }
std::wstreambuf* Logger::RedirectOutputStreamBuffer(std::wstreambuf* buf) std::streambuf* Logger::RedirectOutputStreamBuffer(std::streambuf* buf)
{ {
return output_stream_.rdbuf(buf); return output_stream_.rdbuf(buf);
} }
std::wstreambuf* Logger::RedirectErrorStreamBuffer(std::wstreambuf* buf) std::streambuf* Logger::RedirectErrorStreamBuffer(std::streambuf* buf)
{ {
return error_stream_.rdbuf(buf); return error_stream_.rdbuf(buf);
} }
@ -329,7 +331,7 @@ void Logger::ShowConsole(bool show)
HWND console = ::AllocateConsole(); HWND console = ::AllocateConsole();
if (!console) if (!console)
{ {
KGE_WARN(L"AllocConsole failed"); KGE_WARN("AllocConsole failed");
} }
else else
{ {

View File

@ -70,19 +70,11 @@ public:
Error ///< 错误 Error ///< 错误
}; };
/// \~chinese
/// @brief Êä³öÁ÷
using OutputStream = std::wostream;
/// \~chinese
/// @brief ¿ØÖÆÌ¨ÑÕÉ«
using ConsoleColor = Function<OutputStream&(OutputStream&)>;
/// \~chinese /// \~chinese
/// @brief 打印日志 /// @brief 打印日志
/// @param level 日志级别 /// @param level 日志级别
/// @param format 格式字符串 /// @param format 格式字符串
void Printf(Level level, const wchar_t* format, ...); void Printf(Level level, const char* format, ...);
/// \~chinese /// \~chinese
/// @brief 打印日志 /// @brief 打印日志
@ -113,19 +105,19 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取输出流 /// @brief 获取输出流
std::wostream& GetOutputStream(); OutputStream& GetOutputStream();
/// \~chinese /// \~chinese
/// @brief 获取错误流 /// @brief 获取错误流
std::wostream& GetErrorStream(); OutputStream& GetErrorStream();
/// \~chinese /// \~chinese
/// @brief 重定向输出流 /// @brief 重定向输出流
std::wstreambuf* RedirectOutputStreamBuffer(std::wstreambuf* buf); std::streambuf* RedirectOutputStreamBuffer(std::streambuf* buf);
/// \~chinese /// \~chinese
/// @brief 重定向错误流 /// @brief 重定向错误流
std::wstreambuf* RedirectErrorStreamBuffer(std::wstreambuf* buf); std::streambuf* RedirectErrorStreamBuffer(std::streambuf* buf);
/// \~chinese /// \~chinese
/// @brief 重置输出流 /// @brief 重置输出流
@ -190,7 +182,7 @@ void Logger::Println(Level level, _Args&&... args)
// Format message // Format message
(void)std::initializer_list<int>{ ((sstream << ' ' << args), 0)... }; (void)std::initializer_list<int>{ ((sstream << ' ' << args), 0)... };
sstream << L"\r\n"; sstream << "\r\n";
Output(level, sstream); Output(level, sstream);
} }
@ -201,18 +193,18 @@ inline void Logger::ResetConsoleColor() const
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), default_stderr_color_); ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), default_stderr_color_);
} }
inline Logger::OutputStream& Logger::DefaultOutputColor(OutputStream& out) inline OutputStream& Logger::DefaultOutputColor(OutputStream& out)
{ {
::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_); ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_);
return out; return out;
} }
inline std::wostream& Logger::GetOutputStream() inline OutputStream& Logger::GetOutputStream()
{ {
return output_stream_; return output_stream_;
} }
inline std::wostream& Logger::GetErrorStream() inline OutputStream& Logger::GetErrorStream()
{ {
return error_stream_; return error_stream_;
} }

View File

@ -88,9 +88,8 @@ void ObjectBase::SetName(String const& name)
String ObjectBase::DumpObject() String ObjectBase::DumpObject()
{ {
String name = oc::string_to_wide(typeid(*this).name()); return String::format("{ class=\"%s\" id=%d refcount=%d name=\"%s\" }", typeid(*this).name(), GetObjectID(),
return String::format(L"{ class=\"%s\" id=%d refcount=%d name=\"%s\" }", name.c_str(), GetObjectID(), GetRefCount(), GetRefCount(), GetName().c_str());
GetName().c_str());
} }
bool ObjectBase::IsTracingLeaks() bool ObjectBase::IsTracingLeaks()
@ -110,12 +109,12 @@ void ObjectBase::StopTracingLeaks()
void ObjectBase::DumpTracingObjects() void ObjectBase::DumpTracingObjects()
{ {
KGE_SYS_LOG(L"-------------------------- All Objects --------------------------"); KGE_SYS_LOG("-------------------------- All Objects --------------------------");
for (const auto object : tracing_objects) for (const auto object : tracing_objects)
{ {
KGE_SYS_LOG(L"%s", object->DumpObject().c_str()); KGE_SYS_LOG("%s", object->DumpObject().c_str());
} }
KGE_SYS_LOG(L"------------------------- Total size: %d -------------------------", tracing_objects.size()); KGE_SYS_LOG("------------------------- Total size: %d -------------------------", tracing_objects.size());
} }
Vector<ObjectBase*>& ObjectBase::GetTracingObjects() Vector<ObjectBase*>& ObjectBase::GetTracingObjects()

View File

@ -48,28 +48,28 @@ Resource::Data Resource::GetData() const
HRSRC res_info = FindResourceW(nullptr, MAKEINTRESOURCE(id_), type_); HRSRC res_info = FindResourceW(nullptr, MAKEINTRESOURCE(id_), type_);
if (res_info == nullptr) if (res_info == nullptr)
{ {
KGE_ERROR(L"FindResource failed"); KGE_ERROR("FindResource failed");
break; break;
} }
HGLOBAL res_data = LoadResource(nullptr, res_info); HGLOBAL res_data = LoadResource(nullptr, res_info);
if (res_data == nullptr) if (res_data == nullptr)
{ {
KGE_ERROR(L"LoadResource failed"); KGE_ERROR("LoadResource failed");
break; break;
} }
DWORD size = SizeofResource(nullptr, res_info); DWORD size = SizeofResource(nullptr, res_info);
if (size == 0) if (size == 0)
{ {
KGE_ERROR(L"SizeofResource failed"); KGE_ERROR("SizeofResource failed");
break; break;
} }
LPVOID buffer = LockResource(res_data); LPVOID buffer = LockResource(res_data);
if (buffer == nullptr) if (buffer == nullptr)
{ {
KGE_ERROR(L"LockResource failed"); KGE_ERROR("LockResource failed");
break; break;
} }

View File

@ -29,10 +29,10 @@ namespace kiwano
* @brief * @brief
* @details * @details
* exe * exe
* L"WAVE" * "WAVE"
* IDR_WAVE_1: * IDR_WAVE_1:
* @code * @code
* Resource(IDR_WAVE_1, L"WAVE"); * Resource(IDR_WAVE_1, "WAVE");
* @endcode * @endcode
* : * :
* https://docs.microsoft.com/en-us/windows/desktop/menurc/resources * https://docs.microsoft.com/en-us/windows/desktop/menurc/resources

View File

@ -94,12 +94,13 @@ const Duration Duration::Hour = 60 * Duration::Minute;
namespace namespace
{ {
const auto duration_regex = std::wregex(LR"(^[-+]?([0-9]*(\.[0-9]*)?(h|m|s|ms)+)+$)"); const auto duration_regex = std::regex(R"(^[-+]?([0-9]*(\.[0-9]*)?(h|m|s|ms)+)+$)");
typedef std::unordered_map<String, Duration> UnitMap; typedef std::unordered_map<String, Duration> UnitMap;
const auto unit_map = UnitMap{
{ L"ms", Duration::Ms }, { L"s", Duration::Second }, { L"m", Duration::Minute }, { L"h", Duration::Hour } const auto unit_map =
}; UnitMap{ { "ms", Duration::Ms }, { "s", Duration::Second }, { "m", Duration::Minute }, { "h", Duration::Hour } };
} // namespace } // namespace
Duration::Duration() Duration::Duration()
@ -137,14 +138,14 @@ String Duration::ToString() const
{ {
if (IsZero()) if (IsZero())
{ {
return String(L"0s"); return String("0s");
} }
String result; String result;
long total_ms = milliseconds_; long total_ms = milliseconds_;
if (total_ms < 0) if (total_ms < 0)
{ {
result.append(L"-"); result.append("-");
total_ms = -total_ms; total_ms = -total_ms;
} }
@ -155,21 +156,21 @@ String Duration::ToString() const
if (hour) if (hour)
{ {
result.append(String::parse(hour)).append(L"h"); result.append(String::parse(hour)).append("h");
result.append(String::parse(min)).append(L"m"); result.append(String::parse(min)).append("m");
} }
else if (min) else if (min)
{ {
result.append(String::parse(min)).append(L"m"); result.append(String::parse(min)).append("m");
} }
if (ms != 0) if (ms != 0)
{ {
result.append(String::parse(static_cast<float>(sec) + static_cast<float>(ms) / 1000.f)).append(L"s"); result.append(String::parse(static_cast<float>(sec) + static_cast<float>(ms) / 1000.f)).append("s");
} }
else if (sec != 0) else if (sec != 0)
{ {
result.append(String::parse(sec)).append(L"s"); result.append(String::parse(sec)).append("s");
} }
return result; return result;
} }
@ -359,15 +360,15 @@ Duration Duration::Parse(const String& format)
throw std::runtime_error("Duration::Parse failed, invalid duration"); throw std::runtime_error("Duration::Parse failed, invalid duration");
} }
if (format.empty() || format == L"0") if (format.empty() || format == "0")
{ {
return ret; return ret;
} }
// ·ûºÅλ // ·ûºÅλ
if (format[0] == L'-' || format[0] == L'+') if (format[0] == '-' || format[0] == '+')
{ {
negative = (format[0] == L'-'); negative = (format[0] == '-');
pos++; pos++;
} }
@ -378,35 +379,37 @@ Duration Duration::Parse(const String& format)
for (; i < len; ++i) for (; i < len; ++i)
{ {
wchar_t ch = format[i]; wchar_t ch = format[i];
if (!(ch == L'.' || L'0' <= ch && ch <= L'9')) if (!(ch == '.' || '0' <= ch && ch <= '9'))
{ {
break; break;
} }
} }
String num_str = format.substr(pos, i - pos); String num_str = format.substr(pos, i - pos);
pos = i;
if (num_str.empty() || num_str == L".") pos = i;
if (num_str.empty() || num_str == ".")
throw std::runtime_error("Duration::Parse failed, invalid duration"); throw std::runtime_error("Duration::Parse failed, invalid duration");
// µ¥Î» // µ¥Î»
for (; i < len; ++i) for (; i < len; ++i)
{ {
wchar_t ch = format[i]; wchar_t ch = format[i];
if (ch == L'.' || L'0' <= ch && ch <= L'9') if (ch == '.' || '0' <= ch && ch <= '9')
{ {
break; break;
} }
} }
String unit_str = format.substr(pos, i - pos); String unit_str = format.substr(pos, i - pos);
pos = i;
pos = i;
if (unit_map.find(unit_str) == unit_map.end()) if (unit_map.find(unit_str) == unit_map.end())
throw std::runtime_error("Duration::Parse failed, invalid duration"); throw std::runtime_error("Duration::Parse failed, invalid duration");
double num = std::wcstod(num_str.c_str(), nullptr); double num = std::stod(num_str.c_str());
Duration unit = unit_map.at(unit_str); Duration unit = unit_map.at(unit_str);
ret += unit * num; ret += unit * num;
} }

View File

@ -111,7 +111,7 @@ void Application::Use(ComponentBase* component)
{ {
#if defined(KGE_DEBUG) #if defined(KGE_DEBUG)
if (comps_.contains(component)) if (std::find(comps_.begin(), comps_.end(), component) != comps_.end())
{ {
KGE_ASSERT(false && "Component already exists!"); KGE_ASSERT(false && "Component already exists!");
} }

View File

@ -32,9 +32,9 @@ inline String ConvertPathFormat(String const& path)
String result = path; String result = path;
for (size_t i = 0; i < len; i++) for (size_t i = 0; i < len; i++)
{ {
if (result[i] == L'\\') if (result[i] == '\\')
{ {
result[i] = L'/'; result[i] = '/';
} }
} }
return result; return result;
@ -42,7 +42,7 @@ inline String ConvertPathFormat(String const& path)
inline bool IsFileExists(String const& path) inline bool IsFileExists(String const& path)
{ {
DWORD dwAttrib = ::GetFileAttributesW(path.c_str()); DWORD dwAttrib = ::GetFileAttributesA(path.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
} }
@ -55,9 +55,9 @@ FileSystem::~FileSystem() {}
void FileSystem::AddSearchPath(String const& path) void FileSystem::AddSearchPath(String const& path)
{ {
String search_path = ConvertPathFormat(path); String search_path = ConvertPathFormat(path);
if (!search_path.empty() && search_path[search_path.length() - 1] != L'/') if (!search_path.empty() && search_path[search_path.length() - 1] != '/')
{ {
search_path += L"/"; search_path += "/";
} }
search_paths_.push_back(search_path); search_paths_.push_back(search_path);
@ -70,9 +70,9 @@ void FileSystem::SetSearchPaths(Vector<String> const& paths)
for (auto& path : search_paths_) for (auto& path : search_paths_)
{ {
path = ConvertPathFormat(path); path = ConvertPathFormat(path);
if (!path.empty() && path[path.length() - 1] != L'/') if (!path.empty() && path[path.length() - 1] != '/')
{ {
path += L"/"; path += "/";
} }
} }
} }
@ -81,7 +81,7 @@ String FileSystem::GetFullPathForFile(String const& file) const
{ {
if (file.empty()) if (file.empty())
{ {
return L""; return "";
} }
if (IsAbsolutePath(file)) if (IsAbsolutePath(file))
@ -126,7 +126,7 @@ String FileSystem::GetFullPathForFile(String const& file) const
} }
// File not found // File not found
return L""; return "";
} }
void FileSystem::AddFileLookupRule(String const& key, String const& file_path) void FileSystem::AddFileLookupRule(String const& key, String const& file_path)
@ -157,12 +157,12 @@ bool FileSystem::IsFileExists(String const& file_path) const
bool FileSystem::IsAbsolutePath(String const& path) const bool FileSystem::IsAbsolutePath(String const& path) const
{ {
// like "C:\some.file" // like "C:\some.file"
return path.length() > 2 && ((std::isalpha(path[0]) && path[1] == L':') || (path[0] == L'/' && path[1] == L'/')); return path.length() > 2 && ((std::isalpha(path[0]) && path[1] == ':') || (path[0] == '/' && path[1] == '/'));
} }
bool FileSystem::RemoveFile(String const& file_path) const bool FileSystem::RemoveFile(String const& file_path) const
{ {
if (::DeleteFileW(file_path.c_str())) if (::DeleteFileA(file_path.c_str()))
return true; return true;
return false; return false;
} }
@ -170,7 +170,7 @@ bool FileSystem::RemoveFile(String const& file_path) const
bool FileSystem::ExtractResourceToFile(Resource const& res, String const& dest_file_name) const bool FileSystem::ExtractResourceToFile(Resource const& res, String const& dest_file_name) const
{ {
HANDLE file_handle = HANDLE file_handle =
::CreateFileW(dest_file_name.c_str(), GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ::CreateFileA(dest_file_name.c_str(), GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE) if (file_handle == INVALID_HANDLE_VALUE)
return false; return false;
@ -187,7 +187,7 @@ bool FileSystem::ExtractResourceToFile(Resource const& res, String const& dest_f
else else
{ {
::CloseHandle(file_handle); ::CloseHandle(file_handle);
::DeleteFile(dest_file_name.c_str()); ::DeleteFileA(dest_file_name.c_str());
} }
return false; return false;
} }

View File

@ -117,9 +117,9 @@ struct DbgHelp
DbgHelp g_DbgHelp; DbgHelp g_DbgHelp;
} // namespace } // namespace
void PrintErrorCode(LPCWSTR lpszFunction) void PrintErrorCode(LPCSTR lpszFunction)
{ {
KGE_ERROR(L"%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError())); KGE_ERROR("%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError()));
} }
void PrintCallStackOnContext(PCONTEXT pContext) void PrintCallStackOnContext(PCONTEXT pContext)
@ -165,14 +165,14 @@ void PrintCallStackOnContext(PCONTEXT pContext)
constexpr int STACKWALK_MAX_NAMELEN = 1024; constexpr int STACKWALK_MAX_NAMELEN = 1024;
BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN]; BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
KGE_ERROR(L"========== Stack trace =========="); KGE_ERROR("========== Stack trace ==========");
while (true) while (true)
{ {
if (!g_DbgHelp.StackWalk64(dwMachineType, hProcess, hThread, &sf, pContext, NULL, if (!g_DbgHelp.StackWalk64(dwMachineType, hProcess, hThread, &sf, pContext, NULL,
g_DbgHelp.SymFunctionTableAccess64, g_DbgHelp.SymGetModuleBase64, NULL)) g_DbgHelp.SymFunctionTableAccess64, g_DbgHelp.SymGetModuleBase64, NULL))
{ {
PrintErrorCode(L"StackWalk64"); PrintErrorCode("StackWalk64");
break; break;
} }
@ -190,7 +190,7 @@ void PrintCallStackOnContext(PCONTEXT pContext)
DWORD64 dwDisplacement; DWORD64 dwDisplacement;
if (!g_DbgHelp.SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, &dwDisplacement, pSymbol)) if (!g_DbgHelp.SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, &dwDisplacement, pSymbol))
{ {
PrintErrorCode(L"SymGetSymFromAddr64"); PrintErrorCode("SymGetSymFromAddr64");
break; break;
} }
@ -201,14 +201,11 @@ void PrintCallStackOnContext(PCONTEXT pContext)
DWORD dwLineDisplacement; DWORD dwLineDisplacement;
if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo)) if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
{ {
String functionName = MultiByteToWide(pSymbol->Name); KGE_ERROR("%s (%d): %s", lineInfo.FileName, lineInfo.LineNumber, pSymbol->Name);
String fileName = MultiByteToWide(lineInfo.FileName);
KGE_ERROR(L"%s (%d): %s", fileName.c_str(), lineInfo.LineNumber, functionName.c_str());
} }
else else
{ {
String functionName = MultiByteToWide(pSymbol->Name); KGE_ERROR("(filename not available): %s", pSymbol->Name);
KGE_ERROR(L"(filename not available): %s", functionName.c_str());
} }
if (sf.AddrReturn.Offset == 0) if (sf.AddrReturn.Offset == 0)
@ -236,5 +233,6 @@ void PrintCallStack()
g_DbgHelp.SymCleanup(hProcess); g_DbgHelp.SymCleanup(hProcess);
} }
} // namespace win32 } // namespace win32
} // namespace kiwano } // namespace kiwano

View File

@ -34,7 +34,6 @@
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX #define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
#define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX #define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP #define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
#define KGE_WND_CLASS_NAME L"KiwanoAppWnd"
namespace kiwano namespace kiwano
{ {
@ -98,7 +97,7 @@ void ChangeFullScreenResolution(uint32_t width, uint32_t height, WCHAR* device_n
mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (::ChangeDisplaySettingsExW(device_name, &mode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) if (::ChangeDisplaySettingsExW(device_name, &mode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
KGE_ERROR(L"ChangeDisplaySettings failed"); KGE_ERROR("ChangeDisplaySettings failed");
} }
void RestoreResolution(WCHAR* device_name) void RestoreResolution(WCHAR* device_name)
@ -165,7 +164,7 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui
HINSTANCE hinst = GetModuleHandleW(nullptr); HINSTANCE hinst = GetModuleHandleW(nullptr);
WNDCLASSEX wcex = { 0 }; WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpszClassName = KGE_WND_CLASS_NAME; wcex.lpszClassName = L"KiwanoAppWnd";
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
wcex.lpfnWndProc = WindowImpl::WndProc; wcex.lpfnWndProc = WindowImpl::WndProc;
wcex.hIcon = nullptr; wcex.hIcon = nullptr;
@ -229,14 +228,14 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui
height = win_height; height = win_height;
} }
handle_ = ::CreateWindowExW(is_fullscreen_ ? WS_EX_TOPMOST : 0, KGE_WND_CLASS_NAME, title.c_str(), GetStyle(), left, handle_ = ::CreateWindowExA(is_fullscreen_ ? WS_EX_TOPMOST : 0, "KiwanoAppWnd", title.c_str(), GetStyle(), left,
top, width, height, nullptr, nullptr, hinst, nullptr); top, width, height, nullptr, nullptr, hinst, nullptr);
if (handle_ == nullptr) if (handle_ == nullptr)
{ {
::UnregisterClass(KGE_WND_CLASS_NAME, hinst); ::UnregisterClassW(L"KiwanoAppWnd", hinst);
KGE_ERROR(L"Failed with HRESULT of %08X", HRESULT_FROM_WIN32(GetLastError())); KGE_ERROR("Failed with HRESULT of %08X", HRESULT_FROM_WIN32(GetLastError()));
throw std::runtime_error("Create window failed"); throw std::runtime_error("Create window failed");
} }
@ -276,7 +275,7 @@ void WindowImpl::PumpEvents()
void WindowImpl::SetTitle(String const& title) void WindowImpl::SetTitle(String const& title)
{ {
if (handle_) if (handle_)
::SetWindowTextW(handle_, title.c_str()); ::SetWindowTextA(handle_, title.c_str());
} }
void WindowImpl::SetIcon(uint32_t icon_resource) void WindowImpl::SetIcon(uint32_t icon_resource)
@ -551,11 +550,11 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
{ {
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam) if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{ {
KGE_SYS_LOG(L"Window minimized"); KGE_SYS_LOG("Window minimized");
} }
else else
{ {
// KGE_SYS_LOG(L"Window resized"); // KGE_SYS_LOG("Window resized");
window->width_ = ((uint32_t)(short)LOWORD(lparam)); window->width_ = ((uint32_t)(short)LOWORD(lparam));
window->height_ = ((uint32_t)(short)HIWORD(lparam)); window->height_ = ((uint32_t)(short)HIWORD(lparam));
@ -591,9 +590,9 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
case WM_SETTEXT: case WM_SETTEXT:
{ {
KGE_SYS_LOG(L"Window title changed"); KGE_SYS_LOG("Window title changed");
window->title_ = String::cstr(reinterpret_cast<LPCWSTR>(lparam)); window->title_ = WideToMultiByte(reinterpret_cast<LPCWSTR>(lparam));
WindowTitleChangedEventPtr evt = new WindowTitleChangedEvent; WindowTitleChangedEventPtr evt = new WindowTitleChangedEvent;
evt->title = window->title_; evt->title = window->title_;
@ -603,13 +602,13 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
case WM_SETICON: case WM_SETICON:
{ {
KGE_SYS_LOG(L"Window icon changed"); KGE_SYS_LOG("Window icon changed");
} }
break; break;
case WM_DISPLAYCHANGE: case WM_DISPLAYCHANGE:
{ {
KGE_SYS_LOG(L"The display resolution has changed"); KGE_SYS_LOG("The display resolution has changed");
::InvalidateRect(hwnd, nullptr, FALSE); ::InvalidateRect(hwnd, nullptr, FALSE);
} }
@ -623,7 +622,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
case WM_CLOSE: case WM_CLOSE:
{ {
KGE_SYS_LOG(L"Window is closing"); KGE_SYS_LOG("Window is closing");
WindowClosedEventPtr evt = new WindowClosedEvent; WindowClosedEventPtr evt = new WindowClosedEvent;
window->PushEvent(evt); window->PushEvent(evt);
@ -633,7 +632,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
case WM_DESTROY: case WM_DESTROY:
{ {
KGE_SYS_LOG(L"Window was destroyed"); KGE_SYS_LOG("Window was destroyed");
::PostQuitMessage(0); ::PostQuitMessage(0);
return 0; return 0;

View File

@ -49,7 +49,7 @@ inline void WarnIfFailed(HRESULT hr)
{ {
PrintCallStack(); PrintCallStack();
KGE_WARN(L"Failed with HRESULT of %08X", hr); KGE_WARN("Failed with HRESULT of %08X", hr);
} }
} }

View File

@ -27,6 +27,7 @@ namespace win32
{ {
namespace dlls namespace dlls
{ {
Shlwapi::Shlwapi() Shlwapi::Shlwapi()
: shlwapi() : shlwapi()
, PathFileExistsW(nullptr) , PathFileExistsW(nullptr)
@ -39,10 +40,11 @@ Shlwapi::Shlwapi()
} }
else else
{ {
KGE_ERROR(L"Load shlapi.dll failed"); KGE_ERROR("Load shlapi.dll failed");
throw std::runtime_error("Load shlapi.dll failed"); throw std::runtime_error("Load shlapi.dll failed");
} }
} }
} // namespace dlls } // namespace dlls
} // namespace win32 } // namespace win32
} // namespace kiwano } // namespace kiwano

View File

@ -48,21 +48,21 @@ public:
_In_opt_ const D2D1_BITMAP_PROPERTIES* properties, _In_opt_ const D2D1_BITMAP_PROPERTIES* properties,
_In_ ComPtr<IWICFormatConverter> converter) override; _In_ ComPtr<IWICFormatConverter> converter) override;
HRESULT CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder>& decoder, const String& file_path) override; HRESULT CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder>& decoder, _In_ LPCWSTR file_path) override;
HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, _In_ void* data,
const Resource& resource) override; DWORD data_size) override;
HRESULT CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& text_format, String const& family, HRESULT CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& text_format, _In_ LPCWSTR family,
_In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight, _In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) override; DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) override;
HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, String const& text, HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, _In_ LPCWSTR text,
_In_ ComPtr<IDWriteTextFormat> text_format) override; UINT32 length, _In_ ComPtr<IDWriteTextFormat> text_format) override;
HRESULT SetDpi(float dpi) override; HRESULT SetDpi(float dpi) override;
HRESULT SetLogicalSize(Size logical_size) override; HRESULT SetLogicalSize(float width, float height) override;
HRESULT HandleDeviceLost(_In_ ComPtr<IDXGIDevice> dxgi_device, HRESULT HandleDeviceLost(_In_ ComPtr<IDXGIDevice> dxgi_device,
_In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) override; _In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) override;
@ -292,7 +292,7 @@ HRESULT D2DDeviceResources::SetDpi(float dpi)
return CreateWindowSizeDependentResources(); return CreateWindowSizeDependentResources();
} }
HRESULT D2DDeviceResources::SetLogicalSize(Size) HRESULT D2DDeviceResources::SetLogicalSize(float width, float height)
{ {
return CreateWindowSizeDependentResources(); return CreateWindowSizeDependentResources();
} }
@ -355,14 +355,14 @@ HRESULT D2DDeviceResources::CreateBitmapFromConverter(_Out_ ComPtr<ID2D1Bitmap>&
} }
HRESULT D2DDeviceResources::CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder>& decoder, HRESULT D2DDeviceResources::CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder>& decoder,
const String& file_path) _In_ LPCWSTR file_path)
{ {
if (!imaging_factory_) if (!imaging_factory_)
return E_UNEXPECTED; return E_UNEXPECTED;
ComPtr<IWICBitmapDecoder> decoder_output; ComPtr<IWICBitmapDecoder> decoder_output;
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(file_path.c_str(), nullptr, GENERIC_READ, HRESULT hr = imaging_factory_->CreateDecoderFromFilename(file_path, nullptr, GENERIC_READ,
WICDecodeMetadataCacheOnLoad, &decoder_output); WICDecodeMetadataCacheOnLoad, &decoder_output);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -372,14 +372,13 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapD
return hr; return hr;
} }
HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, _In_ void* data,
const Resource& resource) DWORD data_size)
{ {
if (!imaging_factory_) if (!imaging_factory_)
return E_UNEXPECTED; return E_UNEXPECTED;
Resource::Data res_data = resource.GetData(); HRESULT hr = data ? S_OK : E_FAIL;
HRESULT hr = res_data ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -388,7 +387,7 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBit
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = stream->InitializeFromMemory(static_cast<WICInProcPointer>(res_data.buffer), res_data.size); hr = stream->InitializeFromMemory(static_cast<WICInProcPointer>(data), data_size);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -406,7 +405,7 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBit
return hr; return hr;
} }
HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& text_format, String const& family, HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& text_format, _In_ LPCWSTR family,
_In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight, _In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size)
{ {
@ -414,7 +413,7 @@ HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& te
return E_UNEXPECTED; return E_UNEXPECTED;
ComPtr<IDWriteTextFormat> output; ComPtr<IDWriteTextFormat> output;
HRESULT hr = dwrite_factory_->CreateTextFormat(family.c_str(), collection.get(), weight, style, stretch, font_size, HRESULT hr = dwrite_factory_->CreateTextFormat(family, collection.get(), weight, style, stretch, font_size,
L"", &output); L"", &output);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -424,15 +423,15 @@ HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& te
return hr; return hr;
} }
HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, String const& text, HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, _In_ LPCWSTR text,
_In_ ComPtr<IDWriteTextFormat> text_format) UINT32 length, _In_ ComPtr<IDWriteTextFormat> text_format)
{ {
if (!dwrite_factory_) if (!dwrite_factory_)
return E_UNEXPECTED; return E_UNEXPECTED;
ComPtr<IDWriteTextLayout> output; ComPtr<IDWriteTextLayout> output;
HRESULT hr = dwrite_factory_->CreateTextLayout(text.c_str(), static_cast<UINT32>(text.length()), text_format.get(),
0, 0, &output); HRESULT hr = dwrite_factory_->CreateTextLayout(text, length, text_format.get(), 0, 0, &output);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -19,7 +19,6 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/Resource.h>
#include <kiwano/render/DirectX/helper.h> #include <kiwano/render/DirectX/helper.h>
#include <d2d1.h> #include <d2d1.h>
#include <d2d1_1.h> #include <d2d1_1.h>
@ -43,21 +42,21 @@ public:
_In_opt_ const D2D1_BITMAP_PROPERTIES* properties, _In_opt_ const D2D1_BITMAP_PROPERTIES* properties,
_In_ ComPtr<IWICFormatConverter> converter) = 0; _In_ ComPtr<IWICFormatConverter> converter) = 0;
virtual HRESULT CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder> & decoder, const String& file_path) = 0; virtual HRESULT CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder> & decoder, _In_ LPCWSTR file_path) = 0;
virtual HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder> & decoder, virtual HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder> & decoder, _In_ void* data,
const Resource& resource) = 0; DWORD data_size) = 0;
virtual HRESULT CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format, String const& family, virtual HRESULT CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format, _In_ LPCWSTR family,
_In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight, _In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) = 0; DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) = 0;
virtual HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, String const& text, virtual HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, _In_ LPCWSTR text,
_In_ ComPtr<IDWriteTextFormat> text_format) = 0; UINT32 length, _In_ ComPtr<IDWriteTextFormat> text_format) = 0;
virtual HRESULT SetDpi(float dpi) = 0; virtual HRESULT SetDpi(float dpi) = 0;
virtual HRESULT SetLogicalSize(Size logical_size) = 0; virtual HRESULT SetLogicalSize(float width, float height) = 0;
virtual HRESULT HandleDeviceLost(_In_ ComPtr<IDXGIDevice> dxgi_device, virtual HRESULT HandleDeviceLost(_In_ ComPtr<IDXGIDevice> dxgi_device,
_In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) = 0; _In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) = 0;
@ -69,26 +68,31 @@ public:
KGE_ASSERT(factory_); KGE_ASSERT(factory_);
return factory_.get(); return factory_.get();
} }
inline IWICImagingFactory* GetWICImagingFactory() inline IWICImagingFactory* GetWICImagingFactory()
{ {
KGE_ASSERT(imaging_factory_); KGE_ASSERT(imaging_factory_);
return imaging_factory_.get(); return imaging_factory_.get();
} }
inline IDWriteFactory* GetDWriteFactory() inline IDWriteFactory* GetDWriteFactory()
{ {
KGE_ASSERT(dwrite_factory_); KGE_ASSERT(dwrite_factory_);
return dwrite_factory_.get(); return dwrite_factory_.get();
} }
inline ID2D1Device* GetDevice() inline ID2D1Device* GetDevice()
{ {
KGE_ASSERT(device_); KGE_ASSERT(device_);
return device_.get(); return device_.get();
} }
inline ID2D1DeviceContext* GetDeviceContext() inline ID2D1DeviceContext* GetDeviceContext()
{ {
KGE_ASSERT(device_context_); KGE_ASSERT(device_context_);
return device_context_.get(); return device_context_.get();
} }
inline ID2D1Bitmap1* GetTargetBitmap() inline ID2D1Bitmap1* GetTargetBitmap()
{ {
KGE_ASSERT(target_bitmap_); KGE_ASSERT(target_bitmap_);

View File

@ -254,7 +254,7 @@ STDMETHODIMP FontFileEnumerator::SetFilePaths(Vector<String> const& filePaths)
{ {
try try
{ {
filePaths_.assign(filePaths); filePaths_.assign(filePaths.begin(), filePaths.end());
} }
catch (std::bad_alloc&) catch (std::bad_alloc&)
{ {
@ -305,7 +305,9 @@ HRESULT STDMETHODCALLTYPE FontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFil
if (nextIndex_ < filePaths_.size()) if (nextIndex_ < filePaths_.size())
{ {
hr = pFactory_->CreateFontFileReference(filePaths_[nextIndex_].c_str(), NULL, &currentFile_); WideString file_name = MultiByteToWide(filePaths_[nextIndex_]);
hr = pFactory_->CreateFontFileReference(file_name.c_str(), NULL, &currentFile_);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -671,7 +673,7 @@ STDMETHODIMP ResourceFontFileEnumerator::SetResources(Vector<Resource> const& re
{ {
try try
{ {
resources_.assign(resources); resources_.assign(resources.begin(), resources.end());
} }
catch (std::bad_alloc&) catch (std::bad_alloc&)
{ {

View File

@ -19,6 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/Resource.h>
#include <kiwano/render/DirectX/D2DDeviceResources.h> #include <kiwano/render/DirectX/D2DDeviceResources.h>
namespace kiwano namespace kiwano

View File

@ -152,7 +152,7 @@ void RenderContextImpl::DrawTextLayout(TextLayout const& layout, Point const& of
} }
else else
{ {
KGE_ERROR(L"Failed to draw text layout with HRESULT of %08X", hr); KGE_ERROR("Failed to draw text layout with HRESULT of %08X", hr);
} }
} }
} }

View File

@ -47,7 +47,7 @@ RendererImpl::RendererImpl()
void RendererImpl::SetupComponent() void RendererImpl::SetupComponent()
{ {
KGE_SYS_LOG(L"Creating device resources"); KGE_SYS_LOG("Creating device resources");
win32::ThrowIfFailed(::CoInitialize(nullptr)); win32::ThrowIfFailed(::CoInitialize(nullptr));
@ -116,7 +116,7 @@ void RendererImpl::SetupComponent()
void RendererImpl::DestroyComponent() void RendererImpl::DestroyComponent()
{ {
KGE_SYS_LOG(L"Destroying device resources"); KGE_SYS_LOG("Destroying device resources");
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get()); d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get());
res_font_file_loader_.reset(); res_font_file_loader_.reset();
@ -205,16 +205,16 @@ void RendererImpl::CreateTexture(Texture& texture, String const& file_path)
if (!FileSystem::GetInstance().IsFileExists(file_path)) if (!FileSystem::GetInstance().IsFileExists(file_path))
{ {
KGE_WARN(L"Texture file '%s' not found!", file_path.c_str()); KGE_WARN("Texture file '%s' not found!", file_path.c_str());
hr = E_FAIL; hr = E_FAIL;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
String full_path = FileSystem::GetInstance().GetFullPathForFile(file_path); WideString full_path = MultiByteToWide(FileSystem::GetInstance().GetFullPathForFile(file_path));
ComPtr<IWICBitmapDecoder> decoder; ComPtr<IWICBitmapDecoder> decoder;
hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path); hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path.c_str());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -244,7 +244,7 @@ void RendererImpl::CreateTexture(Texture& texture, String const& file_path)
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_WARN(L"Load texture failed with HRESULT of %08X!", hr); KGE_WARN("Load texture failed with HRESULT of %08X!", hr);
} }
} }
@ -258,29 +258,36 @@ void RendererImpl::CreateTexture(Texture& texture, Resource const& resource)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICBitmapDecoder> decoder; Resource::Data data = resource.GetData();
hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, resource);
hr = data ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICBitmapFrameDecode> source; ComPtr<IWICBitmapDecoder> decoder;
hr = decoder->GetFrame(0, &source); hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, data.buffer, (DWORD)data.size);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICFormatConverter> converter; ComPtr<IWICBitmapFrameDecode> source;
hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA, hr = decoder->GetFrame(0, &source);
WICBitmapDitherTypeNone, nullptr, 0.f,
WICBitmapPaletteTypeMedianCut);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<ID2D1Bitmap> bitmap; ComPtr<IWICFormatConverter> converter;
hr = d2d_res_->CreateBitmapFromConverter(bitmap, nullptr, converter); hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone, nullptr, 0.f,
WICBitmapPaletteTypeMedianCut);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
texture.SetBitmap(bitmap); ComPtr<ID2D1Bitmap> bitmap;
hr = d2d_res_->CreateBitmapFromConverter(bitmap, nullptr, converter);
if (SUCCEEDED(hr))
{
texture.SetBitmap(bitmap);
}
} }
} }
} }
@ -289,7 +296,7 @@ void RendererImpl::CreateTexture(Texture& texture, Resource const& resource)
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_WARN(L"Load texture failed with HRESULT of %08X!", hr); KGE_WARN("Load texture failed with HRESULT of %08X!", hr);
} }
} }
@ -303,16 +310,16 @@ void RendererImpl::CreateGifImage(GifImage& gif, String const& file_path)
if (!FileSystem::GetInstance().IsFileExists(file_path)) if (!FileSystem::GetInstance().IsFileExists(file_path))
{ {
KGE_WARN(L"Gif texture file '%s' not found!", file_path.c_str()); KGE_WARN("Gif texture file '%s' not found!", file_path.c_str());
hr = E_FAIL; hr = E_FAIL;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
String full_path = FileSystem::GetInstance().GetFullPathForFile(file_path); WideString full_path = MultiByteToWide(FileSystem::GetInstance().GetFullPathForFile(file_path));
ComPtr<IWICBitmapDecoder> decoder; ComPtr<IWICBitmapDecoder> decoder;
hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path); hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path.c_str());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -322,7 +329,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, String const& file_path)
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_WARN(L"Load GIF texture failed with HRESULT of %08X!", hr); KGE_WARN("Load GIF texture failed with HRESULT of %08X!", hr);
} }
} }
@ -336,18 +343,25 @@ void RendererImpl::CreateGifImage(GifImage& gif, Resource const& resource)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICBitmapDecoder> decoder; Resource::Data data = resource.GetData();
hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, resource);
hr = data ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
gif.SetDecoder(decoder); ComPtr<IWICBitmapDecoder> decoder;
hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, data.buffer, (DWORD)data.size);
if (SUCCEEDED(hr))
{
gif.SetDecoder(decoder);
}
} }
} }
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_WARN(L"Load GIF texture failed with HRESULT of %08X!", hr); KGE_WARN("Load GIF texture failed with HRESULT of %08X!", hr);
} }
} }
@ -506,7 +520,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, GifImage const& g
if (FAILED(hr)) if (FAILED(hr))
{ {
KGE_WARN(L"Load GIF frame failed with HRESULT of %08X!", hr); KGE_WARN("Load GIF frame failed with HRESULT of %08X!", hr);
} }
} }
@ -522,7 +536,7 @@ void RendererImpl::CreateFontCollection(Font& font, String const& file_path)
{ {
if (!FileSystem::GetInstance().IsFileExists(file_path)) if (!FileSystem::GetInstance().IsFileExists(file_path))
{ {
KGE_WARN(L"Font file '%s' not found!", file_path.c_str()); KGE_WARN("Font file '%s' not found!", file_path.c_str());
hr = E_FAIL; hr = E_FAIL;
} }
} }
@ -595,10 +609,10 @@ void RendererImpl::CreateTextFormat(TextLayout& layout)
{ {
const TextStyle& style = layout.GetStyle(); const TextStyle& style = layout.GetStyle();
hr = d2d_res_->CreateTextFormat(output, style.font_family, style.font ? style.font->GetCollection() : nullptr, hr = d2d_res_->CreateTextFormat(
DWRITE_FONT_WEIGHT(style.font_weight), output, MultiByteToWide(style.font_family).c_str(), style.font ? style.font->GetCollection() : nullptr,
style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_WEIGHT(style.font_weight), style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, style.font_size); DWRITE_FONT_STRETCH_NORMAL, style.font_size);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -620,7 +634,9 @@ void RendererImpl::CreateTextLayout(TextLayout& layout)
ComPtr<IDWriteTextLayout> output; ComPtr<IDWriteTextLayout> output;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = d2d_res_->CreateTextLayout(output, layout.GetText(), layout.GetTextFormat()); WideString text = MultiByteToWide(layout.GetText());
hr = d2d_res_->CreateTextLayout(output, text.c_str(), text.length(), layout.GetTextFormat());
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -941,7 +957,7 @@ void RendererImpl::Resize(uint32_t width, uint32_t height)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = d2d_res_->SetLogicalSize(output_size_); hr = d2d_res_->SetLogicalSize(output_size_.x, output_size_.y);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include <kiwano/core/ObjectBase.h> #include <kiwano/core/ObjectBase.h>
#include <kiwano/core/Resource.h>
#include <kiwano/render/DirectX/D2DDeviceResources.h> #include <kiwano/render/DirectX/D2DDeviceResources.h>
namespace kiwano namespace kiwano

View File

@ -22,6 +22,7 @@
namespace kiwano namespace kiwano
{ {
LocalStorage::LocalStorage(String const& file_path, String const& field) LocalStorage::LocalStorage(String const& file_path, String const& field)
{ {
SetFilePath(file_path); SetFilePath(file_path);
@ -30,75 +31,76 @@ LocalStorage::LocalStorage(String const& file_path, String const& field)
bool LocalStorage::Exists(String const& key) const bool LocalStorage::Exists(String const& key) const
{ {
wchar_t temp[256] = { 0 }; char temp[256] = { 0 };
::GetPrivateProfileStringW(field_name_.c_str(), key.c_str(), L"", temp, 255, file_path_.c_str()); ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), "", temp, 255, file_path_.c_str());
return temp[0] == L'\0'; return temp[0] == '\0';
} }
bool LocalStorage::SaveInt(String const& key, int val) const bool LocalStorage::SaveInt(String const& key, int val) const
{ {
BOOL ret = ::WritePrivateProfileStringW(field_name_.c_str(), key.c_str(), std::to_wstring(val).c_str(), BOOL ret =
file_path_.c_str()); ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str());
return ret == TRUE; return ret == TRUE;
} }
bool LocalStorage::SaveFloat(String const& key, float val) const bool LocalStorage::SaveFloat(String const& key, float val) const
{ {
BOOL ret = ::WritePrivateProfileStringW(field_name_.c_str(), key.c_str(), std::to_wstring(val).c_str(), BOOL ret =
file_path_.c_str()); ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str());
return ret == TRUE; return ret == TRUE;
} }
bool LocalStorage::SaveDouble(String const& key, double val) const bool LocalStorage::SaveDouble(String const& key, double val) const
{ {
BOOL ret = ::WritePrivateProfileStringW(field_name_.c_str(), key.c_str(), std::to_wstring(val).c_str(), BOOL ret =
file_path_.c_str()); ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str());
return ret == TRUE; return ret == TRUE;
} }
bool LocalStorage::SaveBool(String const& key, bool val) const bool LocalStorage::SaveBool(String const& key, bool val) const
{ {
BOOL ret = ::WritePrivateProfileStringW(field_name_.c_str(), key.c_str(), (val ? L"1" : L"0"), file_path_.c_str()); BOOL ret = ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), (val ? "1" : "0"), file_path_.c_str());
return ret == TRUE; return ret == TRUE;
} }
bool LocalStorage::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(), key.c_str(), val.c_str(), file_path_.c_str()); BOOL ret = ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), val.c_str(), file_path_.c_str());
return ret == TRUE; return ret == TRUE;
} }
int LocalStorage::GetInt(String const& key, int default_value) const int LocalStorage::GetInt(String const& key, int default_value) const
{ {
return ::GetPrivateProfileIntW(field_name_.c_str(), key.c_str(), default_value, file_path_.c_str()); return ::GetPrivateProfileIntA(field_name_.c_str(), key.c_str(), default_value, file_path_.c_str());
} }
float LocalStorage::GetFloat(String const& key, float default_value) const float LocalStorage::GetFloat(String const& key, float default_value) const
{ {
wchar_t temp[32] = { 0 }; char temp[32] = { 0 };
String default_str = String::parse(default_value); String default_str = String::parse(default_value);
::GetPrivateProfileStringW(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str()); ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str());
return std::stof(temp); return std::stof(temp);
} }
double LocalStorage::GetDouble(String const& key, double default_value) const double LocalStorage::GetDouble(String const& key, double default_value) const
{ {
wchar_t temp[32] = { 0 }; char temp[32] = { 0 };
String default_str = String::parse(default_value); String default_str = String::parse(default_value);
::GetPrivateProfileStringW(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str()); ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str());
return std::stod(temp); return std::stod(temp);
} }
bool LocalStorage::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(), key.c_str(), default_value ? 1 : 0, file_path_.c_str()); int nValue = ::GetPrivateProfileIntA(field_name_.c_str(), key.c_str(), default_value ? 1 : 0, file_path_.c_str());
return nValue == TRUE; return nValue == TRUE;
} }
String LocalStorage::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 }; char temp[256] = { 0 };
::GetPrivateProfileStringW(field_name_.c_str(), key.c_str(), default_value.c_str(), temp, 255, file_path_.c_str()); ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_value.c_str(), temp, 255, file_path_.c_str());
return temp; return temp;
} }
} // namespace kiwano } // namespace kiwano

View File

@ -34,8 +34,8 @@ KGE_DECLARE_SMART_PTR(LocalStorage);
/// 例如, 保存游戏最高分, 以便下次进行游戏时读取: /// 例如, 保存游戏最高分, 以便下次进行游戏时读取:
/// @code /// @code
/// LocalStorage data; // 创建数据对象 /// LocalStorage data; // 创建数据对象
/// data.SaveInt(L"best-score", 20); // 保存最高分 20 /// data.SaveInt("best-score", 20); // 保存最高分 20
/// int best = data.GetInt(L"best-score"); // 读取之前储存的最高分 /// int best = data.GetInt("best-score"); // 读取之前储存的最高分
/// @endcode /// @endcode
class KGE_API LocalStorage : public virtual ObjectBase class KGE_API LocalStorage : public virtual ObjectBase
{ {
@ -44,7 +44,7 @@ public:
/// @brief 构建本地存储对象 /// @brief 构建本地存储对象
/// @param file_path 文件储存路径 /// @param file_path 文件储存路径
/// @param field 字段名 /// @param field 字段名
LocalStorage(String const& file_path = L"data.ini", String const& field = L"defalut"); LocalStorage(String const& file_path = "data.ini", String const& field = "defalut");
/// \~chinese /// \~chinese
/// @brief 获取文件储存路径 /// @brief 获取文件储存路径

View File

@ -34,13 +34,13 @@ bool LoadXmlData(ResourceCache* loader, const pugi::xml_node& elem);
namespace namespace
{ {
Map<String, Function<bool(ResourceCache*, Json const&)>> load_json_funcs = { Map<String, Function<bool(ResourceCache*, Json const&)>> load_json_funcs = {
{ L"latest", __resource_cache_01::LoadJsonData }, { "latest", __resource_cache_01::LoadJsonData },
{ L"0.1", __resource_cache_01::LoadJsonData }, { "0.1", __resource_cache_01::LoadJsonData },
}; };
Map<String, Function<bool(ResourceCache*, const pugi::xml_node&)>> load_xml_funcs = { Map<String, Function<bool(ResourceCache*, const pugi::xml_node&)>> load_xml_funcs = {
{ L"latest", __resource_cache_01::LoadXmlData }, { "latest", __resource_cache_01::LoadXmlData },
{ L"0.1", __resource_cache_01::LoadXmlData }, { "0.1", __resource_cache_01::LoadXmlData },
}; };
} // namespace } // namespace
@ -55,12 +55,13 @@ bool ResourceCache::LoadFromJsonFile(String const& file_path)
{ {
if (!FileSystem::GetInstance().IsFileExists(file_path)) if (!FileSystem::GetInstance().IsFileExists(file_path))
{ {
KGE_ERROR(L"ResourceCache::LoadFromJsonFile failed: File not found."); KGE_ERROR("ResourceCache::LoadFromJsonFile failed: File not found.");
return false; return false;
} }
Json json_data; Json json_data;
std::wifstream ifs;
std::ifstream ifs;
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try try
@ -72,14 +73,12 @@ bool ResourceCache::LoadFromJsonFile(String const& file_path)
} }
catch (std::wifstream::failure& e) catch (std::wifstream::failure& e)
{ {
KGE_ERROR(L"ResourceCache::LoadFromJsonFile failed: Cannot open file. (%s)", KGE_ERROR("ResourceCache::LoadFromJsonFile failed: Cannot open file. (%s)", e.what());
oc::string_to_wide(e.what()).c_str());
return false; return false;
} }
catch (oc::json_exception& e) catch (Json::exception& e)
{ {
KGE_ERROR(L"ResourceCache::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", KGE_ERROR("ResourceCache::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", e.what());
oc::string_to_wide(e.what()).c_str());
return false; return false;
} }
return LoadFromJson(json_data); return LoadFromJson(json_data);
@ -89,7 +88,7 @@ bool ResourceCache::LoadFromJson(Json const& json_data)
{ {
try try
{ {
String version = json_data[L"version"]; String version = json_data["version"];
auto load = load_json_funcs.find(version); auto load = load_json_funcs.find(version);
if (load != load_json_funcs.end()) if (load != load_json_funcs.end())
@ -98,17 +97,16 @@ bool ResourceCache::LoadFromJson(Json const& json_data)
} }
else if (version.empty()) else if (version.empty())
{ {
return load_json_funcs[L"latest"](this, json_data); return load_json_funcs["latest"](this, json_data);
} }
else else
{ {
throw std::runtime_error("unknown JSON data version"); throw std::runtime_error("unknown JSON data version");
} }
} }
catch (std::exception& e) catch (Json::exception& e)
{ {
KGE_ERROR(L"ResourceCache::LoadFromJson failed: JSON data is invalid. (%s)", KGE_ERROR("ResourceCache::LoadFromJson failed: JSON data is invalid. (%s)", e.what());
oc::string_to_wide(e.what()).c_str());
return false; return false;
} }
return false; return false;
@ -118,7 +116,7 @@ bool ResourceCache::LoadFromXmlFile(String const& file_path)
{ {
if (!FileSystem::GetInstance().IsFileExists(file_path)) if (!FileSystem::GetInstance().IsFileExists(file_path))
{ {
KGE_ERROR(L"ResourceCache::LoadFromXmlFile failed: File not found."); KGE_ERROR("ResourceCache::LoadFromXmlFile failed: File not found.");
return false; return false;
} }
@ -133,17 +131,17 @@ bool ResourceCache::LoadFromXmlFile(String const& file_path)
} }
else else
{ {
KGE_ERROR(L"XML [%s] parsed with errors: %s", full_path.c_str(), result.description()); KGE_ERROR("XML [%s] parsed with errors: %s", full_path.c_str(), result.description());
return false; return false;
} }
} }
bool ResourceCache::LoadFromXml(const pugi::xml_document& doc) bool ResourceCache::LoadFromXml(const pugi::xml_document& doc)
{ {
if (pugi::xml_node root = doc.child(L"resources")) if (pugi::xml_node root = doc.child("resources"))
{ {
String version; String version;
if (auto version_node = root.child(L"version")) if (auto version_node = root.child("version"))
version = version_node.child_value(); version = version_node.child_value();
auto load = load_xml_funcs.find(version); auto load = load_xml_funcs.find(version);
@ -153,16 +151,16 @@ bool ResourceCache::LoadFromXml(const pugi::xml_document& doc)
} }
else if (version.empty()) else if (version.empty())
{ {
return load_xml_funcs[L"latest"](this, root); return load_xml_funcs["latest"](this, root);
} }
else else
{ {
KGE_ERROR(L"Unknown version"); KGE_ERROR("Unknown version");
return false; return false;
} }
} }
KGE_ERROR(L"Unknown version"); KGE_ERROR("Unknown version");
return false; return false;
} }
@ -308,108 +306,102 @@ struct GlobalData
String path; String path;
}; };
bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String& id, const String& type,
const String* file) const String& file)
{ {
if (!gdata || !id) if (!gdata)
return false; return false;
if (type && (*type) == L"gif") if (type == "gif")
{ {
// GIF image // GIF image
GifImagePtr gif = new (std::nothrow) GifImage; GifImagePtr gif = new (std::nothrow) GifImage;
if (gif && gif->Load(gdata->path + (*file))) if (gif && gif->Load(gdata->path + file))
{ {
return loader->AddObject(*id, gif); return loader->AddObject(id, gif);
} }
} }
if (file && !(*file).empty()) if (file.empty())
{ {
// Simple image // Simple image
FramePtr frame = new (std::nothrow) Frame; FramePtr frame = new (std::nothrow) Frame;
if (frame && frame->Load(gdata->path + (*file))) if (frame && frame->Load(gdata->path + file))
{ {
return loader->AddObject(*id, frame); return loader->AddObject(id, frame);
} }
} }
return false; return false;
} }
bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String& id,
const Vector<const wchar_t*>* files) const Vector<String>& files)
{ {
if (!gdata || !id) if (!gdata)
return false; return false;
if (files.empty())
return true;
// Frames // Frames
if (files) Vector<FramePtr> frames;
frames.reserve(files.size());
for (const auto& file : files)
{ {
Vector<FramePtr> frames; FramePtr frame = new Frame;
frames.reserve(files->size()); if (frame->Load(gdata->path + file))
for (const auto& file : (*files))
{ {
FramePtr frame = new Frame; frames.push_back(frame);
if (frame->Load(gdata->path + (file)))
{
frames.push_back(frame);
}
}
FrameSequencePtr frame_seq = FrameSequence::Create(frames);
if (frame_seq)
{
return !!loader->AddObject(*id, frame_seq);
} }
} }
FrameSequencePtr frame_seq = FrameSequence::Create(frames);
if (frame_seq)
{
return !!loader->AddObject(id, frame_seq);
}
return false; return false;
} }
bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* file, int rows, bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String& id, const String& file, int rows,
int cols, float padding_x, float padding_y) int cols, float padding_x, float padding_y)
{ {
if (!gdata || !id) if (!gdata)
return false; return false;
if (file) if (!file.empty())
{ {
if (!(*file).empty()) if (rows || cols)
{ {
if (rows || cols) // Frame slices
FramePtr frame = new (std::nothrow) Frame;
if (frame && frame->Load(gdata->path + file))
{ {
// Frame slices return !!loader->AddFrameSequence(id, frame, std::max(cols, 1), std::max(rows, 1), padding_x,
FramePtr frame = new (std::nothrow) Frame; padding_y);
if (frame && frame->Load(gdata->path + (*file)))
{
return !!loader->AddFrameSequence(*id, frame, std::max(cols, 1), std::max(rows, 1), padding_x,
padding_y);
}
} }
else }
else
{
// Simple image
FramePtr frame = new (std::nothrow) Frame;
if (frame && frame->Load(gdata->path + file))
{ {
// Simple image return loader->AddObject(id, frame);
FramePtr frame = new (std::nothrow) Frame;
if (frame && frame->Load(gdata->path + (*file)))
{
return loader->AddObject(*id, frame);
}
} }
} }
} }
return false; return false;
} }
bool LoadFontsFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* file) bool LoadFontsFromData(ResourceCache* loader, GlobalData* gdata, const String& id, const String& file)
{ {
if (!gdata || !id) if (!gdata)
return false; return false;
if (file) FontPtr font = new (std::nothrow) Font;
if (font && font->Load(gdata->path + file))
{ {
FontPtr font = new (std::nothrow) Font; return loader->AddObject(id, font);
if (font && font->Load(gdata->path + (*file)))
{
return loader->AddObject(*id, font);
}
} }
return false; return false;
} }
@ -417,50 +409,50 @@ bool LoadFontsFromData(ResourceCache* loader, GlobalData* gdata, const String* i
bool LoadJsonData(ResourceCache* loader, Json const& json_data) bool LoadJsonData(ResourceCache* loader, Json const& json_data)
{ {
GlobalData global_data; GlobalData global_data;
if (json_data.count(L"path")) if (json_data.count("path"))
{ {
global_data.path = json_data[L"path"]; global_data.path = json_data["path"];
} }
if (json_data.count(L"images")) if (json_data.count("images"))
{ {
for (const auto& image : json_data[L"images"]) for (const auto& image : json_data["images"])
{ {
const String *id = nullptr, *type = nullptr, *file = nullptr; String id, type, file;
int rows = 0, cols = 0; int rows = 0, cols = 0;
if (image.count(L"id")) if (image.count("id"))
id = &image[L"id"].as_string(); id = image["id"].get<String>();
if (image.count(L"type")) if (image.count("type"))
type = &image[L"type"].as_string(); type = image["type"].get<String>();
if (image.count(L"file")) if (image.count("file"))
file = &image[L"file"].as_string(); file = image["file"].get<String>();
if (image.count(L"rows")) if (image.count("rows"))
rows = image[L"rows"].as_int(); rows = image["rows"].get<int>();
if (image.count(L"cols")) if (image.count("cols"))
cols = image[L"cols"].as_int(); cols = image["cols"].get<int>();
if (rows || cols) if (rows || cols)
{ {
float padding_x = 0, padding_y = 0; float padding_x = 0, padding_y = 0;
if (image.count(L"padding-x")) if (image.count("padding-x"))
padding_x = image[L"padding-x"].get<float>(); padding_x = image["padding-x"].get<float>();
if (image.count(L"padding-y")) if (image.count("padding-y"))
padding_y = image[L"padding-y"].get<float>(); padding_y = image["padding-y"].get<float>();
if (!LoadTexturesFromData(loader, &global_data, id, file, rows, cols, padding_x, padding_y)) if (!LoadTexturesFromData(loader, &global_data, id, file, rows, cols, padding_x, padding_y))
return false; return false;
} }
if (image.count(L"files")) if (image.count("files"))
{ {
Vector<const wchar_t*> files; Vector<String> files;
files.reserve(image[L"files"].size()); files.reserve(image["files"].size());
for (const auto& file : image[L"files"]) for (const auto& file : image["files"])
{ {
files.push_back(file.as_string().c_str()); files.push_back(file.get<String>());
} }
if (!LoadTexturesFromData(loader, &global_data, id, &files)) if (!LoadTexturesFromData(loader, &global_data, id, files))
return false; return false;
} }
else else
@ -471,16 +463,16 @@ bool LoadJsonData(ResourceCache* loader, Json const& json_data)
} }
} }
if (json_data.count(L"fonts")) if (json_data.count("fonts"))
{ {
for (const auto& font : json_data[L"fonts"]) for (const auto& font : json_data["fonts"])
{ {
const String *id = nullptr, *file = nullptr; String id, file;
if (font.count(L"id")) if (font.count("id"))
id = &font[L"id"].as_string(); id = font["id"].get<String>();
if (font.count(L"file")) if (font.count("file"))
file = &font[L"file"].as_string(); file = font["file"].get<String>();
if (!LoadFontsFromData(loader, &global_data, id, file)) if (!LoadFontsFromData(loader, &global_data, id, file))
return false; return false;
@ -492,73 +484,73 @@ bool LoadJsonData(ResourceCache* loader, Json const& json_data)
bool LoadXmlData(ResourceCache* loader, const pugi::xml_node& elem) bool LoadXmlData(ResourceCache* loader, const pugi::xml_node& elem)
{ {
GlobalData global_data; GlobalData global_data;
if (auto path = elem.child(L"path")) if (auto path = elem.child("path"))
{ {
global_data.path = path.child_value(); global_data.path = path.child_value();
} }
if (auto images = elem.child(L"images")) if (auto images = elem.child("images"))
{ {
for (auto image : images.children()) for (auto image : images.children())
{ {
String id, type, file; String id, type, file;
int rows = 0, cols = 0; int rows = 0, cols = 0;
if (auto attr = image.attribute(L"id")) if (auto attr = image.attribute("id"))
id.assign(attr.value()); id.assign(attr.value());
if (auto attr = image.attribute(L"type")) if (auto attr = image.attribute("type"))
type = attr.value(); type = attr.value();
if (auto attr = image.attribute(L"file")) if (auto attr = image.attribute("file"))
file = attr.value(); file = attr.value();
if (auto attr = image.attribute(L"rows")) if (auto attr = image.attribute("rows"))
rows = attr.as_int(0); rows = attr.as_int(0);
if (auto attr = image.attribute(L"cols")) if (auto attr = image.attribute("cols"))
cols = attr.as_int(0); cols = attr.as_int(0);
if (rows || cols) if (rows || cols)
{ {
float padding_x = 0, padding_y = 0; float padding_x = 0, padding_y = 0;
if (auto attr = image.attribute(L"padding-x")) if (auto attr = image.attribute("padding-x"))
padding_x = attr.as_float(0.0f); padding_x = attr.as_float(0.0f);
if (auto attr = image.attribute(L"padding-y")) if (auto attr = image.attribute("padding-y"))
padding_y = attr.as_float(0.0f); padding_y = attr.as_float(0.0f);
if (!LoadTexturesFromData(loader, &global_data, &id, &file, rows, cols, padding_x, padding_y)) if (!LoadTexturesFromData(loader, &global_data, id, file, rows, cols, padding_x, padding_y))
return false; return false;
} }
if (file.empty() && !image.empty()) if (file.empty() && !image.empty())
{ {
Vector<const wchar_t*> files_arr; Vector<String> files_arr;
for (auto file : image.children()) for (auto file : image.children())
{ {
if (auto path = file.attribute(L"path")) if (auto path = file.attribute("path"))
{ {
files_arr.push_back(path.value()); files_arr.push_back(path.value());
} }
} }
if (!LoadTexturesFromData(loader, &global_data, &id, &files_arr)) if (!LoadTexturesFromData(loader, &global_data, id, files_arr))
return false; return false;
} }
else else
{ {
if (!LoadTexturesFromData(loader, &global_data, &id, &type, &file)) if (!LoadTexturesFromData(loader, &global_data, id, type, file))
return false; return false;
} }
} }
} }
if (auto fonts = elem.child(L"fonts")) if (auto fonts = elem.child("fonts"))
{ {
for (auto font : fonts.children()) for (auto font : fonts.children())
{ {
String id, file; String id, file;
if (auto attr = font.attribute(L"id")) if (auto attr = font.attribute("id"))
id.assign(attr.value()); id.assign(attr.value());
if (auto attr = font.attribute(L"file")) if (auto attr = font.attribute("file"))
file = attr.value(); file = attr.value();
if (!LoadFontsFromData(loader, &global_data, &id, &file)) if (!LoadFontsFromData(loader, &global_data, id, file))
return false; return false;
} }
} }