Refactor Singleton && Singleton mode ResourceCache
This commit is contained in:
		
							parent
							
								
									bd58cf1b49
								
							
						
					
					
						commit
						222b09f166
					
				|  | @ -81,7 +81,7 @@ namespace kiwano | ||||||
| 				return false; | 				return false; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			hr = Audio::Instance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); | 			hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); | ||||||
| 			if (FAILED(hr)) | 			if (FAILED(hr)) | ||||||
| 			{ | 			{ | ||||||
| 				if (wave_data_) | 				if (wave_data_) | ||||||
|  |  | ||||||
|  | @ -45,9 +45,9 @@ namespace kiwano | ||||||
| 			//ImGui::StyleColorsClassic();
 | 			//ImGui::StyleColorsClassic();
 | ||||||
| 
 | 
 | ||||||
| 			// Setup Platform/Renderer bindings
 | 			// Setup Platform/Renderer bindings
 | ||||||
| 			Init(Window::Instance()->GetHandle()); | 			Init(Window::GetInstance()->GetHandle()); | ||||||
| 
 | 
 | ||||||
| 			target_window_ = Renderer::Instance()->GetTargetWindow(); | 			target_window_ = Renderer::GetInstance()->GetTargetWindow(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void ImGuiModule::DestroyComponent() | 		void ImGuiModule::DestroyComponent() | ||||||
|  | @ -64,9 +64,9 @@ namespace kiwano | ||||||
| 			io.DeltaTime = dt.Seconds(); | 			io.DeltaTime = dt.Seconds(); | ||||||
| 
 | 
 | ||||||
| 			// Read keyboard modifiers inputs
 | 			// Read keyboard modifiers inputs
 | ||||||
| 			io.KeyCtrl = Input::Instance()->IsDown(KeyCode::Ctrl); | 			io.KeyCtrl = Input::GetInstance()->IsDown(KeyCode::Ctrl); | ||||||
| 			io.KeyShift = Input::Instance()->IsDown(KeyCode::Shift); | 			io.KeyShift = Input::GetInstance()->IsDown(KeyCode::Shift); | ||||||
| 			io.KeyAlt = Input::Instance()->IsDown(KeyCode::Alt); | 			io.KeyAlt = Input::GetInstance()->IsDown(KeyCode::Alt); | ||||||
| 			io.KeySuper = false; | 			io.KeySuper = false; | ||||||
| 			// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
 | 			// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
 | ||||||
| 
 | 
 | ||||||
|  | @ -106,7 +106,7 @@ namespace kiwano | ||||||
| 			io.KeyMap[ImGuiKey_Y] = KeyCode::Y; | 			io.KeyMap[ImGuiKey_Y] = KeyCode::Y; | ||||||
| 			io.KeyMap[ImGuiKey_Z] = KeyCode::Z; | 			io.KeyMap[ImGuiKey_Z] = KeyCode::Z; | ||||||
| 
 | 
 | ||||||
| 			ImGui_Impl_Init(Renderer::Instance()); | 			ImGui_Impl_Init(Renderer::GetInstance()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void ImGuiModule::BeforeRender() | 		void ImGuiModule::BeforeRender() | ||||||
|  | @ -213,7 +213,7 @@ namespace kiwano | ||||||
| 			KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); | 			KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); | ||||||
| 
 | 
 | ||||||
| 			// Setup display size (every frame to accommodate for window resizing)
 | 			// Setup display size (every frame to accommodate for window resizing)
 | ||||||
| 			Size display_size = Renderer::Instance()->GetOutputSize(); | 			Size display_size = Renderer::GetInstance()->GetOutputSize(); | ||||||
| 			io.DisplaySize = ImVec2(display_size.x, display_size.y); | 			io.DisplaySize = ImVec2(display_size.x, display_size.y); | ||||||
| 
 | 
 | ||||||
| 			ImGui::NewFrame(); | 			ImGui::NewFrame(); | ||||||
|  | @ -238,7 +238,7 @@ namespace kiwano | ||||||
| 				::SetCursorPos(pos.x, pos.y); | 				::SetCursorPos(pos.x, pos.y); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			Point pos = Input::Instance()->GetMousePos(); | 			Point pos = Input::GetInstance()->GetMousePos(); | ||||||
| 			io.MousePos = ImVec2(pos.x, pos.y); | 			io.MousePos = ImVec2(pos.x, pos.y); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -260,7 +260,7 @@ namespace kiwano | ||||||
| 			case ImGuiMouseCursor_Hand:         cursor = MouseCursor::Hand; break; | 			case ImGuiMouseCursor_Hand:         cursor = MouseCursor::Hand; break; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			Window::Instance()->SetMouseCursor(cursor); | 			Window::GetInstance()->SetMouseCursor(cursor); | ||||||
| 		} | 		} | ||||||
| 		void ImGuiModule::UpdateGamepads() | 		void ImGuiModule::UpdateGamepads() | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -124,7 +124,7 @@ namespace kiwano | ||||||
| 		{ | 		{ | ||||||
|             Rect bounds = GetBounds(); |             Rect bounds = GetBounds(); | ||||||
| 
 | 
 | ||||||
|             auto renderer = Renderer::Instance(); |             auto renderer = Renderer::GetInstance(); | ||||||
|             renderer->SetTransform(transform_matrix_); |             renderer->SetTransform(transform_matrix_); | ||||||
|             renderer->FillRectangle(bounds, Color(Color::Red, .4f)); |             renderer->FillRectangle(bounds, Color(Color::Red, .4f)); | ||||||
|             renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 4.f); |             renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 4.f); | ||||||
|  | @ -659,7 +659,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void VisualActor::PrepareRender() | 	void VisualActor::PrepareRender() | ||||||
| 	{ | 	{ | ||||||
| 		auto renderer = Renderer::Instance(); | 		auto renderer = Renderer::GetInstance(); | ||||||
| 		renderer->SetTransform(transform_matrix_); | 		renderer->SetTransform(transform_matrix_); | ||||||
| 		renderer->SetOpacity(displayed_opacity_); | 		renderer->SetOpacity(displayed_opacity_); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ namespace kiwano | ||||||
| 		: cache_expired_(false) | 		: cache_expired_(false) | ||||||
| 		, stroke_width_(1.0f) | 		, stroke_width_(1.0f) | ||||||
| 	{ | 	{ | ||||||
| 		auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); | 		auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext(); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			ctx->CreateCompatibleRenderTarget(&render_target_) | 			ctx->CreateCompatibleRenderTarget(&render_target_) | ||||||
|  | @ -96,7 +96,7 @@ namespace kiwano | ||||||
| 		if (bitmap_cached_) | 		if (bitmap_cached_) | ||||||
| 		{ | 		{ | ||||||
| 			Rect bitmap_rect(0.f, 0.f, bitmap_cached_->GetSize().width, bitmap_cached_->GetSize().height); | 			Rect bitmap_rect(0.f, 0.f, bitmap_cached_->GetSize().width, bitmap_cached_->GetSize().height); | ||||||
| 			Renderer::Instance()->DrawBitmap( | 			Renderer::GetInstance()->DrawBitmap( | ||||||
| 				bitmap_cached_, | 				bitmap_cached_, | ||||||
| 				bitmap_rect, | 				bitmap_rect, | ||||||
| 				bitmap_rect | 				bitmap_rect | ||||||
|  | @ -121,7 +121,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join) | 	void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join) | ||||||
| 	{ | 	{ | ||||||
| 		outline_join_style_ = Renderer::Instance()->GetD2DDeviceResources()->GetStrokeStyle(outline_join); | 		outline_join_style_ = Renderer::GetInstance()->GetD2DDeviceResources()->GetStrokeStyle(outline_join); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style) | 	void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style) | ||||||
|  | @ -135,7 +135,7 @@ namespace kiwano | ||||||
| 			text_style_.outline, | 			text_style_.outline, | ||||||
| 			DX::ConvertToColorF(text_style_.outline_color), | 			DX::ConvertToColorF(text_style_.outline_color), | ||||||
| 			text_style_.outline_width, | 			text_style_.outline_width, | ||||||
| 			Renderer::Instance()->GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) | 			Renderer::GetInstance()->GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// clear text format
 | 		// clear text format
 | ||||||
|  | @ -271,7 +271,7 @@ namespace kiwano | ||||||
| 		if (!text_format_) | 		if (!text_format_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				Renderer::Instance()->GetD2DDeviceResources()->CreateTextFormat( | 				Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextFormat( | ||||||
| 					text_format_, | 					text_format_, | ||||||
| 					text_font_, | 					text_font_, | ||||||
| 					text_style_ | 					text_style_ | ||||||
|  | @ -282,7 +282,7 @@ namespace kiwano | ||||||
| 		ComPtr<IDWriteTextLayout> text_layout; | 		ComPtr<IDWriteTextLayout> text_layout; | ||||||
| 		Size layout_size; | 		Size layout_size; | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			Renderer::Instance()->GetD2DDeviceResources()->CreateTextLayout( | 			Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextLayout( | ||||||
| 				text_layout, | 				text_layout, | ||||||
| 				layout_size, | 				layout_size, | ||||||
| 				text, | 				text, | ||||||
|  | @ -365,7 +365,7 @@ namespace kiwano | ||||||
| 		current_geometry_ = nullptr; | 		current_geometry_ = nullptr; | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) | 			Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) | ||||||
| 		); | 		); | ||||||
| 		 | 		 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
|  |  | ||||||
|  | @ -60,7 +60,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void DebugNode::OnRender() | 	void DebugNode::OnRender() | ||||||
| 	{ | 	{ | ||||||
| 		auto renderer = Renderer::Instance(); | 		auto renderer = Renderer::GetInstance(); | ||||||
| 
 | 
 | ||||||
| 		renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); | 		renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); | ||||||
| 		renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle( | 		renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle( | ||||||
|  | @ -89,9 +89,9 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 		ss << "Render: " << Renderer::Instance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; | 		ss << "Render: " << Renderer::GetInstance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; | ||||||
| 
 | 
 | ||||||
| 		ss << "Primitives / sec: " << Renderer::Instance()->GetStatus().primitives * frame_time_.size() << std::endl; | 		ss << "Primitives / sec: " << Renderer::GetInstance()->GetStatus().primitives * frame_time_.size() << std::endl; | ||||||
| 
 | 
 | ||||||
| 		PROCESS_MEMORY_COUNTERS_EX pmc; | 		PROCESS_MEMORY_COUNTERS_EX pmc; | ||||||
| 		GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); | 		GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	bool Frame::Load(Resource const& res) | 	bool Frame::Load(Resource const& res) | ||||||
| 	{ | 	{ | ||||||
| 		ImagePtr image = ImageCache::Instance()->AddImage(res); | 		ImagePtr image = ImageCache::GetInstance()->AddImage(res); | ||||||
| 		if (image && image->IsValid()) | 		if (image && image->IsValid()) | ||||||
| 		{ | 		{ | ||||||
| 			SetImage(image); | 			SetImage(image); | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 			if (!frame_rt_) | 			if (!frame_rt_) | ||||||
| 			{ | 			{ | ||||||
| 				auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); | 				auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext(); | ||||||
| 				ThrowIfFailed( | 				ThrowIfFailed( | ||||||
| 					ctx->CreateCompatibleRenderTarget(&frame_rt_) | 					ctx->CreateCompatibleRenderTarget(&frame_rt_) | ||||||
| 				); | 				); | ||||||
|  | @ -105,7 +105,7 @@ namespace kiwano | ||||||
| 		if (frame_to_render_) | 		if (frame_to_render_) | ||||||
| 		{ | 		{ | ||||||
| 			Rect bounds = GetBounds(); | 			Rect bounds = GetBounds(); | ||||||
| 			Renderer::Instance()->DrawBitmap(frame_to_render_, bounds, bounds); | 			Renderer::GetInstance()->DrawBitmap(frame_to_render_, bounds, bounds); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ namespace kiwano | ||||||
| 	Layer::Layer() | 	Layer::Layer() | ||||||
| 		: swallow_(false) | 		: swallow_(false) | ||||||
| 	{ | 	{ | ||||||
| 		SetSize(Renderer::Instance()->GetOutputSize()); | 		SetSize(Renderer::GetInstance()->GetOutputSize()); | ||||||
| 
 | 
 | ||||||
| 		auto handler = MakeClosure(this, &Layer::HandleMessages); | 		auto handler = MakeClosure(this, &Layer::HandleMessages); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -129,12 +129,12 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		if (geo_) | 		if (geo_) | ||||||
| 		{ | 		{ | ||||||
| 			Renderer::Instance()->FillGeometry( | 			Renderer::GetInstance()->FillGeometry( | ||||||
| 				geo_, | 				geo_, | ||||||
| 				fill_color_ | 				fill_color_ | ||||||
| 			); | 			); | ||||||
| 
 | 
 | ||||||
| 			Renderer::Instance()->DrawGeometry( | 			Renderer::GetInstance()->DrawGeometry( | ||||||
| 				geo_, | 				geo_, | ||||||
| 				stroke_color_, | 				stroke_color_, | ||||||
| 				stroke_width_, | 				stroke_width_, | ||||||
|  | @ -165,7 +165,7 @@ namespace kiwano | ||||||
| 		ComPtr<ID2D1PathGeometry> path_geo; | 		ComPtr<ID2D1PathGeometry> path_geo; | ||||||
| 		ComPtr<ID2D1GeometrySink> path_sink; | 		ComPtr<ID2D1GeometrySink> path_sink; | ||||||
| 
 | 
 | ||||||
| 		HRESULT hr = Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); | 		HRESULT hr = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
|  | @ -222,7 +222,7 @@ namespace kiwano | ||||||
| 	void RectNode::SetRect(Rect const& rect) | 	void RectNode::SetRect(Rect const& rect) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1RectangleGeometry> geo; | 		ComPtr<ID2D1RectangleGeometry> geo; | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) | 		if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) | ||||||
| 		{ | 		{ | ||||||
|  | @ -264,7 +264,7 @@ namespace kiwano | ||||||
| 	void RoundedRectNode::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) | 	void RoundedRectNode::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1RoundedRectangleGeometry> geo; | 		ComPtr<ID2D1RoundedRectangleGeometry> geo; | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( | 		if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( | ||||||
| 			D2D1::RoundedRect( | 			D2D1::RoundedRect( | ||||||
|  | @ -313,7 +313,7 @@ namespace kiwano | ||||||
| 	void CircleNode::SetCircle(Point const& center, float radius) | 	void CircleNode::SetCircle(Point const& center, float radius) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1EllipseGeometry> geo; | 		ComPtr<ID2D1EllipseGeometry> geo; | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(factory->CreateEllipseGeometry( | 		if (SUCCEEDED(factory->CreateEllipseGeometry( | ||||||
| 			D2D1::Ellipse( | 			D2D1::Ellipse( | ||||||
|  | @ -361,7 +361,7 @@ namespace kiwano | ||||||
| 	void EllipseNode::SetEllipse(Point const& center, float radius_x, float radius_y) | 	void EllipseNode::SetEllipse(Point const& center, float radius_x, float radius_y) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1EllipseGeometry> geo; | 		ComPtr<ID2D1EllipseGeometry> geo; | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(factory->CreateEllipseGeometry( | 		if (SUCCEEDED(factory->CreateEllipseGeometry( | ||||||
| 			D2D1::Ellipse( | 			D2D1::Ellipse( | ||||||
|  | @ -393,7 +393,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		current_geometry_ = nullptr; | 		current_geometry_ = nullptr; | ||||||
| 
 | 
 | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			factory->CreatePathGeometry(¤t_geometry_) | 			factory->CreatePathGeometry(¤t_geometry_) | ||||||
|  |  | ||||||
|  | @ -87,7 +87,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		if (frame_) | 		if (frame_) | ||||||
| 		{ | 		{ | ||||||
| 			Renderer::Instance()->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); | 			Renderer::GetInstance()->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ namespace kiwano | ||||||
| 		stage_ = this; | 		stage_ = this; | ||||||
| 
 | 
 | ||||||
| 		SetAnchor(0, 0); | 		SetAnchor(0, 0); | ||||||
| 		SetSize(Renderer::Instance()->GetOutputSize()); | 		SetSize(Renderer::GetInstance()->GetOutputSize()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Stage::~Stage() | 	Stage::~Stage() | ||||||
|  |  | ||||||
|  | @ -303,7 +303,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (text_layout_) | 		if (text_layout_) | ||||||
| 		{ | 		{ | ||||||
|             auto renderer = Renderer::Instance(); |             auto renderer = Renderer::GetInstance(); | ||||||
|             renderer->SetTextStyle( |             renderer->SetTextStyle( | ||||||
| 				GetDisplayedOpacity(), | 				GetDisplayedOpacity(), | ||||||
| 				style_.color, | 				style_.color, | ||||||
|  | @ -328,7 +328,7 @@ namespace kiwano | ||||||
| 		if (text_.empty()) | 		if (text_.empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
|         auto renderer = Renderer::Instance(); |         auto renderer = Renderer::GetInstance(); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
|             renderer->GetD2DDeviceResources()->CreateTextFormat( |             renderer->GetD2DDeviceResources()->CreateTextFormat( | ||||||
|  |  | ||||||
|  | @ -66,18 +66,18 @@ namespace kiwano | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				Renderer::Instance()->CreateLayer(in_layer_) | 				Renderer::GetInstance()->CreateLayer(in_layer_) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			ThrowIfFailed( | ||||||
| 				Renderer::Instance()->CreateLayer(out_layer_) | 				Renderer::GetInstance()->CreateLayer(out_layer_) | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		window_size_ = Renderer::Instance()->GetOutputSize(); | 		window_size_ = Renderer::GetInstance()->GetOutputSize(); | ||||||
| 		out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f }; | 		out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f }; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -101,7 +101,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void Transition::Render() | 	void Transition::Render() | ||||||
| 	{ | 	{ | ||||||
| 		auto renderer = Renderer::Instance(); | 		auto renderer = Renderer::GetInstance(); | ||||||
| 
 | 
 | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -521,7 +521,7 @@ namespace kiwano | ||||||
| 		geo_ = nullptr; | 		geo_ = nullptr; | ||||||
| 		geo_sink_ = nullptr; | 		geo_sink_ = nullptr; | ||||||
| 
 | 
 | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			factory->CreatePathGeometry(&geo_) | 			factory->CreatePathGeometry(&geo_) | ||||||
|  |  | ||||||
|  | @ -27,18 +27,18 @@ | ||||||
| 
 | 
 | ||||||
| #ifndef KGE_LOG | #ifndef KGE_LOG | ||||||
| #	ifdef KGE_DEBUG | #	ifdef KGE_DEBUG | ||||||
| #		define KGE_LOG(FORMAT, ...) kiwano::Logger::Instance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) | #		define KGE_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) | ||||||
| #	else | #	else | ||||||
| #		define KGE_LOG __noop | #		define KGE_LOG __noop | ||||||
| #	endif | #	endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef KGE_WARNING_LOG | #ifndef KGE_WARNING_LOG | ||||||
| #	define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::Instance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) | #	define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef KGE_ERROR_LOG | #ifndef KGE_ERROR_LOG | ||||||
| #	define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::Instance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) | #	define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -274,7 +274,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	inline std::wostream& Logger::DefaultOutputColor(std::wostream& out) | 	inline std::wostream& Logger::DefaultOutputColor(std::wostream& out) | ||||||
| 	{ | 	{ | ||||||
| 		::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::Instance()->default_stdout_color_); | 		::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::GetInstance()->default_stdout_color_); | ||||||
| 		return out; | 		return out; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ | ||||||
| #ifndef KGE_DECLARE_SINGLETON | #ifndef KGE_DECLARE_SINGLETON | ||||||
| #define KGE_DECLARE_SINGLETON( CLASS )			\ | #define KGE_DECLARE_SINGLETON( CLASS )			\ | ||||||
| 	friend ::kiwano::Singleton< CLASS >;  \ | 	friend ::kiwano::Singleton< CLASS >;  \ | ||||||
| 	friend ::std::default_delete< CLASS > | 	friend typename std::unique_ptr< CLASS >::deleter_type | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -37,21 +37,24 @@ namespace kiwano | ||||||
| 	struct Singleton | 	struct Singleton | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		static inline _Ty* Instance() | 		static inline _Ty* GetInstance() | ||||||
| 		{ | 		{ | ||||||
| 			if (!instance_) | 			if (!instance_) | ||||||
| 			{ | 			{ | ||||||
| 				std::call_once(once_, Init); | 				std::call_once(once_, InitInstance); | ||||||
| 			} | 			} | ||||||
| 			return instance_.get(); | 			return instance_.get(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline void Init() | 		static inline void InitInstance() | ||||||
| 		{ | 		{ | ||||||
| 			if (!instance_) instance_.reset(new (std::nothrow) _Ty); | 			if (!instance_) | ||||||
|  | 			{ | ||||||
|  | 				instance_.reset(new (std::nothrow) _Ty); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline void Destroy() | 		static inline void DestroyInstance() | ||||||
| 		{ | 		{ | ||||||
| 			instance_.reset(); | 			instance_.reset(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ | ||||||
| #include "../base/input.h" | #include "../base/input.h" | ||||||
| #include "../base/Director.h" | #include "../base/Director.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/render.h" | ||||||
|  | #include "../utils/ResourceCache.h" | ||||||
| #include <windowsx.h>  // GET_X_LPARAM, GET_Y_LPARAM
 | #include <windowsx.h>  // GET_X_LPARAM, GET_Y_LPARAM
 | ||||||
| #include <imm.h>  // ImmAssociateContext
 | #include <imm.h>  // ImmAssociateContext
 | ||||||
| #include <mutex>  // std::mutex
 | #include <mutex>  // std::mutex
 | ||||||
|  | @ -64,9 +65,9 @@ namespace kiwano | ||||||
| 			::CoInitialize(nullptr) | 			::CoInitialize(nullptr) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		Use(Renderer::Instance()); | 		Use(Renderer::GetInstance()); | ||||||
| 		Use(Input::Instance()); | 		Use(Input::GetInstance()); | ||||||
| 		Use(Director::Instance()); | 		Use(Director::GetInstance()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Application::~Application() | 	Application::~Application() | ||||||
|  | @ -79,7 +80,7 @@ namespace kiwano | ||||||
| 	void Application::Init(const Options& options) | 	void Application::Init(const Options& options) | ||||||
| 	{ | 	{ | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			Window::Instance()->Create( | 			Window::GetInstance()->Create( | ||||||
| 				options.title, | 				options.title, | ||||||
| 				options.width, | 				options.width, | ||||||
| 				options.height, | 				options.height, | ||||||
|  | @ -89,8 +90,8 @@ namespace kiwano | ||||||
| 			) | 			) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		Renderer::Instance()->SetClearColor(options.clear_color); | 		Renderer::GetInstance()->SetClearColor(options.clear_color); | ||||||
| 		Renderer::Instance()->SetVSyncEnabled(options.vsync); | 		Renderer::GetInstance()->SetVSyncEnabled(options.vsync); | ||||||
| 
 | 
 | ||||||
| 		// Setup all components
 | 		// Setup all components
 | ||||||
| 		for (Component* c : components_) | 		for (Component* c : components_) | ||||||
|  | @ -100,14 +101,14 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (options.debug) | 		if (options.debug) | ||||||
| 		{ | 		{ | ||||||
| 			Director::Instance()->ShowDebugInfo(true); | 			Director::GetInstance()->ShowDebugInfo(true); | ||||||
| 			Renderer::Instance()->SetCollectingStatus(true); | 			Renderer::GetInstance()->SetCollectingStatus(true); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Everything is ready
 | 		// Everything is ready
 | ||||||
| 		OnReady(); | 		OnReady(); | ||||||
| 
 | 
 | ||||||
| 		HWND hwnd = Window::Instance()->GetHandle(); | 		HWND hwnd = Window::GetInstance()->GetHandle(); | ||||||
| 
 | 
 | ||||||
| 		// disable imm
 | 		// disable imm
 | ||||||
| 		::ImmAssociateContext(hwnd, nullptr); | 		::ImmAssociateContext(hwnd, nullptr); | ||||||
|  | @ -120,7 +121,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void Application::Run() | 	void Application::Run() | ||||||
| 	{ | 	{ | ||||||
| 		HWND hwnd = Window::Instance()->GetHandle(); | 		HWND hwnd = Window::GetInstance()->GetHandle(); | ||||||
| 
 | 
 | ||||||
| 		if (!hwnd) | 		if (!hwnd) | ||||||
| 			throw std::exception("Calling Application::Run before Application::Init"); | 			throw std::exception("Calling Application::Run before Application::Init"); | ||||||
|  | @ -128,7 +129,7 @@ namespace kiwano | ||||||
| 		if (hwnd) | 		if (hwnd) | ||||||
| 		{ | 		{ | ||||||
| 			end_ = false; | 			end_ = false; | ||||||
| 			Window::Instance()->Prepare(); | 			Window::GetInstance()->Prepare(); | ||||||
| 
 | 
 | ||||||
| 			MSG msg = {}; | 			MSG msg = {}; | ||||||
| 			while (::GetMessageW(&msg, nullptr, 0, 0) && !end_) | 			while (::GetMessageW(&msg, nullptr, 0, 0) && !end_) | ||||||
|  | @ -158,13 +159,14 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Destroy all instances
 | 		// Destroy all instances
 | ||||||
| 		Director::Destroy(); | 		ResourceCache::DestroyInstance(); | ||||||
| 		Input::Destroy(); | 		Director::DestroyInstance(); | ||||||
| 		Renderer::Destroy(); | 		Input::DestroyInstance(); | ||||||
| 		Window::Destroy(); | 		Renderer::DestroyInstance(); | ||||||
|  | 		Window::DestroyInstance(); | ||||||
| 
 | 
 | ||||||
| 		// DO NOT destroy Logger instance manually
 | 		// DO NOT destroy Logger instance manually
 | ||||||
| 		// Logger::Destroy();
 | 		// Logger::DestroyInstance();
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Application::Use(Component* component) | 	void Application::Use(Component* component) | ||||||
|  | @ -379,7 +381,7 @@ namespace kiwano | ||||||
| 			{ | 			{ | ||||||
| 				KGE_LOG(L"Window resized"); | 				KGE_LOG(L"Window resized"); | ||||||
| 
 | 
 | ||||||
| 				Window::Instance()->UpdateWindowRect(); | 				Window::GetInstance()->UpdateWindowRect(); | ||||||
| 
 | 
 | ||||||
| 				Event evt(Event::WindowResized); | 				Event evt(Event::WindowResized); | ||||||
| 				evt.win.width = LOWORD(lparam); | 				evt.win.width = LOWORD(lparam); | ||||||
|  | @ -405,7 +407,7 @@ namespace kiwano | ||||||
| 		{ | 		{ | ||||||
| 			bool active = (LOWORD(wparam) != WA_INACTIVE); | 			bool active = (LOWORD(wparam) != WA_INACTIVE); | ||||||
| 
 | 
 | ||||||
| 			Window::Instance()->SetActive(active); | 			Window::GetInstance()->SetActive(active); | ||||||
| 
 | 
 | ||||||
| 			Event evt(Event::WindowFocusChanged); | 			Event evt(Event::WindowFocusChanged); | ||||||
| 			evt.win.focus = active; | 			evt.win.focus = active; | ||||||
|  |  | ||||||
|  | @ -174,7 +174,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void D2DDeviceResources::DiscardResources() | 	void D2DDeviceResources::DiscardResources() | ||||||
| 	{ | 	{ | ||||||
| 		ImageCache::Instance()->Clear(); | 		ImageCache::GetInstance()->Clear(); | ||||||
| 
 | 
 | ||||||
| 		factory_.Reset(); | 		factory_.Reset(); | ||||||
| 		device_.Reset(); | 		device_.Reset(); | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ namespace kiwano | ||||||
| 		saved_frame_.Reset(); | 		saved_frame_.Reset(); | ||||||
| 		decoder_.Reset(); | 		decoder_.Reset(); | ||||||
| 
 | 
 | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); | 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetWICImagingFactory(); | ||||||
| 
 | 
 | ||||||
| 		if (res.IsFileType()) | 		if (res.IsFileType()) | ||||||
| 		{ | 		{ | ||||||
|  | @ -124,7 +124,7 @@ namespace kiwano | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
| 			// Format convert to 32bppPBGRA which D2D expects
 | 			// Format convert to 32bppPBGRA which D2D expects
 | ||||||
| 			auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); | 			auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetWICImagingFactory(); | ||||||
| 			hr = factory->CreateFormatConverter(&converter); | 			hr = factory->CreateFormatConverter(&converter); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -141,7 +141,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
| 			auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); | 			auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext(); | ||||||
| 
 | 
 | ||||||
| 			// Create a D2DBitmap from IWICBitmapSource
 | 			// Create a D2DBitmap from IWICBitmapSource
 | ||||||
| 			raw_frame_.Reset(); | 			raw_frame_.Reset(); | ||||||
|  | @ -504,7 +504,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
| 			auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); | 			auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetWICImagingFactory(); | ||||||
| 			hr = factory->CreatePalette(&wic_palette); | 			hr = factory->CreatePalette(&wic_palette); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -46,11 +46,11 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (res.IsFileType()) | 		if (res.IsFileType()) | ||||||
| 		{ | 		{ | ||||||
| 			hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); | 			hr = Renderer::GetInstance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); | 			hr = Renderer::GetInstance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
|  |  | ||||||
|  | @ -44,7 +44,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		KGE_LOG(L"Creating device resources"); | 		KGE_LOG(L"Creating device resources"); | ||||||
| 
 | 
 | ||||||
| 		hwnd_ = Window::Instance()->GetHandle(); | 		hwnd_ = Window::GetInstance()->GetHandle(); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed(hwnd_ ? S_OK : E_FAIL); | 		ThrowIfFailed(hwnd_ ? S_OK : E_FAIL); | ||||||
| 		 | 		 | ||||||
|  | @ -86,7 +86,7 @@ namespace kiwano | ||||||
| 			CreateDeviceResources() | 			CreateDeviceResources() | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		output_size_ = Window::Instance()->GetSize(); | 		output_size_ = Window::GetInstance()->GetSize(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Renderer::DestroyComponent() | 	void Renderer::DestroyComponent() | ||||||
|  |  | ||||||
|  | @ -112,7 +112,7 @@ namespace kiwano | ||||||
| 			if (evt.type == Event::MouseHover) | 			if (evt.type == Event::MouseHover) | ||||||
| 			{ | 			{ | ||||||
| 				SetStatus(Status::Hover); | 				SetStatus(Status::Hover); | ||||||
| 				Window::Instance()->SetMouseCursor(MouseCursor::Hand); | 				Window::GetInstance()->SetMouseCursor(MouseCursor::Hand); | ||||||
| 
 | 
 | ||||||
| 				if (mouse_over_callback_) | 				if (mouse_over_callback_) | ||||||
| 					mouse_over_callback_(); | 					mouse_over_callback_(); | ||||||
|  | @ -120,7 +120,7 @@ namespace kiwano | ||||||
| 			else if (evt.type == Event::MouseOut) | 			else if (evt.type == Event::MouseOut) | ||||||
| 			{ | 			{ | ||||||
| 				SetStatus(Status::Normal); | 				SetStatus(Status::Normal); | ||||||
| 				Window::Instance()->SetMouseCursor(MouseCursor::Arrow); | 				Window::GetInstance()->SetMouseCursor(MouseCursor::Arrow); | ||||||
| 
 | 
 | ||||||
| 				if (mouse_out_callback_) | 				if (mouse_out_callback_) | ||||||
| 					mouse_out_callback_(); | 					mouse_out_callback_(); | ||||||
|  |  | ||||||
|  | @ -23,164 +23,38 @@ | ||||||
| #include "../2d/Frame.h" | #include "../2d/Frame.h" | ||||||
| #include "../2d/FrameSequence.h" | #include "../2d/FrameSequence.h" | ||||||
| #include "../renderer/GifImage.h" | #include "../renderer/GifImage.h" | ||||||
| #include "FileUtil.h" |  | ||||||
| #include <fstream> | #include <fstream> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	namespace __res_loader_01 | 	namespace __resource_cache_01 | ||||||
| 	{ | 	{ | ||||||
| 		struct GlobalData | 		bool LoadJsonData(ResourceCache* loader, Json const& json_data); | ||||||
| 		{ | 		bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem); | ||||||
| 			String path; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		bool LoadImagesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, |  | ||||||
| 			const String* file, const Array<const wchar_t*>* files, int rows, int cols) |  | ||||||
| 		{ |  | ||||||
| 			if (!gdata || !id) return false; |  | ||||||
| 
 |  | ||||||
| 			if (file) |  | ||||||
| 			{ |  | ||||||
| 				// Gif image
 |  | ||||||
| 				if (type && (*type) == L"gif") |  | ||||||
| 				{ |  | ||||||
| 					return loader->AddGifImage(*id, Resource(gdata->path + (*file))); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				if (!(*file).empty()) |  | ||||||
| 				{ |  | ||||||
| 					if (rows || cols) |  | ||||||
| 					{ |  | ||||||
| 						// Frame slices
 |  | ||||||
| 						return !!loader->AddFrameSequence(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1)); |  | ||||||
| 					} |  | ||||||
| 					else |  | ||||||
| 					{ |  | ||||||
| 						// Simple image
 |  | ||||||
| 						return loader->AddFrame(*id, Resource(gdata->path + (*file))); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			// Frames
 |  | ||||||
| 			if (files) |  | ||||||
| 			{ |  | ||||||
| 				Array<FramePtr> frames; |  | ||||||
| 				frames.reserve(files->size()); |  | ||||||
| 				for (const auto& file : (*files)) |  | ||||||
| 				{ |  | ||||||
| 					FramePtr frame = new Frame; |  | ||||||
| 					if (frame->Load(gdata->path + (file))) |  | ||||||
| 					{ |  | ||||||
| 						frames.push_back(frame); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				return !!loader->AddFrameSequence(*id, frames); |  | ||||||
| 			} |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		bool LoadJsonData(ResourceCache* loader, Json const& json_data) |  | ||||||
| 		{ |  | ||||||
| 			GlobalData global_data; |  | ||||||
| 			if (json_data.count(L"path")) |  | ||||||
| 			{ |  | ||||||
| 				global_data.path = json_data[L"path"]; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (json_data.count(L"images")) |  | ||||||
| 			{ |  | ||||||
| 				for (const auto& image : json_data[L"images"]) |  | ||||||
| 				{ |  | ||||||
| 					const String* id = nullptr, *type = nullptr, *file = nullptr; |  | ||||||
| 					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(L"files")) |  | ||||||
| 					{ |  | ||||||
| 						Array<const wchar_t*> files; |  | ||||||
| 						files.reserve(image[L"files"].size()); |  | ||||||
| 						for (const auto& file : image[L"files"]) |  | ||||||
| 						{ |  | ||||||
| 							files.push_back(file.as_string().c_str()); |  | ||||||
| 						} |  | ||||||
| 						if (!LoadImagesFromData(loader, &global_data, id, type, file, &files, rows, cols)) |  | ||||||
| 							return false; |  | ||||||
| 					} |  | ||||||
| 					else |  | ||||||
| 					{ |  | ||||||
| 						if (!LoadImagesFromData(loader, &global_data, id, type, file, nullptr, rows, cols)) |  | ||||||
| 							return false; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			return true; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem) |  | ||||||
| 		{ |  | ||||||
| 			GlobalData global_data; |  | ||||||
| 			if (auto path = elem->FirstChildElement(L"path")) |  | ||||||
| 			{ |  | ||||||
| 				global_data.path = path->GetText(); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (auto images = elem->FirstChildElement(L"images")) |  | ||||||
| 			{ |  | ||||||
| 				for (auto image = images->FirstChildElement(); image; image = image->NextSiblingElement()) |  | ||||||
| 				{ |  | ||||||
| 					String id, type, file; |  | ||||||
| 					int rows = 0, cols = 0; |  | ||||||
| 
 |  | ||||||
| 					if (auto attr = image->Attribute(L"id"))      id.assign(attr); // assign() copies attr content
 |  | ||||||
| 					if (auto attr = image->Attribute(L"type"))    type = attr;     // operator=() just holds attr pointer
 |  | ||||||
| 					if (auto attr = image->Attribute(L"file"))    file = attr; |  | ||||||
| 					if (auto attr = image->IntAttribute(L"rows")) rows = attr; |  | ||||||
| 					if (auto attr = image->IntAttribute(L"cols")) cols = attr; |  | ||||||
| 
 |  | ||||||
| 					if (file.empty() && !image->NoChildren()) |  | ||||||
| 					{ |  | ||||||
| 						Array<const wchar_t*> files_arr; |  | ||||||
| 						for (auto file = image->FirstChildElement(); file; file = file->NextSiblingElement()) |  | ||||||
| 						{ |  | ||||||
| 							if (auto path = file->Attribute(L"path")) |  | ||||||
| 							{ |  | ||||||
| 								files_arr.push_back(path); |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 						if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, &files_arr, rows, cols)) |  | ||||||
| 							return false; |  | ||||||
| 					} |  | ||||||
| 					else |  | ||||||
| 					{ |  | ||||||
| 						if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, nullptr, rows, cols)) |  | ||||||
| 							return false; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			return true; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	namespace | 	namespace | ||||||
| 	{ | 	{ | ||||||
| 		Map<String, Closure<bool(ResourceCache*, Json const&)>> load_json_funcs = { | 		Map<String, Closure<bool(ResourceCache*, Json const&)>> load_json_funcs = { | ||||||
| 			{ L"latest", __res_loader_01::LoadJsonData }, | 			{ L"latest", __resource_cache_01::LoadJsonData }, | ||||||
| 			{ L"0.1", __res_loader_01::LoadJsonData }, | 			{ L"0.1", __resource_cache_01::LoadJsonData }, | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		Map<String, Closure<bool(ResourceCache*, tinyxml2::XMLElement*)>> load_xml_funcs = { | 		Map<String, Closure<bool(ResourceCache*, tinyxml2::XMLElement*)>> load_xml_funcs = { | ||||||
| 			{ L"latest", __res_loader_01::LoadXmlData }, | 			{ L"latest", __resource_cache_01::LoadXmlData }, | ||||||
| 			{ L"0.1", __res_loader_01::LoadXmlData }, | 			{ L"0.1", __resource_cache_01::LoadXmlData }, | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	ResourceCache::ResourceCache() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ResourceCache::~ResourceCache() | ||||||
|  | 	{ | ||||||
|  | 		Clear(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	bool ResourceCache::LoadFromJsonFile(String const& file_path) | 	bool ResourceCache::LoadFromJsonFile(String const& file_path) | ||||||
| 	{ | 	{ | ||||||
| 		Json json_data; | 		Json json_data; | ||||||
|  | @ -479,18 +353,152 @@ namespace kiwano | ||||||
| 		cache_.erase(id); | 		cache_.erase(id); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void ResourceCache::Destroy() | 	void ResourceCache::Clear() | ||||||
| 	{ | 	{ | ||||||
| 		cache_.clear(); | 		cache_.clear(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ResourceCache::ResourceCache() |  | ||||||
| 	{ |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 	ResourceCache::~ResourceCache() | namespace kiwano | ||||||
| { | { | ||||||
| 		Destroy(); | 	namespace __resource_cache_01 | ||||||
|  | 	{ | ||||||
|  | 		struct GlobalData | ||||||
|  | 		{ | ||||||
|  | 			String path; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		bool LoadImagesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, | ||||||
|  | 			const String* file, const Array<const wchar_t*>* files, int rows, int cols) | ||||||
|  | 		{ | ||||||
|  | 			if (!gdata || !id) return false; | ||||||
|  | 
 | ||||||
|  | 			if (file) | ||||||
|  | 			{ | ||||||
|  | 				// Gif image
 | ||||||
|  | 				if (type && (*type) == L"gif") | ||||||
|  | 				{ | ||||||
|  | 					return loader->AddGifImage(*id, Resource(gdata->path + (*file))); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				if (!(*file).empty()) | ||||||
|  | 				{ | ||||||
|  | 					if (rows || cols) | ||||||
|  | 					{ | ||||||
|  | 						// Frame slices
 | ||||||
|  | 						return !!loader->AddFrameSequence(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1)); | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 					{ | ||||||
|  | 						// Simple image
 | ||||||
|  | 						return loader->AddFrame(*id, Resource(gdata->path + (*file))); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Frames
 | ||||||
|  | 			if (files) | ||||||
|  | 			{ | ||||||
|  | 				Array<FramePtr> frames; | ||||||
|  | 				frames.reserve(files->size()); | ||||||
|  | 				for (const auto& file : (*files)) | ||||||
|  | 				{ | ||||||
|  | 					FramePtr frame = new Frame; | ||||||
|  | 					if (frame->Load(gdata->path + (file))) | ||||||
|  | 					{ | ||||||
|  | 						frames.push_back(frame); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				return !!loader->AddFrameSequence(*id, frames); | ||||||
|  | 			} | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		bool LoadJsonData(ResourceCache* loader, Json const& json_data) | ||||||
|  | 		{ | ||||||
|  | 			GlobalData global_data; | ||||||
|  | 			if (json_data.count(L"path")) | ||||||
|  | 			{ | ||||||
|  | 				global_data.path = json_data[L"path"]; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (json_data.count(L"images")) | ||||||
|  | 			{ | ||||||
|  | 				for (const auto& image : json_data[L"images"]) | ||||||
|  | 				{ | ||||||
|  | 					const String* id = nullptr, * type = nullptr, * file = nullptr; | ||||||
|  | 					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(L"files")) | ||||||
|  | 					{ | ||||||
|  | 						Array<const wchar_t*> files; | ||||||
|  | 						files.reserve(image[L"files"].size()); | ||||||
|  | 						for (const auto& file : image[L"files"]) | ||||||
|  | 						{ | ||||||
|  | 							files.push_back(file.as_string().c_str()); | ||||||
|  | 						} | ||||||
|  | 						if (!LoadImagesFromData(loader, &global_data, id, type, file, &files, rows, cols)) | ||||||
|  | 							return false; | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 					{ | ||||||
|  | 						if (!LoadImagesFromData(loader, &global_data, id, type, file, nullptr, rows, cols)) | ||||||
|  | 							return false; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem) | ||||||
|  | 		{ | ||||||
|  | 			GlobalData global_data; | ||||||
|  | 			if (auto path = elem->FirstChildElement(L"path")) | ||||||
|  | 			{ | ||||||
|  | 				global_data.path = path->GetText(); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (auto images = elem->FirstChildElement(L"images")) | ||||||
|  | 			{ | ||||||
|  | 				for (auto image = images->FirstChildElement(); image; image = image->NextSiblingElement()) | ||||||
|  | 				{ | ||||||
|  | 					String id, type, file; | ||||||
|  | 					int rows = 0, cols = 0; | ||||||
|  | 
 | ||||||
|  | 					if (auto attr = image->Attribute(L"id"))      id.assign(attr); // assign() copies attr content
 | ||||||
|  | 					if (auto attr = image->Attribute(L"type"))    type = attr;     // operator=() just holds attr pointer
 | ||||||
|  | 					if (auto attr = image->Attribute(L"file"))    file = attr; | ||||||
|  | 					if (auto attr = image->IntAttribute(L"rows")) rows = attr; | ||||||
|  | 					if (auto attr = image->IntAttribute(L"cols")) cols = attr; | ||||||
|  | 
 | ||||||
|  | 					if (file.empty() && !image->NoChildren()) | ||||||
|  | 					{ | ||||||
|  | 						Array<const wchar_t*> files_arr; | ||||||
|  | 						for (auto file = image->FirstChildElement(); file; file = file->NextSiblingElement()) | ||||||
|  | 						{ | ||||||
|  | 							if (auto path = file->Attribute(L"path")) | ||||||
|  | 							{ | ||||||
|  | 								files_arr.push_back(path); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 						if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, &files_arr, rows, cols)) | ||||||
|  | 							return false; | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 					{ | ||||||
|  | 						if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, nullptr, rows, cols)) | ||||||
|  | 							return false; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/helper.h" | #include "../common/helper.h" | ||||||
| #include "../common/Json.hpp" | #include "../common/Json.hpp" | ||||||
|  | #include "../common/Singleton.hpp" | ||||||
| #include "../base/Resource.h" | #include "../base/Resource.h" | ||||||
| #include "../2d/include-forwards.h" | #include "../2d/include-forwards.h" | ||||||
| #include "../renderer/GifImage.h" | #include "../renderer/GifImage.h" | ||||||
|  | @ -31,7 +32,10 @@ namespace kiwano | ||||||
| { | { | ||||||
| 	// 资源缓存
 | 	// 资源缓存
 | ||||||
| 	class KGE_API ResourceCache | 	class KGE_API ResourceCache | ||||||
|  | 		: public Singleton<ResourceCache> | ||||||
| 	{ | 	{ | ||||||
|  | 		KGE_DECLARE_SINGLETON(ResourceCache); | ||||||
|  | 
 | ||||||
| 	public: | 	public: | ||||||
| 		// 从 JSON 文件加载资源信息
 | 		// 从 JSON 文件加载资源信息
 | ||||||
| 		bool LoadFromJsonFile(String const& file_path); | 		bool LoadFromJsonFile(String const& file_path); | ||||||
|  | @ -89,8 +93,8 @@ namespace kiwano | ||||||
| 		// 删除指定资源
 | 		// 删除指定资源
 | ||||||
| 		void Delete(String const& id); | 		void Delete(String const& id); | ||||||
| 
 | 
 | ||||||
| 		// 销毁所有资源
 | 		// 清空所有资源
 | ||||||
| 		void Destroy(); | 		void Clear(); | ||||||
| 
 | 
 | ||||||
| 		template<typename _Ty> | 		template<typename _Ty> | ||||||
| 		_Ty* Get(String const& id) const | 		_Ty* Get(String const& id) const | ||||||
|  | @ -101,7 +105,7 @@ namespace kiwano | ||||||
| 			return dynamic_cast<_Ty*>((*iter).second.Get()); | 			return dynamic_cast<_Ty*>((*iter).second.Get()); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	public: | 	protected: | ||||||
| 		ResourceCache(); | 		ResourceCache(); | ||||||
| 
 | 
 | ||||||
| 		virtual ~ResourceCache(); | 		virtual ~ResourceCache(); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue