Change default char code
This commit is contained in:
		
							parent
							
								
									b763064b3d
								
							
						
					
					
						commit
						1e93eddb88
					
				|  | @ -93,11 +93,11 @@ struct json_lexer | |||
| 			break; | ||||
| 
 | ||||
| 		case 't': | ||||
| 			return scan_literal(L"true", token_type::LITERAL_TRUE); | ||||
| 			return scan_literal("true", token_type::LITERAL_TRUE); | ||||
| 		case 'f': | ||||
| 			return scan_literal(L"false", token_type::LITERAL_FALSE); | ||||
| 			return scan_literal("false", token_type::LITERAL_FALSE); | ||||
| 		case 'n': | ||||
| 			return scan_literal(L"null", token_type::LITERAL_NULL); | ||||
| 			return scan_literal("null", token_type::LITERAL_NULL); | ||||
| 
 | ||||
| 		case '\"': | ||||
| 			return scan_string(); | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ class vector | |||
| public: | ||||
| 	using value_type				= _Ty; | ||||
| 	using size_type					= size_t; | ||||
| 	using difference_type			= ptrdiff_t; | ||||
| 	using reference					= value_type&; | ||||
| 	using const_reference			= const value_type&; | ||||
| 	using iterator					= value_type*; | ||||
|  | @ -70,6 +71,7 @@ public: | |||
| 	inline bool						empty() const							{ return size_ == 0; } | ||||
| 	inline size_type				size() const							{ return size_; } | ||||
| 	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 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]; } | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -15,7 +15,7 @@ | |||
| #define HEADER_PUGICONFIG_HPP | ||||
| 
 | ||||
| // Uncomment this to enable wchar_t mode
 | ||||
| #define PUGIXML_WCHAR_MODE | ||||
| // #define PUGIXML_WCHAR_MODE
 | ||||
| 
 | ||||
| // Uncomment this to enable compact mode
 | ||||
| // #define PUGIXML_COMPACT
 | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ AudioEngine::~AudioEngine() {} | |||
| 
 | ||||
| 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); | ||||
| 
 | ||||
|  | @ -56,7 +56,7 @@ void AudioEngine::SetupComponent() | |||
| 
 | ||||
| void AudioEngine::DestroyComponent() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Destroying audio resources"); | ||||
|     KGE_SYS_LOG("Destroying audio resources"); | ||||
| 
 | ||||
|     if (mastering_voice_) | ||||
|     { | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ bool Sound::Load(String const& 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; | ||||
|     } | ||||
| 
 | ||||
|  | @ -79,7 +79,7 @@ bool Sound::Load(String const& file_path) | |||
|     HRESULT hr = transcoder_.LoadMediaFile(full_path); | ||||
|     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; | ||||
|     } | ||||
| 
 | ||||
|  | @ -103,7 +103,7 @@ bool Sound::Load(Resource const& res) | |||
|     HRESULT hr = transcoder_.LoadMediaResource(res); | ||||
|     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; | ||||
|     } | ||||
| 
 | ||||
|  | @ -126,7 +126,7 @@ void Sound::Play(int loop_count) | |||
| { | ||||
|     if (!opened_) | ||||
|     { | ||||
|         KGE_ERROR(L"Sound must be opened first!"); | ||||
|         KGE_ERROR("Sound must be opened first!"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -157,7 +157,7 @@ void Sound::Play(int loop_count) | |||
| 
 | ||||
|     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); | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ HRESULT Transcoder::LoadMediaFile(String const& file_path) | |||
| 
 | ||||
|     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)) | ||||
|     { | ||||
|  | @ -105,7 +105,7 @@ HRESULT Transcoder::LoadMediaResource(Resource const& res) | |||
| 
 | ||||
|     if (stream == nullptr) | ||||
|     { | ||||
|         KGE_ERROR(L"SHCreateMemStream failed"); | ||||
|         KGE_ERROR("SHCreateMemStream failed"); | ||||
|         return E_OUTOFMEMORY; | ||||
|     } | ||||
| 
 | ||||
|  | @ -198,7 +198,7 @@ HRESULT Transcoder::ReadSource(IMFSourceReader* reader) | |||
| 
 | ||||
|         if (data == nullptr) | ||||
|         { | ||||
|             KGE_ERROR(L"Low memory"); | ||||
|             KGE_ERROR("Low memory"); | ||||
|             hr = E_OUTOFMEMORY; | ||||
|         } | ||||
|         else | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ XAudio2::XAudio2() | |||
|     } | ||||
|     else | ||||
|     { | ||||
|         KGE_ERROR(L"Load xaudio2.dll failed"); | ||||
|         KGE_ERROR("Load xaudio2.dll failed"); | ||||
|         throw std::runtime_error("Load xaudio2.dll failed"); | ||||
|     } | ||||
| } | ||||
|  | @ -79,7 +79,7 @@ MediaFoundation::MediaFoundation() | |||
|     } | ||||
|     else | ||||
|     { | ||||
|         KGE_ERROR(L"Load Mfplat.dll failed"); | ||||
|         KGE_ERROR("Load Mfplat.dll failed"); | ||||
|         throw std::runtime_error("Load Mfplat.dll failed"); | ||||
|     } | ||||
| 
 | ||||
|  | @ -92,7 +92,7 @@ MediaFoundation::MediaFoundation() | |||
|     } | ||||
|     else | ||||
|     { | ||||
|         KGE_ERROR(L"Load Mfreadwrite.dll failed"); | ||||
|         KGE_ERROR("Load Mfreadwrite.dll failed"); | ||||
|         throw std::runtime_error("Load Mfreadwrite.dll failed"); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <codecvt> | ||||
| #include <thread> | ||||
| #include <kiwano/core/Logger.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) | ||||
| { | ||||
|     ByteString* recv_buffer = (ByteString*)userp; | ||||
|     uint32_t    total       = size * nmemb; | ||||
|     String*  recv_buffer = (String*)userp; | ||||
|     uint32_t total       = size * nmemb; | ||||
| 
 | ||||
|     // add data to the end of recv_buffer
 | ||||
|     // 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; | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
| public: | ||||
|  | @ -102,8 +67,8 @@ public: | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     bool Init(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, ByteString* response_data, | ||||
|               ByteString* response_header, char* error_buffer) | ||||
|     bool Init(HttpClient* client, Vector<String> const& headers, String const& url, String* response_data, | ||||
|               String* response_header, char* error_buffer) | ||||
|     { | ||||
|         if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) | ||||
|             return false; | ||||
|  | @ -112,7 +77,7 @@ public: | |||
|         if (!SetOption(CURLOPT_CONNECTTIMEOUT, client->GetTimeoutForConnect())) | ||||
|             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 (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L)) | ||||
|  | @ -167,8 +132,8 @@ public: | |||
|     } | ||||
| 
 | ||||
| public: | ||||
|     static inline bool GetRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                   long* response_code, ByteString* response_data, ByteString* response_header, | ||||
|     static inline bool GetRequest(HttpClient* client, Vector<String> const& headers, String const& url, | ||||
|                                   long* response_code, String* response_data, String* response_header, | ||||
|                                   char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|  | @ -176,9 +141,9 @@ public: | |||
|                && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.Perform(response_code); | ||||
|     } | ||||
| 
 | ||||
|     static inline bool PostRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                    ByteString const& request_data, long* response_code, ByteString* response_data, | ||||
|                                    ByteString* response_header, char* error_buffer) | ||||
|     static inline bool PostRequest(HttpClient* client, Vector<String> const& headers, String const& url, | ||||
|                                    String const& request_data, long* response_code, String* response_data, | ||||
|                                    String* response_header, char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|         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); | ||||
|     } | ||||
| 
 | ||||
|     static inline bool PutRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                   ByteString const& request_data, long* response_code, ByteString* response_data, | ||||
|                                   ByteString* response_header, char* error_buffer) | ||||
|     static inline bool PutRequest(HttpClient* client, Vector<String> const& headers, String const& url, | ||||
|                                   String const& request_data, long* response_code, String* response_data, | ||||
|                                   String* response_header, char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|         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); | ||||
|     } | ||||
| 
 | ||||
|     static inline bool DeleteRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                      long* response_code, ByteString* response_data, ByteString* response_header, | ||||
|     static inline bool DeleteRequest(HttpClient* client, Vector<String> const& headers, String const& url, | ||||
|                                      long* response_code, String* response_data, String* response_header, | ||||
|                                      char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|  | @ -276,20 +241,19 @@ void HttpClient::NetworkThread() | |||
| 
 | ||||
| void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response) | ||||
| { | ||||
|     bool       ok                 = false; | ||||
|     long       response_code      = 0; | ||||
|     char       error_message[256] = { 0 }; | ||||
|     ByteString response_header; | ||||
|     ByteString response_data; | ||||
|     bool   ok                 = false; | ||||
|     long   response_code      = 0; | ||||
|     char   error_message[256] = { 0 }; | ||||
|     String response_header; | ||||
|     String response_data; | ||||
|     String url  = request->GetUrl(); | ||||
|     String data = request->GetData(); | ||||
| 
 | ||||
|     ByteString url  = convert_to_utf8(request->GetUrl()); | ||||
|     ByteString data = convert_to_utf8(request->GetData()); | ||||
| 
 | ||||
|     Vector<ByteString> headers; | ||||
|     Vector<String> headers; | ||||
|     headers.reserve(request->GetHeaders().size()); | ||||
|     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()) | ||||
|  | @ -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); | ||||
|         break; | ||||
|     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; | ||||
|     } | ||||
| 
 | ||||
|     response->SetResponseCode(response_code); | ||||
|     response->SetHeader(MultiByteToWide(response_header)); | ||||
|     response->SetData(convert_from_utf8(response_data)); | ||||
|     response->SetHeader(response_header); | ||||
|     response->SetData(response_data); | ||||
|     if (!ok) | ||||
|     { | ||||
|         response->SetSucceed(false); | ||||
|         response->SetError(MultiByteToWide(error_message)); | ||||
|         response->SetError(error_message); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|  |  | |||
|  | @ -66,7 +66,7 @@ HttpRequestPtr HttpRequest::Create(String const& url, HttpType type, Json const& | |||
| 
 | ||||
| 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(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -513,7 +513,7 @@ void Actor::AddChild(Actor* child, int zorder) | |||
|         { | ||||
|             if (parent == child) | ||||
|             { | ||||
|                 KGE_ERROR(L"A actor cannot be its own parent"); | ||||
|                 KGE_ERROR("A actor cannot be its own parent"); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ class comma_numpunct : public std::numpunct<wchar_t> | |||
| private: | ||||
|     virtual wchar_t do_thousands_sep() const override | ||||
|     { | ||||
|         return L','; | ||||
|         return ','; | ||||
|     } | ||||
| 
 | ||||
|     virtual std::string do_grouping() const override | ||||
|  | @ -46,7 +46,7 @@ private: | |||
| 
 | ||||
| DebugActor::DebugActor() | ||||
| { | ||||
|     SetName(L"kiwano-debug-actor"); | ||||
|     SetName("kiwano-debug-actor"); | ||||
|     SetPosition(Point{ 10, 10 }); | ||||
|     SetResponsible(true); | ||||
|     SetCascadeOpacityEnabled(true); | ||||
|  | @ -60,7 +60,7 @@ DebugActor::DebugActor() | |||
|     fill_brush->SetColor(Color::White); | ||||
| 
 | ||||
|     TextStyle style; | ||||
|     style.font_family  = L"Arial"; | ||||
|     style.font_family  = "Arial"; | ||||
|     style.font_size    = 16.f; | ||||
|     style.font_weight  = FontWeight::Normal; | ||||
|     style.line_spacing = 20.f; | ||||
|  |  | |||
|  | @ -43,12 +43,12 @@ Stage::~Stage() {} | |||
| 
 | ||||
| void Stage::OnEnter() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Stage entered"); | ||||
|     KGE_SYS_LOG("Stage entered"); | ||||
| } | ||||
| 
 | ||||
| void Stage::OnExit() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Stage exited"); | ||||
|     KGE_SYS_LOG("Stage exited"); | ||||
| } | ||||
| 
 | ||||
| void Stage::RenderBorder(RenderContext& ctx) | ||||
|  |  | |||
|  | @ -175,7 +175,7 @@ public: | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     virtual ActionPtr Reverse() const override | ||||
|     { | ||||
|         KGE_ERROR(L"Reverse() not supported in ActionMoveTo"); | ||||
|         KGE_ERROR("Reverse() not supported in ActionMoveTo"); | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|  | @ -243,7 +243,7 @@ public: | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     virtual ActionPtr Reverse() const override | ||||
|     { | ||||
|         KGE_ERROR(L"Reverse() not supported in ActionJumpTo"); | ||||
|         KGE_ERROR("Reverse() not supported in ActionJumpTo"); | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|  | @ -308,7 +308,7 @@ public: | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     virtual ActionPtr Reverse() const override | ||||
|     { | ||||
|         KGE_ERROR(L"Reverse() not supported in ActionScaleTo"); | ||||
|         KGE_ERROR("Reverse() not supported in ActionScaleTo"); | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|  | @ -340,7 +340,7 @@ public: | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     virtual ActionPtr Reverse() const override | ||||
|     { | ||||
|         KGE_ERROR(L"Reverse() not supported in ActionFadeTo"); | ||||
|         KGE_ERROR("Reverse() not supported in ActionFadeTo"); | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|  | @ -429,7 +429,7 @@ public: | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     virtual ActionPtr Reverse() const override | ||||
|     { | ||||
|         KGE_ERROR(L"Reverse() not supported in ActionRotateTo"); | ||||
|         KGE_ERROR("Reverse() not supported in ActionRotateTo"); | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|  | @ -465,7 +465,7 @@ public: | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override | ||||
|     { | ||||
|         KGE_ERROR(L"Reverse() not supported in ActionCustom"); | ||||
|         KGE_ERROR("Reverse() not supported in ActionCustom"); | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,9 +9,9 @@ | |||
| //#define KGE_ASSERT(EXPR)  __noop            // Disable asserts
 | ||||
| 
 | ||||
| //---- 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_WARN(FORMAT, ...)      wprintf(FORMAT L"\n", __VA_ARGS__)
 | ||||
| //#define KGE_ERROR(FORMAT, ...)        wprintf(FORMAT L"\n", __VA_ARGS__)
 | ||||
| //#define KGE_SYS_LOG(FORMAT, ...)              wprintf(FORMAT "\n", __VA_ARGS__)
 | ||||
| //#define KGE_WARN(FORMAT, ...)      wprintf(FORMAT "\n", __VA_ARGS__)
 | ||||
| //#define KGE_ERROR(FORMAT, ...)        wprintf(FORMAT "\n", __VA_ARGS__)
 | ||||
| 
 | ||||
| //---- Define attributes of all API symbols declarations for DLL
 | ||||
| //#define KGE_USE_DLL
 | ||||
|  |  | |||
|  | @ -19,9 +19,6 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <3rd-party/OuterC/oc/oc.h> | ||||
| #include <kiwano/core/Singleton.h> | ||||
| #include <kiwano/macros.h> | ||||
| #include <list> | ||||
| #include <map> | ||||
| #include <queue> | ||||
|  | @ -30,25 +27,42 @@ | |||
| #include <stack> | ||||
| #include <unordered_map> | ||||
| #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 | ||||
| { | ||||
| /// \~chinese
 | ||||
| /// @brief 字符串容器
 | ||||
| using String = oc::wstring; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 窄字符串容器
 | ||||
| using ByteString = oc::string; | ||||
| /// @brief 输入流
 | ||||
| using InputStream = std::istream; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 输出流
 | ||||
| using OutputStream = std::ostream; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 字符串容器
 | ||||
| using String = oc::string; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 宽字符串容器
 | ||||
| using WideString = oc::wstring; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 字符串流
 | ||||
| using StringStream = std::wstringstream; | ||||
| using StringStream = std::stringstream; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 宽字符串流
 | ||||
| using WideStringStream = std::wstringstream; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 线性数组容器
 | ||||
| template <typename _Ty, typename... _Args> | ||||
| using Vector = oc::vector<_Ty, _Args...>; | ||||
| using Vector = std::vector<_Ty, _Args...>; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 链表容器
 | ||||
|  | @ -99,10 +113,6 @@ using Function = oc::function<_FuncTy>; | |||
| /// @brief 单值容器
 | ||||
| using Any = oc::any; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief JSON对象容器
 | ||||
| using Json = oc::basic_json<Map, Vector, String, int, double, bool, std::allocator>; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 侵入式链表容器
 | ||||
| template <typename _Ty> | ||||
|  | @ -118,6 +128,10 @@ using IntrusiveListItem = oc::intrusive_list_item<_Ty>; | |||
| template <typename _Ty, typename _RefProxyTy> | ||||
| using IntrusivePtr = oc::intrusive_ptr<_Ty, _RefProxyTy>; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief JSON对象容器
 | ||||
| using Json = nlohmann::basic_json<Map, Vector, String>; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 不可拷贝对象
 | ||||
| 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); | ||||
| } | ||||
| 
 | ||||
| inline ByteString WideToMultiByte(const String& str) | ||||
| inline String WideToMultiByte(const WideString& 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); | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -40,12 +40,6 @@ Library::~Library() | |||
| } | ||||
| 
 | ||||
| bool Library::Load(String const& lib) | ||||
| { | ||||
|     instance_ = ::LoadLibraryW(lib.c_str()); | ||||
|     return IsValid(); | ||||
| } | ||||
| 
 | ||||
| bool Library::Load(ByteString const& lib) | ||||
| { | ||||
|     instance_ = ::LoadLibraryA(lib.c_str()); | ||||
|     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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,7 +20,6 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/macros.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
|  | @ -47,11 +46,6 @@ public: | |||
|     /// @param lib DLL文件路径
 | ||||
|     bool Load(String const& lib); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 加载DLL
 | ||||
|     /// @param lib DLL文件路径
 | ||||
|     bool Load(ByteString const& lib); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 是否有效
 | ||||
|     bool IsValid() const; | ||||
|  | @ -63,13 +57,13 @@ public: | |||
|     /// \~chinese
 | ||||
|     /// @brief 检索指定的DLL中的输出库函数地址
 | ||||
|     /// @param proc_name 函数名
 | ||||
|     FARPROC GetProcess(ByteString const& proc_name); | ||||
|     FARPROC GetProcess(String const& proc_name); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 检索指定的DLL中的输出库函数地址
 | ||||
|     /// @param proc_name 函数名
 | ||||
|     template <typename _Proc> | ||||
|     inline _Proc GetProcess(ByteString const& proc_name) | ||||
|     inline _Proc GetProcess(String const& proc_name) | ||||
|     { | ||||
|         return reinterpret_cast<_Proc>(GetProcess(proc_name)); | ||||
|     } | ||||
|  |  | |||
|  | @ -141,7 +141,7 @@ const WORD reset = white; | |||
| }  // namespace console_colors
 | ||||
| 
 | ||||
| #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); \ | ||||
|         return _out;                                                                     \ | ||||
|  | @ -175,8 +175,8 @@ Logger::Logger() | |||
|     : enabled_(true) | ||||
|     , default_stdout_color_(0) | ||||
|     , default_stderr_color_(0) | ||||
|     , output_stream_(std::wcout.rdbuf()) | ||||
|     , error_stream_(std::wcerr.rdbuf()) | ||||
|     , output_stream_(std::cout.rdbuf()) | ||||
|     , error_stream_(std::cerr.rdbuf()) | ||||
| { | ||||
|     ResetOutputStream(); | ||||
| } | ||||
|  | @ -186,7 +186,7 @@ Logger::~Logger() | |||
|     FreeAllocatedConsole(); | ||||
| } | ||||
| 
 | ||||
| void Logger::Printf(Level level, const wchar_t* format, ...) | ||||
| void Logger::Printf(Level level, const char* format, ...) | ||||
| { | ||||
|     if (!enabled_) | ||||
|         return; | ||||
|  | @ -200,11 +200,11 @@ void Logger::Printf(Level level, const wchar_t* format, ...) | |||
|         va_list args = nullptr; | ||||
|         va_start(args, format); | ||||
| 
 | ||||
|         static wchar_t temp_buffer[1024 * 3 + 1]; | ||||
|         const auto     len = ::_vscwprintf(format, args) + 1; | ||||
|         ::_vsnwprintf_s(temp_buffer, len, len, format, args); | ||||
|         static char temp_buffer[1024 * 3 + 1]; | ||||
|         const auto     len = ::_vscprintf(format, args) + 1; | ||||
|         ::_vsnprintf_s(temp_buffer, len, len, format, args); | ||||
| 
 | ||||
|         sstream << ' ' << temp_buffer << L"\r\n"; | ||||
|         sstream << ' ' << temp_buffer << "\r\n"; | ||||
| 
 | ||||
|         va_end(args); | ||||
|     } | ||||
|  | @ -219,16 +219,16 @@ void Logger::Prepare(Level level, StringStream& sstream) | |||
|     switch (level) | ||||
|     { | ||||
|     case Level::Info: | ||||
|         prefix = L"[INFO] "; | ||||
|         prefix = "[INFO] "; | ||||
|         break; | ||||
|     case Level::System: | ||||
|         prefix = L"[SYSTEM] "; | ||||
|         prefix = "[SYSTEM] "; | ||||
|         break; | ||||
|     case Level::Warning: | ||||
|         prefix = L"[WARN] "; | ||||
|         prefix = "[WARN] "; | ||||
|         break; | ||||
|     case Level::Error: | ||||
|         prefix = L"[ERROR] "; | ||||
|         prefix = "[ERROR] "; | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  | @ -236,11 +236,13 @@ void Logger::Prepare(Level level, StringStream& sstream) | |||
|     time_t  unix = std::time(nullptr); | ||||
|     std::tm tmbuf; | ||||
|     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) | ||||
| { | ||||
|     using ConsoleColor = Function<OutputStream&(OutputStream&)>; | ||||
| 
 | ||||
|     OutputStream* ostream = nullptr; | ||||
|     ConsoleColor  color   = nullptr; | ||||
| 
 | ||||
|  | @ -269,7 +271,7 @@ void Logger::Output(Level level, StringStream& sstream) | |||
|     { | ||||
|         auto output = sstream.str(); | ||||
|         color(*ostream) << output << std::flush; | ||||
|         ::OutputDebugStringW(output.c_str()); | ||||
|         ::OutputDebugStringA(output.c_str()); | ||||
| 
 | ||||
|         ResetConsoleColor(); | ||||
|     } | ||||
|  | @ -297,20 +299,20 @@ void Logger::ResetOutputStream() | |||
| 
 | ||||
|         // replace the C++ global locale with the user-preferred locale
 | ||||
|         (void)std::locale::global(std::locale("")); | ||||
|         (void)std::wcout.imbue(std::locale()); | ||||
|         (void)std::wcerr.imbue(std::locale()); | ||||
|         (void)std::cout.imbue(std::locale()); | ||||
|         (void)std::cerr.imbue(std::locale()); | ||||
| 
 | ||||
|         RedirectOutputStreamBuffer(std::wcout.rdbuf()); | ||||
|         RedirectErrorStreamBuffer(std::wcerr.rdbuf()); | ||||
|         RedirectOutputStreamBuffer(std::cout.rdbuf()); | ||||
|         RedirectErrorStreamBuffer(std::cerr.rdbuf()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::wstreambuf* Logger::RedirectOutputStreamBuffer(std::wstreambuf* buf) | ||||
| std::streambuf* Logger::RedirectOutputStreamBuffer(std::streambuf* 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); | ||||
| } | ||||
|  | @ -329,7 +331,7 @@ void Logger::ShowConsole(bool show) | |||
|             HWND console = ::AllocateConsole(); | ||||
|             if (!console) | ||||
|             { | ||||
|                 KGE_WARN(L"AllocConsole failed"); | ||||
|                 KGE_WARN("AllocConsole failed"); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  |  | |||
|  | @ -70,19 +70,11 @@ public: | |||
|         Error     ///< 错误
 | ||||
|     }; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief Êä³öÁ÷
 | ||||
|     using OutputStream = std::wostream; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief ¿ØÖÆÌ¨ÑÕÉ«
 | ||||
|     using ConsoleColor = Function<OutputStream&(OutputStream&)>; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 打印日志
 | ||||
|     /// @param level 日志级别
 | ||||
|     /// @param format 格式字符串
 | ||||
|     void Printf(Level level, const wchar_t* format, ...); | ||||
|     void Printf(Level level, const char* format, ...); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 打印日志
 | ||||
|  | @ -113,19 +105,19 @@ public: | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取输出流
 | ||||
|     std::wostream& GetOutputStream(); | ||||
|     OutputStream& GetOutputStream(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取错误流
 | ||||
|     std::wostream& GetErrorStream(); | ||||
|     OutputStream& GetErrorStream(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 重定向输出流
 | ||||
|     std::wstreambuf* RedirectOutputStreamBuffer(std::wstreambuf* buf); | ||||
|     std::streambuf* RedirectOutputStreamBuffer(std::streambuf* buf); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 重定向错误流
 | ||||
|     std::wstreambuf* RedirectErrorStreamBuffer(std::wstreambuf* buf); | ||||
|     std::streambuf* RedirectErrorStreamBuffer(std::streambuf* buf); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 重置输出流
 | ||||
|  | @ -190,7 +182,7 @@ void Logger::Println(Level level, _Args&&... args) | |||
|     // Format message
 | ||||
|     (void)std::initializer_list<int>{ ((sstream << ' ' << args), 0)... }; | ||||
| 
 | ||||
|     sstream << L"\r\n"; | ||||
|     sstream << "\r\n"; | ||||
| 
 | ||||
|     Output(level, sstream); | ||||
| } | ||||
|  | @ -201,18 +193,18 @@ inline void Logger::ResetConsoleColor() const | |||
|     ::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_); | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
| inline std::wostream& Logger::GetOutputStream() | ||||
| inline OutputStream& Logger::GetOutputStream() | ||||
| { | ||||
|     return output_stream_; | ||||
| } | ||||
| 
 | ||||
| inline std::wostream& Logger::GetErrorStream() | ||||
| inline OutputStream& Logger::GetErrorStream() | ||||
| { | ||||
|     return error_stream_; | ||||
| } | ||||
|  |  | |||
|  | @ -88,9 +88,8 @@ void ObjectBase::SetName(String const& name) | |||
| 
 | ||||
| String ObjectBase::DumpObject() | ||||
| { | ||||
|     String name = oc::string_to_wide(typeid(*this).name()); | ||||
|     return String::format(L"{ class=\"%s\" id=%d refcount=%d name=\"%s\" }", name.c_str(), GetObjectID(), GetRefCount(), | ||||
|                           GetName().c_str()); | ||||
|     return String::format("{ class=\"%s\" id=%d refcount=%d name=\"%s\" }", typeid(*this).name(), GetObjectID(), | ||||
|                           GetRefCount(), GetName().c_str()); | ||||
| } | ||||
| 
 | ||||
| bool ObjectBase::IsTracingLeaks() | ||||
|  | @ -110,12 +109,12 @@ void ObjectBase::StopTracingLeaks() | |||
| 
 | ||||
| void ObjectBase::DumpTracingObjects() | ||||
| { | ||||
|     KGE_SYS_LOG(L"-------------------------- All Objects --------------------------"); | ||||
|     KGE_SYS_LOG("-------------------------- All 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() | ||||
|  |  | |||
|  | @ -48,28 +48,28 @@ Resource::Data Resource::GetData() const | |||
|         HRSRC res_info = FindResourceW(nullptr, MAKEINTRESOURCE(id_), type_); | ||||
|         if (res_info == nullptr) | ||||
|         { | ||||
|             KGE_ERROR(L"FindResource failed"); | ||||
|             KGE_ERROR("FindResource failed"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         HGLOBAL res_data = LoadResource(nullptr, res_info); | ||||
|         if (res_data == nullptr) | ||||
|         { | ||||
|             KGE_ERROR(L"LoadResource failed"); | ||||
|             KGE_ERROR("LoadResource failed"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         DWORD size = SizeofResource(nullptr, res_info); | ||||
|         if (size == 0) | ||||
|         { | ||||
|             KGE_ERROR(L"SizeofResource failed"); | ||||
|             KGE_ERROR("SizeofResource failed"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         LPVOID buffer = LockResource(res_data); | ||||
|         if (buffer == nullptr) | ||||
|         { | ||||
|             KGE_ERROR(L"LockResource failed"); | ||||
|             KGE_ERROR("LockResource failed"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,10 +29,10 @@ namespace kiwano | |||
|  * @brief 资源 | ||||
|  * @details | ||||
|  *   资源是保存在 exe 中的二进制数据, | ||||
|  *   例如,一份音频资源的类型为 L"WAVE",名称标识符为 | ||||
|  *   例如,一份音频资源的类型为 "WAVE",名称标识符为 | ||||
|  * IDR_WAVE_1,那么可以这样指定该资源: | ||||
|  *   @code | ||||
|  *     Resource(IDR_WAVE_1, L"WAVE"); | ||||
|  *     Resource(IDR_WAVE_1, "WAVE"); | ||||
|  *   @endcode | ||||
|  *   了解资源的更多信息: | ||||
|  * https://docs.microsoft.com/en-us/windows/desktop/menurc/resources
 | ||||
|  |  | |||
|  | @ -94,12 +94,13 @@ const Duration Duration::Hour   = 60 * Duration::Minute; | |||
| 
 | ||||
| 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; | ||||
| 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
 | ||||
| 
 | ||||
| Duration::Duration() | ||||
|  | @ -137,14 +138,14 @@ String Duration::ToString() const | |||
| { | ||||
|     if (IsZero()) | ||||
|     { | ||||
|         return String(L"0s"); | ||||
|         return String("0s"); | ||||
|     } | ||||
| 
 | ||||
|     String result; | ||||
|     long   total_ms = milliseconds_; | ||||
|     if (total_ms < 0) | ||||
|     { | ||||
|         result.append(L"-"); | ||||
|         result.append("-"); | ||||
|         total_ms = -total_ms; | ||||
|     } | ||||
| 
 | ||||
|  | @ -155,21 +156,21 @@ String Duration::ToString() const | |||
| 
 | ||||
|     if (hour) | ||||
|     { | ||||
|         result.append(String::parse(hour)).append(L"h"); | ||||
|         result.append(String::parse(min)).append(L"m"); | ||||
|         result.append(String::parse(hour)).append("h"); | ||||
|         result.append(String::parse(min)).append("m"); | ||||
|     } | ||||
|     else if (min) | ||||
|     { | ||||
|         result.append(String::parse(min)).append(L"m"); | ||||
|         result.append(String::parse(min)).append("m"); | ||||
|     } | ||||
| 
 | ||||
|     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) | ||||
|     { | ||||
|         result.append(String::parse(sec)).append(L"s"); | ||||
|         result.append(String::parse(sec)).append("s"); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
|  | @ -359,15 +360,15 @@ Duration Duration::Parse(const String& format) | |||
|         throw std::runtime_error("Duration::Parse failed, invalid duration"); | ||||
|     } | ||||
| 
 | ||||
|     if (format.empty() || format == L"0") | ||||
|     if (format.empty() || format == "0") | ||||
|     { | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     // ·ûºÅλ
 | ||||
|     if (format[0] == L'-' || format[0] == L'+') | ||||
|     if (format[0] == '-' || format[0] == '+') | ||||
|     { | ||||
|         negative = (format[0] == L'-'); | ||||
|         negative = (format[0] == '-'); | ||||
|         pos++; | ||||
|     } | ||||
| 
 | ||||
|  | @ -378,35 +379,37 @@ Duration Duration::Parse(const String& format) | |||
|         for (; i < len; ++i) | ||||
|         { | ||||
|             wchar_t ch = format[i]; | ||||
|             if (!(ch == L'.' || L'0' <= ch && ch <= L'9')) | ||||
|             if (!(ch == '.' || '0' <= ch && ch <= '9')) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         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"); | ||||
| 
 | ||||
|         // µ¥Î»
 | ||||
|         for (; i < len; ++i) | ||||
|         { | ||||
|             wchar_t ch = format[i]; | ||||
|             if (ch == L'.' || L'0' <= ch && ch <= L'9') | ||||
|             if (ch == '.' || '0' <= ch && ch <= '9') | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         String unit_str = format.substr(pos, i - pos); | ||||
|         pos             = i; | ||||
| 
 | ||||
|         pos = i; | ||||
| 
 | ||||
|         if (unit_map.find(unit_str) == unit_map.end()) | ||||
|             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); | ||||
|         ret += unit * num; | ||||
|     } | ||||
|  |  | |||
|  | @ -111,7 +111,7 @@ void Application::Use(ComponentBase* component) | |||
|     { | ||||
| 
 | ||||
| #if defined(KGE_DEBUG) | ||||
|         if (comps_.contains(component)) | ||||
|         if (std::find(comps_.begin(), comps_.end(), component) != comps_.end()) | ||||
|         { | ||||
|             KGE_ASSERT(false && "Component already exists!"); | ||||
|         } | ||||
|  |  | |||
|  | @ -32,9 +32,9 @@ inline String ConvertPathFormat(String const& path) | |||
|     String result = path; | ||||
|     for (size_t i = 0; i < len; i++) | ||||
|     { | ||||
|         if (result[i] == L'\\') | ||||
|         if (result[i] == '\\') | ||||
|         { | ||||
|             result[i] = L'/'; | ||||
|             result[i] = '/'; | ||||
|         } | ||||
|     } | ||||
|     return result; | ||||
|  | @ -42,7 +42,7 @@ inline String ConvertPathFormat(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)); | ||||
| } | ||||
|  | @ -55,9 +55,9 @@ FileSystem::~FileSystem() {} | |||
| void FileSystem::AddSearchPath(String const& 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); | ||||
|  | @ -70,9 +70,9 @@ void FileSystem::SetSearchPaths(Vector<String> const& paths) | |||
|     for (auto& path : search_paths_) | ||||
|     { | ||||
|         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()) | ||||
|     { | ||||
|         return L""; | ||||
|         return ""; | ||||
|     } | ||||
| 
 | ||||
|     if (IsAbsolutePath(file)) | ||||
|  | @ -126,7 +126,7 @@ String FileSystem::GetFullPathForFile(String const& file) const | |||
|     } | ||||
| 
 | ||||
|     // File not found
 | ||||
|     return L""; | ||||
|     return ""; | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
|     // 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 | ||||
| { | ||||
|     if (::DeleteFileW(file_path.c_str())) | ||||
|     if (::DeleteFileA(file_path.c_str())) | ||||
|         return true; | ||||
|     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 | ||||
| { | ||||
|     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) | ||||
|         return false; | ||||
|  | @ -187,7 +187,7 @@ bool FileSystem::ExtractResourceToFile(Resource const& res, String const& dest_f | |||
|     else | ||||
|     { | ||||
|         ::CloseHandle(file_handle); | ||||
|         ::DeleteFile(dest_file_name.c_str()); | ||||
|         ::DeleteFileA(dest_file_name.c_str()); | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  |  | |||
|  | @ -117,9 +117,9 @@ struct DbgHelp | |||
| DbgHelp g_DbgHelp; | ||||
| }  // 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) | ||||
|  | @ -165,14 +165,14 @@ void PrintCallStackOnContext(PCONTEXT pContext) | |||
|     constexpr int STACKWALK_MAX_NAMELEN = 1024; | ||||
|     BYTE          symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN]; | ||||
| 
 | ||||
|     KGE_ERROR(L"==========  Stack trace  =========="); | ||||
|     KGE_ERROR("==========  Stack trace  =========="); | ||||
| 
 | ||||
|     while (true) | ||||
|     { | ||||
|         if (!g_DbgHelp.StackWalk64(dwMachineType, hProcess, hThread, &sf, pContext, NULL, | ||||
|                                    g_DbgHelp.SymFunctionTableAccess64, g_DbgHelp.SymGetModuleBase64, NULL)) | ||||
|         { | ||||
|             PrintErrorCode(L"StackWalk64"); | ||||
|             PrintErrorCode("StackWalk64"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  | @ -190,7 +190,7 @@ void PrintCallStackOnContext(PCONTEXT pContext) | |||
|         DWORD64 dwDisplacement; | ||||
|         if (!g_DbgHelp.SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, &dwDisplacement, pSymbol)) | ||||
|         { | ||||
|             PrintErrorCode(L"SymGetSymFromAddr64"); | ||||
|             PrintErrorCode("SymGetSymFromAddr64"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  | @ -201,14 +201,11 @@ void PrintCallStackOnContext(PCONTEXT pContext) | |||
|         DWORD dwLineDisplacement; | ||||
|         if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo)) | ||||
|         { | ||||
|             String functionName = MultiByteToWide(pSymbol->Name); | ||||
|             String fileName     = MultiByteToWide(lineInfo.FileName); | ||||
|             KGE_ERROR(L"%s (%d): %s", fileName.c_str(), lineInfo.LineNumber, functionName.c_str()); | ||||
|             KGE_ERROR("%s (%d): %s", lineInfo.FileName, lineInfo.LineNumber, pSymbol->Name); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             String functionName = MultiByteToWide(pSymbol->Name); | ||||
|             KGE_ERROR(L"(filename not available): %s", functionName.c_str()); | ||||
|             KGE_ERROR("(filename not available): %s", pSymbol->Name); | ||||
|         } | ||||
| 
 | ||||
|         if (sf.AddrReturn.Offset == 0) | ||||
|  | @ -236,5 +233,6 @@ void PrintCallStack() | |||
| 
 | ||||
|     g_DbgHelp.SymCleanup(hProcess); | ||||
| } | ||||
| 
 | ||||
| }  // namespace win32
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -34,7 +34,6 @@ | |||
| #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_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP | ||||
| #define KGE_WND_CLASS_NAME L"KiwanoAppWnd" | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|     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) | ||||
|  | @ -165,7 +164,7 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui | |||
|     HINSTANCE  hinst   = GetModuleHandleW(nullptr); | ||||
|     WNDCLASSEX wcex    = { 0 }; | ||||
|     wcex.cbSize        = sizeof(WNDCLASSEX); | ||||
|     wcex.lpszClassName = KGE_WND_CLASS_NAME; | ||||
|     wcex.lpszClassName = L"KiwanoAppWnd"; | ||||
|     wcex.style         = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; | ||||
|     wcex.lpfnWndProc   = WindowImpl::WndProc; | ||||
|     wcex.hIcon         = nullptr; | ||||
|  | @ -229,14 +228,14 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui | |||
|         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); | ||||
| 
 | ||||
|     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"); | ||||
|     } | ||||
| 
 | ||||
|  | @ -276,7 +275,7 @@ void WindowImpl::PumpEvents() | |||
| void WindowImpl::SetTitle(String const& title) | ||||
| { | ||||
|     if (handle_) | ||||
|         ::SetWindowTextW(handle_, title.c_str()); | ||||
|         ::SetWindowTextA(handle_, title.c_str()); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
|         { | ||||
|             KGE_SYS_LOG(L"Window minimized"); | ||||
|             KGE_SYS_LOG("Window minimized"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // KGE_SYS_LOG(L"Window resized");
 | ||||
|             // KGE_SYS_LOG("Window resized");
 | ||||
| 
 | ||||
|             window->width_ = ((uint32_t)(short)LOWORD(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: | ||||
|     { | ||||
|         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; | ||||
|         evt->title                     = window->title_; | ||||
|  | @ -603,13 +602,13 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | |||
| 
 | ||||
|     case WM_SETICON: | ||||
|     { | ||||
|         KGE_SYS_LOG(L"Window icon changed"); | ||||
|         KGE_SYS_LOG("Window icon changed"); | ||||
|     } | ||||
|     break; | ||||
| 
 | ||||
|     case WM_DISPLAYCHANGE: | ||||
|     { | ||||
|         KGE_SYS_LOG(L"The display resolution has changed"); | ||||
|         KGE_SYS_LOG("The display resolution has changed"); | ||||
| 
 | ||||
|         ::InvalidateRect(hwnd, nullptr, FALSE); | ||||
|     } | ||||
|  | @ -623,7 +622,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | |||
| 
 | ||||
|     case WM_CLOSE: | ||||
|     { | ||||
|         KGE_SYS_LOG(L"Window is closing"); | ||||
|         KGE_SYS_LOG("Window is closing"); | ||||
| 
 | ||||
|         WindowClosedEventPtr evt = new WindowClosedEvent; | ||||
|         window->PushEvent(evt); | ||||
|  | @ -633,7 +632,7 @@ LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA | |||
| 
 | ||||
|     case WM_DESTROY: | ||||
|     { | ||||
|         KGE_SYS_LOG(L"Window was destroyed"); | ||||
|         KGE_SYS_LOG("Window was destroyed"); | ||||
| 
 | ||||
|         ::PostQuitMessage(0); | ||||
|         return 0; | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ inline void WarnIfFailed(HRESULT hr) | |||
|     { | ||||
|         PrintCallStack(); | ||||
| 
 | ||||
|         KGE_WARN(L"Failed with HRESULT of %08X", hr); | ||||
|         KGE_WARN("Failed with HRESULT of %08X", hr); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ namespace win32 | |||
| { | ||||
| namespace dlls | ||||
| { | ||||
| 
 | ||||
| Shlwapi::Shlwapi() | ||||
|     : shlwapi() | ||||
|     , PathFileExistsW(nullptr) | ||||
|  | @ -39,10 +40,11 @@ Shlwapi::Shlwapi() | |||
|     } | ||||
|     else | ||||
|     { | ||||
|         KGE_ERROR(L"Load shlapi.dll failed"); | ||||
|         KGE_ERROR("Load shlapi.dll failed"); | ||||
|         throw std::runtime_error("Load shlapi.dll failed"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| }  // namespace dlls
 | ||||
| }  // namespace win32
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -48,21 +48,21 @@ public: | |||
|                                       _In_opt_ const D2D1_BITMAP_PROPERTIES* properties, | ||||
|                                       _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, | ||||
|                                             const Resource&                  resource) override; | ||||
|     HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, _In_ void* data, | ||||
|                                             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, | ||||
|                              DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) override; | ||||
| 
 | ||||
|     HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, String const& text, | ||||
|                              _In_ ComPtr<IDWriteTextFormat> text_format) override; | ||||
|     HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, _In_ LPCWSTR text, | ||||
|                              UINT32 length, _In_ ComPtr<IDWriteTextFormat> text_format) 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, | ||||
|                              _In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) override; | ||||
|  | @ -292,7 +292,7 @@ HRESULT D2DDeviceResources::SetDpi(float dpi) | |||
|     return CreateWindowSizeDependentResources(); | ||||
| } | ||||
| 
 | ||||
| HRESULT D2DDeviceResources::SetLogicalSize(Size) | ||||
| HRESULT D2DDeviceResources::SetLogicalSize(float width, float height) | ||||
| { | ||||
|     return CreateWindowSizeDependentResources(); | ||||
| } | ||||
|  | @ -355,14 +355,14 @@ HRESULT D2DDeviceResources::CreateBitmapFromConverter(_Out_ ComPtr<ID2D1Bitmap>& | |||
| } | ||||
| 
 | ||||
| HRESULT D2DDeviceResources::CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapDecoder>& decoder, | ||||
|                                                         const String&                    file_path) | ||||
|                                                         _In_ LPCWSTR                     file_path) | ||||
| { | ||||
|     if (!imaging_factory_) | ||||
|         return E_UNEXPECTED; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|  | @ -372,14 +372,13 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapD | |||
|     return hr; | ||||
| } | ||||
| 
 | ||||
| HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, | ||||
|                                                             const Resource&                  resource) | ||||
| HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, _In_ void* data, | ||||
|                                                             DWORD data_size) | ||||
| { | ||||
|     if (!imaging_factory_) | ||||
|         return E_UNEXPECTED; | ||||
| 
 | ||||
|     Resource::Data res_data = resource.GetData(); | ||||
|     HRESULT        hr       = res_data ? S_OK : E_FAIL; | ||||
|     HRESULT hr = data ? S_OK : E_FAIL; | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|  | @ -388,7 +387,7 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBit | |||
| 
 | ||||
|         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)) | ||||
|  | @ -406,7 +405,7 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBit | |||
|     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, | ||||
|                                              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; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|  | @ -424,15 +423,15 @@ HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& te | |||
|     return hr; | ||||
| } | ||||
| 
 | ||||
| HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, String const& text, | ||||
|                                              _In_ ComPtr<IDWriteTextFormat> text_format) | ||||
| HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, _In_ LPCWSTR text, | ||||
|                                              UINT32 length, _In_ ComPtr<IDWriteTextFormat> text_format) | ||||
| { | ||||
|     if (!dwrite_factory_) | ||||
|         return E_UNEXPECTED; | ||||
| 
 | ||||
|     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)) | ||||
|     { | ||||
|  |  | |||
|  | @ -19,7 +19,6 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano/render/DirectX/helper.h> | ||||
| #include <d2d1.h> | ||||
| #include <d2d1_1.h> | ||||
|  | @ -43,21 +42,21 @@ public: | |||
|                                               _In_opt_ const D2D1_BITMAP_PROPERTIES* properties, | ||||
|                                               _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, | ||||
|                                                     const Resource& resource) = 0; | ||||
|     virtual HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder> & decoder, _In_ void* data, | ||||
|                                                     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, | ||||
|                                      DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) = 0; | ||||
| 
 | ||||
|     virtual HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, String const& text, | ||||
|                                      _In_ ComPtr<IDWriteTextFormat> text_format) = 0; | ||||
|     virtual HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, _In_ LPCWSTR text, | ||||
|                                      UINT32 length, _In_ ComPtr<IDWriteTextFormat> text_format) = 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, | ||||
|                                      _In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) = 0; | ||||
|  | @ -69,26 +68,31 @@ public: | |||
|         KGE_ASSERT(factory_); | ||||
|         return factory_.get(); | ||||
|     } | ||||
| 
 | ||||
|     inline IWICImagingFactory* GetWICImagingFactory() | ||||
|     { | ||||
|         KGE_ASSERT(imaging_factory_); | ||||
|         return imaging_factory_.get(); | ||||
|     } | ||||
| 
 | ||||
|     inline IDWriteFactory* GetDWriteFactory() | ||||
|     { | ||||
|         KGE_ASSERT(dwrite_factory_); | ||||
|         return dwrite_factory_.get(); | ||||
|     } | ||||
| 
 | ||||
|     inline ID2D1Device* GetDevice() | ||||
|     { | ||||
|         KGE_ASSERT(device_); | ||||
|         return device_.get(); | ||||
|     } | ||||
| 
 | ||||
|     inline ID2D1DeviceContext* GetDeviceContext() | ||||
|     { | ||||
|         KGE_ASSERT(device_context_); | ||||
|         return device_context_.get(); | ||||
|     } | ||||
| 
 | ||||
|     inline ID2D1Bitmap1* GetTargetBitmap() | ||||
|     { | ||||
|         KGE_ASSERT(target_bitmap_); | ||||
|  |  | |||
|  | @ -254,7 +254,7 @@ STDMETHODIMP FontFileEnumerator::SetFilePaths(Vector<String> const& filePaths) | |||
| { | ||||
|     try | ||||
|     { | ||||
|         filePaths_.assign(filePaths); | ||||
|         filePaths_.assign(filePaths.begin(), filePaths.end()); | ||||
|     } | ||||
|     catch (std::bad_alloc&) | ||||
|     { | ||||
|  | @ -305,7 +305,9 @@ HRESULT STDMETHODCALLTYPE FontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFil | |||
| 
 | ||||
|     if (nextIndex_ < filePaths_.size()) | ||||
|     { | ||||
|         hr = pFactory_->CreateFontFileReference(filePaths_[nextIndex_].c_str(), NULL, ¤tFile_); | ||||
|         WideString file_name = MultiByteToWide(filePaths_[nextIndex_]); | ||||
| 
 | ||||
|         hr = pFactory_->CreateFontFileReference(file_name.c_str(), NULL, ¤tFile_); | ||||
| 
 | ||||
|         if (SUCCEEDED(hr)) | ||||
|         { | ||||
|  | @ -671,7 +673,7 @@ STDMETHODIMP ResourceFontFileEnumerator::SetResources(Vector<Resource> const& re | |||
| { | ||||
|     try | ||||
|     { | ||||
|         resources_.assign(resources); | ||||
|         resources_.assign(resources.begin(), resources.end()); | ||||
|     } | ||||
|     catch (std::bad_alloc&) | ||||
|     { | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano/render/DirectX/D2DDeviceResources.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
|  |  | |||
|  | @ -152,7 +152,7 @@ void RenderContextImpl::DrawTextLayout(TextLayout const& layout, Point const& of | |||
|         } | ||||
|         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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ RendererImpl::RendererImpl() | |||
| 
 | ||||
| void RendererImpl::SetupComponent() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Creating device resources"); | ||||
|     KGE_SYS_LOG("Creating device resources"); | ||||
| 
 | ||||
|     win32::ThrowIfFailed(::CoInitialize(nullptr)); | ||||
| 
 | ||||
|  | @ -116,7 +116,7 @@ void RendererImpl::SetupComponent() | |||
| 
 | ||||
| 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()); | ||||
|     res_font_file_loader_.reset(); | ||||
|  | @ -205,16 +205,16 @@ void RendererImpl::CreateTexture(Texture& texture, String const& 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; | ||||
|     } | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|         String full_path = FileSystem::GetInstance().GetFullPathForFile(file_path); | ||||
|         WideString full_path = MultiByteToWide(FileSystem::GetInstance().GetFullPathForFile(file_path)); | ||||
| 
 | ||||
|         ComPtr<IWICBitmapDecoder> decoder; | ||||
|         hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path); | ||||
|         hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path.c_str()); | ||||
| 
 | ||||
|         if (SUCCEEDED(hr)) | ||||
|         { | ||||
|  | @ -244,7 +244,7 @@ void RendererImpl::CreateTexture(Texture& texture, String const& file_path) | |||
| 
 | ||||
|     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)) | ||||
|     { | ||||
|         ComPtr<IWICBitmapDecoder> decoder; | ||||
|         hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, resource); | ||||
|         Resource::Data data = resource.GetData(); | ||||
| 
 | ||||
|         hr = data ? S_OK : E_FAIL; | ||||
| 
 | ||||
|         if (SUCCEEDED(hr)) | ||||
|         { | ||||
|             ComPtr<IWICBitmapFrameDecode> source; | ||||
|             hr = decoder->GetFrame(0, &source); | ||||
|             ComPtr<IWICBitmapDecoder> decoder; | ||||
|             hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, data.buffer, (DWORD)data.size); | ||||
| 
 | ||||
|             if (SUCCEEDED(hr)) | ||||
|             { | ||||
|                 ComPtr<IWICFormatConverter> converter; | ||||
|                 hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA, | ||||
|                                                      WICBitmapDitherTypeNone, nullptr, 0.f, | ||||
|                                                      WICBitmapPaletteTypeMedianCut); | ||||
|                 ComPtr<IWICBitmapFrameDecode> source; | ||||
|                 hr = decoder->GetFrame(0, &source); | ||||
| 
 | ||||
|                 if (SUCCEEDED(hr)) | ||||
|                 { | ||||
|                     ComPtr<ID2D1Bitmap> bitmap; | ||||
|                     hr = d2d_res_->CreateBitmapFromConverter(bitmap, nullptr, converter); | ||||
|                     ComPtr<IWICFormatConverter> converter; | ||||
|                     hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA, | ||||
|                                                          WICBitmapDitherTypeNone, nullptr, 0.f, | ||||
|                                                          WICBitmapPaletteTypeMedianCut); | ||||
| 
 | ||||
|                     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)) | ||||
|     { | ||||
|         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)) | ||||
|     { | ||||
|         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; | ||||
|     } | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|         String full_path = FileSystem::GetInstance().GetFullPathForFile(file_path); | ||||
|         WideString full_path = MultiByteToWide(FileSystem::GetInstance().GetFullPathForFile(file_path)); | ||||
| 
 | ||||
|         ComPtr<IWICBitmapDecoder> decoder; | ||||
|         hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path); | ||||
|         hr = d2d_res_->CreateBitmapDecoderFromFile(decoder, full_path.c_str()); | ||||
| 
 | ||||
|         if (SUCCEEDED(hr)) | ||||
|         { | ||||
|  | @ -322,7 +329,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, String const& file_path) | |||
| 
 | ||||
|     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)) | ||||
|     { | ||||
|         ComPtr<IWICBitmapDecoder> decoder; | ||||
|         hr = d2d_res_->CreateBitmapDecoderFromResource(decoder, resource); | ||||
|         Resource::Data data = resource.GetData(); | ||||
| 
 | ||||
|         hr = data ? S_OK : E_FAIL; | ||||
| 
 | ||||
|         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)) | ||||
|     { | ||||
|         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)) | ||||
|     { | ||||
|         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)) | ||||
|         { | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
|  | @ -595,10 +609,10 @@ void RendererImpl::CreateTextFormat(TextLayout& layout) | |||
|     { | ||||
|         const TextStyle& style = layout.GetStyle(); | ||||
| 
 | ||||
|         hr = d2d_res_->CreateTextFormat(output, style.font_family, style.font ? style.font->GetCollection() : nullptr, | ||||
|                                         DWRITE_FONT_WEIGHT(style.font_weight), | ||||
|                                         style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, | ||||
|                                         DWRITE_FONT_STRETCH_NORMAL, style.font_size); | ||||
|         hr = d2d_res_->CreateTextFormat( | ||||
|             output, MultiByteToWide(style.font_family).c_str(), style.font ? style.font->GetCollection() : nullptr, | ||||
|             DWRITE_FONT_WEIGHT(style.font_weight), style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, | ||||
|             DWRITE_FONT_STRETCH_NORMAL, style.font_size); | ||||
|     } | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|  | @ -620,7 +634,9 @@ void RendererImpl::CreateTextLayout(TextLayout& layout) | |||
|     ComPtr<IDWriteTextLayout> output; | ||||
|     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)) | ||||
|  | @ -941,7 +957,7 @@ void RendererImpl::Resize(uint32_t width, uint32_t height) | |||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|         hr = d2d_res_->SetLogicalSize(output_size_); | ||||
|         hr = d2d_res_->SetLogicalSize(output_size_.x, output_size_.y); | ||||
|     } | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano/render/DirectX/D2DDeviceResources.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 
 | ||||
| LocalStorage::LocalStorage(String const& file_path, String const& field) | ||||
| { | ||||
|     SetFilePath(file_path); | ||||
|  | @ -30,75 +31,76 @@ LocalStorage::LocalStorage(String const& file_path, String const& field) | |||
| 
 | ||||
| bool LocalStorage::Exists(String const& key) const | ||||
| { | ||||
|     wchar_t temp[256] = { 0 }; | ||||
|     ::GetPrivateProfileStringW(field_name_.c_str(), key.c_str(), L"", temp, 255, file_path_.c_str()); | ||||
|     return temp[0] == L'\0'; | ||||
|     char temp[256] = { 0 }; | ||||
|     ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), "", temp, 255, file_path_.c_str()); | ||||
|     return temp[0] == '\0'; | ||||
| } | ||||
| 
 | ||||
| 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(), | ||||
|                                             file_path_.c_str()); | ||||
|     BOOL ret = | ||||
|         ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str()); | ||||
|     return ret == TRUE; | ||||
| } | ||||
| 
 | ||||
| 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(), | ||||
|                                             file_path_.c_str()); | ||||
|     BOOL ret = | ||||
|         ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str()); | ||||
|     return ret == TRUE; | ||||
| } | ||||
| 
 | ||||
| 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(), | ||||
|                                             file_path_.c_str()); | ||||
|     BOOL ret = | ||||
|         ::WritePrivateProfileStringA(field_name_.c_str(), key.c_str(), std::to_string(val).c_str(), file_path_.c_str()); | ||||
|     return ret == TRUE; | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
|     wchar_t temp[32]    = { 0 }; | ||||
|     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()); | ||||
|     char   temp[32]    = { 0 }; | ||||
|     String default_str = String::parse(default_value); | ||||
|     ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str()); | ||||
|     return std::stof(temp); | ||||
| } | ||||
| 
 | ||||
| double LocalStorage::GetDouble(String const& key, double default_value) const | ||||
| { | ||||
|     wchar_t temp[32]    = { 0 }; | ||||
|     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()); | ||||
|     char   temp[32]    = { 0 }; | ||||
|     String default_str = String::parse(default_value); | ||||
|     ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_str.c_str(), temp, 31, file_path_.c_str()); | ||||
|     return std::stod(temp); | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| String LocalStorage::GetString(String const& key, String const& default_value) const | ||||
| { | ||||
|     wchar_t temp[256] = { 0 }; | ||||
|     ::GetPrivateProfileStringW(field_name_.c_str(), key.c_str(), default_value.c_str(), temp, 255, file_path_.c_str()); | ||||
|     char temp[256] = { 0 }; | ||||
|     ::GetPrivateProfileStringA(field_name_.c_str(), key.c_str(), default_value.c_str(), temp, 255, file_path_.c_str()); | ||||
|     return temp; | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -34,8 +34,8 @@ KGE_DECLARE_SMART_PTR(LocalStorage); | |||
| /// 例如, 保存游戏最高分, 以便下次进行游戏时读取:
 | ||||
| ///   @code
 | ||||
| ///     LocalStorage data;                      // 创建数据对象
 | ||||
| ///     data.SaveInt(L"best-score", 20);        // 保存最高分 20
 | ||||
| ///     int best = data.GetInt(L"best-score");  // 读取之前储存的最高分
 | ||||
| ///     data.SaveInt("best-score", 20);        // 保存最高分 20
 | ||||
| ///     int best = data.GetInt("best-score");  // 读取之前储存的最高分
 | ||||
| ///   @endcode
 | ||||
| class KGE_API LocalStorage : public virtual ObjectBase | ||||
| { | ||||
|  | @ -44,7 +44,7 @@ public: | |||
|     /// @brief 构建本地存储对象
 | ||||
|     /// @param file_path 文件储存路径
 | ||||
|     /// @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
 | ||||
|     /// @brief 获取文件储存路径
 | ||||
|  |  | |||
|  | @ -34,13 +34,13 @@ bool LoadXmlData(ResourceCache* loader, const pugi::xml_node& elem); | |||
| namespace | ||||
| { | ||||
| Map<String, Function<bool(ResourceCache*, Json const&)>> load_json_funcs = { | ||||
|     { L"latest", __resource_cache_01::LoadJsonData }, | ||||
|     { L"0.1", __resource_cache_01::LoadJsonData }, | ||||
|     { "latest", __resource_cache_01::LoadJsonData }, | ||||
|     { "0.1", __resource_cache_01::LoadJsonData }, | ||||
| }; | ||||
| 
 | ||||
| Map<String, Function<bool(ResourceCache*, const pugi::xml_node&)>> load_xml_funcs = { | ||||
|     { L"latest", __resource_cache_01::LoadXmlData }, | ||||
|     { L"0.1", __resource_cache_01::LoadXmlData }, | ||||
|     { "latest", __resource_cache_01::LoadXmlData }, | ||||
|     { "0.1", __resource_cache_01::LoadXmlData }, | ||||
| }; | ||||
| }  // namespace
 | ||||
| 
 | ||||
|  | @ -55,12 +55,13 @@ bool ResourceCache::LoadFromJsonFile(String const& 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; | ||||
|     } | ||||
| 
 | ||||
|     Json           json_data; | ||||
|     std::wifstream ifs; | ||||
|     Json json_data; | ||||
| 
 | ||||
|     std::ifstream ifs; | ||||
|     ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); | ||||
| 
 | ||||
|     try | ||||
|  | @ -72,14 +73,12 @@ bool ResourceCache::LoadFromJsonFile(String const& file_path) | |||
|     } | ||||
|     catch (std::wifstream::failure& e) | ||||
|     { | ||||
|         KGE_ERROR(L"ResourceCache::LoadFromJsonFile failed: Cannot open file. (%s)", | ||||
|                   oc::string_to_wide(e.what()).c_str()); | ||||
|         KGE_ERROR("ResourceCache::LoadFromJsonFile failed: Cannot open file. (%s)", e.what()); | ||||
|         return false; | ||||
|     } | ||||
|     catch (oc::json_exception& e) | ||||
|     catch (Json::exception& e) | ||||
|     { | ||||
|         KGE_ERROR(L"ResourceCache::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", | ||||
|                   oc::string_to_wide(e.what()).c_str()); | ||||
|         KGE_ERROR("ResourceCache::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", e.what()); | ||||
|         return false; | ||||
|     } | ||||
|     return LoadFromJson(json_data); | ||||
|  | @ -89,7 +88,7 @@ bool ResourceCache::LoadFromJson(Json const& json_data) | |||
| { | ||||
|     try | ||||
|     { | ||||
|         String version = json_data[L"version"]; | ||||
|         String version = json_data["version"]; | ||||
| 
 | ||||
|         auto load = load_json_funcs.find(version); | ||||
|         if (load != load_json_funcs.end()) | ||||
|  | @ -98,17 +97,16 @@ bool ResourceCache::LoadFromJson(Json const& json_data) | |||
|         } | ||||
|         else if (version.empty()) | ||||
|         { | ||||
|             return load_json_funcs[L"latest"](this, json_data); | ||||
|             return load_json_funcs["latest"](this, json_data); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             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)", | ||||
|                   oc::string_to_wide(e.what()).c_str()); | ||||
|         KGE_ERROR("ResourceCache::LoadFromJson failed: JSON data is invalid. (%s)", e.what()); | ||||
|         return false; | ||||
|     } | ||||
|     return false; | ||||
|  | @ -118,7 +116,7 @@ bool ResourceCache::LoadFromXmlFile(String const& 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; | ||||
|     } | ||||
| 
 | ||||
|  | @ -133,17 +131,17 @@ bool ResourceCache::LoadFromXmlFile(String const& file_path) | |||
|     } | ||||
|     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; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
|         if (auto version_node = root.child(L"version")) | ||||
|         if (auto version_node = root.child("version")) | ||||
|             version = version_node.child_value(); | ||||
| 
 | ||||
|         auto load = load_xml_funcs.find(version); | ||||
|  | @ -153,16 +151,16 @@ bool ResourceCache::LoadFromXml(const pugi::xml_document& doc) | |||
|         } | ||||
|         else if (version.empty()) | ||||
|         { | ||||
|             return load_xml_funcs[L"latest"](this, root); | ||||
|             return load_xml_funcs["latest"](this, root); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             KGE_ERROR(L"Unknown  version"); | ||||
|             KGE_ERROR("Unknown  version"); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     KGE_ERROR(L"Unknown  version"); | ||||
|     KGE_ERROR("Unknown  version"); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
|  | @ -308,108 +306,102 @@ struct GlobalData | |||
|     String path; | ||||
| }; | ||||
| 
 | ||||
| bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, | ||||
|                           const String* file) | ||||
| bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String& id, const String& type, | ||||
|                           const String& file) | ||||
| { | ||||
|     if (!gdata || !id) | ||||
|     if (!gdata) | ||||
|         return false; | ||||
| 
 | ||||
|     if (type && (*type) == L"gif") | ||||
|     if (type == "gif") | ||||
|     { | ||||
|         // GIF image
 | ||||
|         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
 | ||||
|         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; | ||||
| } | ||||
| 
 | ||||
| bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, | ||||
|                           const Vector<const wchar_t*>* files) | ||||
| bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String& id, | ||||
|                           const Vector<String>& files) | ||||
| { | ||||
|     if (!gdata || !id) | ||||
|     if (!gdata) | ||||
|         return false; | ||||
| 
 | ||||
|     if (files.empty()) | ||||
|         return true; | ||||
| 
 | ||||
|     // Frames
 | ||||
|     if (files) | ||||
|     Vector<FramePtr> frames; | ||||
|     frames.reserve(files.size()); | ||||
|     for (const auto& file : files) | ||||
|     { | ||||
|         Vector<FramePtr> frames; | ||||
|         frames.reserve(files->size()); | ||||
|         for (const auto& file : (*files)) | ||||
|         FramePtr frame = new Frame; | ||||
|         if (frame->Load(gdata->path + file)) | ||||
|         { | ||||
|             FramePtr frame = new 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); | ||||
|             frames.push_back(frame); | ||||
|         } | ||||
|     } | ||||
|     FrameSequencePtr frame_seq = FrameSequence::Create(frames); | ||||
|     if (frame_seq) | ||||
|     { | ||||
|         return !!loader->AddObject(id, frame_seq); | ||||
|     } | ||||
|     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) | ||||
| { | ||||
|     if (!gdata || !id) | ||||
|     if (!gdata) | ||||
|         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
 | ||||
|                 FramePtr frame = new (std::nothrow) Frame; | ||||
|                 if (frame && frame->Load(gdata->path + (*file))) | ||||
|                 { | ||||
|                     return !!loader->AddFrameSequence(*id, frame, std::max(cols, 1), std::max(rows, 1), padding_x, | ||||
|                                                       padding_y); | ||||
|                 } | ||||
|                 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
 | ||||
|                 FramePtr frame = new (std::nothrow) Frame; | ||||
|                 if (frame && frame->Load(gdata->path + (*file))) | ||||
|                 { | ||||
|                     return loader->AddObject(*id, frame); | ||||
|                 } | ||||
|                 return loader->AddObject(id, frame); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     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; | ||||
| 
 | ||||
|     if (file) | ||||
|     FontPtr font = new (std::nothrow) Font; | ||||
|     if (font && font->Load(gdata->path + file)) | ||||
|     { | ||||
|         FontPtr font = new (std::nothrow) Font; | ||||
|         if (font && font->Load(gdata->path + (*file))) | ||||
|         { | ||||
|             return loader->AddObject(*id, font); | ||||
|         } | ||||
|         return loader->AddObject(id, font); | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | @ -417,50 +409,50 @@ bool LoadFontsFromData(ResourceCache* loader, GlobalData* gdata, const String* i | |||
| bool LoadJsonData(ResourceCache* loader, Json const& json_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; | ||||
|             int           rows = 0, cols = 0; | ||||
|             String id, type, file; | ||||
|             int    rows = 0, cols = 0; | ||||
| 
 | ||||
|             if (image.count(L"id")) | ||||
|                 id = &image[L"id"].as_string(); | ||||
|             if (image.count(L"type")) | ||||
|                 type = &image[L"type"].as_string(); | ||||
|             if (image.count(L"file")) | ||||
|                 file = &image[L"file"].as_string(); | ||||
|             if (image.count(L"rows")) | ||||
|                 rows = image[L"rows"].as_int(); | ||||
|             if (image.count(L"cols")) | ||||
|                 cols = image[L"cols"].as_int(); | ||||
|             if (image.count("id")) | ||||
|                 id = image["id"].get<String>(); | ||||
|             if (image.count("type")) | ||||
|                 type = image["type"].get<String>(); | ||||
|             if (image.count("file")) | ||||
|                 file = image["file"].get<String>(); | ||||
|             if (image.count("rows")) | ||||
|                 rows = image["rows"].get<int>(); | ||||
|             if (image.count("cols")) | ||||
|                 cols = image["cols"].get<int>(); | ||||
| 
 | ||||
|             if (rows || cols) | ||||
|             { | ||||
|                 float padding_x = 0, padding_y = 0; | ||||
|                 if (image.count(L"padding-x")) | ||||
|                     padding_x = image[L"padding-x"].get<float>(); | ||||
|                 if (image.count(L"padding-y")) | ||||
|                     padding_y = image[L"padding-y"].get<float>(); | ||||
|                 if (image.count("padding-x")) | ||||
|                     padding_x = image["padding-x"].get<float>(); | ||||
|                 if (image.count("padding-y")) | ||||
|                     padding_y = image["padding-y"].get<float>(); | ||||
| 
 | ||||
|                 if (!LoadTexturesFromData(loader, &global_data, id, file, rows, cols, padding_x, padding_y)) | ||||
|                     return false; | ||||
|             } | ||||
| 
 | ||||
|             if (image.count(L"files")) | ||||
|             if (image.count("files")) | ||||
|             { | ||||
|                 Vector<const wchar_t*> files; | ||||
|                 files.reserve(image[L"files"].size()); | ||||
|                 for (const auto& file : image[L"files"]) | ||||
|                 Vector<String> files; | ||||
|                 files.reserve(image["files"].size()); | ||||
|                 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; | ||||
|             } | ||||
|             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")) | ||||
|                 id = &font[L"id"].as_string(); | ||||
|             if (font.count(L"file")) | ||||
|                 file = &font[L"file"].as_string(); | ||||
|             if (font.count("id")) | ||||
|                 id = font["id"].get<String>(); | ||||
|             if (font.count("file")) | ||||
|                 file = font["file"].get<String>(); | ||||
| 
 | ||||
|             if (!LoadFontsFromData(loader, &global_data, id, file)) | ||||
|                 return false; | ||||
|  | @ -492,73 +484,73 @@ bool LoadJsonData(ResourceCache* loader, Json const& json_data) | |||
| bool LoadXmlData(ResourceCache* loader, const pugi::xml_node& elem) | ||||
| { | ||||
|     GlobalData global_data; | ||||
|     if (auto path = elem.child(L"path")) | ||||
|     if (auto path = elem.child("path")) | ||||
|     { | ||||
|         global_data.path = path.child_value(); | ||||
|     } | ||||
| 
 | ||||
|     if (auto images = elem.child(L"images")) | ||||
|     if (auto images = elem.child("images")) | ||||
|     { | ||||
|         for (auto image : images.children()) | ||||
|         { | ||||
|             String id, type, file; | ||||
|             int    rows = 0, cols = 0; | ||||
| 
 | ||||
|             if (auto attr = image.attribute(L"id")) | ||||
|             if (auto attr = image.attribute("id")) | ||||
|                 id.assign(attr.value()); | ||||
|             if (auto attr = image.attribute(L"type")) | ||||
|             if (auto attr = image.attribute("type")) | ||||
|                 type = attr.value(); | ||||
|             if (auto attr = image.attribute(L"file")) | ||||
|             if (auto attr = image.attribute("file")) | ||||
|                 file = attr.value(); | ||||
|             if (auto attr = image.attribute(L"rows")) | ||||
|             if (auto attr = image.attribute("rows")) | ||||
|                 rows = attr.as_int(0); | ||||
|             if (auto attr = image.attribute(L"cols")) | ||||
|             if (auto attr = image.attribute("cols")) | ||||
|                 cols = attr.as_int(0); | ||||
| 
 | ||||
|             if (rows || cols) | ||||
|             { | ||||
|                 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); | ||||
|                 if (auto attr = image.attribute(L"padding-y")) | ||||
|                 if (auto attr = image.attribute("padding-y")) | ||||
|                     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; | ||||
|             } | ||||
| 
 | ||||
|             if (file.empty() && !image.empty()) | ||||
|             { | ||||
|                 Vector<const wchar_t*> files_arr; | ||||
|                 Vector<String> files_arr; | ||||
|                 for (auto file : image.children()) | ||||
|                 { | ||||
|                     if (auto path = file.attribute(L"path")) | ||||
|                     if (auto path = file.attribute("path")) | ||||
|                     { | ||||
|                         files_arr.push_back(path.value()); | ||||
|                     } | ||||
|                 } | ||||
|                 if (!LoadTexturesFromData(loader, &global_data, &id, &files_arr)) | ||||
|                 if (!LoadTexturesFromData(loader, &global_data, id, files_arr)) | ||||
|                     return false; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (!LoadTexturesFromData(loader, &global_data, &id, &type, &file)) | ||||
|                 if (!LoadTexturesFromData(loader, &global_data, id, type, file)) | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (auto fonts = elem.child(L"fonts")) | ||||
|     if (auto fonts = elem.child("fonts")) | ||||
|     { | ||||
|         for (auto font : fonts.children()) | ||||
|         { | ||||
|             String id, file; | ||||
|             if (auto attr = font.attribute(L"id")) | ||||
|             if (auto attr = font.attribute("id")) | ||||
|                 id.assign(attr.value()); | ||||
|             if (auto attr = font.attribute(L"file")) | ||||
|             if (auto attr = font.attribute("file")) | ||||
|                 file = attr.value(); | ||||
| 
 | ||||
|             if (!LoadFontsFromData(loader, &global_data, &id, &file)) | ||||
|             if (!LoadFontsFromData(loader, &global_data, id, file)) | ||||
|                 return false; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue