[deploy] Merge pull request #34 from KiwanoEngine/dev
Add Director, Stage, Actor, ResourceCache, ImageCache and more
This commit is contained in:
		
						commit
						b5d67a2720
					
				
							
								
								
									
										34
									
								
								appveyor.yml
								
								
								
								
							
							
						
						
									
										34
									
								
								appveyor.yml
								
								
								
								
							|  | @ -2,19 +2,26 @@ version: 0.9.{build} | ||||||
| 
 | 
 | ||||||
| skip_tags: true | skip_tags: true | ||||||
| 
 | 
 | ||||||
|  | # fetch repository as zip archive | ||||||
|  | shallow_clone: true | ||||||
|  | 
 | ||||||
| # pull_requests: | # pull_requests: | ||||||
| #   do_not_increment_build_number: true | #   do_not_increment_build_number: true | ||||||
| 
 | 
 | ||||||
|  | # Do not build feature branch with open Pull Requests | ||||||
|  | # skip_branch_with_pr: true | ||||||
|  | 
 | ||||||
| # image: | # image: | ||||||
| # - Visual Studio 2019 | # - Visual Studio 2019 | ||||||
| # - Visual Studio 2017 | # - Visual Studio 2017 | ||||||
| # - Visual Studio 2015 | # - Visual Studio 2015 | ||||||
| 
 | 
 | ||||||
| environment: | environment: | ||||||
|  |   global: | ||||||
|     time_out_mins: 5 |     time_out_mins: 5 | ||||||
|     job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration) |     job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration) | ||||||
|     flag_to_deploy: false |     flag_to_deploy: false | ||||||
|   APPVEYOR_API_TOKEN: |     appveyor_api_token: | ||||||
|       secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= |       secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= | ||||||
|   matrix: |   matrix: | ||||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 |     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||||
|  | @ -24,6 +31,12 @@ environment: | ||||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 |     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||||
|       VS_PLATFORM_TOOLSET: v140 |       VS_PLATFORM_TOOLSET: v140 | ||||||
| 
 | 
 | ||||||
|  | matrix: | ||||||
|  |   fast_finish: true # set this flag to immediately finish build once one of the jobs fails | ||||||
|  |   # allow_failures: | ||||||
|  |   #   - platform: x86 | ||||||
|  |   #     configuration: Debug | ||||||
|  | 
 | ||||||
| skip_commits: | skip_commits: | ||||||
|   message: /\[chore\]/ |   message: /\[chore\]/ | ||||||
| 
 | 
 | ||||||
|  | @ -34,14 +47,6 @@ only_commits: | ||||||
|     - scripts/**/*.ps1 |     - scripts/**/*.ps1 | ||||||
|     - appveyor.yml |     - appveyor.yml | ||||||
| 
 | 
 | ||||||
| for: |  | ||||||
| - |  | ||||||
|   branches: |  | ||||||
|     except: |  | ||||||
|       - master |  | ||||||
|   only_commits: |  | ||||||
|     message: /\[build\]/ |  | ||||||
| 
 |  | ||||||
| configuration: | configuration: | ||||||
| - Debug | - Debug | ||||||
| - Release | - Release | ||||||
|  | @ -62,6 +67,17 @@ build: | ||||||
|   project: projects/Kiwano.sln |   project: projects/Kiwano.sln | ||||||
|   verbosity: minimal |   verbosity: minimal | ||||||
| 
 | 
 | ||||||
|  | for: | ||||||
|  | - | ||||||
|  |   branches: | ||||||
|  |     except: | ||||||
|  |       - master | ||||||
|  |   only_commits: | ||||||
|  |     message: /\[build\]/ | ||||||
|  | - | ||||||
|  |   branches: | ||||||
|  |     only: | ||||||
|  |       - master | ||||||
|   after_build: |   after_build: | ||||||
|   - ps: .\scripts\appveyor\wait_for_other_jobs.ps1 |   - ps: .\scripts\appveyor\wait_for_other_jobs.ps1 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,27 +1,38 @@ | ||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\Action.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionDelay.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionGroup.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionHelper.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionManager.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionWalk.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionTween.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\Animation.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\Frame.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\GifSprite.h" /> |     <ClInclude Include="..\src\kiwano\2d\GifSprite.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\base\ComPtr.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\Director.h" /> |     <ClInclude Include="..\src\kiwano\base\Director.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\types.h" /> |     <ClInclude Include="..\src\kiwano\base\types.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\basic_json.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\function.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\core.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\intrusive_list.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\intrusive_ptr.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\noncopyable.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\singleton.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\string.hpp" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\vector.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\kiwano.h" /> |     <ClInclude Include="..\src\kiwano\kiwano.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\config.h" /> |     <ClInclude Include="..\src\kiwano\config.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\macros.h" /> |     <ClInclude Include="..\src\kiwano\macros.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\include-forwards.h" /> |     <ClInclude Include="..\src\kiwano\2d\include-forwards.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Action.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionGroup.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionHelper.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionManager.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionTween.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Animation.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Canvas.h" /> |     <ClInclude Include="..\src\kiwano\2d\Canvas.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Color.h" /> |     <ClInclude Include="..\src\kiwano\2d\Color.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\DebugNode.h" /> |     <ClInclude Include="..\src\kiwano\2d\DebugActor.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Font.hpp" /> |     <ClInclude Include="..\src\kiwano\2d\Font.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Frames.h" /> |     <ClInclude Include="..\src\kiwano\2d\FrameSequence.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ShapeNode.h" /> |     <ClInclude Include="..\src\kiwano\2d\ShapeActor.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\GifImage.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Image.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Layer.h" /> |     <ClInclude Include="..\src\kiwano\2d\Layer.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Actor.h" /> |     <ClInclude Include="..\src\kiwano\2d\Actor.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Stage.h" /> |     <ClInclude Include="..\src\kiwano\2d\Stage.h" /> | ||||||
|  | @ -37,7 +48,7 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\base\EventListener.h" /> |     <ClInclude Include="..\src\kiwano\base\EventListener.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\Input.h" /> |     <ClInclude Include="..\src\kiwano\base\Input.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\keys.hpp" /> |     <ClInclude Include="..\src\kiwano\base\keys.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\logs.h" /> |     <ClInclude Include="..\src\kiwano\base\Logger.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\Object.h" /> |     <ClInclude Include="..\src\kiwano\base\Object.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\RefCounter.hpp" /> |     <ClInclude Include="..\src\kiwano\base\RefCounter.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\Resource.h" /> |     <ClInclude Include="..\src\kiwano\base\Resource.h" /> | ||||||
|  | @ -45,17 +56,7 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\base\Timer.h" /> |     <ClInclude Include="..\src\kiwano\base\Timer.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\TimerManager.h" /> |     <ClInclude Include="..\src\kiwano\base\TimerManager.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\time.h" /> |     <ClInclude Include="..\src\kiwano\base\time.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\base\window.h" /> |     <ClInclude Include="..\src\kiwano\base\Window.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\common\Array.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Closure.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\ComPtr.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\helper.h" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\IntrusiveList.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\IntrusivePtr.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Json.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Noncopyable.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Singleton.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\String.hpp" /> |  | ||||||
|     <ClInclude Include="..\src\kiwano\math\constants.hpp" /> |     <ClInclude Include="..\src\kiwano\math\constants.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\math\ease.hpp" /> |     <ClInclude Include="..\src\kiwano\math\ease.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\math\helper.h" /> |     <ClInclude Include="..\src\kiwano\math\helper.h" /> | ||||||
|  | @ -70,8 +71,12 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\D3D10DeviceResources.h" /> |     <ClInclude Include="..\src\kiwano\renderer\D3D10DeviceResources.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\D3D11DeviceResources.h" /> |     <ClInclude Include="..\src\kiwano\renderer\D3D11DeviceResources.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\D3DDeviceResourcesBase.h" /> |     <ClInclude Include="..\src\kiwano\renderer\D3DDeviceResourcesBase.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Geometry.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\GifImage.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\helper.hpp" /> |     <ClInclude Include="..\src\kiwano\renderer\helper.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\render.h" /> |     <ClInclude Include="..\src\kiwano\renderer\Image.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\ImageCache.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Renderer.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\TextRenderer.h" /> |     <ClInclude Include="..\src\kiwano\renderer\TextRenderer.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\third-party\StackWalker\StackWalker.h" /> |     <ClInclude Include="..\src\kiwano\third-party\StackWalker\StackWalker.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.h" /> |     <ClInclude Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.h" /> | ||||||
|  | @ -80,22 +85,23 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\utils\DataUtil.h" /> |     <ClInclude Include="..\src\kiwano\utils\DataUtil.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\utils\FileUtil.h" /> |     <ClInclude Include="..\src\kiwano\utils\FileUtil.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\utils\Path.h" /> |     <ClInclude Include="..\src\kiwano\utils\Path.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\utils\ResLoader.h" /> |     <ClInclude Include="..\src\kiwano\utils\ResourceCache.h" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Action.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\Action.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ActionGroup.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionDelay.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ActionManager.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionGroup.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ActionTween.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionManager.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Animation.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionWalk.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionTween.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\Animation.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Canvas.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Canvas.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Color.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Color.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\DebugNode.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\DebugActor.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Frames.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Frame.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ShapeNode.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\FrameSequence.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\GifImage.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\ShapeActor.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\GifSprite.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\GifSprite.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Image.cpp" /> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Layer.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Layer.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Actor.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Actor.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Stage.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Stage.cpp" /> | ||||||
|  | @ -106,20 +112,24 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\base\EventDispatcher.cpp" /> |     <ClCompile Include="..\src\kiwano\base\EventDispatcher.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\EventListener.cpp" /> |     <ClCompile Include="..\src\kiwano\base\EventListener.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\Input.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Input.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\logs.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Logger.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\Object.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Object.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\Resource.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Resource.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\Director.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Director.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\Timer.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Timer.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\TimerManager.cpp" /> |     <ClCompile Include="..\src\kiwano\base\TimerManager.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\time.cpp" /> |     <ClCompile Include="..\src\kiwano\base\time.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\base\window.cpp" /> |     <ClCompile Include="..\src\kiwano\base\Window.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\platform\Application.cpp" /> |     <ClCompile Include="..\src\kiwano\platform\Application.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\platform\modules.cpp" /> |     <ClCompile Include="..\src\kiwano\platform\modules.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D2DDeviceResources.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\D2DDeviceResources.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D3D10DeviceResources.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\D3D10DeviceResources.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D3D11DeviceResources.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\D3D11DeviceResources.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\render.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\Geometry.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\GifImage.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Image.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\ImageCache.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Renderer.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\TextRenderer.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\TextRenderer.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\third-party\StackWalker\StackWalker.cpp" /> |     <ClCompile Include="..\src\kiwano\third-party\StackWalker\StackWalker.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.cpp" /> |     <ClCompile Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.cpp" /> | ||||||
|  | @ -128,7 +138,7 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\utils\DataUtil.cpp" /> |     <ClCompile Include="..\src\kiwano\utils\DataUtil.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\utils\FileUtil.cpp" /> |     <ClCompile Include="..\src\kiwano\utils\FileUtil.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\utils\Path.cpp" /> |     <ClCompile Include="..\src\kiwano\utils\Path.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\utils\ResLoader.cpp" /> |     <ClCompile Include="..\src\kiwano\utils\ResourceCache.cpp" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup Label="ProjectConfigurations"> |   <ItemGroup Label="ProjectConfigurations"> | ||||||
|     <ProjectConfiguration Include="Debug|Win32"> |     <ProjectConfiguration Include="Debug|Win32"> | ||||||
|  |  | ||||||
|  | @ -10,9 +10,6 @@ | ||||||
|     <Filter Include="ui"> |     <Filter Include="ui"> | ||||||
|       <UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier> |       <UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier> | ||||||
|     </Filter> |     </Filter> | ||||||
|     <Filter Include="common"> |  | ||||||
|       <UniqueIdentifier>{86e2d0f2-a9d0-4456-b6a5-d480228bbf82}</UniqueIdentifier> |  | ||||||
|     </Filter> |  | ||||||
|     <Filter Include="platform"> |     <Filter Include="platform"> | ||||||
|       <UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier> |       <UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier> | ||||||
|     </Filter> |     </Filter> | ||||||
|  | @ -34,6 +31,12 @@ | ||||||
|     <Filter Include="third-party\tinyxml2"> |     <Filter Include="third-party\tinyxml2"> | ||||||
|       <UniqueIdentifier>{0cae76f7-7016-4a45-bb26-a130fbce8024}</UniqueIdentifier> |       <UniqueIdentifier>{0cae76f7-7016-4a45-bb26-a130fbce8024}</UniqueIdentifier> | ||||||
|     </Filter> |     </Filter> | ||||||
|  |     <Filter Include="2d\action"> | ||||||
|  |       <UniqueIdentifier>{9314f30d-5742-48b6-94e5-e3b4284106f6}</UniqueIdentifier> | ||||||
|  |     </Filter> | ||||||
|  |     <Filter Include="core"> | ||||||
|  |       <UniqueIdentifier>{86e2d0f2-a9d0-4456-b6a5-d480228bbf82}</UniqueIdentifier> | ||||||
|  |     </Filter> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\src\kiwano\ui\Button.h"> |     <ClInclude Include="..\src\kiwano\ui\Button.h"> | ||||||
|  | @ -42,42 +45,15 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\ui\Menu.h"> |     <ClInclude Include="..\src\kiwano\ui\Menu.h"> | ||||||
|       <Filter>ui</Filter> |       <Filter>ui</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Action.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionGroup.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionHelper.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionManager.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ActionTween.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Animation.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Canvas.h"> |     <ClInclude Include="..\src\kiwano\2d\Canvas.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Color.h"> |     <ClInclude Include="..\src\kiwano\2d\Color.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\DebugNode.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Font.hpp"> |     <ClInclude Include="..\src\kiwano\2d\Font.hpp"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Frames.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Image.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\2d\include-forwards.h"> |     <ClInclude Include="..\src\kiwano\2d\include-forwards.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -99,21 +75,6 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Transition.h"> |     <ClInclude Include="..\src\kiwano\2d\Transition.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\common\ComPtr.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\helper.h"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\IntrusiveList.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\IntrusivePtr.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Singleton.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\base\Component.h"> |     <ClInclude Include="..\src\kiwano\base\Component.h"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -129,9 +90,6 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\base\keys.hpp"> |     <ClInclude Include="..\src\kiwano\base\keys.hpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\base\logs.h"> |  | ||||||
|       <Filter>base</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\base\RefCounter.hpp"> |     <ClInclude Include="..\src\kiwano\base\RefCounter.hpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -153,9 +111,6 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\helper.hpp"> |     <ClInclude Include="..\src\kiwano\renderer\helper.hpp"> | ||||||
|       <Filter>renderer</Filter> |       <Filter>renderer</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\render.h"> |  | ||||||
|       <Filter>renderer</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\TextRenderer.h"> |     <ClInclude Include="..\src\kiwano\renderer\TextRenderer.h"> | ||||||
|       <Filter>renderer</Filter> |       <Filter>renderer</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -186,9 +141,6 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\utils\Path.h"> |     <ClInclude Include="..\src\kiwano\utils\Path.h"> | ||||||
|       <Filter>utils</Filter> |       <Filter>utils</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\utils\ResLoader.h"> |  | ||||||
|       <Filter>utils</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\config.h" /> |     <ClInclude Include="..\src\kiwano\config.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\macros.h" /> |     <ClInclude Include="..\src\kiwano\macros.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\math\helper.h"> |     <ClInclude Include="..\src\kiwano\math\helper.h"> | ||||||
|  | @ -200,9 +152,6 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\base\Input.h"> |     <ClInclude Include="..\src\kiwano\base\Input.h"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\base\window.h"> |  | ||||||
|       <Filter>base</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\base\SmartPtr.hpp"> |     <ClInclude Include="..\src\kiwano\base\SmartPtr.hpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -222,9 +171,6 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\base\AsyncTask.h"> |     <ClInclude Include="..\src\kiwano\base\AsyncTask.h"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\GifImage.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\third-party\StackWalker\StackWalker.h"> |     <ClInclude Include="..\src\kiwano\third-party\StackWalker\StackWalker.h"> | ||||||
|       <Filter>third-party\StackWalker</Filter> |       <Filter>third-party\StackWalker</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -240,27 +186,9 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\2d\GifSprite.h"> |     <ClInclude Include="..\src\kiwano\2d\GifSprite.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\common\Closure.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Noncopyable.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\String.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Json.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\common\Array.hpp"> |  | ||||||
|       <Filter>common</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.h"> |     <ClInclude Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.h"> | ||||||
|       <Filter>third-party\tinyxml2</Filter> |       <Filter>third-party\tinyxml2</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ShapeNode.h"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClInclude> |  | ||||||
|     <ClInclude Include="..\src\kiwano\base\Director.h"> |     <ClInclude Include="..\src\kiwano\base\Director.h"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  | @ -270,6 +198,96 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Stage.h"> |     <ClInclude Include="..\src\kiwano\2d\Stage.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\Frame.h"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\GifImage.h"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Image.h"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\Action.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionGroup.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionHelper.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionTween.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionManager.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\Animation.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\ImageCache.h"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\utils\ResourceCache.h"> | ||||||
|  |       <Filter>utils</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\FrameSequence.h"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\basic_json.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\function.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\intrusive_list.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\intrusive_ptr.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\noncopyable.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\singleton.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\string.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\vector.hpp"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\base\ComPtr.hpp"> | ||||||
|  |       <Filter>base</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\core\core.h"> | ||||||
|  |       <Filter>core</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\DebugActor.h"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\ShapeActor.h"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Geometry.h"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionDelay.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionWalk.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\base\Logger.h"> | ||||||
|  |       <Filter>base</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\base\Window.h"> | ||||||
|  |       <Filter>base</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Renderer.h"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="..\src\kiwano\ui\Button.cpp"> |     <ClCompile Include="..\src\kiwano\ui\Button.cpp"> | ||||||
|  | @ -278,36 +296,12 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\ui\Menu.cpp"> |     <ClCompile Include="..\src\kiwano\ui\Menu.cpp"> | ||||||
|       <Filter>ui</Filter> |       <Filter>ui</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Action.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ActionGroup.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ActionManager.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ActionTween.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Animation.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Canvas.cpp"> |     <ClCompile Include="..\src\kiwano\2d\Canvas.cpp"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Color.cpp"> |     <ClCompile Include="..\src\kiwano\2d\Color.cpp"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\DebugNode.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Frames.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Image.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Layer.cpp"> |     <ClCompile Include="..\src\kiwano\2d\Layer.cpp"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -326,9 +320,6 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\base\EventListener.cpp"> |     <ClCompile Include="..\src\kiwano\base\EventListener.cpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\base\logs.cpp"> |  | ||||||
|       <Filter>base</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\base\Resource.cpp"> |     <ClCompile Include="..\src\kiwano\base\Resource.cpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -344,9 +335,6 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D3D11DeviceResources.cpp"> |     <ClCompile Include="..\src\kiwano\renderer\D3D11DeviceResources.cpp"> | ||||||
|       <Filter>renderer</Filter> |       <Filter>renderer</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\render.cpp"> |  | ||||||
|       <Filter>renderer</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\TextRenderer.cpp"> |     <ClCompile Include="..\src\kiwano\renderer\TextRenderer.cpp"> | ||||||
|       <Filter>renderer</Filter> |       <Filter>renderer</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -359,15 +347,9 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\utils\Path.cpp"> |     <ClCompile Include="..\src\kiwano\utils\Path.cpp"> | ||||||
|       <Filter>utils</Filter> |       <Filter>utils</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\utils\ResLoader.cpp"> |  | ||||||
|       <Filter>utils</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\base\Input.cpp"> |     <ClCompile Include="..\src\kiwano\base\Input.cpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\base\window.cpp"> |  | ||||||
|       <Filter>base</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\base\Object.cpp"> |     <ClCompile Include="..\src\kiwano\base\Object.cpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -383,9 +365,6 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\base\AsyncTask.cpp"> |     <ClCompile Include="..\src\kiwano\base\AsyncTask.cpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\GifImage.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\third-party\StackWalker\StackWalker.cpp"> |     <ClCompile Include="..\src\kiwano\third-party\StackWalker\StackWalker.cpp"> | ||||||
|       <Filter>third-party\StackWalker</Filter> |       <Filter>third-party\StackWalker</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -398,9 +377,6 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.cpp"> |     <ClCompile Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.cpp"> | ||||||
|       <Filter>third-party\tinyxml2</Filter> |       <Filter>third-party\tinyxml2</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ShapeNode.cpp"> |  | ||||||
|       <Filter>2d</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="..\src\kiwano\base\Director.cpp"> |     <ClCompile Include="..\src\kiwano\base\Director.cpp"> | ||||||
|       <Filter>base</Filter> |       <Filter>base</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | @ -410,5 +386,62 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Stage.cpp"> |     <ClCompile Include="..\src\kiwano\2d\Stage.cpp"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\Frame.cpp"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\GifImage.cpp"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Image.cpp"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\Action.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionGroup.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionTween.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionManager.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\Animation.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\ImageCache.cpp"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\utils\ResourceCache.cpp"> | ||||||
|  |       <Filter>utils</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\FrameSequence.cpp"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\DebugActor.cpp"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\ShapeActor.cpp"> | ||||||
|  |       <Filter>2d</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Geometry.cpp"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionDelay.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionWalk.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\base\Logger.cpp"> | ||||||
|  |       <Filter>base</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\base\Window.cpp"> | ||||||
|  |       <Filter>base</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Renderer.cpp"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/common/IntrusivePtr.hpp> | #include <kiwano/core/intrusive_ptr.hpp> | ||||||
| #include <kiwano/base/Object.h> | #include <kiwano/base/Object.h> | ||||||
| #include "Sound.h" | #include "Sound.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/base/logs.h> | #include <kiwano/base/Logger.h> | ||||||
| #include <kiwano/utils/FileUtil.h> | #include <kiwano/utils/FileUtil.h> | ||||||
| #include "Sound.h" | #include "Sound.h" | ||||||
| #include "audio.h" | #include "audio.h" | ||||||
|  | @ -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_) | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/common/IntrusivePtr.hpp> | #include <kiwano/core/intrusive_ptr.hpp> | ||||||
| #include <kiwano/base/Object.h> | #include <kiwano/base/Object.h> | ||||||
| #include <kiwano/base/Resource.h> | #include <kiwano/base/Resource.h> | ||||||
| #include <xaudio2.h> | #include <xaudio2.h> | ||||||
|  |  | ||||||
|  | @ -23,10 +23,10 @@ | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #include <kiwano/macros.h> | #include <kiwano/macros.h> | ||||||
| #include <kiwano/common/ComPtr.hpp> | #include <kiwano/core/string.hpp> | ||||||
| #include <kiwano/common/String.hpp> | #include <kiwano/base/ComPtr.hpp> | ||||||
| #include <kiwano/base/Resource.h> | #include <kiwano/base/Resource.h> | ||||||
| #include <kiwano/base/logs.h> | #include <kiwano/base/Logger.h> | ||||||
| #include <kiwano/platform/modules.h> | #include <kiwano/platform/modules.h> | ||||||
| #include "audio-modules.h" | #include "audio-modules.h" | ||||||
| #include "Transcoder.h" | #include "Transcoder.h" | ||||||
|  | @ -69,7 +69,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 			if (SUCCEEDED(hr)) | 			if (SUCCEEDED(hr)) | ||||||
| 			{ | 			{ | ||||||
| 				hr = ReadSource(reader.Get(), wave_data, wave_data_size); | 				hr = ReadSource(reader.get(), wave_data, wave_data_size); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return hr; | 			return hr; | ||||||
|  | @ -100,13 +100,13 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 			if (SUCCEEDED(hr)) | 			if (SUCCEEDED(hr)) | ||||||
| 			{ | 			{ | ||||||
| 				hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream); | 				hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.get(), &byte_stream); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (SUCCEEDED(hr)) | 			if (SUCCEEDED(hr)) | ||||||
| 			{ | 			{ | ||||||
| 				hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream( | 				hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream( | ||||||
| 					byte_stream.Get(), | 					byte_stream.get(), | ||||||
| 					nullptr, | 					nullptr, | ||||||
| 					&reader | 					&reader | ||||||
| 				); | 				); | ||||||
|  | @ -114,7 +114,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 			if (SUCCEEDED(hr)) | 			if (SUCCEEDED(hr)) | ||||||
| 			{ | 			{ | ||||||
| 				hr = ReadSource(reader.Get(), wave_data, wave_data_size); | 				hr = ReadSource(reader.get(), wave_data, wave_data_size); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return hr; | 			return hr; | ||||||
|  | @ -146,7 +146,7 @@ namespace kiwano | ||||||
| 				hr = reader->SetCurrentMediaType( | 				hr = reader->SetCurrentMediaType( | ||||||
| 					(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | 					(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | ||||||
| 					0, | 					0, | ||||||
| 					partial_type.Get() | 					partial_type.get() | ||||||
| 				); | 				); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -173,7 +173,7 @@ namespace kiwano | ||||||
| 			{ | 			{ | ||||||
| 				UINT32 size = 0; | 				UINT32 size = 0; | ||||||
| 				hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType( | 				hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType( | ||||||
| 					uncompressed_type.Get(), | 					uncompressed_type.get(), | ||||||
| 					&wave_format_, | 					&wave_format_, | ||||||
| 					&size, | 					&size, | ||||||
| 					(DWORD)MFWaveFormatExConvertFlag_Normal | 					(DWORD)MFWaveFormatExConvertFlag_Normal | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/base/logs.h> | #include <kiwano/base/Logger.h> | ||||||
| #include "audio-modules.h" | #include "audio-modules.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/base/logs.h> | #include <kiwano/base/Logger.h> | ||||||
| #include "audio-modules.h" | #include "audio-modules.h" | ||||||
| #include "audio.h" | #include "audio.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/common/Singleton.hpp> | #include <kiwano/core/singleton.hpp> | ||||||
| #include <kiwano/base/Component.h> | #include <kiwano/base/Component.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  |  | ||||||
|  | @ -33,8 +33,9 @@ namespace kiwano | ||||||
| 		{ | 		{ | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		void ImGuiLayer::OnRender() | 		void ImGuiLayer::OnRender(Renderer* renderer) | ||||||
| 		{ | 		{ | ||||||
|  | 			PrepareRender(renderer); | ||||||
| 			for (const auto& pipeline : pipelines_) | 			for (const auto& pipeline : pipelines_) | ||||||
| 			{ | 			{ | ||||||
| 				pipeline.second(); | 				pipeline.second(); | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		KGE_DECLARE_SMART_PTR(ImGuiLayer); | 		KGE_DECLARE_SMART_PTR(ImGuiLayer); | ||||||
| 
 | 
 | ||||||
| 		using ImGuiPipeline = Closure<void()>; | 		using ImGuiPipeline = Function<void()>; | ||||||
| 
 | 
 | ||||||
| 		class ImGuiLayer | 		class ImGuiLayer | ||||||
| 			: public Layer | 			: public Layer | ||||||
|  | @ -52,7 +52,7 @@ namespace kiwano | ||||||
| 			void RemoveAllItems(); | 			void RemoveAllItems(); | ||||||
| 
 | 
 | ||||||
| 		public: | 		public: | ||||||
| 			void OnRender() override; | 			void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 		protected: | 		protected: | ||||||
| 			Map<String, ImGuiPipeline> pipelines_; | 			Map<String, ImGuiPipeline> pipelines_; | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| // Copyright (C) 2019 Nomango
 | // Copyright (C) 2019 Nomango
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/common/helper.h> | #include <kiwano/core/core.h> | ||||||
| #include <kiwano/common/Closure.hpp> | #include <kiwano/core/Function.hpp> | ||||||
| #include <kiwano/common/IntrusivePtr.hpp> | #include <kiwano/core/intrusive_ptr.hpp> | ||||||
| #include <kiwano/base/Window.h> | #include <kiwano/base/Window.h> | ||||||
| #include <kiwano/base/Input.h> | #include <kiwano/base/Input.h> | ||||||
| #include <kiwano/renderer/render.h> | #include <kiwano/renderer/Renderer.h> | ||||||
| #include "ImGuiModule.h" | #include "ImGuiModule.h" | ||||||
| #include "imgui_impl.h" | #include "imgui_impl.h" | ||||||
| 
 | 
 | ||||||
|  | @ -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() | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/base/Component.h> | #include <kiwano/base/Component.h> | ||||||
| #include <kiwano/common/Singleton.hpp> | #include <kiwano/core/singleton.hpp> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ struct VERTEX_CONSTANT_BUFFER | ||||||
|     float   mvp[4][4]; |     float   mvp[4][4]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Render function
 | // Render Function
 | ||||||
| // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 | ||||||
| void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| // dear imgui: Renderer for Kiwano (DirectX11)
 | // dear imgui: Renderer for Kiwano (DirectX11)
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/base/logs.h> | #include <kiwano/base/Logger.h> | ||||||
| #include "imgui_impl_dx11.h" | #include "imgui_impl_dx11.h" | ||||||
| 
 | 
 | ||||||
| // DirectX
 | // DirectX
 | ||||||
|  | @ -36,7 +36,7 @@ struct VERTEX_CONSTANT_BUFFER | ||||||
|     float   mvp[4][4]; |     float   mvp[4][4]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Render function
 | // Render Function
 | ||||||
| // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 | ||||||
| void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/base/logs.h> | #include <kiwano/base/Logger.h> | ||||||
| #include <kiwano/platform/Application.h> | #include <kiwano/platform/Application.h> | ||||||
| #include "helper.h" | #include "helper.h" | ||||||
| #include "HttpRequest.hpp" | #include "HttpRequest.hpp" | ||||||
|  | @ -105,7 +105,7 @@ namespace | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		bool Init(HttpClient* client, Array<kiwano::string> const& headers, kiwano::string const& url, kiwano::string* response_data, kiwano::string* response_header, char* error_buffer) | 		bool Init(HttpClient* client, Vector<kiwano::string> const& headers, kiwano::string const& url, kiwano::string* response_data, kiwano::string* response_header, char* error_buffer) | ||||||
| 		{ | 		{ | ||||||
| 			if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) | 			if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) | ||||||
| 				return false; | 				return false; | ||||||
|  | @ -171,7 +171,7 @@ namespace | ||||||
| 	public: | 	public: | ||||||
| 		static inline bool GetRequest( | 		static inline bool GetRequest( | ||||||
| 			HttpClient* client, | 			HttpClient* client, | ||||||
| 			Array<kiwano::string> const& headers, | 			Vector<kiwano::string> const& headers, | ||||||
| 			kiwano::string const& url, | 			kiwano::string const& url, | ||||||
| 			long* response_code, | 			long* response_code, | ||||||
| 			kiwano::string* response_data, | 			kiwano::string* response_data, | ||||||
|  | @ -186,7 +186,7 @@ namespace | ||||||
| 
 | 
 | ||||||
| 		static inline bool PostRequest( | 		static inline bool PostRequest( | ||||||
| 			HttpClient* client, | 			HttpClient* client, | ||||||
| 			Array<kiwano::string> const& headers, | 			Vector<kiwano::string> const& headers, | ||||||
| 			kiwano::string const& url, | 			kiwano::string const& url, | ||||||
| 			kiwano::string const& request_data, | 			kiwano::string const& request_data, | ||||||
| 			long* response_code, | 			long* response_code, | ||||||
|  | @ -204,7 +204,7 @@ namespace | ||||||
| 
 | 
 | ||||||
| 		static inline bool PutRequest( | 		static inline bool PutRequest( | ||||||
| 			HttpClient* client, | 			HttpClient* client, | ||||||
| 			Array<kiwano::string> const& headers, | 			Vector<kiwano::string> const& headers, | ||||||
| 			kiwano::string const& url, | 			kiwano::string const& url, | ||||||
| 			kiwano::string const& request_data, | 			kiwano::string const& request_data, | ||||||
| 			long* response_code, | 			long* response_code, | ||||||
|  | @ -222,7 +222,7 @@ namespace | ||||||
| 
 | 
 | ||||||
| 		static inline bool DeleteRequest( | 		static inline bool DeleteRequest( | ||||||
| 			HttpClient* client, | 			HttpClient* client, | ||||||
| 			Array<kiwano::string> const& headers, | 			Vector<kiwano::string> const& headers, | ||||||
| 			kiwano::string const& url, | 			kiwano::string const& url, | ||||||
| 			long* response_code, | 			long* response_code, | ||||||
| 			kiwano::string* response_data, | 			kiwano::string* response_data, | ||||||
|  | @ -256,7 +256,7 @@ namespace kiwano | ||||||
| 		{ | 		{ | ||||||
| 			::curl_global_init(CURL_GLOBAL_ALL); | 			::curl_global_init(CURL_GLOBAL_ALL); | ||||||
| 
 | 
 | ||||||
| 			std::thread thread(MakeClosure(this, &HttpClient::NetworkThread)); | 			std::thread thread(bind_func(this, &HttpClient::NetworkThread)); | ||||||
| 			thread.detach(); | 			thread.detach(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -299,7 +299,7 @@ namespace kiwano | ||||||
| 				response_queue_.push(response); | 				response_queue_.push(response); | ||||||
| 				response_mutex_.unlock(); | 				response_mutex_.unlock(); | ||||||
| 
 | 
 | ||||||
| 				Application::PreformInMainThread(MakeClosure(this, &HttpClient::DispatchResponseCallback)); | 				Application::PreformInMainThread(bind_func(this, &HttpClient::DispatchResponseCallback)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -314,7 +314,7 @@ namespace kiwano | ||||||
| 			kiwano::string url = convert_to_utf8(request->GetUrl()); | 			kiwano::string url = convert_to_utf8(request->GetUrl()); | ||||||
| 			kiwano::string data = convert_to_utf8(request->GetData()); | 			kiwano::string data = convert_to_utf8(request->GetData()); | ||||||
| 
 | 
 | ||||||
| 			Array<kiwano::string> headers; | 			Vector<kiwano::string> headers; | ||||||
| 			headers.reserve(request->GetHeaders().size()); | 			headers.reserve(request->GetHeaders().size()); | ||||||
| 			for (const auto& pair : request->GetHeaders()) | 			for (const auto& pair : request->GetHeaders()) | ||||||
| 			{ | 			{ | ||||||
|  |  | ||||||
|  | @ -19,8 +19,8 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/common/helper.h> | #include <kiwano/core/core.h> | ||||||
| #include <kiwano/common/Singleton.hpp> | #include <kiwano/core/singleton.hpp> | ||||||
| #include <kiwano/base/Component.h> | #include <kiwano/base/Component.h> | ||||||
| #include <mutex> | #include <mutex> | ||||||
| #include <condition_variable> | #include <condition_variable> | ||||||
|  |  | ||||||
|  | @ -19,15 +19,15 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/common/Closure.hpp> | #include <kiwano/core/Function.hpp> | ||||||
| #include <kiwano/common/Json.hpp> | #include <kiwano/core/basic_json.hpp> | ||||||
| #include <kiwano/base/Object.h> | #include <kiwano/base/Object.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	namespace network | 	namespace network | ||||||
| 	{ | 	{ | ||||||
| 		typedef Closure<void(HttpRequestPtr, HttpResponsePtr)> ResponseCallback; | 		typedef Function<void(HttpRequestPtr, HttpResponsePtr)> ResponseCallback; | ||||||
| 
 | 
 | ||||||
| 		class KGE_API HttpRequest | 		class KGE_API HttpRequest | ||||||
| 			: public Object | 			: public Object | ||||||
|  |  | ||||||
|  | @ -19,8 +19,8 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/common/Closure.hpp> | #include <kiwano/core/Function.hpp> | ||||||
| #include <kiwano/common/Json.hpp> | #include <kiwano/core/basic_json.hpp> | ||||||
| #include <kiwano/base/Object.h> | #include <kiwano/base/Object.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  |  | ||||||
|  | @ -19,10 +19,9 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "Action.h" |  | ||||||
| #include "Stage.h" | #include "Stage.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -72,66 +71,70 @@ namespace kiwano | ||||||
| 			OnUpdate(dt); | 			OnUpdate(dt); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (!children_.IsEmpty()) | 		if (!children_.is_empty()) | ||||||
| 		{ | 		{ | ||||||
| 			ActorPtr next; | 			ActorPtr next; | ||||||
| 			for (auto child = children_.First(); child; child = next) | 			for (auto child = children_.first_item(); child; child = next) | ||||||
| 			{ | 			{ | ||||||
| 				next = child->NextItem(); | 				next = child->next_item(); | ||||||
| 				child->Update(dt); | 				child->Update(dt); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Actor::Render() | 	void Actor::Render(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		if (!visible_) | 		if (!visible_) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		UpdateTransform(); | 		UpdateTransform(); | ||||||
| 
 | 
 | ||||||
| 		if (children_.IsEmpty()) | 		if (children_.is_empty()) | ||||||
| 		{ | 		{ | ||||||
| 			PrepareRender(); | 			OnRender(renderer); | ||||||
| 			OnRender(); |  | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			// render children those are less than 0 in Z-Order
 | 			// render children those are less than 0 in Z-Order
 | ||||||
| 			Actor* child = children_.First().Get(); | 			Actor* child = children_.first_item().get(); | ||||||
| 			while (child) | 			while (child) | ||||||
| 			{ | 			{ | ||||||
| 				if (child->GetZOrder() >= 0) | 				if (child->GetZOrder() >= 0) | ||||||
| 					break; | 					break; | ||||||
| 
 | 
 | ||||||
| 				child->Render(); | 				child->Render(renderer); | ||||||
| 				child = child->NextItem().Get(); | 				child = child->next_item().get(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			PrepareRender(); | 			OnRender(renderer); | ||||||
| 			OnRender(); |  | ||||||
| 
 | 
 | ||||||
| 			while (child) | 			while (child) | ||||||
| 			{ | 			{ | ||||||
| 				child->Render(); | 				child->Render(renderer); | ||||||
| 				child = child->NextItem().Get(); | 				child = child->next_item().get(); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void Actor::PrepareRender(Renderer* renderer) | ||||||
|  | 	{ | ||||||
|  | 		renderer->SetTransform(transform_matrix_); | ||||||
|  | 		renderer->SetOpacity(displayed_opacity_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void Actor::RenderBorder() | 	void Actor::RenderBorder() | ||||||
| 	{ | 	{ | ||||||
| 		if (show_border_) | 		if (show_border_) | ||||||
| 		{ | 		{ | ||||||
|             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); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto child = children_.First(); child; child = child->NextItem()) | 		for (auto child = children_.first_item(); child; child = child->next_item()) | ||||||
| 		{ | 		{ | ||||||
| 			child->RenderBorder(); | 			child->RenderBorder(); | ||||||
| 		} | 		} | ||||||
|  | @ -143,9 +146,9 @@ namespace kiwano | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		ActorPtr prev; | 		ActorPtr prev; | ||||||
| 		for (auto child = children_.Last(); child; child = prev) | 		for (auto child = children_.last_item(); child; child = prev) | ||||||
| 		{ | 		{ | ||||||
| 			prev = child->PrevItem(); | 			prev = child->prev_item(); | ||||||
| 			child->Dispatch(evt); | 			child->Dispatch(evt); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -198,13 +201,13 @@ namespace kiwano | ||||||
| 		EventDispatcher::Dispatch(evt); | 		EventDispatcher::Dispatch(evt); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Matrix const & Actor::GetTransformMatrix()  const | 	Matrix3x2 const & Actor::GetTransformMatrix()  const | ||||||
| 	{ | 	{ | ||||||
| 		UpdateTransform(); | 		UpdateTransform(); | ||||||
| 		return transform_matrix_; | 		return transform_matrix_; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Matrix const & Actor::GetTransformInverseMatrix()  const | 	Matrix3x2 const & Actor::GetTransformInverseMatrix()  const | ||||||
| 	{ | 	{ | ||||||
| 		UpdateTransform(); | 		UpdateTransform(); | ||||||
| 		if (dirty_transform_inverse_) | 		if (dirty_transform_inverse_) | ||||||
|  | @ -225,16 +228,16 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (is_fast_transform_) | 		if (is_fast_transform_) | ||||||
| 		{ | 		{ | ||||||
| 			transform_matrix_ = Matrix::Translation(transform_.position); | 			transform_matrix_ = Matrix3x2::Translation(transform_.position); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			// matrix multiplication is optimized by expression template
 | 			// matrix multiplication is optimized by expression template
 | ||||||
|             transform_matrix_ = Matrix::SRT(transform_.position, transform_.scale, transform_.rotation); |             transform_matrix_ = Matrix3x2::SRT(transform_.position, transform_.scale, transform_.rotation); | ||||||
| 
 | 
 | ||||||
|             if (!transform_.skew.IsOrigin()) |             if (!transform_.skew.IsOrigin()) | ||||||
|             { |             { | ||||||
|                 transform_matrix_ = Matrix::Skewing(transform_.skew) * transform_matrix_; |                 transform_matrix_ = Matrix3x2::Skewing(transform_.skew) * transform_matrix_; | ||||||
|             } |             } | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -246,7 +249,7 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// update children's transform
 | 		// update children's transform
 | ||||||
| 		for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) | 		for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) | ||||||
| 			child->dirty_transform_ = true; | 			child->dirty_transform_ = true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -261,7 +264,7 @@ namespace kiwano | ||||||
| 			displayed_opacity_ = opacity_; | 			displayed_opacity_ = opacity_; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) | 		for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			child->UpdateOpacity(); | 			child->UpdateOpacity(); | ||||||
| 		} | 		} | ||||||
|  | @ -272,7 +275,7 @@ namespace kiwano | ||||||
| 		if (scene && stage_ != scene) | 		if (scene && stage_ != scene) | ||||||
| 		{ | 		{ | ||||||
| 			stage_ = scene; | 			stage_ = scene; | ||||||
| 			for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) | 			for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) | ||||||
| 			{ | 			{ | ||||||
| 				child->stage_ = scene; | 				child->stage_ = scene; | ||||||
| 			} | 			} | ||||||
|  | @ -285,28 +288,28 @@ namespace kiwano | ||||||
| 		{ | 		{ | ||||||
| 			ActorPtr me = this; | 			ActorPtr me = this; | ||||||
| 
 | 
 | ||||||
| 			parent_->children_.Remove(me); | 			parent_->children_.remove_item(me); | ||||||
| 
 | 
 | ||||||
| 			Actor* sibling = parent_->children_.Last().Get(); | 			Actor* sibling = parent_->children_.last_item().get(); | ||||||
| 
 | 
 | ||||||
| 			if (sibling && sibling->GetZOrder() > z_order_) | 			if (sibling && sibling->GetZOrder() > z_order_) | ||||||
| 			{ | 			{ | ||||||
| 				sibling = sibling->PrevItem().Get(); | 				sibling = sibling->prev_item().get(); | ||||||
| 				while (sibling) | 				while (sibling) | ||||||
| 				{ | 				{ | ||||||
| 					if (sibling->GetZOrder() <= z_order_) | 					if (sibling->GetZOrder() <= z_order_) | ||||||
| 						break; | 						break; | ||||||
| 					sibling = sibling->PrevItem().Get(); | 					sibling = sibling->prev_item().get(); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (sibling) | 			if (sibling) | ||||||
| 			{ | 			{ | ||||||
| 				parent_->children_.InsertAfter(me, sibling); | 				parent_->children_.insert_after(me, sibling); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				parent_->children_.PushFront(me); | 				parent_->children_.push_front_item(me); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -520,15 +523,15 @@ namespace kiwano | ||||||
| #ifdef KGE_DEBUG | #ifdef KGE_DEBUG | ||||||
| 
 | 
 | ||||||
| 			if (child->parent_) | 			if (child->parent_) | ||||||
| 				KGE_ERROR_LOG(L"The node to be added already has a parent"); | 				KGE_ERROR_LOG(L"The actor to be added already has a parent"); | ||||||
| 
 | 
 | ||||||
| 			for (Actor* parent = parent_; parent; parent = parent->parent_) | 			for (Actor* parent = parent_; parent; parent = parent->parent_) | ||||||
| 				if (parent == child) | 				if (parent == child) | ||||||
| 					KGE_ERROR_LOG(L"A node cannot be its own parent"); | 					KGE_ERROR_LOG(L"A actor cannot be its own parent"); | ||||||
| 
 | 
 | ||||||
| #endif // KGE_DEBUG
 | #endif // KGE_DEBUG
 | ||||||
| 
 | 
 | ||||||
| 			children_.PushBack(child); | 			children_.push_back_item(child); | ||||||
| 			child->parent_ = this; | 			child->parent_ = this; | ||||||
| 			child->SetStage(this->stage_); | 			child->SetStage(this->stage_); | ||||||
| 			child->dirty_transform_ = true; | 			child->dirty_transform_ = true; | ||||||
|  | @ -537,11 +540,11 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Actor::AddChildren(Array<ActorPtr> const& children) | 	void Actor::AddChildren(Vector<ActorPtr> const& children) | ||||||
| 	{ | 	{ | ||||||
| 		for (const auto& node : children) | 		for (const auto& actor : children) | ||||||
| 		{ | 		{ | ||||||
| 			this->AddChild(node); | 			this->AddChild(actor); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -555,12 +558,12 @@ namespace kiwano | ||||||
| 		return GetTransformMatrix().Transform(GetBounds()); | 		return GetTransformMatrix().Transform(GetBounds()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Array<ActorPtr> Actor::GetChildren(String const& name) const | 	Vector<ActorPtr> Actor::GetChildren(String const& name) const | ||||||
| 	{ | 	{ | ||||||
| 		Array<ActorPtr> children; | 		Vector<ActorPtr> children; | ||||||
| 		size_t hash_code = std::hash<String>{}(name); | 		size_t hash_code = std::hash<String>{}(name); | ||||||
| 
 | 
 | ||||||
| 		for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) | 		for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			if (child->hash_name_ == hash_code && child->IsName(name)) | 			if (child->hash_name_ == hash_code && child->IsName(name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -574,7 +577,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		size_t hash_code = std::hash<String>{}(name); | 		size_t hash_code = std::hash<String>{}(name); | ||||||
| 
 | 
 | ||||||
| 		for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) | 		for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			if (child->hash_name_ == hash_code && child->IsName(name)) | 			if (child->hash_name_ == hash_code && child->IsName(name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -599,27 +602,27 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void Actor::RemoveChild(ActorPtr child) | 	void Actor::RemoveChild(ActorPtr child) | ||||||
| 	{ | 	{ | ||||||
| 		RemoveChild(child.Get()); | 		RemoveChild(child.get()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Actor::RemoveChild(Actor * child) | 	void Actor::RemoveChild(Actor * child) | ||||||
| 	{ | 	{ | ||||||
| 		KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception"); | 		KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception"); | ||||||
| 
 | 
 | ||||||
| 		if (children_.IsEmpty()) | 		if (children_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		if (child) | 		if (child) | ||||||
| 		{ | 		{ | ||||||
| 			child->parent_ = nullptr; | 			child->parent_ = nullptr; | ||||||
| 			if (child->stage_) child->SetStage(nullptr); | 			if (child->stage_) child->SetStage(nullptr); | ||||||
| 			children_.Remove(ActorPtr(child)); | 			children_.remove_item(ActorPtr(child)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Actor::RemoveChildren(String const& child_name) | 	void Actor::RemoveChildren(String const& child_name) | ||||||
| 	{ | 	{ | ||||||
| 		if (children_.IsEmpty()) | 		if (children_.is_empty()) | ||||||
| 		{ | 		{ | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  | @ -627,9 +630,9 @@ namespace kiwano | ||||||
| 		size_t hash_code = std::hash<String>{}(child_name); | 		size_t hash_code = std::hash<String>{}(child_name); | ||||||
| 
 | 
 | ||||||
| 		Actor* next; | 		Actor* next; | ||||||
| 		for (Actor* child = children_.First().Get(); child; child = next) | 		for (Actor* child = children_.first_item().get(); child; child = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = child->NextItem().Get(); | 			next = child->next_item().get(); | ||||||
| 
 | 
 | ||||||
| 			if (child->hash_name_ == hash_code && child->IsName(child_name)) | 			if (child->hash_name_ == hash_code && child->IsName(child_name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -640,7 +643,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void Actor::RemoveAllChildren() | 	void Actor::RemoveAllChildren() | ||||||
| 	{ | 	{ | ||||||
| 		children_.Clear(); | 		children_.clear_items(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Actor::SetResponsible(bool enable) | 	void Actor::SetResponsible(bool enable) | ||||||
|  | @ -657,12 +660,4 @@ namespace kiwano | ||||||
| 		return GetBounds().ContainsPoint(local); | 		return GetBounds().ContainsPoint(local); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	void VisualNode::PrepareRender() |  | ||||||
| 	{ |  | ||||||
|         auto renderer = Renderer::Instance(); |  | ||||||
|         renderer->SetTransform(transform_matrix_); |  | ||||||
|         renderer->SetOpacity(displayed_opacity_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -21,13 +21,14 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "include-forwards.h" | #include "include-forwards.h" | ||||||
| #include "Transform.hpp" | #include "Transform.hpp" | ||||||
| #include "ActionManager.h" | #include "action/ActionManager.h" | ||||||
| #include "../base/TimerManager.h" | #include "../base/TimerManager.h" | ||||||
| #include "../base/EventDispatcher.h" | #include "../base/EventDispatcher.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	class Director; | 	class Director; | ||||||
|  | 	class Renderer; | ||||||
| 
 | 
 | ||||||
| 	// 角色
 | 	// 角色
 | ||||||
| 	class KGE_API Actor | 	class KGE_API Actor | ||||||
|  | @ -35,14 +36,14 @@ namespace kiwano | ||||||
| 		, public TimerManager | 		, public TimerManager | ||||||
| 		, public ActionManager | 		, public ActionManager | ||||||
| 		, public EventDispatcher | 		, public EventDispatcher | ||||||
| 		, public IntrusiveListItem<ActorPtr> | 		, public intrusive_list_item<ActorPtr> | ||||||
| 	{ | 	{ | ||||||
| 		friend class Director; | 		friend class Director; | ||||||
| 		friend class Transition; | 		friend class Transition; | ||||||
| 		friend class IntrusiveList<ActorPtr>; | 		friend class intrusive_list<ActorPtr>; | ||||||
| 
 | 
 | ||||||
| 		using Children = IntrusiveList<ActorPtr>; | 		using Children = intrusive_list<ActorPtr>; | ||||||
| 		using UpdateCallback = Closure<void(Duration)>; | 		using UpdateCallback = Function<void(Duration)>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		Actor(); | 		Actor(); | ||||||
|  | @ -51,7 +52,7 @@ namespace kiwano | ||||||
| 		virtual void OnUpdate(Duration dt) { KGE_UNUSED(dt); } | 		virtual void OnUpdate(Duration dt) { KGE_UNUSED(dt); } | ||||||
| 
 | 
 | ||||||
| 		// 渲染角色
 | 		// 渲染角色
 | ||||||
| 		virtual void OnRender() {} | 		virtual void OnRender(Renderer* renderer) { KGE_UNUSED(renderer); } | ||||||
| 
 | 
 | ||||||
| 		// 获取显示状态
 | 		// 获取显示状态
 | ||||||
| 		bool IsVisible()				const	{ return visible_; } | 		bool IsVisible()				const	{ return visible_; } | ||||||
|  | @ -77,7 +78,7 @@ namespace kiwano | ||||||
| 		// 获取 y 坐标
 | 		// 获取 y 坐标
 | ||||||
| 		float GetPositionY()			const	{ return transform_.position.y; } | 		float GetPositionY()			const	{ return transform_.position.y; } | ||||||
| 
 | 
 | ||||||
| 		// 获取横向缩放比例
 | 		// »ñÈ¡Ëõ·Å±ÈÀý
 | ||||||
| 		Point GetScale()				const	{ return transform_.scale; } | 		Point GetScale()				const	{ return transform_.scale; } | ||||||
| 
 | 
 | ||||||
| 		// 获取横向缩放比例
 | 		// 获取横向缩放比例
 | ||||||
|  | @ -135,16 +136,16 @@ namespace kiwano | ||||||
| 		Transform GetTransform()		const	{ return transform_; } | 		Transform GetTransform()		const	{ return transform_; } | ||||||
| 
 | 
 | ||||||
| 		// 获取边框
 | 		// 获取边框
 | ||||||
| 		Rect GetBounds() const; | 		virtual Rect GetBounds() const; | ||||||
| 
 | 
 | ||||||
| 		// 获取外切包围盒
 | 		// 获取外切包围盒
 | ||||||
| 		Rect GetBoundingBox() const; | 		virtual Rect GetBoundingBox() const; | ||||||
| 
 | 
 | ||||||
| 		// 获取二维变换矩阵
 | 		// 获取二维变换矩阵
 | ||||||
| 		Matrix const& GetTransformMatrix()  const; | 		Matrix3x2 const& GetTransformMatrix()  const; | ||||||
| 
 | 
 | ||||||
| 		// 获取二维变换的逆矩阵
 | 		// 获取二维变换的逆矩阵
 | ||||||
| 		Matrix const& GetTransformInverseMatrix()  const; | 		Matrix3x2 const& GetTransformInverseMatrix()  const; | ||||||
| 
 | 
 | ||||||
| 		// 获取父角色
 | 		// 获取父角色
 | ||||||
| 		inline Actor* GetParent() const { return parent_; } | 		inline Actor* GetParent() const { return parent_; } | ||||||
|  | @ -342,11 +343,11 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		// 添加多个子角色
 | 		// 添加多个子角色
 | ||||||
| 		void AddChildren( | 		void AddChildren( | ||||||
| 			Array<ActorPtr> const& children | 			Vector<ActorPtr> const& children | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 获取所有名称相同的子角色
 | 		// 获取所有名称相同的子角色
 | ||||||
| 		Array<ActorPtr> GetChildren( | 		Vector<ActorPtr> GetChildren( | ||||||
| 			String const& name | 			String const& name | ||||||
| 		) const; | 		) const; | ||||||
| 
 | 
 | ||||||
|  | @ -379,6 +380,9 @@ namespace kiwano | ||||||
| 		// 从父角色移除
 | 		// 从父角色移除
 | ||||||
| 		void RemoveFromParent(); | 		void RemoveFromParent(); | ||||||
| 
 | 
 | ||||||
|  | 		// ʼþ·Ö·¢
 | ||||||
|  | 		void Dispatch(Event& evt) override; | ||||||
|  | 
 | ||||||
| 		// 暂停角色更新
 | 		// 暂停角色更新
 | ||||||
| 		inline void PauseUpdating()									{ update_pausing_ = true; } | 		inline void PauseUpdating()									{ update_pausing_ = true; } | ||||||
| 
 | 
 | ||||||
|  | @ -403,16 +407,12 @@ namespace kiwano | ||||||
| 			float anchor_y | 			float anchor_y | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 	public: |  | ||||||
| 		// 事件分发
 |  | ||||||
| 		void Dispatch(Event& evt) override; |  | ||||||
| 
 |  | ||||||
| 	protected: | 	protected: | ||||||
| 		virtual void PrepareRender() {} |  | ||||||
| 
 |  | ||||||
| 		virtual void Update(Duration dt); | 		virtual void Update(Duration dt); | ||||||
| 
 | 
 | ||||||
| 		virtual void Render(); | 		virtual void Render(Renderer* renderer); | ||||||
|  | 
 | ||||||
|  | 		void PrepareRender(Renderer* renderer); | ||||||
| 
 | 
 | ||||||
| 		void RenderBorder(); | 		void RenderBorder(); | ||||||
| 
 | 
 | ||||||
|  | @ -447,17 +447,8 @@ namespace kiwano | ||||||
| 		bool			is_fast_transform_; | 		bool			is_fast_transform_; | ||||||
| 		mutable bool	dirty_transform_; | 		mutable bool	dirty_transform_; | ||||||
| 		mutable bool	dirty_transform_inverse_; | 		mutable bool	dirty_transform_inverse_; | ||||||
| 		mutable Matrix	transform_matrix_; | 		mutable Matrix3x2	transform_matrix_; | ||||||
| 		mutable Matrix	transform_matrix_inverse_; | 		mutable Matrix3x2	transform_matrix_inverse_; | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// 可视化角色
 |  | ||||||
| 	class KGE_API VisualNode |  | ||||||
| 		: public Actor |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		virtual void PrepareRender() override; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,9 +19,8 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Canvas.h" | #include "Canvas.h" | ||||||
| #include "Image.h" | #include "../base/Logger.h" | ||||||
| #include "../base/logs.h" | #include "../renderer/Renderer.h" | ||||||
| #include "../renderer/render.h" |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -29,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_) | ||||||
|  | @ -52,7 +51,7 @@ namespace kiwano | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			ITextRenderer::Create( | 			ITextRenderer::Create( | ||||||
| 				&text_renderer_, | 				&text_renderer_, | ||||||
| 				render_target_.Get() | 				render_target_.get() | ||||||
| 			) | 			) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | @ -87,7 +86,7 @@ namespace kiwano | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Canvas::OnRender() | 	void Canvas::OnRender(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		if (cache_expired_) | 		if (cache_expired_) | ||||||
| 		{ | 		{ | ||||||
|  | @ -96,8 +95,10 @@ namespace kiwano | ||||||
| 		 | 		 | ||||||
| 		if (bitmap_cached_) | 		if (bitmap_cached_) | ||||||
| 		{ | 		{ | ||||||
|  | 			PrepareRender(renderer); | ||||||
|  | 
 | ||||||
| 			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->DrawBitmap( | ||||||
| 				bitmap_cached_, | 				bitmap_cached_, | ||||||
| 				bitmap_rect, | 				bitmap_rect, | ||||||
| 				bitmap_rect | 				bitmap_rect | ||||||
|  | @ -122,7 +123,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) | ||||||
|  | @ -136,7 +137,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
 | ||||||
|  | @ -160,7 +161,7 @@ namespace kiwano | ||||||
| 		return stroke_width_; | 		return stroke_width_; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Canvas::SetBrushTransform(Matrix const & transform) | 	void Canvas::SetBrushTransform(Matrix3x2 const & transform) | ||||||
| 	{ | 	{ | ||||||
| 		render_target_->SetTransform(DX::ConvertToMatrix3x2F(transform)); | 		render_target_->SetTransform(DX::ConvertToMatrix3x2F(transform)); | ||||||
| 	} | 	} | ||||||
|  | @ -170,9 +171,9 @@ namespace kiwano | ||||||
| 		render_target_->DrawLine( | 		render_target_->DrawLine( | ||||||
| 			D2D1::Point2F(begin.x, begin.y), | 			D2D1::Point2F(begin.x, begin.y), | ||||||
| 			D2D1::Point2F(end.x, end.y), | 			D2D1::Point2F(end.x, end.y), | ||||||
| 			stroke_brush_.Get(), | 			stroke_brush_.get(), | ||||||
| 			stroke_width_, | 			stroke_width_, | ||||||
| 			outline_join_style_.Get() | 			outline_join_style_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -188,9 +189,9 @@ namespace kiwano | ||||||
| 				radius, | 				radius, | ||||||
| 				radius | 				radius | ||||||
| 			), | 			), | ||||||
| 			stroke_brush_.Get(), | 			stroke_brush_.get(), | ||||||
| 			stroke_width_, | 			stroke_width_, | ||||||
| 			outline_join_style_.Get() | 			outline_join_style_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -206,9 +207,9 @@ namespace kiwano | ||||||
| 				radius_x, | 				radius_x, | ||||||
| 				radius_y | 				radius_y | ||||||
| 			), | 			), | ||||||
| 			stroke_brush_.Get(), | 			stroke_brush_.get(), | ||||||
| 			stroke_width_, | 			stroke_width_, | ||||||
| 			outline_join_style_.Get() | 			outline_join_style_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -222,9 +223,9 @@ namespace kiwano | ||||||
| 				rect.origin.x + rect.size.x, | 				rect.origin.x + rect.size.x, | ||||||
| 				rect.origin.y + rect.size.y | 				rect.origin.y + rect.size.y | ||||||
| 			), | 			), | ||||||
| 			stroke_brush_.Get(), | 			stroke_brush_.get(), | ||||||
| 			stroke_width_, | 			stroke_width_, | ||||||
| 			outline_join_style_.Get() | 			outline_join_style_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -242,9 +243,9 @@ namespace kiwano | ||||||
| 				radius_x, | 				radius_x, | ||||||
| 				radius_y | 				radius_y | ||||||
| 			), | 			), | ||||||
| 			stroke_brush_.Get(), | 			stroke_brush_.get(), | ||||||
| 			stroke_width_, | 			stroke_width_, | ||||||
| 			outline_join_style_.Get() | 			outline_join_style_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -254,11 +255,11 @@ namespace kiwano | ||||||
| 		if (image && image->GetBitmap()) | 		if (image && image->GetBitmap()) | ||||||
| 		{ | 		{ | ||||||
| 			render_target_->DrawBitmap( | 			render_target_->DrawBitmap( | ||||||
| 				image->GetBitmap().Get(), | 				image->GetBitmap().get(), | ||||||
| 				D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()), | 				D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()), | ||||||
| 				opacity, | 				opacity, | ||||||
| 				D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | 				D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | ||||||
| 				DX::ConvertToRectF(image->GetCropRect()) | 				D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()) | ||||||
| 			); | 			); | ||||||
| 			cache_expired_ = true; | 			cache_expired_ = true; | ||||||
| 		} | 		} | ||||||
|  | @ -272,7 +273,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_ | ||||||
|  | @ -283,7 +284,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, | ||||||
|  | @ -293,7 +294,7 @@ namespace kiwano | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		ThrowIfFailed( | 		ThrowIfFailed( | ||||||
| 			text_layout->Draw(nullptr, text_renderer_.Get(), point.x, point.y) | 			text_layout->Draw(nullptr, text_renderer_.get(), point.x, point.y) | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -308,7 +309,7 @@ namespace kiwano | ||||||
| 				radius, | 				radius, | ||||||
| 				radius | 				radius | ||||||
| 			), | 			), | ||||||
| 			fill_brush_.Get() | 			fill_brush_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -324,7 +325,7 @@ namespace kiwano | ||||||
| 				radius_x, | 				radius_x, | ||||||
| 				radius_y | 				radius_y | ||||||
| 			), | 			), | ||||||
| 			fill_brush_.Get() | 			fill_brush_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -338,7 +339,7 @@ namespace kiwano | ||||||
| 				rect.origin.x + rect.size.x, | 				rect.origin.x + rect.size.x, | ||||||
| 				rect.origin.y + rect.size.y | 				rect.origin.y + rect.size.y | ||||||
| 			), | 			), | ||||||
| 			fill_brush_.Get() | 			fill_brush_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -356,7 +357,7 @@ namespace kiwano | ||||||
| 				radius_x, | 				radius_x, | ||||||
| 				radius_y | 				radius_y | ||||||
| 			), | 			), | ||||||
| 			fill_brush_.Get() | 			fill_brush_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -366,7 +367,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( | ||||||
|  | @ -394,7 +395,7 @@ namespace kiwano | ||||||
| 			current_sink_->AddLine(DX::ConvertToPoint2F(point)); | 			current_sink_->AddLine(DX::ConvertToPoint2F(point)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Canvas::AddLines(Array<Point> const& points) | 	void Canvas::AddLines(Vector<Point> const& points) | ||||||
| 	{ | 	{ | ||||||
| 		if (current_sink_ && !points.empty()) | 		if (current_sink_ && !points.empty()) | ||||||
| 		{ | 		{ | ||||||
|  | @ -438,10 +439,10 @@ namespace kiwano | ||||||
| 	void Canvas::StrokePath() | 	void Canvas::StrokePath() | ||||||
| 	{ | 	{ | ||||||
| 		render_target_->DrawGeometry( | 		render_target_->DrawGeometry( | ||||||
| 			current_geometry_.Get(), | 			current_geometry_.get(), | ||||||
| 			stroke_brush_.Get(), | 			stroke_brush_.get(), | ||||||
| 			stroke_width_, | 			stroke_width_, | ||||||
| 			outline_join_style_.Get() | 			outline_join_style_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -449,8 +450,8 @@ namespace kiwano | ||||||
| 	void Canvas::FillPath() | 	void Canvas::FillPath() | ||||||
| 	{ | 	{ | ||||||
| 		render_target_->FillGeometry( | 		render_target_->FillGeometry( | ||||||
| 			current_geometry_.Get(), | 			current_geometry_.get(), | ||||||
| 			fill_brush_.Get() | 			fill_brush_.get() | ||||||
| 		); | 		); | ||||||
| 		cache_expired_ = true; | 		cache_expired_ = true; | ||||||
| 	} | 	} | ||||||
|  | @ -463,8 +464,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	ImagePtr Canvas::ExportToImage() const | 	ImagePtr Canvas::ExportToImage() const | ||||||
| 	{ | 	{ | ||||||
| 		auto image = new Image(GetBitmap()); | 		ImagePtr image = new Image(GetBitmap()); | ||||||
| 		image->Crop(Rect(Point{}, this->GetSize())); |  | ||||||
| 		return image; | 		return image; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,15 +22,18 @@ | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "Font.hpp" | #include "Font.hpp" | ||||||
| #include "TextStyle.hpp" | #include "TextStyle.hpp" | ||||||
|  | #include "../renderer/Image.h" | ||||||
| #include "../renderer/TextRenderer.h" | #include "../renderer/TextRenderer.h" | ||||||
| 
 | 
 | ||||||
|  | #ifdef DrawText | ||||||
| #	undef DrawText | #	undef DrawText | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	// 画布
 | 	// 画布
 | ||||||
| 	class KGE_API Canvas | 	class KGE_API Canvas | ||||||
| 		: public VisualNode | 		: public Actor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		Canvas(); | 		Canvas(); | ||||||
|  | @ -137,7 +140,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		// 添加多条线段
 | 		// 添加多条线段
 | ||||||
| 		void AddLines( | 		void AddLines( | ||||||
| 			Array<Point> const& points | 			Vector<Point> const& points | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 添加一条三次方贝塞尔曲线
 | 		// 添加一条三次方贝塞尔曲线
 | ||||||
|  | @ -202,13 +205,13 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		// 变换画笔
 | 		// 变换画笔
 | ||||||
| 		void SetBrushTransform( | 		void SetBrushTransform( | ||||||
| 			Matrix const& transform | 			Matrix3x2 const& transform | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 导出为图片
 | 		// 导出为图片
 | ||||||
| 		ImagePtr ExportToImage() const; | 		ImagePtr ExportToImage() const; | ||||||
| 
 | 
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		ComPtr<ID2D1Bitmap> const& GetBitmap() const; | 		ComPtr<ID2D1Bitmap> const& GetBitmap() const; | ||||||
|  |  | ||||||
|  | @ -18,9 +18,9 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "DebugNode.h" | #include "DebugActor.h" | ||||||
| #include "Text.h" | #include "Text.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <psapi.h> | #include <psapi.h> | ||||||
| 
 | 
 | ||||||
|  | @ -28,10 +28,10 @@ | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	DebugNode::DebugNode() | 	DebugActor::DebugActor() | ||||||
| 		: background_color_(0.0f, 0.0f, 0.0f, 0.7f) | 		: background_color_(0.0f, 0.0f, 0.0f, 0.7f) | ||||||
| 	{ | 	{ | ||||||
| 		SetName(L"kiwano-debug-node"); | 		SetName(L"kiwano-debug-actor"); | ||||||
| 		SetPosition(10, 10); | 		SetPosition(10, 10); | ||||||
| 		SetResponsible(true); | 		SetResponsible(true); | ||||||
| 		SetCascadeOpacityEnabled(true); | 		SetCascadeOpacityEnabled(true); | ||||||
|  | @ -54,13 +54,13 @@ namespace kiwano | ||||||
| 		AddListener(Event::MouseOut, [=](const Event&) { SetOpacity(1.f); }); | 		AddListener(Event::MouseOut, [=](const Event&) { SetOpacity(1.f); }); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DebugNode::~DebugNode() | 	DebugActor::~DebugActor() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void DebugNode::OnRender() | 	void DebugActor::OnRender(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		auto renderer = Renderer::Instance(); | 		PrepareRender(renderer); | ||||||
| 
 | 
 | ||||||
| 		renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); | 		renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); | ||||||
| 		renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle( | 		renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle( | ||||||
|  | @ -69,7 +69,7 @@ namespace kiwano | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void DebugNode::OnUpdate(Duration dt) | 	void DebugActor::OnUpdate(Duration dt) | ||||||
| 	{ | 	{ | ||||||
| 		KGE_UNUSED(dt); | 		KGE_UNUSED(dt); | ||||||
| 
 | 
 | ||||||
|  | @ -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)); | ||||||
|  | @ -23,21 +23,21 @@ | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	class KGE_API DebugNode | 	class KGE_API DebugActor | ||||||
| 		: public VisualNode | 		: public Actor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		DebugNode(); | 		DebugActor(); | ||||||
| 
 | 
 | ||||||
| 		virtual ~DebugNode(); | 		virtual ~DebugActor(); | ||||||
| 
 | 
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 		void OnUpdate(Duration dt) override; | 		void OnUpdate(Duration dt) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Color		background_color_; | 		Color		background_color_; | ||||||
| 		TextPtr		debug_text_; | 		TextPtr		debug_text_; | ||||||
| 		Array<Time>	frame_time_; | 		Vector<Time>	frame_time_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  | @ -0,0 +1,73 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #include "Frame.h" | ||||||
|  | #include "../renderer/ImageCache.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	Frame::Frame() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Frame::Frame(Resource const& res) | ||||||
|  | 	{ | ||||||
|  | 		Load(res); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Frame::Frame(ImagePtr image) | ||||||
|  | 		: image_(image) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bool Frame::Load(Resource const& res) | ||||||
|  | 	{ | ||||||
|  | 		ImagePtr image = ImageCache::GetInstance()->AddImage(res); | ||||||
|  | 		if (image && image->IsValid()) | ||||||
|  | 		{ | ||||||
|  | 			SetImage(image); | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Frame::Crop(Rect const& crop_rect) | ||||||
|  | 	{ | ||||||
|  | 		if (image_) | ||||||
|  | 		{ | ||||||
|  | 			auto bitmap_size = image_->GetSize(); | ||||||
|  | 			crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.x); | ||||||
|  | 			crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.y); | ||||||
|  | 			crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.x - crop_rect.origin.x); | ||||||
|  | 			crop_rect_.size.y = std::min(std::max(crop_rect.size.y, 0.f), bitmap_size.y - crop_rect.origin.y); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Frame::SetImage(ImagePtr image) | ||||||
|  | 	{ | ||||||
|  | 		image_ = image; | ||||||
|  | 		if (image_) | ||||||
|  | 		{ | ||||||
|  | 			crop_rect_.origin.x = crop_rect_.origin.y = 0; | ||||||
|  | 			crop_rect_.size.x = image_->GetWidth(); | ||||||
|  | 			crop_rect_.size.y = image_->GetHeight(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,75 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "../renderer/Image.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	// ֡ͼÏñ
 | ||||||
|  | 	class KGE_API Frame | ||||||
|  | 		: public Object | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		Frame(); | ||||||
|  | 
 | ||||||
|  | 		explicit Frame( | ||||||
|  | 			Resource const& res | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		explicit Frame( | ||||||
|  | 			ImagePtr image | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		bool Load( | ||||||
|  | 			Resource const& res | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// ²Ã¼ô¾ØÐÎ
 | ||||||
|  | 		void Crop( | ||||||
|  | 			Rect const& crop_rect	/* ²Ã¼ô¾ØÐÎ */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// »ñÈ¡¿í¶È
 | ||||||
|  | 		float GetWidth() const					{ return crop_rect_.size.x; } | ||||||
|  | 
 | ||||||
|  | 		// »ñÈ¡¸ß¶È
 | ||||||
|  | 		float GetHeight() const					{ return crop_rect_.size.y; } | ||||||
|  | 
 | ||||||
|  | 		// »ñÈ¡´óС
 | ||||||
|  | 		Size GetSize() const					{ return crop_rect_.size; } | ||||||
|  | 
 | ||||||
|  | 		// »ñÈ¡²Ã¼ôλÖÃ
 | ||||||
|  | 		Point GetCropPoint() const				{ return crop_rect_.origin; } | ||||||
|  | 
 | ||||||
|  | 		// »ñÈ¡²Ã¼ô¾ØÐÎ
 | ||||||
|  | 		inline Rect const& GetCropRect() const	{ return crop_rect_; } | ||||||
|  | 
 | ||||||
|  | 		// »ñȡλͼ
 | ||||||
|  | 		inline ImagePtr GetImage() const		{ return image_; } | ||||||
|  | 
 | ||||||
|  | 		// ÉèÖÃλͼ
 | ||||||
|  | 		void SetImage(ImagePtr image); | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		ImagePtr image_; | ||||||
|  | 		Rect crop_rect_; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | @ -18,28 +18,28 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Frames.h" | #include "FrameSequence.h" | ||||||
| #include "Image.h" | #include "Frame.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	Frames::Frames() | 	FrameSequence::FrameSequence() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Frames::Frames(Array<ImagePtr> const& frames) | 	FrameSequence::FrameSequence(Vector<FramePtr> const& frames) | ||||||
| 	{ | 	{ | ||||||
| 		this->Add(frames); | 		this->AddFrames(frames); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Frames::~Frames() | 	FrameSequence::~FrameSequence() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Frames::Add(ImagePtr frame) | 	void FrameSequence::AddFrame(FramePtr frame) | ||||||
| 	{ | 	{ | ||||||
| 		KGE_ASSERT(frame && "Frames::Add failed, NULL pointer exception"); | 		KGE_ASSERT(frame && "FrameSequence::Add failed, NULL pointer exception"); | ||||||
| 
 | 
 | ||||||
| 		if (frame) | 		if (frame) | ||||||
| 		{ | 		{ | ||||||
|  | @ -47,7 +47,7 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Frames::Add(Array<ImagePtr> const& frames) | 	void FrameSequence::AddFrames(Vector<FramePtr> const& frames) | ||||||
| 	{ | 	{ | ||||||
| 		if (frames_.empty()) | 		if (frames_.empty()) | ||||||
| 			frames_ = frames; | 			frames_ = frames; | ||||||
|  | @ -55,40 +55,43 @@ namespace kiwano | ||||||
| 		{ | 		{ | ||||||
| 			frames_.reserve(frames_.size() + frames.size()); | 			frames_.reserve(frames_.size() + frames.size()); | ||||||
| 			for (const auto& image : frames) | 			for (const auto& image : frames) | ||||||
| 				Add(image); | 				AddFrame(image); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Array<ImagePtr> const& Frames::GetFrames() const | 	FramePtr FrameSequence::GetFrame(size_t index) const | ||||||
|  | 	{ | ||||||
|  | 		KGE_ASSERT(index < frames_.size()); | ||||||
|  | 		return frames_[index]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Vector<FramePtr> const& FrameSequence::GetFrames() const | ||||||
| 	{ | 	{ | ||||||
| 		return frames_; | 		return frames_; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	FramesPtr Frames::Clone() const | 	FrameSequencePtr FrameSequence::Clone() const | ||||||
| 	{ | 	{ | ||||||
| 		auto animation = new (std::nothrow) Frames; | 		auto frame_seq = new (std::nothrow) FrameSequence; | ||||||
| 		if (animation) | 		if (frame_seq) | ||||||
| 		{ | 		{ | ||||||
| 			for (const auto& frame : frames_) | 			frame_seq->AddFrames(frames_); | ||||||
| 			{ |  | ||||||
| 				animation->Add(frame); |  | ||||||
| 		} | 		} | ||||||
| 		} | 		return frame_seq; | ||||||
| 		return animation; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	FramesPtr Frames::Reverse() const | 	FrameSequencePtr FrameSequence::Reverse() const | ||||||
| 	{ | 	{ | ||||||
| 		auto animation = new (std::nothrow) Frames; | 		auto frame_seq = new (std::nothrow) FrameSequence; | ||||||
| 		if (!frames_.empty()) | 		if (!frames_.empty()) | ||||||
| 		{ | 		{ | ||||||
| 			for (auto iter = frames_.crbegin(), crend = frames_.crend(); iter != crend; ++iter) | 			for (auto iter = frames_.crbegin(), crend = frames_.crend(); iter != crend; ++iter) | ||||||
| 			{ | 			{ | ||||||
| 				if (*iter) | 				if (*iter) | ||||||
| 					animation->Add(*iter); | 					frame_seq->AddFrame(*iter); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return animation; | 		return frame_seq; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | @ -24,38 +24,41 @@ | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	// 序列帧
 | 	// 序列帧
 | ||||||
| 	class KGE_API Frames | 	class KGE_API FrameSequence | ||||||
| 		: public Object | 		: public Object | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		Frames(); | 		FrameSequence(); | ||||||
| 
 | 
 | ||||||
| 		explicit Frames( | 		explicit FrameSequence( | ||||||
| 			Array<ImagePtr> const& frames	/* ÐòÁÐÖ¡ */ | 			Vector<FramePtr> const& frames	/* 帧序列 */ | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~Frames(); | 		virtual ~FrameSequence(); | ||||||
| 
 | 
 | ||||||
| 		// 添加关键帧
 | 		// 添加关键帧
 | ||||||
| 		void Add( | 		void AddFrame( | ||||||
| 			ImagePtr frame | 			FramePtr frame | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 添加多个关键帧
 | 		// 添加多个关键帧
 | ||||||
| 		void Add( | 		void AddFrames( | ||||||
| 			Array<ImagePtr> const& frames | 			Vector<FramePtr> const& frames | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 获取关键帧
 | 		// 获取关键帧
 | ||||||
| 		Array<ImagePtr> const& GetFrames() const; | 		FramePtr GetFrame(size_t index) const; | ||||||
|  | 
 | ||||||
|  | 		// 获取关键帧
 | ||||||
|  | 		Vector<FramePtr> const& GetFrames() const; | ||||||
| 
 | 
 | ||||||
| 		// 获取帧动画的拷贝对象
 | 		// 获取帧动画的拷贝对象
 | ||||||
| 		FramesPtr Clone() const; | 		FrameSequencePtr Clone() const; | ||||||
| 
 | 
 | ||||||
| 		// 获取帧动画的倒转
 | 		// 获取帧动画的倒转
 | ||||||
| 		FramesPtr Reverse() const; | 		FrameSequencePtr Reverse() const; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Array<ImagePtr>	frames_; | 		Vector<FramePtr>	frames_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  | @ -19,8 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "GifSprite.h" | #include "GifSprite.h" | ||||||
| #include "GifImage.h" | #include "../base/Logger.h" | ||||||
| #include "../base/logs.h" |  | ||||||
| #include "../platform/modules.h" | #include "../platform/modules.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -70,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_) | ||||||
| 				); | 				); | ||||||
|  | @ -87,7 +86,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void GifSprite::Update(Duration dt) | 	void GifSprite::Update(Duration dt) | ||||||
| 	{ | 	{ | ||||||
| 		VisualNode::Update(dt); | 		Actor::Update(dt); | ||||||
| 
 | 
 | ||||||
| 		if (image_ && animating_) | 		if (image_ && animating_) | ||||||
| 		{ | 		{ | ||||||
|  | @ -101,12 +100,14 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void GifSprite::OnRender() | 	void GifSprite::OnRender(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		if (frame_to_render_) | 		if (frame_to_render_ && renderer->CheckVisibility(size_, transform_matrix_)) | ||||||
| 		{ | 		{ | ||||||
|  | 			PrepareRender(renderer); | ||||||
|  | 
 | ||||||
| 			Rect bounds = GetBounds(); | 			Rect bounds = GetBounds(); | ||||||
| 			Renderer::Instance()->DrawBitmap(frame_to_render_, bounds, bounds); | 			renderer->DrawBitmap(frame_to_render_, bounds, bounds); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -164,7 +165,7 @@ namespace kiwano | ||||||
| 				loop_count_++; | 				loop_count_++; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			frame_rt_->DrawBitmap(image_->GetRawFrame().Get(), image_->GetFramePosition()); | 			frame_rt_->DrawBitmap(image_->GetRawFrame().get(), image_->GetFramePosition()); | ||||||
| 			hr = frame_rt_->EndDraw(); | 			hr = frame_rt_->EndDraw(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,16 +21,17 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "../base/Resource.h" | #include "../base/Resource.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
|  | #include "../renderer/GifImage.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	class KGE_API GifSprite | 	class KGE_API GifSprite | ||||||
| 		: public VisualNode | 		: public Actor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		using LoopDoneCallback = Closure<void(int)>; | 		using LoopDoneCallback = Function<void(int)>; | ||||||
| 		using DoneCallback = Closure<void()>; | 		using DoneCallback = Function<void()>; | ||||||
| 
 | 
 | ||||||
| 		GifSprite(); | 		GifSprite(); | ||||||
| 
 | 
 | ||||||
|  | @ -66,7 +67,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		inline DoneCallback GetDoneCallback() const					{ return done_cb_; } | 		inline DoneCallback GetDoneCallback() const					{ return done_cb_; } | ||||||
| 
 | 
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		void Update(Duration dt) override; | 		void Update(Duration dt) override; | ||||||
|  |  | ||||||
|  | @ -1,184 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Kiwano - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #include "Image.h" |  | ||||||
| #include "../base/logs.h" |  | ||||||
| #include "../platform/modules.h" |  | ||||||
| #include "../utils/FileUtil.h" |  | ||||||
| 
 |  | ||||||
| namespace kiwano |  | ||||||
| { |  | ||||||
| 	Image::Image() |  | ||||||
| 		: bitmap_(nullptr) |  | ||||||
| 		, crop_rect_() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Image::Image(Resource const& res) |  | ||||||
| 		: Image() |  | ||||||
| 	{ |  | ||||||
| 		this->Load(res); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Image::Image(Resource const& res, Rect const& crop_rect) |  | ||||||
| 		: Image() |  | ||||||
| 	{ |  | ||||||
| 		this->Load(res); |  | ||||||
| 		this->Crop(crop_rect); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Image::Image(ComPtr<ID2D1Bitmap> const & bitmap) |  | ||||||
| 		: Image() |  | ||||||
| 	{ |  | ||||||
| 		SetBitmap(bitmap); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Image::~Image() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool Image::Load(Resource const& res) |  | ||||||
| 	{ |  | ||||||
| 		HRESULT hr = S_OK; |  | ||||||
| 		ComPtr<ID2D1Bitmap> bitmap; |  | ||||||
| 
 |  | ||||||
| 		if (res.IsFileType()) |  | ||||||
| 		{ |  | ||||||
| #if defined(KGE_DEBUG) |  | ||||||
| 			if (!FileUtil::ExistsFile(res.GetFileName())) |  | ||||||
| 			{ |  | ||||||
| 				KGE_WARNING_LOG(L"Image file '%s' not found!", res.GetFileName().c_str()); |  | ||||||
| 				return false; |  | ||||||
| 			} |  | ||||||
| #endif |  | ||||||
| 			hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (FAILED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			KGE_ERROR_LOG(L"Load image file failed with HRESULT of %08X", hr); |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		SetBitmap(bitmap); |  | ||||||
| 		return true; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool Image::IsValid() const |  | ||||||
| 	{ |  | ||||||
| 		return !!bitmap_; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void Image::Crop(Rect const& crop_rect) |  | ||||||
| 	{ |  | ||||||
| 		if (bitmap_) |  | ||||||
| 		{ |  | ||||||
| 			auto bitmap_size = bitmap_->GetSize(); |  | ||||||
| 			crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.width); |  | ||||||
| 			crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.height); |  | ||||||
| 			crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.width - crop_rect.origin.x); |  | ||||||
| 			crop_rect_.size.y = std::min(std::max(crop_rect.size.y, 0.f), bitmap_size.height - crop_rect.origin.y); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float Image::GetWidth() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_.size.x; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float Image::GetHeight() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_.size.y; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Size Image::GetSize() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_.size; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float Image::GetSourceWidth() const |  | ||||||
| 	{ |  | ||||||
| 		if (bitmap_) |  | ||||||
| 		{ |  | ||||||
| 			return bitmap_->GetSize().width; |  | ||||||
| 		} |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float Image::GetSourceHeight() const |  | ||||||
| 	{ |  | ||||||
| 		if (bitmap_) |  | ||||||
| 		{ |  | ||||||
| 			return bitmap_->GetSize().height; |  | ||||||
| 		} |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Size Image::GetSourceSize() const |  | ||||||
| 	{ |  | ||||||
| 		if (bitmap_) |  | ||||||
| 		{ |  | ||||||
| 			auto bitmap_size = bitmap_->GetSize(); |  | ||||||
| 			return Size{ bitmap_size.width, bitmap_size.height }; |  | ||||||
| 		} |  | ||||||
| 		return Size{}; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float Image::GetCropX() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_.origin.x; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float Image::GetCropY() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_.origin.y; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Point Image::GetCropPos() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_.origin; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Rect Image::GetCropRect() const |  | ||||||
| 	{ |  | ||||||
| 		return crop_rect_; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ComPtr<ID2D1Bitmap> const& Image::GetBitmap() const |  | ||||||
| 	{ |  | ||||||
| 		return bitmap_; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void Image::SetBitmap(ComPtr<ID2D1Bitmap> const & bitmap) |  | ||||||
| 	{ |  | ||||||
| 		if (bitmap) |  | ||||||
| 		{ |  | ||||||
| 			bitmap_ = bitmap; |  | ||||||
| 			crop_rect_.origin.x = crop_rect_.origin.y = 0; |  | ||||||
| 			crop_rect_.size.x = bitmap_->GetSize().width; |  | ||||||
| 			crop_rect_.size.y = bitmap_->GetSize().height; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
|  | @ -20,16 +20,16 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Layer.h" | #include "Layer.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | 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 = bind_func(this, &Layer::HandleMessages); | ||||||
| 
 | 
 | ||||||
| 		AddListener(Event::MouseBtnDown, handler); | 		AddListener(Event::MouseBtnDown, handler); | ||||||
| 		AddListener(Event::MouseBtnUp, handler); | 		AddListener(Event::MouseBtnUp, handler); | ||||||
|  | @ -53,9 +53,9 @@ namespace kiwano | ||||||
| 		if (!swallow_) | 		if (!swallow_) | ||||||
| 		{ | 		{ | ||||||
| 			ActorPtr prev; | 			ActorPtr prev; | ||||||
| 			for (auto child = children_.Last(); child; child = prev) | 			for (auto child = children_.last_item(); child; child = prev) | ||||||
| 			{ | 			{ | ||||||
| 				prev = child->PrevItem(); | 				prev = child->prev_item(); | ||||||
| 				child->Dispatch(evt); | 				child->Dispatch(evt); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,300 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #include "ShapeActor.h" | ||||||
|  | #include "../base/Logger.h" | ||||||
|  | #include "../renderer/Renderer.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	ShapeActor::ShapeActor() | ||||||
|  | 		: fill_color_(Color::White) | ||||||
|  | 		, stroke_color_(Color(Color::Black, 0)) | ||||||
|  | 		, stroke_width_(1.f) | ||||||
|  | 		, outline_join_(StrokeStyle::Miter) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ShapeActor::ShapeActor(Geometry geometry) | ||||||
|  | 		: ShapeActor() | ||||||
|  | 	{ | ||||||
|  | 		SetGeometry(geometry); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ShapeActor::~ShapeActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Rect ShapeActor::GetBounds() const | ||||||
|  | 	{ | ||||||
|  | 		if (!geo_) | ||||||
|  | 			return Rect{}; | ||||||
|  | 
 | ||||||
|  | 		return geo_.GetBoundingBox(Matrix3x2()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Rect ShapeActor::GetBoundingBox() const | ||||||
|  | 	{ | ||||||
|  | 		if (!geo_) | ||||||
|  | 			return Rect{}; | ||||||
|  | 
 | ||||||
|  | 		return geo_.GetBoundingBox(GetTransformMatrix()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ShapeActor::SetFillColor(const Color & color) | ||||||
|  | 	{ | ||||||
|  | 		fill_color_ = color; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ShapeActor::SetStrokeColor(const Color & color) | ||||||
|  | 	{ | ||||||
|  | 		stroke_color_ = color; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ShapeActor::SetStrokeWidth(float width) | ||||||
|  | 	{ | ||||||
|  | 		stroke_width_ = std::max(width, 0.f); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ShapeActor::SetOutlineJoinStyle(StrokeStyle outline_join) | ||||||
|  | 	{ | ||||||
|  | 		outline_join_ = outline_join; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ShapeActor::OnRender(Renderer* renderer) | ||||||
|  | 	{ | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			PrepareRender(renderer); | ||||||
|  | 
 | ||||||
|  | 			renderer->FillGeometry( | ||||||
|  | 				geo_, | ||||||
|  | 				fill_color_ | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			renderer->DrawGeometry( | ||||||
|  | 				geo_, | ||||||
|  | 				stroke_color_, | ||||||
|  | 				stroke_width_, | ||||||
|  | 				outline_join_ | ||||||
|  | 			); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 	// LineActor
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 	LineActor::LineActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	LineActor::LineActor(Point const& end) | ||||||
|  | 	{ | ||||||
|  | 		SetEndPoint(end); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	LineActor::~LineActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void LineActor::SetEndPoint(Point const& end) | ||||||
|  | 	{ | ||||||
|  | 		geo_ = Geometry::CreateLine(Point{}, end); | ||||||
|  | 
 | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			SetSize(end); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 	// RectActor
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 	RectActor::RectActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	RectActor::RectActor(Size const& size) | ||||||
|  | 	{ | ||||||
|  | 		SetRectSize(size); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	RectActor::~RectActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void RectActor::SetRectSize(Size const& size) | ||||||
|  | 	{ | ||||||
|  | 		geo_ = Geometry::CreateRect(Rect{ Point{}, size }); | ||||||
|  | 
 | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			SetSize(size); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 	// RoundRectActor
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 	RoundRectActor::RoundRectActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	RoundRectActor::RoundRectActor(Size const& size, Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		SetRoundedRect(size, radius); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	RoundRectActor::~RoundRectActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void RoundRectActor::SetRadius(Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		SetRoundedRect(size_, radius); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void RoundRectActor::SetRectSize(Size const& size) | ||||||
|  | 	{ | ||||||
|  | 		SetRoundedRect(size, radius_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		geo_ = Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius); | ||||||
|  | 
 | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			SetSize(size); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 	// CircleActor
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 	CircleActor::CircleActor() | ||||||
|  | 		: radius_(0.f) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	CircleActor::CircleActor(float radius) | ||||||
|  | 	{ | ||||||
|  | 		SetRadius(radius); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	CircleActor::~CircleActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void CircleActor::SetRadius(float radius) | ||||||
|  | 	{ | ||||||
|  | 		geo_ = Geometry::CreateCircle(Point{}, radius); | ||||||
|  | 
 | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			SetSize(radius * 2, radius * 2); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 	// EllipseActor
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 	EllipseActor::EllipseActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	EllipseActor::EllipseActor(Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		SetRadius(radius); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	EllipseActor::~EllipseActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void EllipseActor::SetRadius(Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		geo_ = Geometry::CreateEllipse(Point{}, radius); | ||||||
|  | 
 | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			SetSize(radius * 2); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 	// PathActor
 | ||||||
|  | 	//-------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | 	PathActor::PathActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	PathActor::~PathActor() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::BeginPath(Point const& begin_pos) | ||||||
|  | 	{ | ||||||
|  | 		sink_.BeginPath(begin_pos); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::EndPath(bool closed) | ||||||
|  | 	{ | ||||||
|  | 		sink_.EndPath(closed); | ||||||
|  | 		geo_ = sink_.GetGeometry(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::AddLine(Point const& point) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddLine(point); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::AddLines(Vector<Point> const& points) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddLines(points); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddBezier(point1, point2, point3); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void PathActor::ClearPath() | ||||||
|  | 	{ | ||||||
|  | 		geo_.SetGeometry(nullptr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -20,22 +20,22 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "../renderer/render.h"  // ID2D1Geometry | #include "../renderer/Geometry.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	// 二维图形角色
 | 	// 二维图形角色
 | ||||||
| 	class KGE_API ShapeNode | 	class KGE_API ShapeActor | ||||||
| 		: public VisualNode | 		: public Actor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		ShapeNode(); | 		ShapeActor(); | ||||||
| 
 | 
 | ||||||
| 		ShapeNode( | 		ShapeActor( | ||||||
| 			ComPtr<ID2D1Geometry> geometry | 			Geometry geometry | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~ShapeNode(); | 		virtual ~ShapeActor(); | ||||||
| 
 | 
 | ||||||
| 		// 获取填充颜色
 | 		// 获取填充颜色
 | ||||||
| 		Color GetFillColor() const				{ return fill_color_; } | 		Color GetFillColor() const				{ return fill_color_; } | ||||||
|  | @ -49,26 +49,11 @@ namespace kiwano | ||||||
| 		// 获取线条相交样式
 | 		// 获取线条相交样式
 | ||||||
| 		StrokeStyle SetOutlineJoinStyle() const	{ return outline_join_; } | 		StrokeStyle SetOutlineJoinStyle() const	{ return outline_join_; } | ||||||
| 
 | 
 | ||||||
|  | 		// »ñÈ¡±ß½ç
 | ||||||
|  | 		Rect GetBounds() const override; | ||||||
|  | 
 | ||||||
| 		// 获取外切包围盒
 | 		// 获取外切包围盒
 | ||||||
| 		Rect GetBoundingBox(); | 		Rect GetBoundingBox() const override; | ||||||
| 
 |  | ||||||
| 		// 判断图形是否包含点
 |  | ||||||
| 		bool ContainsPoint( |  | ||||||
| 			Point const& point |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取图形展开成一条直线的长度
 |  | ||||||
| 		float GetLength(); |  | ||||||
| 
 |  | ||||||
| 		// 计算面积
 |  | ||||||
| 		float ComputeArea(); |  | ||||||
| 
 |  | ||||||
| 		// 计算图形路径上点的位置和切线向量
 |  | ||||||
| 		bool ComputePointAtLength( |  | ||||||
| 			float length, |  | ||||||
| 			Point& point, |  | ||||||
| 			Vec2& tangent |  | ||||||
| 		); |  | ||||||
| 
 | 
 | ||||||
| 		// 设置填充颜色
 | 		// 设置填充颜色
 | ||||||
| 		void SetFillColor( | 		void SetFillColor( | ||||||
|  | @ -91,217 +76,159 @@ namespace kiwano | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 设置形状
 | 		// 设置形状
 | ||||||
| 		inline void SetGeometry(ComPtr<ID2D1Geometry> geometry)	{ geo_ = geometry; } | 		inline void SetGeometry(Geometry geometry)	{ geo_ = geometry; } | ||||||
| 
 | 
 | ||||||
| 		// 获取形状
 | 		// 获取形状
 | ||||||
| 		inline ComPtr<ID2D1Geometry> GetGeometry() const		{ return geo_; } | 		inline Geometry GetGeometry() const			{ return geo_; } | ||||||
| 
 | 
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Color		fill_color_; | 		Color		fill_color_; | ||||||
| 		Color		stroke_color_; | 		Color		stroke_color_; | ||||||
| 		float		stroke_width_; | 		float		stroke_width_; | ||||||
| 		StrokeStyle	outline_join_; | 		StrokeStyle	outline_join_; | ||||||
| 		ComPtr<ID2D1Geometry>	geo_; | 		Geometry	geo_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 直线
 | 	// 直线
 | ||||||
| 	class KGE_API LineNode | 	class KGE_API LineActor | ||||||
| 		: public ShapeNode | 		: public ShapeActor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		LineNode(); | 		LineActor(); | ||||||
| 
 | 
 | ||||||
| 		LineNode( | 		LineActor( | ||||||
| 			Point const& begin, | 			Point const& end_pos | ||||||
| 			Point const& end |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~LineNode(); | 		virtual ~LineActor(); | ||||||
| 
 | 
 | ||||||
| 		Point const& GetBegin() const { return begin_; } | 		Point const& GetEndPoint() const { return end_; } | ||||||
| 
 | 
 | ||||||
| 		Point const& GetEnd() const { return end_; } | 		void SetEndPoint( | ||||||
| 
 |  | ||||||
| 		void SetLine( |  | ||||||
| 			Point const& begin, |  | ||||||
| 			Point const& end |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetBegin( |  | ||||||
| 			Point const& begin |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetEnd( |  | ||||||
| 			Point const& end | 			Point const& end | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Point begin_; |  | ||||||
| 		Point end_; | 		Point end_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 矩形角色
 | 	// 矩形角色
 | ||||||
| 	class KGE_API RectNode | 	class KGE_API RectActor | ||||||
| 		: public ShapeNode | 		: public ShapeActor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		RectNode(); | 		RectActor(); | ||||||
| 
 | 
 | ||||||
| 		RectNode( | 		RectActor( | ||||||
| 			Rect const& rect |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		RectNode( |  | ||||||
| 			Point const& left_top, |  | ||||||
| 			Size const& size | 			Size const& size | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~RectNode(); | 		virtual ~RectActor(); | ||||||
| 
 | 
 | ||||||
| 		Rect const& GetRect() const { return rect_; } | 		void SetRectSize(Size const& size); | ||||||
| 
 | 
 | ||||||
| 		void SetRect(Rect const& rect); | 		inline Size const& GetRectSize() const { return size_; } | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Rect rect_; | 		Size size_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 圆角矩形角色
 | 	// 圆角矩形角色
 | ||||||
| 	class KGE_API RoundedRectNode | 	class KGE_API RoundRectActor | ||||||
| 		: public ShapeNode | 		: public ShapeActor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		RoundedRectNode(); | 		RoundRectActor(); | ||||||
| 
 | 
 | ||||||
| 		RoundedRectNode( | 		RoundRectActor( | ||||||
| 			Rect const& rect, | 			Size const& size, | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~RoundedRectNode(); | 		virtual ~RoundRectActor(); | ||||||
| 
 |  | ||||||
| 		float GetRadiusX() const { return radius_x_; } |  | ||||||
| 
 |  | ||||||
| 		float GetRadiusY() const { return radius_y_; } |  | ||||||
| 
 | 
 | ||||||
| 		void SetRadius( | 		void SetRadius( | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		Rect const& GetRect() const { return rect_; } | 		void SetRectSize( | ||||||
| 
 | 			Size const& size | ||||||
| 		void SetRect( |  | ||||||
| 			Rect const& rect |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		void SetRoundedRect( | 		void SetRoundedRect( | ||||||
| 			Rect const& rect, | 			Size const& size, | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | 		inline Vec2 GetRadius() const	{ return radius_; } | ||||||
|  | 
 | ||||||
|  | 		inline Size GetRectSize() const	{ return size_; } | ||||||
|  | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Rect	rect_; | 		Size size_; | ||||||
| 		float	radius_x_; | 		Vec2 radius_; | ||||||
| 		float	radius_y_; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 圆形角色
 | 	// 圆形角色
 | ||||||
| 	class KGE_API CircleNode | 	class KGE_API CircleActor | ||||||
| 		: public ShapeNode | 		: public ShapeActor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		CircleNode(); | 		CircleActor(); | ||||||
| 
 | 
 | ||||||
| 		CircleNode( | 		CircleActor( | ||||||
| 			Point const& center, |  | ||||||
| 			float radius | 			float radius | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~CircleNode(); | 		virtual ~CircleActor(); | ||||||
| 
 | 
 | ||||||
| 		float GetRadius() const { return radius_; } | 		inline float GetRadius() const { return radius_; } | ||||||
| 
 | 
 | ||||||
| 		void SetRadius( | 		void SetRadius(float radius); | ||||||
| 			float radius |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		Point const& GetCenter() const { return center_; } |  | ||||||
| 
 |  | ||||||
| 		void SetCenter( |  | ||||||
| 			Point const& center |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetCircle( |  | ||||||
| 			Point const& center, |  | ||||||
| 			float radius |  | ||||||
| 		); |  | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Point center_; |  | ||||||
| 		float radius_; | 		float radius_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 椭圆角色
 | 	// 椭圆角色
 | ||||||
| 	class KGE_API EllipseNode | 	class KGE_API EllipseActor | ||||||
| 		: public ShapeNode | 		: public ShapeActor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		EllipseNode(); | 		EllipseActor(); | ||||||
| 
 | 
 | ||||||
| 		EllipseNode( | 		EllipseActor( | ||||||
| 			Point const& center, | 			Vec2 const& radius | ||||||
| 			float radius_x, |  | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~EllipseNode(); | 		virtual ~EllipseActor(); | ||||||
| 
 | 
 | ||||||
| 		float GetRadiusX() const { return radius_x_; } | 		Vec2 GetRadius() const { return radius_; } | ||||||
| 
 |  | ||||||
| 		float GetRadiusY() const { return radius_y_; } |  | ||||||
| 
 | 
 | ||||||
| 		void SetRadius( | 		void SetRadius( | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		Point const& GetCenter() const { return center_; } |  | ||||||
| 
 |  | ||||||
| 		void SetCenter( |  | ||||||
| 			Point const& center |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetEllipse( |  | ||||||
| 			Point const& center, |  | ||||||
| 			float radius_x, |  | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Point center_; | 		Vec2 radius_; | ||||||
| 		float radius_x_; |  | ||||||
| 		float radius_y_; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 路径角色
 | 	// 路径角色
 | ||||||
| 	class KGE_API PathNode | 	class KGE_API PathActor | ||||||
| 		: public ShapeNode | 		: public ShapeActor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		PathNode(); | 		PathActor(); | ||||||
| 
 | 
 | ||||||
| 		virtual ~PathNode(); | 		virtual ~PathActor(); | ||||||
| 
 | 
 | ||||||
| 		// 开始添加路径
 | 		// 开始添加路径
 | ||||||
| 		void BeginPath( | 		void BeginPath( | ||||||
|  | @ -320,7 +247,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		// 添加多条线段
 | 		// 添加多条线段
 | ||||||
| 		void AddLines( | 		void AddLines( | ||||||
| 			Array<Point> const& points | 			Vector<Point> const& points | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 添加一条三次方贝塞尔曲线
 | 		// 添加一条三次方贝塞尔曲线
 | ||||||
|  | @ -343,8 +270,7 @@ namespace kiwano | ||||||
| 		void ClearPath(); | 		void ClearPath(); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		ComPtr<ID2D1PathGeometry>	current_geometry_; | 		GeometrySink sink_; | ||||||
| 		ComPtr<ID2D1GeometrySink>	current_sink_; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | @ -1,479 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Kiwano - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #include "ShapeNode.h" |  | ||||||
| #include "../base/logs.h" |  | ||||||
| 
 |  | ||||||
| namespace kiwano |  | ||||||
| { |  | ||||||
| 	ShapeNode::ShapeNode() |  | ||||||
| 		: fill_color_(Color::White) |  | ||||||
| 		, stroke_color_(Color(Color::Black, 0)) |  | ||||||
| 		, stroke_width_(1.f) |  | ||||||
| 		, outline_join_(StrokeStyle::Miter) |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ShapeNode::ShapeNode(ComPtr<ID2D1Geometry> geometry) |  | ||||||
| 		: ShapeNode() |  | ||||||
| 	{ |  | ||||||
| 		SetGeometry(geometry); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ShapeNode::~ShapeNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Rect ShapeNode::GetBoundingBox() |  | ||||||
| 	{ |  | ||||||
| 		if (!geo_) |  | ||||||
| 			return Rect{}; |  | ||||||
| 
 |  | ||||||
| 		D2D1_RECT_F rect; |  | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->GetBounds(D2D1::Matrix3x2F::Identity(), &rect); |  | ||||||
| 		return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float ShapeNode::GetLength() |  | ||||||
| 	{ |  | ||||||
| 		float length = 0.f; |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			// no matter it failed or not
 |  | ||||||
| 			geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); |  | ||||||
| 		} |  | ||||||
| 		return length; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool ShapeNode::ComputePointAtLength(float length, Point& point, Vec2& tangent) |  | ||||||
| 	{ |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			if (SUCCEEDED(geo_->ComputePointAtLength( |  | ||||||
| 				length, |  | ||||||
| 				D2D1::Matrix3x2F::Identity(), |  | ||||||
| 				DX::ConvertToPoint2F(&point), |  | ||||||
| 				DX::ConvertToPoint2F(&tangent)))) |  | ||||||
| 			{ |  | ||||||
| 				return true; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float ShapeNode::ComputeArea() |  | ||||||
| 	{ |  | ||||||
| 		if (!geo_) |  | ||||||
| 			return 0.f; |  | ||||||
| 
 |  | ||||||
| 		float area = 0.f; |  | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); |  | ||||||
| 		return area; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool ShapeNode::ContainsPoint(Point const& point) |  | ||||||
| 	{ |  | ||||||
| 		if (!geo_) |  | ||||||
| 			return false; |  | ||||||
| 
 |  | ||||||
| 		BOOL ret = 0; |  | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->FillContainsPoint( |  | ||||||
| 			DX::ConvertToPoint2F(point), |  | ||||||
| 			D2D1::Matrix3x2F::Identity(), |  | ||||||
| 			&ret |  | ||||||
| 		); |  | ||||||
| 		return !!ret; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ShapeNode::SetFillColor(const Color & color) |  | ||||||
| 	{ |  | ||||||
| 		fill_color_ = color; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ShapeNode::SetStrokeColor(const Color & color) |  | ||||||
| 	{ |  | ||||||
| 		stroke_color_ = color; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ShapeNode::SetStrokeWidth(float width) |  | ||||||
| 	{ |  | ||||||
| 		stroke_width_ = std::max(width, 0.f); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ShapeNode::SetOutlineJoinStyle(StrokeStyle outline_join) |  | ||||||
| 	{ |  | ||||||
| 		outline_join_ = outline_join; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ShapeNode::OnRender() |  | ||||||
| 	{ |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			Renderer::Instance()->FillGeometry( |  | ||||||
| 				geo_, |  | ||||||
| 				fill_color_ |  | ||||||
| 			); |  | ||||||
| 
 |  | ||||||
| 			Renderer::Instance()->DrawGeometry( |  | ||||||
| 				geo_, |  | ||||||
| 				stroke_color_, |  | ||||||
| 				stroke_width_, |  | ||||||
| 				outline_join_ |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// LineNode
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	LineNode::LineNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	LineNode::LineNode(Point const& begin, Point const& end) |  | ||||||
| 	{ |  | ||||||
| 		SetLine(begin, end); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	LineNode::~LineNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void LineNode::SetLine(Point const& begin, Point const& end) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1PathGeometry> path_geo; |  | ||||||
| 		ComPtr<ID2D1GeometrySink> path_sink; |  | ||||||
| 
 |  | ||||||
| 		HRESULT hr = Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			hr = path_geo->Open(&path_sink); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			path_sink->BeginFigure(DX::ConvertToPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED); |  | ||||||
| 			path_sink->AddLine(DX::ConvertToPoint2F(end)); |  | ||||||
| 			path_sink->EndFigure(D2D1_FIGURE_END_OPEN); |  | ||||||
| 			hr = path_sink->Close(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = path_geo; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void LineNode::SetBegin(Point const& begin) |  | ||||||
| 	{ |  | ||||||
| 		SetLine(begin, end_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void LineNode::SetEnd(Point const& end) |  | ||||||
| 	{ |  | ||||||
| 		SetLine(begin_, end); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// RectNode
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	RectNode::RectNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	RectNode::RectNode(Rect const& rect) |  | ||||||
| 	{ |  | ||||||
| 		SetRect(rect); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	RectNode::RectNode(Point const& left_top, Size const& size) |  | ||||||
| 	{ |  | ||||||
| 		SetRect(Rect{ left_top, size }); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	RectNode::~RectNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void RectNode::SetRect(Rect const& rect) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1RectangleGeometry> geo; |  | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = geo; |  | ||||||
| 			rect_ = rect; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// RoundedRectNode
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	RoundedRectNode::RoundedRectNode() |  | ||||||
| 		: radius_x_(0.f) |  | ||||||
| 		, radius_y_(0.f) |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	RoundedRectNode::RoundedRectNode(Rect const& rect, float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		SetRoundedRect(rect, radius_x, radius_y); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	RoundedRectNode::~RoundedRectNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void RoundedRectNode::SetRadius(float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		SetRoundedRect(rect_, radius_x, radius_y); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void RoundedRectNode::SetRect(Rect const& rect) |  | ||||||
| 	{ |  | ||||||
| 		SetRoundedRect(rect, radius_x_, radius_y_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void RoundedRectNode::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1RoundedRectangleGeometry> geo; |  | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( |  | ||||||
| 			D2D1::RoundedRect( |  | ||||||
| 				DX::ConvertToRectF(rect), |  | ||||||
| 				radius_x, |  | ||||||
| 				radius_y |  | ||||||
| 			), |  | ||||||
| 			&geo))) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = geo; |  | ||||||
| 			rect_ = rect; |  | ||||||
| 			radius_x_ = radius_x; |  | ||||||
| 			radius_y_ = radius_y; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// CircleNode
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	CircleNode::CircleNode() |  | ||||||
| 		: radius_(0.f) |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	CircleNode::CircleNode(Point const& center, float radius) |  | ||||||
| 	{ |  | ||||||
| 		SetCircle(center, radius); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	CircleNode::~CircleNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void CircleNode::SetRadius(float radius) |  | ||||||
| 	{ |  | ||||||
| 		SetCircle(center_, radius); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void CircleNode::SetCenter(Point const& center) |  | ||||||
| 	{ |  | ||||||
| 		SetCircle(center, radius_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void CircleNode::SetCircle(Point const& center, float radius) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1EllipseGeometry> geo; |  | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(factory->CreateEllipseGeometry( |  | ||||||
| 			D2D1::Ellipse( |  | ||||||
| 				DX::ConvertToPoint2F(center), |  | ||||||
| 				radius, |  | ||||||
| 				radius), |  | ||||||
| 			&geo))) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = geo; |  | ||||||
| 			center_ = center; |  | ||||||
| 			radius_ = radius; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// EllipseNode
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	EllipseNode::EllipseNode() |  | ||||||
| 		: radius_x_(0.f) |  | ||||||
| 		, radius_y_(0.f) |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	EllipseNode::EllipseNode(Point const& center, float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		SetEllipse(center, radius_x, radius_y); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	EllipseNode::~EllipseNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void EllipseNode::SetRadius(float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		SetEllipse(center_, radius_x, radius_y); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void EllipseNode::SetCenter(Point const& center) |  | ||||||
| 	{ |  | ||||||
| 		SetEllipse(center, radius_x_, radius_y_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void EllipseNode::SetEllipse(Point const& center, float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1EllipseGeometry> geo; |  | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(factory->CreateEllipseGeometry( |  | ||||||
| 			D2D1::Ellipse( |  | ||||||
| 				DX::ConvertToPoint2F(center), |  | ||||||
| 				radius_x, |  | ||||||
| 				radius_y), |  | ||||||
| 			&geo))) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = geo; |  | ||||||
| 			radius_x_ = radius_x; |  | ||||||
| 			radius_y_ = radius_y; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// PathNode
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	PathNode::PathNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	PathNode::~PathNode() |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::BeginPath(Point const& begin_pos) |  | ||||||
| 	{ |  | ||||||
| 		current_geometry_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			factory->CreatePathGeometry(¤t_geometry_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			current_geometry_->Open(¤t_sink_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::EndPath(bool closed) |  | ||||||
| 	{ |  | ||||||
| 		if (current_sink_) |  | ||||||
| 		{ |  | ||||||
| 			current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); |  | ||||||
| 			ThrowIfFailed( |  | ||||||
| 				current_sink_->Close() |  | ||||||
| 			); |  | ||||||
| 
 |  | ||||||
| 			geo_ = current_geometry_; |  | ||||||
| 
 |  | ||||||
| 			current_sink_ = nullptr; |  | ||||||
| 			current_geometry_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::AddLine(Point const& point) |  | ||||||
| 	{ |  | ||||||
| 		if (current_sink_) |  | ||||||
| 			current_sink_->AddLine(DX::ConvertToPoint2F(point)); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::AddLines(Array<Point> const& points) |  | ||||||
| 	{ |  | ||||||
| 		if (current_sink_ && !points.empty()) |  | ||||||
| 		{ |  | ||||||
| 			current_sink_->AddLines( |  | ||||||
| 				reinterpret_cast<const D2D_POINT_2F*>(&points[0]), |  | ||||||
| 				static_cast<UINT32>(points.size()) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::AddBezier(Point const& point1, Point const& point2, Point const& point3) |  | ||||||
| 	{ |  | ||||||
| 		if (current_sink_) |  | ||||||
| 		{ |  | ||||||
| 			current_sink_->AddBezier( |  | ||||||
| 				D2D1::BezierSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point1), |  | ||||||
| 					DX::ConvertToPoint2F(point2), |  | ||||||
| 					DX::ConvertToPoint2F(point3) |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) |  | ||||||
| 	{ |  | ||||||
| 		if (current_sink_) |  | ||||||
| 		{ |  | ||||||
| 			current_sink_->AddArc( |  | ||||||
| 				D2D1::ArcSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point), |  | ||||||
| 					DX::ConvertToSizeF(radius), |  | ||||||
| 					rotation, |  | ||||||
| 					clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, |  | ||||||
| 					is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void PathNode::ClearPath() |  | ||||||
| 	{ |  | ||||||
| 		geo_ = nullptr; |  | ||||||
| 		current_sink_ = nullptr; |  | ||||||
| 		current_geometry_ = nullptr; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
|  | @ -19,79 +19,77 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Sprite.h" | #include "Sprite.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	Sprite::Sprite() | 	Sprite::Sprite() | ||||||
| 		: image_(nullptr) | 		: frame_(nullptr) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Sprite::Sprite(ImagePtr image) |  | ||||||
| 		: image_(nullptr) |  | ||||||
| 	{ |  | ||||||
| 		Load(image); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Sprite::Sprite(Resource const& res) | 	Sprite::Sprite(Resource const& res) | ||||||
| 		: image_(nullptr) | 		: frame_(nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		Load(res); | 		Load(res); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Sprite::Sprite(Resource const& res, const Rect& crop_rect) | 	Sprite::Sprite(Resource const& res, const Rect& crop_rect) | ||||||
| 		: image_(nullptr) | 		: frame_(nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		Load(res); | 		Load(res); | ||||||
| 		Crop(crop_rect); | 		Crop(crop_rect); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	Sprite::Sprite(FramePtr frame) | ||||||
|  | 		: frame_(nullptr) | ||||||
|  | 	{ | ||||||
|  | 		SetFrame(frame); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	Sprite::~Sprite() | 	Sprite::~Sprite() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool Sprite::Load(ImagePtr image) |  | ||||||
| 	{ |  | ||||||
| 		if (image && image_ != image) |  | ||||||
| 		{ |  | ||||||
| 			image_ = image; |  | ||||||
| 
 |  | ||||||
| 			Actor::SetSize(image_->GetWidth(), image_->GetHeight()); |  | ||||||
| 			return true; |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool Sprite::Load(Resource const& res) | 	bool Sprite::Load(Resource const& res) | ||||||
| 	{ | 	{ | ||||||
| 		ImagePtr image = new (std::nothrow) Image; | 		FramePtr frame = new (std::nothrow) Frame; | ||||||
| 		if (image->Load(res)) | 		if (frame->Load(res)) | ||||||
| 		{ | 		{ | ||||||
| 			return Load(image); | 			SetFrame(frame); | ||||||
|  | 			return true; | ||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Sprite::Crop(const Rect& crop_rect) | 	void Sprite::Crop(const Rect& crop_rect) | ||||||
| 	{ | 	{ | ||||||
| 		image_->Crop(crop_rect); | 		if (frame_) | ||||||
| 		Actor::SetSize( | 		{ | ||||||
| 			std::min(std::max(crop_rect.size.x, 0.f), image_->GetSourceWidth() - image_->GetCropX()), | 			frame_->Crop(crop_rect); | ||||||
| 			std::min(std::max(crop_rect.size.y, 0.f), image_->GetSourceHeight() - image_->GetCropY()) | 			SetSize(frame_->GetWidth(), frame_->GetHeight()); | ||||||
| 		); | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ImagePtr Sprite::GetImage() const | 	void Sprite::SetFrame(FramePtr frame) | ||||||
| 	{ | 	{ | ||||||
| 		return image_; | 		if (frame_ != frame) | ||||||
|  | 		{ | ||||||
|  | 			frame_ = frame; | ||||||
|  | 			if (frame_) | ||||||
|  | 			{ | ||||||
|  | 				SetSize(frame_->GetWidth(), frame_->GetHeight()); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Sprite::OnRender() | 	void Sprite::OnRender(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		if (image_) | 		if (frame_ && renderer->CheckVisibility(size_, transform_matrix_)) | ||||||
| 		{ | 		{ | ||||||
| 			Renderer::Instance()->DrawImage(image_, GetBounds()); | 			PrepareRender(renderer); | ||||||
|  | 
 | ||||||
|  | 			renderer->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -20,54 +20,52 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "Image.h" | #include "Frame.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	// ¾«Áé
 | 	// ¾«Áé
 | ||||||
| 	class KGE_API Sprite | 	class KGE_API Sprite | ||||||
| 		: public VisualNode | 		: public Actor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		Sprite(); | 		Sprite(); | ||||||
| 
 | 
 | ||||||
| 		explicit Sprite( |  | ||||||
| 			ImagePtr image |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		explicit Sprite( | 		explicit Sprite( | ||||||
| 			Resource const& res | 			Resource const& res | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		explicit Sprite( | 		explicit Sprite( | ||||||
| 			Resource const& res, | 			Resource const& res, | ||||||
| 			const Rect& crop_rect	/* 裁剪矩形 */ | 			Rect const& crop_rect	/* ²Ã¼ô¾ØÐÎ */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		explicit Sprite( | ||||||
|  | 			FramePtr frame | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~Sprite(); | 		virtual ~Sprite(); | ||||||
| 
 | 
 | ||||||
| 		// 加载图片文件
 | 		// ¼ÓÔØÍ¼Ïñ×ÊÔ´
 | ||||||
| 		bool Load( | 		bool Load( | ||||||
| 			Resource const& res | 			Resource const& res | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 加载图片
 | 		// ²Ã¼ô¾ØÐÎ
 | ||||||
| 		bool Load( |  | ||||||
| 			ImagePtr image |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 将图片裁剪为矩形
 |  | ||||||
| 		void Crop( | 		void Crop( | ||||||
| 			const Rect& crop_rect	/* 裁剪矩形 */ | 			const Rect& crop_rect | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 获取 Image 对象
 | 		// »ñȡ֡ͼÏñ
 | ||||||
| 		ImagePtr GetImage() const; | 		inline FramePtr GetFrame() const { return frame_; } | ||||||
|  | 
 | ||||||
|  | 		// ÉèÖÃ֡ͼÏñ
 | ||||||
|  | 		void SetFrame(FramePtr frame); | ||||||
| 
 | 
 | ||||||
| 		// äÖȾ¾«Áé
 | 		// äÖȾ¾«Áé
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		ImagePtr image_; | 		FramePtr frame_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,8 +19,8 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Stage.h" | #include "Stage.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -19,8 +19,8 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Text.h" | #include "Text.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -297,13 +297,13 @@ namespace kiwano | ||||||
| 		style_.outline_stroke = outline_stroke; | 		style_.outline_stroke = outline_stroke; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Text::OnRender() | 	void Text::OnRender(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		UpdateLayout(); | 		UpdateLayout(); | ||||||
| 
 | 
 | ||||||
| 		if (text_layout_) | 		if (text_layout_ && renderer->CheckVisibility(layout_size_, transform_matrix_)) | ||||||
| 		{ | 		{ | ||||||
|             auto renderer = Renderer::Instance(); | 			PrepareRender(renderer); | ||||||
| 			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( | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ namespace kiwano | ||||||
| { | { | ||||||
| 	// 文本
 | 	// 文本
 | ||||||
| 	class KGE_API Text | 	class KGE_API Text | ||||||
| 		: public VisualNode | 		: public Actor | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		Text(); | 		Text(); | ||||||
|  | @ -203,7 +203,7 @@ namespace kiwano | ||||||
| 			TextStyle const& style | 			TextStyle const& style | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		void UpdateLayout() const; | 		void UpdateLayout() const; | ||||||
|  |  | ||||||
|  | @ -21,9 +21,9 @@ | ||||||
| #include "Transition.h" | #include "Transition.h" | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "Stage.h" | #include "Stage.h" | ||||||
| #include "../base/window.h" | #include "../base/Window.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| #include "../renderer/render.h" | #include "../renderer/Renderer.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -65,19 +65,15 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (in_scene_) | 		if (in_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			Renderer::GetInstance()->CreateLayer(in_layer_); | ||||||
| 				Renderer::Instance()->CreateLayer(in_layer_) |  | ||||||
| 			); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			ThrowIfFailed( | 			Renderer::GetInstance()->CreateLayer(out_layer_); | ||||||
| 				Renderer::Instance()->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 }; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -99,10 +95,8 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Transition::Render() | 	void Transition::Render(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		auto renderer = Renderer::Instance(); |  | ||||||
| 
 |  | ||||||
| 		if (out_scene_) | 		if (out_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			renderer->PushClip( | 			renderer->PushClip( | ||||||
|  | @ -111,7 +105,7 @@ namespace kiwano | ||||||
| 			); | 			); | ||||||
| 			renderer->PushLayer(out_layer_, out_layer_prop_); | 			renderer->PushLayer(out_layer_, out_layer_prop_); | ||||||
| 
 | 
 | ||||||
| 			out_scene_->Render(); | 			out_scene_->Render(renderer); | ||||||
| 
 | 
 | ||||||
| 			renderer->PopLayer(); | 			renderer->PopLayer(); | ||||||
| 			renderer->PopClip(); | 			renderer->PopClip(); | ||||||
|  | @ -125,7 +119,7 @@ namespace kiwano | ||||||
| 			); | 			); | ||||||
| 			renderer->PushLayer(in_layer_, in_layer_prop_); | 			renderer->PushLayer(in_layer_, in_layer_prop_); | ||||||
| 
 | 
 | ||||||
| 			in_scene_->Render(); | 			in_scene_->Render(renderer); | ||||||
| 
 | 
 | ||||||
| 			renderer->PopLayer(); | 			renderer->PopLayer(); | ||||||
| 			renderer->PopClip(); | 			renderer->PopClip(); | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	class Director; | 	class Director; | ||||||
|  | 	class Renderer; | ||||||
| 
 | 
 | ||||||
| 	// 舞台过渡
 | 	// 舞台过渡
 | ||||||
| 	class KGE_API Transition | 	class KGE_API Transition | ||||||
|  | @ -49,7 +50,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		virtual void Update(Duration dt); | 		virtual void Update(Duration dt); | ||||||
| 
 | 
 | ||||||
| 		virtual void Render(); | 		virtual void Render(Renderer* renderer); | ||||||
| 
 | 
 | ||||||
| 		virtual void Stop(); | 		virtual void Stop(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Action.h" | #include "Action.h" | ||||||
| #include "Actor.h" | #include "../Actor.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -19,21 +19,21 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "include-forwards.h" | #include "../include-forwards.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	using ActionCallback = Closure<void()>; | 	using ActionCallback = Function<void()>; | ||||||
| 
 | 
 | ||||||
| 	class ActionManager; | 	class ActionManager; | ||||||
| 
 | 
 | ||||||
| 	class KGE_API Action | 	class KGE_API Action | ||||||
| 		: public Object | 		: public Object | ||||||
| 		, protected IntrusiveListItem<ActionPtr> | 		, protected intrusive_list_item<ActionPtr> | ||||||
| 	{ | 	{ | ||||||
| 		friend class ActionManager; | 		friend class ActionManager; | ||||||
| 		friend class ActionGroup; | 		friend class ActionGroup; | ||||||
| 		friend class IntrusiveList<ActionPtr>; | 		friend class intrusive_list<ActionPtr>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		enum class Status | 		enum class Status | ||||||
|  | @ -0,0 +1,40 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #include "ActionDelay.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	ActionDelay::ActionDelay(Duration delay) | ||||||
|  | 	{ | ||||||
|  | 		SetDelay(delay); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionDelay::Clone() const | ||||||
|  | 	{ | ||||||
|  | 		return new ActionDelay(delay_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionDelay::Reverse() const | ||||||
|  | 	{ | ||||||
|  | 		return new ActionDelay(delay_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -19,37 +19,23 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Array.hpp" | #include "Action.h" | ||||||
| #include "String.hpp" |  | ||||||
| #include <set> |  | ||||||
| #include <map> |  | ||||||
| #include <list> |  | ||||||
| #include <queue> |  | ||||||
| #include <unordered_set> |  | ||||||
| #include <unordered_map> |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	using StringStream = std::wstringstream; | 	// 延时动作
 | ||||||
|  | 	class KGE_API ActionDelay | ||||||
|  | 		: public Action | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		ActionDelay( | ||||||
|  | 			Duration delay		/* 持续时长 */ | ||||||
|  | 		); | ||||||
| 
 | 
 | ||||||
| 	template<typename _Ty1, typename _Ty2> | 		// 获取该动作的拷贝对象
 | ||||||
| 	using Pair = std::pair<_Ty1, _Ty2>; | 		ActionPtr Clone() const override; | ||||||
| 
 | 
 | ||||||
| 	template<typename _Ty, typename... _Args> | 		// 获取该动作的倒转
 | ||||||
| 	using List = std::list<_Ty, _Args...>; | 		ActionPtr Reverse() const override; | ||||||
| 
 | 	}; | ||||||
| 	template<typename _Ty, typename... _Args> |  | ||||||
| 	using Queue = std::queue<_Ty, _Args...>; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, typename... _Args> |  | ||||||
| 	using Set = std::set<_Ty, _Args...>; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, typename... _Args> |  | ||||||
| 	using UnorderedSet = std::unordered_set<_Ty, _Args...>; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Kty, typename _Ty, typename... _Args> |  | ||||||
| 	using Map = std::map<_Kty, _Ty, _Args...>; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Kty, typename _Ty, typename... _Args> |  | ||||||
| 	using UnorderedMap = std::unordered_map<_Kty, _Ty, _Args...>; |  | ||||||
| } | } | ||||||
|  | @ -19,8 +19,8 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "ActionGroup.h" | #include "ActionGroup.h" | ||||||
| #include "Actor.h" | #include "../Actor.h" | ||||||
| #include "../base/logs.h" | #include "../../base/Logger.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -33,7 +33,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ActionGroup::ActionGroup(Array<ActionPtr> const& actions, bool sequence) | 	ActionGroup::ActionGroup(Vector<ActionPtr> const& actions, bool sequence) | ||||||
| 		: sequence_(sequence) | 		: sequence_(sequence) | ||||||
| 	{ | 	{ | ||||||
| 		this->Add(actions); | 		this->Add(actions); | ||||||
|  | @ -45,19 +45,19 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void ActionGroup::Init(ActorPtr target) | 	void ActionGroup::Init(ActorPtr target) | ||||||
| 	{ | 	{ | ||||||
| 		if (actions_.IsEmpty()) | 		if (actions_.is_empty()) | ||||||
| 		{ | 		{ | ||||||
| 			Done(); | 			Done(); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
| 		current_ = actions_.First(); | 		current_ = actions_.first_item(); | ||||||
| 		current_->Restart(target);	// init first action
 | 		current_->Restart(target);	// init first action
 | ||||||
| 
 | 
 | ||||||
| 		if (!sequence_) | 		if (!sequence_) | ||||||
| 		{ | 		{ | ||||||
| 			// init all actions
 | 			// init all actions
 | ||||||
| 			for (; current_; current_ = current_->NextItem()) | 			for (; current_; current_ = current_->next_item()) | ||||||
| 			{ | 			{ | ||||||
| 				current_->Restart(target); | 				current_->Restart(target); | ||||||
| 			} | 			} | ||||||
|  | @ -74,7 +74,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 				if (current_->IsDone()) | 				if (current_->IsDone()) | ||||||
| 				{ | 				{ | ||||||
| 					current_ = current_->NextItem(); | 					current_ = current_->next_item(); | ||||||
| 
 | 
 | ||||||
| 					if (current_) | 					if (current_) | ||||||
| 						current_->Restart(target);	// init next action
 | 						current_->Restart(target);	// init next action
 | ||||||
|  | @ -86,7 +86,7 @@ namespace kiwano | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			bool done = true; | 			bool done = true; | ||||||
| 			for (current_ = actions_.First(); current_; current_ = current_->NextItem()) | 			for (current_ = actions_.first_item(); current_; current_ = current_->next_item()) | ||||||
| 			{ | 			{ | ||||||
| 				if (!current_->IsDone()) | 				if (!current_->IsDone()) | ||||||
| 				{ | 				{ | ||||||
|  | @ -106,11 +106,11 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		if (action) | 		if (action) | ||||||
| 		{ | 		{ | ||||||
| 			actions_.PushBack(action); | 			actions_.push_back_item(action); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void ActionGroup::Add(Array<ActionPtr> const& actions) | 	void ActionGroup::Add(Vector<ActionPtr> const& actions) | ||||||
| 	{ | 	{ | ||||||
| 		for (const auto& action : actions) | 		for (const auto& action : actions) | ||||||
| 			Add(action); | 			Add(action); | ||||||
|  | @ -121,7 +121,7 @@ namespace kiwano | ||||||
| 		auto group = new (std::nothrow) ActionGroup(); | 		auto group = new (std::nothrow) ActionGroup(); | ||||||
| 		if (group) | 		if (group) | ||||||
| 		{ | 		{ | ||||||
| 			for (auto action = actions_.First(); action; action = action->NextItem()) | 			for (auto action = actions_.first_item(); action; action = action->next_item()) | ||||||
| 			{ | 			{ | ||||||
| 				if (action) | 				if (action) | ||||||
| 				{ | 				{ | ||||||
|  | @ -135,9 +135,9 @@ namespace kiwano | ||||||
| 	ActionPtr ActionGroup::Reverse() const | 	ActionPtr ActionGroup::Reverse() const | ||||||
| 	{ | 	{ | ||||||
| 		auto group = new (std::nothrow) ActionGroup(); | 		auto group = new (std::nothrow) ActionGroup(); | ||||||
| 		if (group && !actions_.IsEmpty()) | 		if (group && !actions_.is_empty()) | ||||||
| 		{ | 		{ | ||||||
| 			for (auto action = actions_.Last(); action; action = action->PrevItem()) | 			for (auto action = actions_.last_item(); action; action = action->prev_item()) | ||||||
| 			{ | 			{ | ||||||
| 				group->Add(action->Reverse()); | 				group->Add(action->Reverse()); | ||||||
| 			} | 			} | ||||||
|  | @ -28,12 +28,12 @@ namespace kiwano | ||||||
| 		: public Action | 		: public Action | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		using ActionList = IntrusiveList<ActionPtr>; | 		using ActionList = intrusive_list<ActionPtr>; | ||||||
| 
 | 
 | ||||||
| 		ActionGroup(); | 		ActionGroup(); | ||||||
| 
 | 
 | ||||||
| 		explicit ActionGroup( | 		explicit ActionGroup( | ||||||
| 			Array<ActionPtr> const& actions, | 			Vector<ActionPtr> const& actions, | ||||||
| 			bool sequence = true				// 按顺序执行或同时执行
 | 			bool sequence = true				// 按顺序执行或同时执行
 | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | @ -46,7 +46,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		// 添加多个动作
 | 		// 添加多个动作
 | ||||||
| 		void Add( | 		void Add( | ||||||
| 			Array<ActionPtr> const& actions | 			Vector<ActionPtr> const& actions | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 获取所有动作
 | 		// 获取所有动作
 | ||||||
|  | @ -84,7 +84,7 @@ namespace kiwano | ||||||
| 		inline ActionSequence() : ActionGroup() {} | 		inline ActionSequence() : ActionGroup() {} | ||||||
| 
 | 
 | ||||||
| 		KGE_DEPRECATED("ActionSequence is deprecated, use ActionGroup instead") | 		KGE_DEPRECATED("ActionSequence is deprecated, use ActionGroup instead") | ||||||
| 		inline explicit ActionSequence(Array<ActionPtr> const& actions) : ActionGroup(actions, true) {} | 		inline explicit ActionSequence(Vector<ActionPtr> const& actions) : ActionGroup(actions, true) {} | ||||||
| 
 | 
 | ||||||
| 		virtual ~ActionSequence() {} | 		virtual ~ActionSequence() {} | ||||||
| 	}; | 	}; | ||||||
|  | @ -99,7 +99,7 @@ namespace kiwano | ||||||
| 		inline ActionSpawn() : ActionGroup() { sequence_ = false; } | 		inline ActionSpawn() : ActionGroup() { sequence_ = false; } | ||||||
| 
 | 
 | ||||||
| 		KGE_DEPRECATED("ActionSpawn is deprecated, use ActionGroup instead") | 		KGE_DEPRECATED("ActionSpawn is deprecated, use ActionGroup instead") | ||||||
| 		inline explicit ActionSpawn(Array<ActionPtr> const& actions) : ActionGroup(actions, false) {} | 		inline explicit ActionSpawn(Vector<ActionPtr> const& actions) : ActionGroup(actions, false) {} | ||||||
| 
 | 
 | ||||||
| 		virtual ~ActionSpawn() {} | 		virtual ~ActionSpawn() {} | ||||||
| 	}; | 	}; | ||||||
|  | @ -19,8 +19,10 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "ActionGroup.h" |  | ||||||
| #include "ActionTween.h" | #include "ActionTween.h" | ||||||
|  | #include "ActionWalk.h" | ||||||
|  | #include "ActionDelay.h" | ||||||
|  | #include "ActionGroup.h" | ||||||
| #include "Animation.h" | #include "Animation.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -100,63 +102,65 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			MoveBy(Point const& vector) | 		MoveBy(Duration dur, Point const& vector) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionMoveBy(0, vector)); | 			return TweenHelper(new kiwano::ActionMoveBy(dur, vector)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			MoveTo(Point const& pos) | 		MoveTo(Duration dur, Point const& pos) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionMoveTo(0, pos)); | 			return TweenHelper(new kiwano::ActionMoveTo(dur, pos)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 		JumpBy( | 		JumpBy( | ||||||
|  | 			Duration dur, | ||||||
| 			Point const& pos,	/* 目的坐标 */ | 			Point const& pos,	/* 目的坐标 */ | ||||||
| 			float height,		/* 跳跃高度 */ | 			float height,		/* 跳跃高度 */ | ||||||
| 			int jumps = 1)		/* 跳跃次数 */ | 			int jumps = 1)		/* 跳跃次数 */ | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionJumpBy(0, pos, height, jumps)); | 			return TweenHelper(new kiwano::ActionJumpBy(dur, pos, height, jumps)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 		JumpTo( | 		JumpTo( | ||||||
|  | 			Duration dur, | ||||||
| 			Point const& pos,	/* 目的坐标 */ | 			Point const& pos,	/* 目的坐标 */ | ||||||
| 			float height,		/* 跳跃高度 */ | 			float height,		/* 跳跃高度 */ | ||||||
| 			int jumps = 1)		/* 跳跃次数 */ | 			int jumps = 1)		/* 跳跃次数 */ | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionJumpTo(0, pos, height, jumps)); | 			return TweenHelper(new kiwano::ActionJumpTo(dur, pos, height, jumps)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			ScaleBy(float scale) | 		ScaleBy(Duration dur, float scale) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionScaleBy(0, scale)); | 			return TweenHelper(new kiwano::ActionScaleBy(dur, scale)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			ScaleBy(float scale_x, float scale_y) | 		ScaleBy(Duration dur, float scale_x, float scale_y) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionScaleBy(0, scale_x, scale_y)); | 			return TweenHelper(new kiwano::ActionScaleBy(dur, scale_x, scale_y)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			ScaleTo(float scale) | 		ScaleTo(Duration dur, float scale) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionScaleTo(0, scale)); | 			return TweenHelper(new kiwano::ActionScaleTo(dur, scale)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			ScaleTo(float scale_x, float scale_y) | 		ScaleTo(Duration dur, float scale_x, float scale_y) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionScaleTo(0, scale_x, scale_y)); | 			return TweenHelper(new kiwano::ActionScaleTo(dur, scale_x, scale_y)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			FadeTo(float opacity) | 		FadeTo(Duration dur, float opacity) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionFadeTo(0, opacity)); | 			return TweenHelper(new kiwano::ActionFadeTo(dur, opacity)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
|  | @ -172,27 +176,53 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			RotateBy(float rotation) | 		RotateBy(Duration dur, float rotation) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionRotateBy(0, rotation)); | 			return TweenHelper(new kiwano::ActionRotateBy(dur, rotation)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			RotateTo(float rotation) | 		RotateTo(Duration dur, float rotation) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionRotateTo(0, rotation)); | 			return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			Animation(FramesPtr frames) | 		Walk( | ||||||
|  | 			Duration duration,		/* 持续时长 */ | ||||||
|  | 			Geometry const& geo,	/* 路线 */ | ||||||
|  | 			bool rotating = false,	/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,		/* 起点 */ | ||||||
|  | 			float end = 1.f,		/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr	/* 速度变化 */ | ||||||
|  | 		) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::Animation(0, frames)); | 			return TweenHelper(new kiwano::ActionWalk(duration, geo, rotating, start, end, func)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			Custom(kiwano::ActionCustom::TweenFunc tween_func) | 		Walk( | ||||||
|  | 			Duration duration,			/* 持续时长 */ | ||||||
|  | 			GeometrySink& sink,			/* 路线生成器 */ | ||||||
|  | 			bool rotating = false,		/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,			/* 起点 */ | ||||||
|  | 			float end = 1.f,			/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr		/* 速度变化 */ | ||||||
|  | 		) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionCustom(0, tween_func)); | 			return TweenHelper(new kiwano::ActionWalk(duration, sink.GetGeometry(), rotating, start, end, func)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static inline TweenHelper | ||||||
|  | 		Animation(Duration dur, FrameSequencePtr frames) | ||||||
|  | 		{ | ||||||
|  | 			return TweenHelper(new kiwano::Animation(dur, frames)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static inline TweenHelper | ||||||
|  | 		Custom(Duration dur, ActionCustom::TweenFunc tween_func) | ||||||
|  | 		{ | ||||||
|  | 			return TweenHelper(new kiwano::ActionCustom(dur, tween_func)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline ActionHelper | 		static inline ActionHelper | ||||||
|  | @ -202,13 +232,13 @@ namespace kiwano | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline ActionHelper | 		static inline ActionHelper | ||||||
| 			Group(Array<ActionPtr> const& actions, bool sequence = true) | 		Group(Vector<ActionPtr> const& actions, bool sequence = true) | ||||||
| 		{ | 		{ | ||||||
| 			return ActionHelper(new kiwano::ActionGroup(actions, sequence)); | 			return ActionHelper(new kiwano::ActionGroup(actions, sequence)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		static inline ActionHelper | 		static inline ActionHelper | ||||||
| 			Multiple(Array<ActionPtr> const& actions) | 		Multiple(Vector<ActionPtr> const& actions) | ||||||
| 		{ | 		{ | ||||||
| 			return ActionHelper(new kiwano::ActionGroup(actions, false)); | 			return ActionHelper(new kiwano::ActionGroup(actions, false)); | ||||||
| 		} | 		} | ||||||
|  | @ -226,21 +256,21 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		KGE_DEPRECATED("Tween::OpacityTo is deprecated, use Tween::FadeTo instead") | 		KGE_DEPRECATED("Tween::OpacityTo is deprecated, use Tween::FadeTo instead") | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 			OpacityTo(float opacity) | 		OpacityTo(Duration dur, float opacity) | ||||||
| 		{ | 		{ | ||||||
| 			return TweenHelper(new kiwano::ActionFadeTo(0, opacity)); | 			return TweenHelper(new kiwano::ActionFadeTo(dur, opacity)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		KGE_DEPRECATED("Tween::Sequence is deprecated, use Tween::Group instead") | 		KGE_DEPRECATED("Tween::Sequence is deprecated, use Tween::Group instead") | ||||||
| 		static inline ActionHelper | 		static inline ActionHelper | ||||||
| 			Sequence(Array<ActionPtr> const& actions) | 		Sequence(Vector<ActionPtr> const& actions) | ||||||
| 		{ | 		{ | ||||||
| 			return ActionHelper(new kiwano::ActionGroup(actions, true)); | 			return ActionHelper(new kiwano::ActionGroup(actions, true)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		KGE_DEPRECATED("Tween::Spawn is deprecated, use Tween::Multiple instead") | 		KGE_DEPRECATED("Tween::Spawn is deprecated, use Tween::Multiple instead") | ||||||
| 		static inline ActionHelper | 		static inline ActionHelper | ||||||
| 			Spawn(Array<ActionPtr> const& actions) | 		Spawn(Vector<ActionPtr> const& actions) | ||||||
| 		{ | 		{ | ||||||
| 			return ActionHelper(new kiwano::ActionGroup(actions, false)); | 			return ActionHelper(new kiwano::ActionGroup(actions, false)); | ||||||
| 		} | 		} | ||||||
|  | @ -19,26 +19,26 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "ActionManager.h" | #include "ActionManager.h" | ||||||
| #include "Actor.h" | #include "../Actor.h" | ||||||
| #include "../base/logs.h" | #include "../../base/Logger.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	void ActionManager::UpdateActions(ActorPtr target, Duration dt) | 	void ActionManager::UpdateActions(ActorPtr target, Duration dt) | ||||||
| 	{ | 	{ | ||||||
| 		if (actions_.IsEmpty() || !target) | 		if (actions_.is_empty() || !target) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		ActionPtr next; | 		ActionPtr next; | ||||||
| 		for (auto action = actions_.First(); action; action = next) | 		for (auto action = actions_.first_item(); action; action = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = action->NextItem(); | 			next = action->next_item(); | ||||||
| 
 | 
 | ||||||
| 			if (action->IsRunning()) | 			if (action->IsRunning()) | ||||||
| 				action->UpdateStep(target, dt); | 				action->UpdateStep(target, dt); | ||||||
| 
 | 
 | ||||||
| 			if (action->IsRemoveable()) | 			if (action->IsRemoveable()) | ||||||
| 				actions_.Remove(action); | 				actions_.remove_item(action); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -48,17 +48,17 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (action) | 		if (action) | ||||||
| 		{ | 		{ | ||||||
| 			actions_.PushBack(action); | 			actions_.push_back_item(action); | ||||||
| 		} | 		} | ||||||
| 		return action; | 		return action; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ActionPtr ActionManager::GetAction(String const & name) | 	ActionPtr ActionManager::GetAction(String const & name) | ||||||
| 	{ | 	{ | ||||||
| 		if (actions_.IsEmpty()) | 		if (actions_.is_empty()) | ||||||
| 			return nullptr; | 			return nullptr; | ||||||
| 
 | 
 | ||||||
| 		for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) | 		for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) | ||||||
| 			if (action->IsName(name)) | 			if (action->IsName(name)) | ||||||
| 				return action; | 				return action; | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
|  | @ -66,10 +66,10 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void ActionManager::ResumeAllActions() | 	void ActionManager::ResumeAllActions() | ||||||
| 	{ | 	{ | ||||||
| 		if (actions_.IsEmpty()) | 		if (actions_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) | 		for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			action->Resume(); | 			action->Resume(); | ||||||
| 		} | 		} | ||||||
|  | @ -77,10 +77,10 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void ActionManager::PauseAllActions() | 	void ActionManager::PauseAllActions() | ||||||
| 	{ | 	{ | ||||||
| 		if (actions_.IsEmpty()) | 		if (actions_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) | 		for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			action->Pause(); | 			action->Pause(); | ||||||
| 		} | 		} | ||||||
|  | @ -88,10 +88,10 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void ActionManager::StopAllActions() | 	void ActionManager::StopAllActions() | ||||||
| 	{ | 	{ | ||||||
| 		if (actions_.IsEmpty()) | 		if (actions_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) | 		for (auto action = actions_.first_item().get(); action; action = action->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			action->Stop(); | 			action->Stop(); | ||||||
| 		} | 		} | ||||||
|  | @ -25,7 +25,7 @@ namespace kiwano | ||||||
| { | { | ||||||
| 	class KGE_API ActionManager | 	class KGE_API ActionManager | ||||||
| 	{ | 	{ | ||||||
| 		using Actions = IntrusiveList<ActionPtr>; | 		using Actions = intrusive_list<ActionPtr>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		// 添加动作
 | 		// 添加动作
 | ||||||
|  | @ -19,8 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "ActionTween.h" | #include "ActionTween.h" | ||||||
| #include "include-forwards.h" | #include "../Actor.h" | ||||||
| #include "Actor.h" |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -420,218 +419,6 @@ namespace kiwano | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// ActionPath
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	ActionPath::ActionPath(Duration duration, bool rotating, float start, float end, EaseFunc func) |  | ||||||
| 		: ActionTween(duration, func) |  | ||||||
| 		, start_(start) |  | ||||||
| 		, end_(end) |  | ||||||
| 		, rotating_(rotating) |  | ||||||
| 		, path_beginning_(false) |  | ||||||
| 		, geo_(nullptr) |  | ||||||
| 		, geo_sink_(nullptr) |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionPath::Clone() const |  | ||||||
| 	{ |  | ||||||
| 		ActionPathPtr clone = new ActionPath(dur_, rotating_, start_, end_, ease_func_); |  | ||||||
| 		if (clone) |  | ||||||
| 		{ |  | ||||||
| 			clone->SetGeometry(geo_); |  | ||||||
| 		} |  | ||||||
| 		return clone; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionPath::Reverse() const |  | ||||||
| 	{ |  | ||||||
| 		ActionPathPtr reverse = new ActionPath(dur_, rotating_, end_, start_, ease_func_); |  | ||||||
| 		if (reverse) |  | ||||||
| 		{ |  | ||||||
| 			reverse->SetGeometry(geo_); |  | ||||||
| 		} |  | ||||||
| 		return reverse; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float ActionPath::GetPathLength() const |  | ||||||
| 	{ |  | ||||||
| 		float length = 0.f; |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			// no matter it failed or not
 |  | ||||||
| 			geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); |  | ||||||
| 		} |  | ||||||
| 		return length; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool ActionPath::ComputePointAtLength(float length, Point* point, Vec2* tangent) const |  | ||||||
| 	{ |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			HRESULT hr = geo_->ComputePointAtLength( |  | ||||||
| 				length, |  | ||||||
| 				D2D1::Matrix3x2F::Identity(), |  | ||||||
| 				DX::ConvertToPoint2F(point), |  | ||||||
| 				DX::ConvertToPoint2F(tangent) |  | ||||||
| 			); |  | ||||||
| 			return SUCCEEDED(hr); |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::Init(ActorPtr target) |  | ||||||
| 	{ |  | ||||||
| 		start_pos_ = target->GetPosition(); |  | ||||||
| 
 |  | ||||||
| 		if (path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			EndPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (!geo_) |  | ||||||
| 		{ |  | ||||||
| 			Complete(target); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::UpdateTween(ActorPtr target, float percent) |  | ||||||
| 	{ |  | ||||||
| 		float length = GetPathLength() * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); |  | ||||||
| 
 |  | ||||||
| 		Point point, tangent; |  | ||||||
| 		if (ComputePointAtLength(length, &point, &tangent)) |  | ||||||
| 		{ |  | ||||||
| 			target->SetPosition(start_pos_ + point); |  | ||||||
| 
 |  | ||||||
| 			if (rotating_) |  | ||||||
| 			{ |  | ||||||
| 				float ac = math::Acos(tangent.x); |  | ||||||
| 				float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; |  | ||||||
| 				target->SetRotation(rotation); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::BeginPath() |  | ||||||
| 	{ |  | ||||||
| 		if (path_beginning_) return; |  | ||||||
| 		path_beginning_ = true; |  | ||||||
| 
 |  | ||||||
| 		geo_ = nullptr; |  | ||||||
| 		geo_sink_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 		auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			factory->CreatePathGeometry(&geo_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			geo_->Open(&geo_sink_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		geo_sink_->BeginFigure(DX::ConvertToPoint2F(Point{ 0, 0 }), D2D1_FIGURE_BEGIN_FILLED); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::EndPath(bool closed) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) return; |  | ||||||
| 		path_beginning_ = false; |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); |  | ||||||
| 			ThrowIfFailed( |  | ||||||
| 				geo_sink_->Close() |  | ||||||
| 			); |  | ||||||
| 
 |  | ||||||
| 			// Clear geometry sink
 |  | ||||||
| 			geo_sink_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddLine(Point const& point) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddLine(DX::ConvertToPoint2F(point)); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddLines(Array<Point> const& points) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_ && !points.empty()) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddLines( |  | ||||||
| 				reinterpret_cast<const D2D_POINT_2F*>(&points[0]), |  | ||||||
| 				static_cast<UINT32>(points.size()) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddBezier(Point const& point1, Point const& point2, Point const& point3) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddBezier( |  | ||||||
| 				D2D1::BezierSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point1), |  | ||||||
| 					DX::ConvertToPoint2F(point2), |  | ||||||
| 					DX::ConvertToPoint2F(point3) |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddArc( |  | ||||||
| 				D2D1::ArcSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point), |  | ||||||
| 					DX::ConvertToSizeF(radius), |  | ||||||
| 					rotation, |  | ||||||
| 					clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, |  | ||||||
| 					is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::ClearPath() |  | ||||||
| 	{ |  | ||||||
| 		if (path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			EndPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		geo_sink_ = nullptr; |  | ||||||
| 		geo_ = nullptr; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
| 	// ActionCustom
 | 	// ActionCustom
 | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
|  | @ -659,24 +446,4 @@ namespace kiwano | ||||||
| 			tween_func_(target, percent); | 			tween_func_(target, percent); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// ActionDelay
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	ActionDelay::ActionDelay(Duration delay) |  | ||||||
| 	{ |  | ||||||
| 		SetDelay(delay); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionDelay::Clone() const |  | ||||||
| 	{ |  | ||||||
| 		return new ActionDelay(delay_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionDelay::Reverse() const |  | ||||||
| 	{ |  | ||||||
| 		return new ActionDelay(delay_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | @ -20,13 +20,12 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Action.h" | #include "Action.h" | ||||||
| #include "../base/logs.h" | #include "../../base/Logger.h" | ||||||
| #include "../renderer/render.h"  // ID2D1PathGeometry, ID2D1GeometrySink |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	// 缓动函数
 | 	// 缓动函数
 | ||||||
| 	using EaseFunc = Closure<float(float)>; | 	using EaseFunc = Function<float(float)>; | ||||||
| 
 | 
 | ||||||
| 	// 缓动函数枚举
 | 	// 缓动函数枚举
 | ||||||
| 	// See https://easings.net for more information
 | 	// See https://easings.net for more information
 | ||||||
|  | @ -412,97 +411,12 @@ namespace kiwano | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 路径动作
 |  | ||||||
| 	class KGE_API ActionPath |  | ||||||
| 		: public ActionTween |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		ActionPath( |  | ||||||
| 			Duration duration,		/* 持续时长 */ |  | ||||||
| 			bool rotating = false,	/* 沿路径切线方向旋转 */ |  | ||||||
| 			float start = 0.f,		/* 起点 */ |  | ||||||
| 			float end = 1.f,		/* 终点 */ |  | ||||||
| 			EaseFunc func = nullptr	/* 速度变化 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的拷贝对象
 |  | ||||||
| 		ActionPtr Clone() const override; |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的倒转
 |  | ||||||
| 		ActionPtr Reverse() const override; |  | ||||||
| 
 |  | ||||||
| 		// 开始添加路径
 |  | ||||||
| 		void BeginPath(); |  | ||||||
| 
 |  | ||||||
| 		// 结束路径
 |  | ||||||
| 		void EndPath( |  | ||||||
| 			bool closed = false		/* 路径是否闭合 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加一条线段
 |  | ||||||
| 		void AddLine( |  | ||||||
| 			Point const& point		/* 端点 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加多条线段
 |  | ||||||
| 		void AddLines( |  | ||||||
| 			Array<Point> const& points |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加一条三次方贝塞尔曲线
 |  | ||||||
| 		void AddBezier( |  | ||||||
| 			Point const& point1,	/* 贝塞尔曲线的第一个控制点 */ |  | ||||||
| 			Point const& point2,	/* 贝塞尔曲线的第二个控制点 */ |  | ||||||
| 			Point const& point3		/* 贝塞尔曲线的终点 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加弧线
 |  | ||||||
| 		void AddArc( |  | ||||||
| 			Point const& point,		/* 终点 */ |  | ||||||
| 			Size const& radius,		/* 椭圆半径 */ |  | ||||||
| 			float rotation,			/* 椭圆旋转角度 */ |  | ||||||
| 			bool clockwise = true,	/* 顺时针 or 逆时针 */ |  | ||||||
| 			bool is_small = true	/* 是否取小于 180° 的弧 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 清除路径
 |  | ||||||
| 		void ClearPath(); |  | ||||||
| 
 |  | ||||||
| 		// 获取路径长度
 |  | ||||||
| 		float GetPathLength() const; |  | ||||||
| 
 |  | ||||||
| 		// 计算当前路径上指定点坐标和切线
 |  | ||||||
| 		bool ComputePointAtLength(float length, Point* point, Vec2* tangent) const; |  | ||||||
| 
 |  | ||||||
| 		// 获取几何路径
 |  | ||||||
| 		inline ComPtr<ID2D1PathGeometry> GetGeometry() const	{ return geo_; } |  | ||||||
| 
 |  | ||||||
| 		// 设置几何路径
 |  | ||||||
| 		inline void SetGeometry(ComPtr<ID2D1PathGeometry> geo)	{ geo_ = geo; } |  | ||||||
| 
 |  | ||||||
| 	protected: |  | ||||||
| 		void Init(ActorPtr target) override; |  | ||||||
| 
 |  | ||||||
| 		void UpdateTween(ActorPtr target, float percent) override; |  | ||||||
| 
 |  | ||||||
| 	protected: |  | ||||||
| 		bool	path_beginning_; |  | ||||||
| 		bool	rotating_; |  | ||||||
| 		float	start_; |  | ||||||
| 		float	end_; |  | ||||||
| 		Point	start_pos_; |  | ||||||
| 
 |  | ||||||
| 		ComPtr<ID2D1PathGeometry> geo_; |  | ||||||
| 		ComPtr<ID2D1GeometrySink> geo_sink_; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// 自定义动作
 | 	// 自定义动作
 | ||||||
| 	class KGE_API ActionCustom | 	class KGE_API ActionCustom | ||||||
| 		: public ActionTween | 		: public ActionTween | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		using TweenFunc = Closure<void(ActorPtr, float)>; | 		using TweenFunc = Function<void(ActorPtr, float)>; | ||||||
| 
 | 
 | ||||||
| 		ActionCustom( | 		ActionCustom( | ||||||
| 			Duration duration,		/* 持续时长 */ | 			Duration duration,		/* 持续时长 */ | ||||||
|  | @ -529,20 +443,4 @@ namespace kiwano | ||||||
| 		TweenFunc tween_func_; | 		TweenFunc tween_func_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	// 延时动作
 |  | ||||||
| 	class KGE_API ActionDelay |  | ||||||
| 		: public Action |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		ActionDelay( |  | ||||||
| 			Duration delay		/* 持续时长 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的拷贝对象
 |  | ||||||
| 		ActionPtr Clone() const override; |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的倒转
 |  | ||||||
| 		ActionPtr Reverse() const override; |  | ||||||
| 	}; |  | ||||||
| } | } | ||||||
|  | @ -0,0 +1,127 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #include "ActionWalk.h" | ||||||
|  | #include "../Actor.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	ActionWalk::ActionWalk(Duration duration, bool rotating, float start, float end, EaseFunc func) | ||||||
|  | 		: ActionTween(duration, func) | ||||||
|  | 		, start_(start) | ||||||
|  | 		, end_(end) | ||||||
|  | 		, rotating_(rotating) | ||||||
|  | 		, length_(0.f) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionWalk::ActionWalk(Duration duration, Geometry const& path, bool rotating, float start, float end, EaseFunc func) | ||||||
|  | 		: ActionWalk(duration, rotating, start, end, func) | ||||||
|  | 	{ | ||||||
|  | 		path_ = path; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionWalk::Clone() const | ||||||
|  | 	{ | ||||||
|  | 		ActionWalkPtr clone = new ActionWalk(dur_, rotating_, start_, end_, ease_func_); | ||||||
|  | 		if (clone) | ||||||
|  | 		{ | ||||||
|  | 			clone->SetPath(path_); | ||||||
|  | 		} | ||||||
|  | 		return clone; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionWalk::Reverse() const | ||||||
|  | 	{ | ||||||
|  | 		ActionWalkPtr reverse = new ActionWalk(dur_, rotating_, end_, start_, ease_func_); | ||||||
|  | 		if (reverse) | ||||||
|  | 		{ | ||||||
|  | 			reverse->SetPath(path_); | ||||||
|  | 		} | ||||||
|  | 		return reverse; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::Init(ActorPtr target) | ||||||
|  | 	{ | ||||||
|  | 		if (!path_) | ||||||
|  | 		{ | ||||||
|  | 			Complete(target); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		start_pos_ = target->GetPosition(); | ||||||
|  | 		length_ = path_.GetLength(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::UpdateTween(ActorPtr target, float percent) | ||||||
|  | 	{ | ||||||
|  | 		float distance = length_ * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); | ||||||
|  | 
 | ||||||
|  | 		Point point, tangent; | ||||||
|  | 		if (path_.ComputePointAtLength(distance, point, tangent)) | ||||||
|  | 		{ | ||||||
|  | 			target->SetPosition(start_pos_ + point); | ||||||
|  | 
 | ||||||
|  | 			if (rotating_) | ||||||
|  | 			{ | ||||||
|  | 				float ac = math::Acos(tangent.x); | ||||||
|  | 				float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; | ||||||
|  | 				target->SetRotation(rotation); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::BeginPath() | ||||||
|  | 	{ | ||||||
|  | 		sink_.BeginPath(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::EndPath(bool closed) | ||||||
|  | 	{ | ||||||
|  | 		sink_.EndPath(closed); | ||||||
|  | 		path_ = sink_.GetGeometry(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddLine(Point const& point) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddLine(point); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddLines(Vector<Point> const& points) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddLines(points); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddBezier(point1, point2, point3); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::ClearPath() | ||||||
|  | 	{ | ||||||
|  | 		path_.SetGeometry(nullptr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,112 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "ActionTween.h" | ||||||
|  | #include "../../renderer/Geometry.h"  // Geometry, GeometrySink | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	// 路线行走动作
 | ||||||
|  | 	class KGE_API ActionWalk | ||||||
|  | 		: public ActionTween | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		ActionWalk( | ||||||
|  | 			Duration duration,		/* 持续时长 */ | ||||||
|  | 			bool rotating = false,	/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,		/* 起点 */ | ||||||
|  | 			float end = 1.f,		/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr	/* 速度变化 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		ActionWalk( | ||||||
|  | 			Duration duration,		/* 持续时长 */ | ||||||
|  | 			Geometry const& path,	/* 路线 */ | ||||||
|  | 			bool rotating = false,	/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,		/* 起点 */ | ||||||
|  | 			float end = 1.f,		/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr	/* 速度变化 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 获取该动作的拷贝对象
 | ||||||
|  | 		ActionPtr Clone() const override; | ||||||
|  | 
 | ||||||
|  | 		// 获取该动作的倒转
 | ||||||
|  | 		ActionPtr Reverse() const override; | ||||||
|  | 
 | ||||||
|  | 		// 开始添加路线
 | ||||||
|  | 		void BeginPath(); | ||||||
|  | 
 | ||||||
|  | 		// 结束路线
 | ||||||
|  | 		void EndPath( | ||||||
|  | 			bool closed = false		/* 路线是否闭合 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加一条线段
 | ||||||
|  | 		void AddLine( | ||||||
|  | 			Point const& point		/* 端点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加多条线段
 | ||||||
|  | 		void AddLines( | ||||||
|  | 			Vector<Point> const& points | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加一条三次方贝塞尔曲线
 | ||||||
|  | 		void AddBezier( | ||||||
|  | 			Point const& point1,	/* 贝塞尔曲线的第一个控制点 */ | ||||||
|  | 			Point const& point2,	/* 贝塞尔曲线的第二个控制点 */ | ||||||
|  | 			Point const& point3		/* 贝塞尔曲线的终点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加弧线
 | ||||||
|  | 		void AddArc( | ||||||
|  | 			Point const& point,		/* 终点 */ | ||||||
|  | 			Size const& radius,		/* 椭圆半径 */ | ||||||
|  | 			float rotation,			/* 椭圆旋转角度 */ | ||||||
|  | 			bool clockwise = true,	/* 顺时针 or 逆时针 */ | ||||||
|  | 			bool is_small = true	/* 是否取小于 180° 的弧 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 清除路径
 | ||||||
|  | 		void ClearPath(); | ||||||
|  | 
 | ||||||
|  | 		// 获取路线
 | ||||||
|  | 		inline Geometry GetPath() const		{ return path_; } | ||||||
|  | 
 | ||||||
|  | 		// 设置路径
 | ||||||
|  | 		inline void SetPath(Geometry path)	{ path_ = path; } | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		void Init(ActorPtr target) override; | ||||||
|  | 
 | ||||||
|  | 		void UpdateTween(ActorPtr target, float percent) override; | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		bool			rotating_; | ||||||
|  | 		float			start_; | ||||||
|  | 		float			end_; | ||||||
|  | 		float			length_; | ||||||
|  | 		Point			start_pos_; | ||||||
|  | 		Geometry		path_; | ||||||
|  | 		GeometrySink	sink_; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | @ -19,80 +19,79 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Animation.h" | #include "Animation.h" | ||||||
| #include "Frames.h" | #include "../FrameSequence.h" | ||||||
| #include "Image.h" | #include "../Sprite.h" | ||||||
| #include "Sprite.h" |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	Animation::Animation() | 	Animation::Animation() | ||||||
| 		: frames_(nullptr) | 		: frame_seq_(nullptr) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Animation::Animation(Duration duration, FramesPtr animation, EaseFunc func) | 	Animation::Animation(Duration duration, FrameSequencePtr frame_seq, EaseFunc func) | ||||||
| 		: ActionTween(duration, func) | 		: ActionTween(duration, func) | ||||||
| 		, frames_(nullptr) | 		, frame_seq_(nullptr) | ||||||
| 	{ | 	{ | ||||||
| 		this->SetFrames(animation); | 		this->SetFrameSequence(frame_seq); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Animation::~Animation() | 	Animation::~Animation() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	FramesPtr Animation::GetFrames() const | 	FrameSequencePtr Animation::GetFrameSequence() const | ||||||
| 	{ | 	{ | ||||||
| 		return frames_; | 		return frame_seq_; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Animation::SetFrames(FramesPtr frames) | 	void Animation::SetFrameSequence(FrameSequencePtr frames) | ||||||
| 	{ | 	{ | ||||||
| 		frames_ = frames; | 		frame_seq_ = frames; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Animation::Init(ActorPtr target) | 	void Animation::Init(ActorPtr target) | ||||||
| 	{ | 	{ | ||||||
| 		if (!frames_ || frames_->GetFrames().empty()) | 		if (!frame_seq_ || frame_seq_->GetFrames().empty()) | ||||||
| 		{ | 		{ | ||||||
| 			Done(); | 			Done(); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		auto sprite_target = dynamic_cast<Sprite*>(target.Get()); | 		auto sprite_target = dynamic_cast<Sprite*>(target.get()); | ||||||
| 		if (sprite_target && frames_) | 		if (sprite_target && frame_seq_) | ||||||
| 		{ | 		{ | ||||||
| 			sprite_target->Load(frames_->GetFrames()[0]); | 			sprite_target->SetFrame(frame_seq_->GetFrames()[0]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Animation::UpdateTween(ActorPtr target, float percent) | 	void Animation::UpdateTween(ActorPtr target, float percent) | ||||||
| 	{ | 	{ | ||||||
| 		auto sprite_target = dynamic_cast<Sprite*>(target.Get()); | 		auto sprite_target = dynamic_cast<Sprite*>(target.get()); | ||||||
| 
 | 
 | ||||||
| 		KGE_ASSERT(sprite_target && "Animation only supports Sprites"); | 		KGE_ASSERT(sprite_target && "Animation only supports Sprites"); | ||||||
| 
 | 
 | ||||||
| 		const auto& frames = frames_->GetFrames(); | 		const auto& frames = frame_seq_->GetFrames(); | ||||||
| 		auto size = frames.size(); | 		auto size = frames.size(); | ||||||
| 		auto index = std::min(static_cast<size_t>(math::Floor(size * percent)), size - 1); | 		auto index = std::min(static_cast<size_t>(math::Floor(size * percent)), size - 1); | ||||||
| 
 | 
 | ||||||
| 		sprite_target->Load(frames[index]); | 		sprite_target->SetFrame(frames[index]); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ActionPtr Animation::Clone() const | 	ActionPtr Animation::Clone() const | ||||||
| 	{ | 	{ | ||||||
| 		if (frames_) | 		if (frame_seq_) | ||||||
| 		{ | 		{ | ||||||
| 			return new (std::nothrow) Animation(dur_, frames_, ease_func_); | 			return new (std::nothrow) Animation(dur_, frame_seq_, ease_func_); | ||||||
| 		} | 		} | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ActionPtr Animation::Reverse() const | 	ActionPtr Animation::Reverse() const | ||||||
| 	{ | 	{ | ||||||
| 		if (frames_) | 		if (frame_seq_) | ||||||
| 		{ | 		{ | ||||||
| 			FramesPtr frames = frames_->Reverse(); | 			FrameSequencePtr frames = frame_seq_->Reverse(); | ||||||
| 			if (frames) | 			if (frames) | ||||||
| 			{ | 			{ | ||||||
| 				return new (std::nothrow) Animation(dur_, frames, ease_func_); | 				return new (std::nothrow) Animation(dur_, frames, ease_func_); | ||||||
|  | @ -32,18 +32,18 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		Animation( | 		Animation( | ||||||
| 			Duration duration,			/* 动画时长 */ | 			Duration duration,			/* 动画时长 */ | ||||||
| 			FramesPtr frames,			/* ÐòÁÐÖ¡ */ | 			FrameSequencePtr frame_seq,	/* ÐòÁÐÖ¡ */ | ||||||
| 			EaseFunc func = nullptr		/* 速度变化 */ | 			EaseFunc func = nullptr		/* 速度变化 */ | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~Animation(); | 		virtual ~Animation(); | ||||||
| 
 | 
 | ||||||
| 		// 获取动画
 | 		// 获取动画
 | ||||||
| 		FramesPtr GetFrames() const; | 		FrameSequencePtr GetFrameSequence() const; | ||||||
| 
 | 
 | ||||||
| 		// 设置动画
 | 		// 设置动画
 | ||||||
| 		void SetFrames( | 		void SetFrameSequence( | ||||||
| 			FramesPtr frames | 			FrameSequencePtr frames | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// 获取该动作的拷贝对象
 | 		// 获取该动作的拷贝对象
 | ||||||
|  | @ -58,6 +58,6 @@ namespace kiwano | ||||||
| 		void UpdateTween(ActorPtr target, float percent) override; | 		void UpdateTween(ActorPtr target, float percent) override; | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		FramesPtr frames_; | 		FrameSequencePtr frame_seq_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  | @ -20,23 +20,19 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Color.h" | #include "Color.h" | ||||||
| #include "../common/helper.h" | #include "../core/core.h" | ||||||
| #include "../common/ComPtr.hpp" |  | ||||||
| #include "../common/Closure.hpp" |  | ||||||
| #include "../common/Singleton.hpp" |  | ||||||
| #include "../common/IntrusiveList.hpp" |  | ||||||
| #include "../base/time.h" | #include "../base/time.h" | ||||||
| #include "../base/RefCounter.hpp" | #include "../base/RefCounter.hpp" | ||||||
| #include "../base/SmartPtr.hpp" | #include "../base/SmartPtr.hpp" | ||||||
|  | #include "../base/ComPtr.hpp" | ||||||
| #include "../base/Object.h" | #include "../base/Object.h" | ||||||
| #include "../math/helper.h" | #include "../math/helper.h" | ||||||
| #include "../base/types.h" | #include "../base/types.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	KGE_DECLARE_SMART_PTR(Image); | 	KGE_DECLARE_SMART_PTR(Frame); | ||||||
| 	KGE_DECLARE_SMART_PTR(GifImage); | 	KGE_DECLARE_SMART_PTR(FrameSequence); | ||||||
| 	KGE_DECLARE_SMART_PTR(Frames); |  | ||||||
| 
 | 
 | ||||||
| 	KGE_DECLARE_SMART_PTR(Actor); | 	KGE_DECLARE_SMART_PTR(Actor); | ||||||
| 	KGE_DECLARE_SMART_PTR(Stage); | 	KGE_DECLARE_SMART_PTR(Stage); | ||||||
|  | @ -45,13 +41,13 @@ namespace kiwano | ||||||
| 	KGE_DECLARE_SMART_PTR(GifSprite); | 	KGE_DECLARE_SMART_PTR(GifSprite); | ||||||
| 	KGE_DECLARE_SMART_PTR(Text); | 	KGE_DECLARE_SMART_PTR(Text); | ||||||
| 	KGE_DECLARE_SMART_PTR(Canvas); | 	KGE_DECLARE_SMART_PTR(Canvas); | ||||||
| 	KGE_DECLARE_SMART_PTR(ShapeNode); | 	KGE_DECLARE_SMART_PTR(ShapeActor); | ||||||
| 	KGE_DECLARE_SMART_PTR(LineNode); | 	KGE_DECLARE_SMART_PTR(LineActor); | ||||||
| 	KGE_DECLARE_SMART_PTR(RectNode); | 	KGE_DECLARE_SMART_PTR(RectActor); | ||||||
| 	KGE_DECLARE_SMART_PTR(RoundedRectNode); | 	KGE_DECLARE_SMART_PTR(RoundRectActor); | ||||||
| 	KGE_DECLARE_SMART_PTR(CircleNode); | 	KGE_DECLARE_SMART_PTR(CircleActor); | ||||||
| 	KGE_DECLARE_SMART_PTR(EllipseNode); | 	KGE_DECLARE_SMART_PTR(EllipseActor); | ||||||
| 	KGE_DECLARE_SMART_PTR(PathNode); | 	KGE_DECLARE_SMART_PTR(PathActor); | ||||||
| 
 | 
 | ||||||
| 	KGE_DECLARE_SMART_PTR(Action); | 	KGE_DECLARE_SMART_PTR(Action); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionTween); | 	KGE_DECLARE_SMART_PTR(ActionTween); | ||||||
|  | @ -66,7 +62,7 @@ namespace kiwano | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionFadeOut); | 	KGE_DECLARE_SMART_PTR(ActionFadeOut); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionRotateBy); | 	KGE_DECLARE_SMART_PTR(ActionRotateBy); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionRotateTo); | 	KGE_DECLARE_SMART_PTR(ActionRotateTo); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionPath); | 	KGE_DECLARE_SMART_PTR(ActionWalk); | ||||||
| 	KGE_DECLARE_SMART_PTR(Animation); | 	KGE_DECLARE_SMART_PTR(Animation); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionGroup); | 	KGE_DECLARE_SMART_PTR(ActionGroup); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionSpawn); | 	KGE_DECLARE_SMART_PTR(ActionSpawn); | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	AsyncTask::AsyncTask() | 	AsyncTask::AsyncTask() | ||||||
| 		: thread_(MakeClosure(this, &AsyncTask::TaskThread)) | 		: thread_(bind_func(this, &AsyncTask::TaskThread)) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -74,7 +74,7 @@ namespace kiwano | ||||||
| 			func_mutex_.unlock(); | 			func_mutex_.unlock(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		Application::PreformInMainThread(MakeClosure(this, &AsyncTask::Complete)); | 		Application::PreformInMainThread(bind_func(this, &AsyncTask::Complete)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void AsyncTask::Complete() | 	void AsyncTask::Complete() | ||||||
|  |  | ||||||
|  | @ -20,7 +20,6 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Object.h" | #include "Object.h" | ||||||
| #include "../common/Closure.hpp" |  | ||||||
| #include <thread> | #include <thread> | ||||||
| #include <mutex> | #include <mutex> | ||||||
| 
 | 
 | ||||||
|  | @ -28,8 +27,8 @@ namespace kiwano | ||||||
| { | { | ||||||
| 	KGE_DECLARE_SMART_PTR(AsyncTask); | 	KGE_DECLARE_SMART_PTR(AsyncTask); | ||||||
| 
 | 
 | ||||||
| 	typedef Closure<void()> AsyncTaskFunc; | 	typedef Function<void()> AsyncTaskFunc; | ||||||
| 	typedef Closure<void()> AsyncTaskCallback; | 	typedef Function<void()> AsyncTaskCallback; | ||||||
| 
 | 
 | ||||||
| 	class AsyncTask | 	class AsyncTask | ||||||
| 		: public Object | 		: public Object | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "IntrusivePtr.hpp" | #include "../core/intrusive_ptr.hpp" | ||||||
| #include <Unknwnbase.h> | #include <Unknwnbase.h> | ||||||
| #include <type_traits> | #include <type_traits> | ||||||
| 
 | 
 | ||||||
|  | @ -42,6 +42,6 @@ namespace kiwano | ||||||
| 	template< | 	template< | ||||||
| 		typename _Ty, | 		typename _Ty, | ||||||
| 		typename = typename std::enable_if<std::is_base_of<IUnknown, _Ty>::value, int>::type> | 		typename = typename std::enable_if<std::is_base_of<IUnknown, _Ty>::value, int>::type> | ||||||
| 	using ComPtr = IntrusivePtr<_Ty, ComPtrManager>; | 	using ComPtr = intrusive_ptr<_Ty, ComPtrManager>; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | @ -25,6 +25,8 @@ | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | 	class Renderer; | ||||||
|  | 
 | ||||||
| 	class KGE_API Component | 	class KGE_API Component | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
|  | @ -36,7 +38,7 @@ namespace kiwano | ||||||
| 		virtual void AfterUpdate() {} | 		virtual void AfterUpdate() {} | ||||||
| 
 | 
 | ||||||
| 		virtual void BeforeRender() {} | 		virtual void BeforeRender() {} | ||||||
| 		virtual void OnRender() {} | 		virtual void OnRender(Renderer*) {} | ||||||
| 		virtual void AfterRender() {} | 		virtual void AfterRender() {} | ||||||
| 
 | 
 | ||||||
| 		virtual void HandleEvent(Event&) {} | 		virtual void HandleEvent(Event&) {} | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ | ||||||
| #include "../2d/Actor.h" | #include "../2d/Actor.h" | ||||||
| #include "../2d/Stage.h" | #include "../2d/Stage.h" | ||||||
| #include "../2d/Transition.h" | #include "../2d/Transition.h" | ||||||
| #include "../2d/DebugNode.h" | #include "../2d/DebugActor.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -74,15 +74,23 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		if (show) | 		if (show) | ||||||
| 		{ | 		{ | ||||||
| 			if (!debug_node_) | 			if (!debug_actor_) | ||||||
| 				debug_node_ = new DebugNode; | 				debug_actor_ = new DebugActor; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			debug_node_.Reset(); | 			debug_actor_.reset(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void Director::ClearStages() | ||||||
|  | 	{ | ||||||
|  | 		curr_scene_.reset(); | ||||||
|  | 		next_scene_.reset(); | ||||||
|  | 		debug_actor_.reset(); | ||||||
|  | 		transition_.reset(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void Director::OnUpdate(Duration dt) | 	void Director::OnUpdate(Duration dt) | ||||||
| 	{ | 	{ | ||||||
| 		if (transition_) | 		if (transition_) | ||||||
|  | @ -112,23 +120,25 @@ namespace kiwano | ||||||
| 		if (next_scene_) | 		if (next_scene_) | ||||||
| 			next_scene_->Update(dt); | 			next_scene_->Update(dt); | ||||||
| 
 | 
 | ||||||
| 		if (debug_node_) | 		if (debug_actor_) | ||||||
| 			debug_node_->Update(dt); | 			debug_actor_->Update(dt); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Director::OnRender() | 	void Director::OnRender(Renderer* renderer) | ||||||
| 	{ | 	{ | ||||||
| 		if (transition_) | 		if (transition_) | ||||||
| 		{ | 		{ | ||||||
| 			transition_->Render(); | 			transition_->Render(renderer); | ||||||
| 		} | 		} | ||||||
| 		else if (curr_scene_) | 		else if (curr_scene_) | ||||||
| 		{ | 		{ | ||||||
| 			curr_scene_->Render(); | 			curr_scene_->Render(renderer); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (debug_node_) | 		if (debug_actor_) | ||||||
| 			debug_node_->Render(); | 		{ | ||||||
|  | 			debug_actor_->Render(renderer); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Director::AfterRender() | 	void Director::AfterRender() | ||||||
|  | @ -142,8 +152,8 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void Director::HandleEvent(Event& evt) | 	void Director::HandleEvent(Event& evt) | ||||||
| 	{ | 	{ | ||||||
| 		if (debug_node_) | 		if (debug_actor_) | ||||||
| 			debug_node_->Dispatch(evt); | 			debug_actor_->Dispatch(evt); | ||||||
| 
 | 
 | ||||||
| 		if (curr_scene_) | 		if (curr_scene_) | ||||||
| 			curr_scene_->Dispatch(evt); | 			curr_scene_->Dispatch(evt); | ||||||
|  |  | ||||||
|  | @ -20,7 +20,6 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/Singleton.hpp" |  | ||||||
| #include "../2d/include-forwards.h" | #include "../2d/include-forwards.h" | ||||||
| #include "Component.h" | #include "Component.h" | ||||||
| 
 | 
 | ||||||
|  | @ -54,6 +53,9 @@ namespace kiwano | ||||||
| 		// 显示调试信息
 | 		// 显示调试信息
 | ||||||
| 		void ShowDebugInfo(bool show = true); | 		void ShowDebugInfo(bool show = true); | ||||||
| 
 | 
 | ||||||
|  | 		// 헌왕校憩
 | ||||||
|  | 		void ClearStages(); | ||||||
|  | 
 | ||||||
| 	public: | 	public: | ||||||
| 		void SetupComponent() override {} | 		void SetupComponent() override {} | ||||||
| 
 | 
 | ||||||
|  | @ -61,7 +63,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		void OnUpdate(Duration dt) override; | 		void OnUpdate(Duration dt) override; | ||||||
| 
 | 
 | ||||||
| 		void OnRender() override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
| 		void AfterRender() override; | 		void AfterRender() override; | ||||||
| 
 | 
 | ||||||
|  | @ -76,7 +78,7 @@ namespace kiwano | ||||||
| 		bool			render_border_enabled_; | 		bool			render_border_enabled_; | ||||||
| 		StagePtr		curr_scene_; | 		StagePtr		curr_scene_; | ||||||
| 		StagePtr		next_scene_; | 		StagePtr		next_scene_; | ||||||
| 		ActorPtr			debug_node_; | 		ActorPtr		debug_actor_; | ||||||
| 		TransitionPtr	transition_; | 		TransitionPtr	transition_; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,19 +19,19 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "EventDispatcher.h" | #include "EventDispatcher.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	void EventDispatcher::Dispatch(Event& evt) | 	void EventDispatcher::Dispatch(Event& evt) | ||||||
| 	{ | 	{ | ||||||
| 		if (listeners_.IsEmpty()) | 		if (listeners_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		EventListenerPtr next; | 		EventListenerPtr next; | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = next) | 		for (auto listener = listeners_.first_item(); listener; listener = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = listener->NextItem(); | 			next = listener->next_item(); | ||||||
| 
 | 
 | ||||||
| 			if (listener->type_ == evt.type) | 			if (listener->type_ == evt.type) | ||||||
| 			{ | 			{ | ||||||
|  | @ -46,7 +46,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 		if (listener) | 		if (listener) | ||||||
| 		{ | 		{ | ||||||
| 			listeners_.PushBack(listener); | 			listeners_.push_back_item(listener); | ||||||
| 		} | 		} | ||||||
| 		return listener; | 		return listener; | ||||||
| 	} | 	} | ||||||
|  | @ -56,13 +56,13 @@ namespace kiwano | ||||||
| 		EventListenerPtr listener = new EventListener(type, callback, name); | 		EventListenerPtr listener = new EventListener(type, callback, name); | ||||||
| 		if (listener) | 		if (listener) | ||||||
| 		{ | 		{ | ||||||
| 			listeners_.PushBack(listener); | 			listeners_.push_back_item(listener); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void EventDispatcher::StartListeners(String const & listener_name) | 	void EventDispatcher::StartListeners(String const & listener_name) | ||||||
| 	{ | 	{ | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = listener->NextItem()) | 		for (auto listener = listeners_.first_item(); listener; listener = listener->next_item()) | ||||||
| 		{ | 		{ | ||||||
| 			if (listener->IsName(listener_name)) | 			if (listener->IsName(listener_name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -73,7 +73,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void EventDispatcher::StopListeners(String const & listener_name) | 	void EventDispatcher::StopListeners(String const & listener_name) | ||||||
| 	{ | 	{ | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = listener->NextItem()) | 		for (auto listener = listeners_.first_item(); listener; listener = listener->next_item()) | ||||||
| 		{ | 		{ | ||||||
| 			if (listener->IsName(listener_name)) | 			if (listener->IsName(listener_name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -85,20 +85,20 @@ namespace kiwano | ||||||
| 	void EventDispatcher::RemoveListeners(String const & listener_name) | 	void EventDispatcher::RemoveListeners(String const & listener_name) | ||||||
| 	{ | 	{ | ||||||
| 		EventListenerPtr next; | 		EventListenerPtr next; | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = next) | 		for (auto listener = listeners_.first_item(); listener; listener = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = listener->NextItem(); | 			next = listener->next_item(); | ||||||
| 
 | 
 | ||||||
| 			if (listener->IsName(listener_name)) | 			if (listener->IsName(listener_name)) | ||||||
| 			{ | 			{ | ||||||
| 				listeners_.Remove(listener); | 				listeners_.remove_item(listener); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void EventDispatcher::StartListeners(UINT type) | 	void EventDispatcher::StartListeners(UINT type) | ||||||
| 	{ | 	{ | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = listener->NextItem()) | 		for (auto listener = listeners_.first_item(); listener; listener = listener->next_item()) | ||||||
| 		{ | 		{ | ||||||
| 			if (listener->type_ == type) | 			if (listener->type_ == type) | ||||||
| 			{ | 			{ | ||||||
|  | @ -109,7 +109,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void EventDispatcher::StopListeners(UINT type) | 	void EventDispatcher::StopListeners(UINT type) | ||||||
| 	{ | 	{ | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = listener->NextItem()) | 		for (auto listener = listeners_.first_item(); listener; listener = listener->next_item()) | ||||||
| 		{ | 		{ | ||||||
| 			if (listener->type_ == type) | 			if (listener->type_ == type) | ||||||
| 			{ | 			{ | ||||||
|  | @ -121,13 +121,13 @@ namespace kiwano | ||||||
| 	void EventDispatcher::RemoveListeners(UINT type) | 	void EventDispatcher::RemoveListeners(UINT type) | ||||||
| 	{ | 	{ | ||||||
| 		EventListenerPtr next; | 		EventListenerPtr next; | ||||||
| 		for (auto listener = listeners_.First(); listener; listener = next) | 		for (auto listener = listeners_.first_item(); listener; listener = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = listener->NextItem(); | 			next = listener->next_item(); | ||||||
| 
 | 
 | ||||||
| 			if (listener->type_ == type) | 			if (listener->type_ == type) | ||||||
| 			{ | 			{ | ||||||
| 				listeners_.Remove(listener); | 				listeners_.remove_item(listener); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ namespace kiwano | ||||||
| { | { | ||||||
| 	class KGE_API EventDispatcher | 	class KGE_API EventDispatcher | ||||||
| 	{ | 	{ | ||||||
| 		using Listeners = IntrusiveList<EventListenerPtr>; | 		using Listeners = intrusive_list<EventListenerPtr>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		// 添加监听器
 | 		// 添加监听器
 | ||||||
|  |  | ||||||
|  | @ -19,17 +19,14 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
|  | #include "../core/core.h" | ||||||
| #include "../base/SmartPtr.hpp" | #include "../base/SmartPtr.hpp" | ||||||
| #include "../common/helper.h" |  | ||||||
| #include "../common/Closure.hpp" |  | ||||||
| #include "../common/IntrusiveList.hpp" |  | ||||||
| #include "Object.h" | #include "Object.h" | ||||||
| #include "Event.hpp" | #include "Event.hpp" | ||||||
| #include <functional> |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	typedef Closure<void(Event const&)> EventCallback; | 	typedef Function<void(Event const&)> EventCallback; | ||||||
| 
 | 
 | ||||||
| 	class EventDispatcher; | 	class EventDispatcher; | ||||||
| 
 | 
 | ||||||
|  | @ -38,10 +35,10 @@ namespace kiwano | ||||||
| 	// 事件监听器
 | 	// 事件监听器
 | ||||||
| 	class KGE_API EventListener | 	class KGE_API EventListener | ||||||
| 		: public Object | 		: public Object | ||||||
| 		, protected IntrusiveListItem<EventListenerPtr> | 		, protected intrusive_list_item<EventListenerPtr> | ||||||
| 	{ | 	{ | ||||||
| 		friend class EventDispatcher; | 		friend class EventDispatcher; | ||||||
| 		friend class IntrusiveList<EventListenerPtr>; | 		friend class intrusive_list<EventListenerPtr>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		EventListener( | 		EventListener( | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "input.h" | #include "input.h" | ||||||
| #include "logs.h" | #include "Logger.h" | ||||||
| #include <windowsx.h>  // GET_X_LPARAM, GET_Y_LPARAM
 | #include <windowsx.h>  // GET_X_LPARAM, GET_Y_LPARAM
 | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/Singleton.hpp" | #include "../core/core.h" | ||||||
| #include "../math/helper.h" | #include "../math/helper.h" | ||||||
| #include "keys.hpp" | #include "keys.hpp" | ||||||
| #include "Component.h" | #include "Component.h" | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "logs.h" | #include "Logger.h" | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| 
 | 
 | ||||||
|  | @ -20,25 +20,33 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/Singleton.hpp" | #include "../core/core.h" | ||||||
| #include <ctime> | #include <ctime> | ||||||
| #include <iomanip> | #include <iomanip> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| 
 | 
 | ||||||
| #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 | ||||||
|  | 
 | ||||||
|  | #ifndef KGE_PRINT | ||||||
|  | #	define KGE_PRINT(...) ::kiwano::Logger::GetInstance()->Println(__VA_ARGS__) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef KGE_PRINTF | ||||||
|  | #	define KGE_PRINTF(FORMAT, ...) ::kiwano::Logger::GetInstance()->Printf((FORMAT), __VA_ARGS__) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -274,7 +282,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; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Object.h" | #include "Object.h" | ||||||
| #include "logs.h" | #include "Logger.h" | ||||||
| #include <typeinfo> | #include <typeinfo> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -27,7 +27,7 @@ namespace kiwano | ||||||
| 	namespace | 	namespace | ||||||
| 	{ | 	{ | ||||||
| 		bool tracing_leaks = false; | 		bool tracing_leaks = false; | ||||||
| 		Array<Object*> tracing_objects; | 		Vector<Object*> tracing_objects; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	unsigned int Object::last_object_id = 0; | 	unsigned int Object::last_object_id = 0; | ||||||
|  | @ -120,7 +120,7 @@ namespace kiwano | ||||||
| 		KGE_LOG(L"------------------------- Total size: %d -------------------------", tracing_objects.size()); | 		KGE_LOG(L"------------------------- Total size: %d -------------------------", tracing_objects.size()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Array<Object*>& kiwano::Object::__GetTracingObjects() | 	Vector<Object*>& kiwano::Object::__GetTracingObjects() | ||||||
| 	{ | 	{ | ||||||
| 		return tracing_objects; | 		return tracing_objects; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/helper.h" | #include "../core/core.h" | ||||||
| #include "RefCounter.hpp" | #include "RefCounter.hpp" | ||||||
| #include "SmartPtr.hpp" | #include "SmartPtr.hpp" | ||||||
| 
 | 
 | ||||||
|  | @ -60,7 +60,7 @@ namespace kiwano | ||||||
| 		static void DumpTracingObjects(); | 		static void DumpTracingObjects(); | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		static Array<Object*>& __GetTracingObjects(); | 		static Vector<Object*>& __GetTracingObjects(); | ||||||
| 
 | 
 | ||||||
| 		static void __AddObjectToTracingList(Object*); | 		static void __AddObjectToTracingList(Object*); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,12 +20,12 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/Noncopyable.hpp" | #include "../core/noncopyable.hpp" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	class KGE_API RefCounter | 	class KGE_API RefCounter | ||||||
| 		: protected Noncopyable | 		: protected noncopyable | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
| 		// 增加引用计数
 | 		// 增加引用计数
 | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "Resource.h" | #include "Resource.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -62,7 +62,7 @@ namespace kiwano | ||||||
| 	size_t Resource::GetHashCode() const | 	size_t Resource::GetHashCode() const | ||||||
| 	{ | 	{ | ||||||
| 		if (type_ == Type::File) | 		if (type_ == Type::File) | ||||||
| 			return std::hash<String>{}(GetFileName()); | 			return GetFileName().hash(); | ||||||
| 		return std::hash<LPCWSTR>{}(bin_name_); | 		return std::hash<LPCWSTR>{}(bin_name_); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/helper.h" | #include "../core/core.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../base/RefCounter.hpp" | #include "../base/RefCounter.hpp" | ||||||
| #include "../common/IntrusivePtr.hpp" | #include "../core/intrusive_ptr.hpp" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -38,7 +38,7 @@ namespace kiwano | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	template <typename _Ty> | 	template <typename _Ty> | ||||||
| 	using SmartPtr = IntrusivePtr<_Ty, DefaultIntrusivePtrManager>; | 	using SmartPtr = intrusive_ptr<_Ty, DefaultIntrusivePtrManager>; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,9 +19,6 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../common/helper.h" |  | ||||||
| #include "../common/Closure.hpp" |  | ||||||
| #include "../common/IntrusiveList.hpp" |  | ||||||
| #include "Object.h" | #include "Object.h" | ||||||
| #include "time.h" | #include "time.h" | ||||||
| #include <functional> | #include <functional> | ||||||
|  | @ -35,12 +32,12 @@ namespace kiwano | ||||||
|     // 定时任务
 |     // 定时任务
 | ||||||
| 	class KGE_API Timer | 	class KGE_API Timer | ||||||
| 		: public Object | 		: public Object | ||||||
| 		, protected IntrusiveListItem<TimerPtr> | 		, protected intrusive_list_item<TimerPtr> | ||||||
| 	{ | 	{ | ||||||
| 		friend class TimerManager; | 		friend class TimerManager; | ||||||
| 		friend class IntrusiveList<TimerPtr>; | 		friend class intrusive_list<TimerPtr>; | ||||||
| 
 | 
 | ||||||
| 		using Callback = Closure<void()>; | 		using Callback = Function<void()>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		explicit Timer( | 		explicit Timer( | ||||||
|  |  | ||||||
|  | @ -19,25 +19,25 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "TimerManager.h" | #include "TimerManager.h" | ||||||
| #include "../base/logs.h" | #include "../base/Logger.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	void TimerManager::UpdateTimers(Duration dt) | 	void TimerManager::UpdateTimers(Duration dt) | ||||||
| 	{ | 	{ | ||||||
| 		if (timers_.IsEmpty()) | 		if (timers_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		TimerPtr next; | 		TimerPtr next; | ||||||
| 		for (auto timer = timers_.First(); timer; timer = next) | 		for (auto timer = timers_.first_item(); timer; timer = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = timer->NextItem(); | 			next = timer->next_item(); | ||||||
| 
 | 
 | ||||||
| 			bool remove_after_update = false; | 			bool remove_after_update = false; | ||||||
| 			timer->Update(dt, remove_after_update); | 			timer->Update(dt, remove_after_update); | ||||||
| 
 | 
 | ||||||
| 			if (remove_after_update) | 			if (remove_after_update) | ||||||
| 				timers_.Remove(timer); | 				timers_.remove_item(timer); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -48,16 +48,16 @@ namespace kiwano | ||||||
| 		if (timer) | 		if (timer) | ||||||
| 		{ | 		{ | ||||||
| 			timer->Reset(); | 			timer->Reset(); | ||||||
| 			timers_.PushBack(timer); | 			timers_.push_back_item(timer); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void TimerManager::StopTimers(String const& name) | 	void TimerManager::StopTimers(String const& name) | ||||||
| 	{ | 	{ | ||||||
| 		if (timers_.IsEmpty()) | 		if (timers_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get()) | 		for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			if (timer->IsName(name)) | 			if (timer->IsName(name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -68,10 +68,10 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void TimerManager::StartTimers(String const& name) | 	void TimerManager::StartTimers(String const& name) | ||||||
| 	{ | 	{ | ||||||
| 		if (timers_.IsEmpty()) | 		if (timers_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 		 | 		 | ||||||
| 		for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get()) | 		for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			if (timer->IsName(name)) | 			if (timer->IsName(name)) | ||||||
| 			{ | 			{ | ||||||
|  | @ -82,26 +82,26 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void TimerManager::RemoveTimers(String const& name) | 	void TimerManager::RemoveTimers(String const& name) | ||||||
| 	{ | 	{ | ||||||
| 		if (timers_.IsEmpty()) | 		if (timers_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		TimerPtr next; | 		TimerPtr next; | ||||||
| 		for (auto timer = timers_.First(); timer; timer = next) | 		for (auto timer = timers_.first_item(); timer; timer = next) | ||||||
| 		{ | 		{ | ||||||
| 			next = timer->NextItem(); | 			next = timer->next_item(); | ||||||
| 			if (timer->IsName(name)) | 			if (timer->IsName(name)) | ||||||
| 			{ | 			{ | ||||||
| 				timers_.Remove(timer); | 				timers_.remove_item(timer); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void TimerManager::StopAllTimers() | 	void TimerManager::StopAllTimers() | ||||||
| 	{ | 	{ | ||||||
| 		if (timers_.IsEmpty()) | 		if (timers_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get()) | 		for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			timer->Stop(); | 			timer->Stop(); | ||||||
| 		} | 		} | ||||||
|  | @ -109,10 +109,10 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void TimerManager::StartAllTimers() | 	void TimerManager::StartAllTimers() | ||||||
| 	{ | 	{ | ||||||
| 		if (timers_.IsEmpty()) | 		if (timers_.is_empty()) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		for (auto timer = timers_.First().Get(); timer; timer = timer->NextItem().Get()) | 		for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get()) | ||||||
| 		{ | 		{ | ||||||
| 			timer->Start(); | 			timer->Start(); | ||||||
| 		} | 		} | ||||||
|  | @ -120,7 +120,7 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void TimerManager::RemoveAllTimers() | 	void TimerManager::RemoveAllTimers() | ||||||
| 	{ | 	{ | ||||||
| 		timers_.Clear(); | 		timers_.clear_items(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	const TimerManager::Timers & TimerManager::GetAllTimers() const | 	const TimerManager::Timers & TimerManager::GetAllTimers() const | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ namespace kiwano | ||||||
| { | { | ||||||
| 	class KGE_API TimerManager | 	class KGE_API TimerManager | ||||||
| 	{ | 	{ | ||||||
| 		using Timers = IntrusiveList<TimerPtr>; | 		using Timers = intrusive_list<TimerPtr>; | ||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		// Ìí¼ÓÈÎÎñ
 | 		// Ìí¼ÓÈÎÎñ
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,418 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #include "Window.h" | ||||||
|  | #include "Logger.h" | ||||||
|  | 
 | ||||||
|  | #define WINDOW_STYLE			WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | ||||||
|  | #define WINDOW_FULLSCREEN_STYLE	WS_CLIPCHILDREN | WS_POPUP | ||||||
|  | #define KGE_WND_CLASS_NAME		L"KiwanoAppWnd" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	namespace | ||||||
|  | 	{ | ||||||
|  | 		MONITORINFOEX GetMoniterInfoEx(HWND hwnd); | ||||||
|  | 
 | ||||||
|  | 		void AdjustWindow(UINT width, UINT height, DWORD style, UINT* win_width, UINT* win_height); | ||||||
|  | 
 | ||||||
|  | 		void ChangeFullScreenResolution(int width, int height, WCHAR* device_name); | ||||||
|  | 
 | ||||||
|  | 		void RestoreResolution(WCHAR* device_name); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Window::Window() | ||||||
|  | 		: handle_(nullptr) | ||||||
|  | 		, width_(0) | ||||||
|  | 		, height_(0) | ||||||
|  | 		, device_name_(nullptr) | ||||||
|  | 		, is_fullscreen_(false) | ||||||
|  | 		, mouse_cursor_(MouseCursor(-1)) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Window::~Window() | ||||||
|  | 	{ | ||||||
|  | 		if (is_fullscreen_) | ||||||
|  | 			RestoreResolution(device_name_); | ||||||
|  | 
 | ||||||
|  | 		if (device_name_) | ||||||
|  | 		{ | ||||||
|  | 			delete[] device_name_; | ||||||
|  | 			device_name_ = nullptr; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (handle_) | ||||||
|  | 		{ | ||||||
|  | 			::DestroyWindow(handle_); | ||||||
|  | 			handle_ = nullptr; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	HRESULT Window::Create(String const& title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc) | ||||||
|  | 	{ | ||||||
|  | 		HINSTANCE hinst		= GetModuleHandleW(nullptr); | ||||||
|  | 		WNDCLASSEX wcex		= { 0 }; | ||||||
|  | 		wcex.cbSize			= sizeof(WNDCLASSEX); | ||||||
|  | 		wcex.lpszClassName	= KGE_WND_CLASS_NAME; | ||||||
|  | 		wcex.style			= CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; | ||||||
|  | 		wcex.lpfnWndProc	= proc; | ||||||
|  | 		wcex.hIcon			= nullptr; | ||||||
|  | 		wcex.cbClsExtra		= 0; | ||||||
|  | 		wcex.cbWndExtra		= sizeof(LONG_PTR); | ||||||
|  | 		wcex.hInstance		= hinst; | ||||||
|  | 		wcex.hbrBackground	= nullptr; | ||||||
|  | 		wcex.lpszMenuName	= nullptr; | ||||||
|  | 		wcex.hCursor		= nullptr; | ||||||
|  | 
 | ||||||
|  | 		if (icon) | ||||||
|  | 		{ | ||||||
|  | 			wcex.hIcon = (HICON)::LoadImageW(hinst, icon, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		::RegisterClassExW(&wcex); | ||||||
|  | 
 | ||||||
|  | 		// Get the nearest monitor to this window
 | ||||||
|  | 		HMONITOR monitor = ::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY); | ||||||
|  | 
 | ||||||
|  | 		// Get the target monitor info
 | ||||||
|  | 		MONITORINFOEX monitor_info_ex; | ||||||
|  | 		memset(&monitor_info_ex, 0, sizeof(MONITORINFOEX)); | ||||||
|  | 		monitor_info_ex.cbSize = sizeof(MONITORINFOEX); | ||||||
|  | 		::GetMonitorInfoW(monitor, &monitor_info_ex); | ||||||
|  | 
 | ||||||
|  | 		// Save the device name
 | ||||||
|  | 		int len = lstrlenW(monitor_info_ex.szDevice); | ||||||
|  | 		device_name_ = new WCHAR[len + 1]; | ||||||
|  | 		lstrcpyW(device_name_, monitor_info_ex.szDevice); | ||||||
|  | 
 | ||||||
|  | 		int left = -1; | ||||||
|  | 		int top = -1; | ||||||
|  | 
 | ||||||
|  | 		is_fullscreen_ = fullscreen; | ||||||
|  | 
 | ||||||
|  | 		if (is_fullscreen_) | ||||||
|  | 		{ | ||||||
|  | 			top = monitor_info_ex.rcMonitor.top; | ||||||
|  | 			left = monitor_info_ex.rcMonitor.left; | ||||||
|  | 
 | ||||||
|  | 			if (width > monitor_info_ex.rcWork.right - left) | ||||||
|  | 				width = monitor_info_ex.rcWork.right - left; | ||||||
|  | 
 | ||||||
|  | 			if (height > monitor_info_ex.rcWork.bottom - top) | ||||||
|  | 				height = monitor_info_ex.rcWork.bottom - top; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			UINT screenw = monitor_info_ex.rcWork.right - monitor_info_ex.rcWork.left; | ||||||
|  | 			UINT screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top; | ||||||
|  | 
 | ||||||
|  | 			UINT win_width, win_height; | ||||||
|  | 			AdjustWindow( | ||||||
|  | 				width, | ||||||
|  | 				height, | ||||||
|  | 				GetWindowStyle(), | ||||||
|  | 				&win_width, | ||||||
|  | 				&win_height | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			left = monitor_info_ex.rcWork.left + (screenw - win_width) / 2; | ||||||
|  | 			top = monitor_info_ex.rcWork.top + (screenh - win_height) / 2; | ||||||
|  | 			width = win_width; | ||||||
|  | 			height = win_height; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		handle_ = ::CreateWindowExW( | ||||||
|  | 			is_fullscreen_ ? WS_EX_TOPMOST : 0, | ||||||
|  | 			KGE_WND_CLASS_NAME, | ||||||
|  | 			title.c_str(), | ||||||
|  | 			GetWindowStyle(), | ||||||
|  | 			left, | ||||||
|  | 			top, | ||||||
|  | 			width, | ||||||
|  | 			height, | ||||||
|  | 			nullptr, | ||||||
|  | 			nullptr, | ||||||
|  | 			hinst, | ||||||
|  | 			nullptr | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		if (handle_ == nullptr) | ||||||
|  | 		{ | ||||||
|  | 			::UnregisterClass(KGE_WND_CLASS_NAME, hinst); | ||||||
|  | 			return HRESULT_FROM_WIN32(GetLastError()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		RECT rc; | ||||||
|  | 		GetClientRect(handle_, &rc); | ||||||
|  | 		width_ = rc.right - rc.left; | ||||||
|  | 		height_ = rc.bottom - rc.top; | ||||||
|  | 
 | ||||||
|  | 		SetMouseCursor(MouseCursor::Arrow); | ||||||
|  | 		return S_OK; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::Prepare() | ||||||
|  | 	{ | ||||||
|  | 		::ShowWindow(handle_, SW_SHOWNORMAL); | ||||||
|  | 		::UpdateWindow(handle_); | ||||||
|  | 
 | ||||||
|  | 		if (is_fullscreen_) | ||||||
|  | 		{ | ||||||
|  | 			ChangeFullScreenResolution(width_, height_, device_name_); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	String Window::GetTitle() const | ||||||
|  | 	{ | ||||||
|  | 		if (handle_) | ||||||
|  | 		{ | ||||||
|  | 			wchar_t title[256]; | ||||||
|  | 			::GetWindowTextW(handle_, title, 256); | ||||||
|  | 			return title; | ||||||
|  | 		} | ||||||
|  | 		return String(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::SetTitle(String const& title) | ||||||
|  | 	{ | ||||||
|  | 		if (handle_) | ||||||
|  | 			::SetWindowTextW(handle_, title.c_str()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Size Window::GetSize() const | ||||||
|  | 	{ | ||||||
|  | 		return Size{ | ||||||
|  | 			static_cast<float>(width_), | ||||||
|  | 			static_cast<float>(height_) | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float Window::GetWidth() const | ||||||
|  | 	{ | ||||||
|  | 		return static_cast<float>(width_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float Window::GetHeight() const | ||||||
|  | 	{ | ||||||
|  | 		return static_cast<float>(height_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::SetIcon(LPCWSTR icon_resource) | ||||||
|  | 	{ | ||||||
|  | 		if (handle_) | ||||||
|  | 		{ | ||||||
|  | 			HINSTANCE hinstance = GetModuleHandle(nullptr); | ||||||
|  | 			HICON icon = (HICON)::LoadImage( | ||||||
|  | 				hinstance, | ||||||
|  | 				icon_resource, | ||||||
|  | 				IMAGE_ICON, | ||||||
|  | 				0, | ||||||
|  | 				0, | ||||||
|  | 				LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			::SendMessage(handle_, WM_SETICON, ICON_BIG, (LPARAM)icon); | ||||||
|  | 			::SendMessage(handle_, WM_SETICON, ICON_SMALL, (LPARAM)icon); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::Resize(int width, int height) | ||||||
|  | 	{ | ||||||
|  | 		if (handle_ && !is_fullscreen_) | ||||||
|  | 		{ | ||||||
|  | 			RECT rc = { 0, 0, int(width), int(height) }; | ||||||
|  | 			::AdjustWindowRect(&rc, GetWindowStyle(), false); | ||||||
|  | 
 | ||||||
|  | 			width = rc.right - rc.left; | ||||||
|  | 			height = rc.bottom - rc.top; | ||||||
|  | 			::SetWindowPos(handle_, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::SetFullscreen(bool fullscreen, int width, int height) | ||||||
|  | 	{ | ||||||
|  | 		if (is_fullscreen_ != fullscreen || width != width_ || height != height_) | ||||||
|  | 		{ | ||||||
|  | 			is_fullscreen_ = fullscreen; | ||||||
|  | 
 | ||||||
|  | 			if (is_fullscreen_) | ||||||
|  | 			{ | ||||||
|  | 				// move window to (0, 0) before display switch
 | ||||||
|  | 				::SetWindowPos(handle_, HWND_TOPMOST, 0, 0, width_, height_, SWP_NOACTIVATE); | ||||||
|  | 
 | ||||||
|  | 				ChangeFullScreenResolution(width, height, device_name_); | ||||||
|  | 
 | ||||||
|  | 				MONITORINFOEX info = GetMoniterInfoEx(handle_); | ||||||
|  | 
 | ||||||
|  | 				::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle()); | ||||||
|  | 				::SetWindowPos(handle_, HWND_TOPMOST, info.rcMonitor.top, info.rcMonitor.left, width, height, SWP_NOACTIVATE); | ||||||
|  | 
 | ||||||
|  | 				width_ = width; | ||||||
|  | 				height_ = height; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				RestoreResolution(device_name_); | ||||||
|  | 
 | ||||||
|  | 				MONITORINFOEX info = GetMoniterInfoEx(handle_); | ||||||
|  | 
 | ||||||
|  | 				UINT screenw = info.rcWork.right - info.rcWork.left; | ||||||
|  | 				UINT screenh = info.rcWork.bottom - info.rcWork.top; | ||||||
|  | 
 | ||||||
|  | 				UINT win_width, win_height; | ||||||
|  | 				AdjustWindow(width, height, GetWindowStyle(), &win_width, &win_height); | ||||||
|  | 
 | ||||||
|  | 				int left = screenw > win_width ? ((screenw - win_width) / 2) : 0; | ||||||
|  | 				int top = screenh > win_height ? ((screenh - win_height) / 2) : 0; | ||||||
|  | 
 | ||||||
|  | 				::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle()); | ||||||
|  | 				::SetWindowPos(handle_, HWND_NOTOPMOST, left, top, win_width, win_height, SWP_DRAWFRAME | SWP_FRAMECHANGED); | ||||||
|  | 				 | ||||||
|  | 				UpdateWindowRect(); | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			::ShowWindow(handle_, SW_SHOWNORMAL); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::SetMouseCursor(MouseCursor cursor) | ||||||
|  | 	{ | ||||||
|  | 		if (mouse_cursor_ != cursor) | ||||||
|  | 		{ | ||||||
|  | 			mouse_cursor_ = cursor; | ||||||
|  | 
 | ||||||
|  | 			LPTSTR win32_cursor = IDC_ARROW; | ||||||
|  | 			switch (cursor) | ||||||
|  | 			{ | ||||||
|  | 			case MouseCursor::Arrow:		win32_cursor = IDC_ARROW; break; | ||||||
|  | 			case MouseCursor::TextInput:	win32_cursor = IDC_IBEAM; break; | ||||||
|  | 			case MouseCursor::SizeAll:		win32_cursor = IDC_SIZEALL; break; | ||||||
|  | 			case MouseCursor::SizeWE:		win32_cursor = IDC_SIZEWE; break; | ||||||
|  | 			case MouseCursor::SizeNS:		win32_cursor = IDC_SIZENS; break; | ||||||
|  | 			case MouseCursor::SizeNESW:		win32_cursor = IDC_SIZENESW; break; | ||||||
|  | 			case MouseCursor::SizeNWSE:		win32_cursor = IDC_SIZENWSE; break; | ||||||
|  | 			case MouseCursor::Hand:			win32_cursor = IDC_HAND; break; | ||||||
|  | 			} | ||||||
|  | 			::SetCursor(::LoadCursorW(nullptr, win32_cursor)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	HWND Window::GetHandle() const | ||||||
|  | 	{ | ||||||
|  | 		return handle_; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DWORD Window::GetWindowStyle() const | ||||||
|  | 	{ | ||||||
|  | 		return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (WINDOW_STYLE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::UpdateWindowRect() | ||||||
|  | 	{ | ||||||
|  | 		if (!handle_) | ||||||
|  | 			return; | ||||||
|  | 
 | ||||||
|  | 		RECT rc; | ||||||
|  | 		::GetClientRect(handle_, &rc); | ||||||
|  | 
 | ||||||
|  | 		width_ = rc.right - rc.left; | ||||||
|  | 		height_ = rc.bottom - rc.top; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Window::SetActive(bool actived) | ||||||
|  | 	{ | ||||||
|  | 		if (!handle_) | ||||||
|  | 			return; | ||||||
|  | 
 | ||||||
|  | 		if (is_fullscreen_) | ||||||
|  | 		{ | ||||||
|  | 			if (actived) | ||||||
|  | 			{ | ||||||
|  | 				ChangeFullScreenResolution(width_, height_, device_name_); | ||||||
|  | 
 | ||||||
|  | 				MONITORINFOEX info = GetMoniterInfoEx(handle_); | ||||||
|  | 				::SetWindowPos(handle_, HWND_TOPMOST, info.rcMonitor.top, info.rcMonitor.left, width_, height_, SWP_NOACTIVATE); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				RestoreResolution(device_name_); | ||||||
|  | 
 | ||||||
|  | 				::SetWindowPos(handle_, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | ||||||
|  | 				::ShowWindow(handle_, SW_MINIMIZE); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	namespace | ||||||
|  | 	{ | ||||||
|  | 		MONITORINFOEX GetMoniterInfoEx(HWND hwnd) | ||||||
|  | 		{ | ||||||
|  | 			HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); | ||||||
|  | 			MONITORINFOEX monitor_info; | ||||||
|  | 
 | ||||||
|  | 			memset(&monitor_info, 0, sizeof(MONITORINFOEX)); | ||||||
|  | 			monitor_info.cbSize = sizeof(MONITORINFOEX); | ||||||
|  | 			::GetMonitorInfoW(monitor, &monitor_info); | ||||||
|  | 
 | ||||||
|  | 			return monitor_info; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		void AdjustWindow(UINT width, UINT height, DWORD style, UINT* win_width, UINT* win_height) | ||||||
|  | 		{ | ||||||
|  | 			RECT rc; | ||||||
|  | 			::SetRect(&rc, 0, 0, (int)width, (int)height); | ||||||
|  | 			::AdjustWindowRect(&rc, style, false); | ||||||
|  | 
 | ||||||
|  | 			*win_width = rc.right - rc.left; | ||||||
|  | 			*win_height = rc.bottom - rc.top; | ||||||
|  | 
 | ||||||
|  | 			MONITORINFOEX info = GetMoniterInfoEx(NULL); | ||||||
|  | 
 | ||||||
|  | 			UINT screenw = info.rcWork.right - info.rcWork.left; | ||||||
|  | 			UINT screenh = info.rcWork.bottom - info.rcWork.top; | ||||||
|  | 
 | ||||||
|  | 			if (*win_width > screenw) | ||||||
|  | 				*win_width = screenw; | ||||||
|  | 			if (*win_height > screenh) | ||||||
|  | 				*win_height = screenh; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		void ChangeFullScreenResolution(int width, int height, WCHAR* device_name) | ||||||
|  | 		{ | ||||||
|  | 			DEVMODE mode; | ||||||
|  | 
 | ||||||
|  | 			memset(&mode, 0, sizeof(mode)); | ||||||
|  | 			mode.dmSize = sizeof(DEVMODE); | ||||||
|  | 			mode.dmBitsPerPel = ::GetDeviceCaps(::GetDC(0), BITSPIXEL);; | ||||||
|  | 			mode.dmPelsWidth = width; | ||||||
|  | 			mode.dmPelsHeight = height; | ||||||
|  | 			mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; | ||||||
|  | 
 | ||||||
|  | 			if (::ChangeDisplaySettingsExW(device_name, &mode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) | ||||||
|  | 				KGE_ERROR_LOG(L"ChangeDisplaySettings failed"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		void RestoreResolution(WCHAR* device_name) | ||||||
|  | 		{ | ||||||
|  | 			::ChangeDisplaySettingsExW(device_name, NULL, NULL, 0, NULL); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,95 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "../macros.h" | ||||||
|  | #include "../core/core.h" | ||||||
|  | #include "../math/helper.h" | ||||||
|  | #include "types.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	class KGE_API Window | ||||||
|  | 		: public Singleton<Window> | ||||||
|  | 	{ | ||||||
|  | 		KGE_DECLARE_SINGLETON(Window); | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		// 获取标题
 | ||||||
|  | 		String GetTitle() const; | ||||||
|  | 
 | ||||||
|  | 		// 获取窗口大小
 | ||||||
|  | 		Size GetSize() const; | ||||||
|  | 
 | ||||||
|  | 		// 获取窗口宽度
 | ||||||
|  | 		float GetWidth() const; | ||||||
|  | 
 | ||||||
|  | 		// 获取窗口高度
 | ||||||
|  | 		float GetHeight() const; | ||||||
|  | 
 | ||||||
|  | 		// 设置标题
 | ||||||
|  | 		void SetTitle(String const& title); | ||||||
|  | 
 | ||||||
|  | 		// 设置窗口图标
 | ||||||
|  | 		void SetIcon(LPCWSTR icon_resource); | ||||||
|  | 
 | ||||||
|  | 		// 重设窗口大小
 | ||||||
|  | 		void Resize(int width, int height); | ||||||
|  | 
 | ||||||
|  | 		// 设置全屏模式
 | ||||||
|  | 		void SetFullscreen(bool fullscreen, int width, int height); | ||||||
|  | 
 | ||||||
|  | 		// 设置鼠标指针
 | ||||||
|  | 		void SetMouseCursor(MouseCursor cursor); | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		HRESULT Create( | ||||||
|  | 			String const&	title, | ||||||
|  | 			int				width, | ||||||
|  | 			int				height, | ||||||
|  | 			LPCWSTR			icon, | ||||||
|  | 			bool			fullscreen, | ||||||
|  | 			WNDPROC			proc | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		void Prepare(); | ||||||
|  | 
 | ||||||
|  | 		HWND GetHandle() const; | ||||||
|  | 
 | ||||||
|  | 		DWORD GetWindowStyle() const; | ||||||
|  | 
 | ||||||
|  | 		void UpdateWindowRect(); | ||||||
|  | 
 | ||||||
|  | 		void SetActive(bool actived); | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		Window(); | ||||||
|  | 
 | ||||||
|  | 		~Window(); | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		HWND	handle_; | ||||||
|  | 		bool	is_fullscreen_; | ||||||
|  | 		int		width_; | ||||||
|  | 		int		height_; | ||||||
|  | 		WCHAR*	device_name_; | ||||||
|  | 		MouseCursor mouse_cursor_; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "time.h" | #include "time.h" | ||||||
| #include "logs.h" | #include "Logger.h" | ||||||
| #include <regex> | #include <regex> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| 
 | 
 | ||||||
|  | @ -73,7 +73,7 @@ namespace kiwano | ||||||
| 			static LARGE_INTEGER freq = {}; | 			static LARGE_INTEGER freq = {}; | ||||||
| 			if (freq.QuadPart == 0LL) | 			if (freq.QuadPart == 0LL) | ||||||
| 			{ | 			{ | ||||||
| 				// the function will always succceed on systems that run Windows XP or later
 | 				// the Function will always succceed on systems that run Windows XP or later
 | ||||||
| 				QueryPerformanceFrequency(&freq); | 				QueryPerformanceFrequency(&freq); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/String.hpp" | #include "../core/core.h" | ||||||
| #include <ostream> | #include <ostream> | ||||||
| #include <istream> | #include <istream> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,8 +18,8 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include "window.h" | #include "Window.h" | ||||||
| #include "logs.h" | #include "Logger.h" | ||||||
| 
 | 
 | ||||||
| #define WINDOW_STYLE			WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | #define WINDOW_STYLE			WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | ||||||
| #define WINDOW_FULLSCREEN_STYLE	WS_CLIPCHILDREN | WS_POPUP | #define WINDOW_FULLSCREEN_STYLE	WS_CLIPCHILDREN | WS_POPUP | ||||||
|  |  | ||||||
|  | @ -20,9 +20,8 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../macros.h" | #include "../macros.h" | ||||||
| #include "../common/helper.h" | #include "../core/core.h" | ||||||
| #include "../math/helper.h" | #include "../math/helper.h" | ||||||
| #include "../common/Singleton.hpp" |  | ||||||
| #include "types.h" | #include "types.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  |  | ||||||
|  | @ -1,277 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Kiwano - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #pragma once |  | ||||||
| #include <memory> |  | ||||||
| #include <type_traits> |  | ||||||
| #include <exception> |  | ||||||
| 
 |  | ||||||
| namespace kiwano |  | ||||||
| { |  | ||||||
| 	//
 |  | ||||||
| 	// ArrayManager<> with memory operations
 |  | ||||||
| 	//
 |  | ||||||
| 	template<typename _Ty, typename _Alloc, bool _IsClassType = std::is_class<_Ty>::value> |  | ||||||
| 	struct __ArrayManager; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//
 |  | ||||||
| 	// Array<>
 |  | ||||||
| 	// Lightweight std::vector<>-like class
 |  | ||||||
| 	//
 |  | ||||||
| 	template< |  | ||||||
| 		typename _Ty, |  | ||||||
| 		typename _Alloc = std::allocator<_Ty>, |  | ||||||
| 		typename _Manager = __ArrayManager<_Ty, _Alloc>> |  | ||||||
| 	class Array |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		using value_type				= _Ty; |  | ||||||
| 		using size_type					= std::size_t; |  | ||||||
| 		using iterator					= value_type * ; |  | ||||||
| 		using const_iterator			= const value_type*; |  | ||||||
| 		using reference					= value_type & ; |  | ||||||
| 		using const_reference			= const value_type &; |  | ||||||
| 		using reverse_iterator			= std::reverse_iterator<iterator>; |  | ||||||
| 		using const_reverse_iterator	= std::reverse_iterator<const_iterator>; |  | ||||||
| 		using allocator_type			= typename _Alloc; |  | ||||||
| 		using manager					= typename _Manager; |  | ||||||
| 		using initializer_list			= std::initializer_list<value_type>; |  | ||||||
| 
 |  | ||||||
| 	public: |  | ||||||
| 		inline Array()																	: size_(0), capacity_(0), data_(nullptr) { } |  | ||||||
| 		inline Array(size_type count)													: Array() { reserve(count); } |  | ||||||
| 		inline Array(size_type count, const _Ty& val)									: Array() { assign(count, val); } |  | ||||||
| 		inline Array(initializer_list list)												: Array() { assign(list); } |  | ||||||
| 		inline Array(const Array& src)													: Array() { assign(src); } |  | ||||||
| 		inline Array(Array&& src) noexcept												: Array() { swap(src); } |  | ||||||
| 		inline ~Array()																	{ destroy(); } |  | ||||||
| 
 |  | ||||||
| 		template <typename _Iter> |  | ||||||
| 		inline Array(_Iter first, _Iter last)											: Array() { assign(first, last); } |  | ||||||
| 
 |  | ||||||
| 		inline Array&		operator=(const Array& src)									{ if (&src != this) { resize(src.size_); manager::copy_data(begin(), src.cbegin(), size_); } return (*this); } |  | ||||||
| 		inline Array&		operator=(Array&& src) noexcept								{ swap(src); return *this; } |  | ||||||
| 		inline Array&		operator=(initializer_list list)							{ if (list.size()) { assign(list.begin(), list.end()); } else clear(); return (*this); } |  | ||||||
| 
 |  | ||||||
| 		inline Array&		assign(size_type count, const _Ty& val)						{ if (count > 0) { resize(count); manager::copy_data(begin(), count, val); } else clear(); return (*this); } |  | ||||||
| 		inline Array&		assign(const Array& src)									{ return operator=(src); } |  | ||||||
| 		inline Array&		assign(initializer_list list)								{ return operator=(list); } |  | ||||||
| 
 |  | ||||||
| 		template <typename _Iter> |  | ||||||
| 		inline void			assign(_Iter first, _Iter last)								{ auto diff = std::distance(first, last); resize((size_type)diff); auto data = begin(); while (first != last) (*data++) = (*first++); } |  | ||||||
| 
 |  | ||||||
| 		inline void			clear()														{ destroy(); size_ = capacity_ = 0; data_ = nullptr; } |  | ||||||
| 		inline void			swap(Array& rhs) noexcept									{ std::swap(size_, rhs.size_); std::swap(capacity_, rhs.capacity_); std::swap(data_, rhs.data_); } |  | ||||||
| 
 |  | ||||||
| 		inline void			resize(size_type new_size)									{ resize(new_size, _Ty()); } |  | ||||||
| 		void				resize(size_type new_size, const _Ty& v); |  | ||||||
| 		void				reserve(size_type new_capacity); |  | ||||||
| 
 |  | ||||||
| 		inline void			push_back(const _Ty& val)									{ resize(size_ + 1, val); } |  | ||||||
| 		inline void			pop_back()													{ if (empty()) throw std::out_of_range("pop() called on empty vector"); resize(size_ - 1); } |  | ||||||
| 		inline void			push_front(const _Ty& val)									{ if (size_ == 0) push_back(val); else insert(begin(), val); } |  | ||||||
| 
 |  | ||||||
| 		inline iterator		erase(const_iterator where)									{ return erase(where, where + 1); } |  | ||||||
| 		iterator			erase(const_iterator first, const_iterator last); |  | ||||||
| 
 |  | ||||||
| 		iterator			insert(const_iterator where, const _Ty& v); |  | ||||||
| 
 |  | ||||||
| 		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				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]; } |  | ||||||
| 
 |  | ||||||
| 		 |  | ||||||
| 		inline bool						contains(const _Ty& v) const					{ auto data = cbegin();  const auto data_end = cend(); while (data != data_end) if (*(data++) == v) return true; return false; } |  | ||||||
| 		inline size_type				index_of(const_iterator it) const				{ check_offset(it - cbegin(), "invalid array position"); return it - data_; } |  | ||||||
| 
 |  | ||||||
| 		inline iterator					begin()											{ return iterator(data_); } |  | ||||||
| 		inline const_iterator			begin() const									{ return const_iterator(data_); } |  | ||||||
| 		inline const_iterator			cbegin() const									{ return begin(); } |  | ||||||
| 		inline iterator					end()											{ return iterator(data_ + size_); } |  | ||||||
| 		inline const_iterator			end() const										{ return const_iterator(data_ + size_); } |  | ||||||
| 		inline const_iterator			cend() const									{ return end(); } |  | ||||||
| 		inline reverse_iterator			rbegin()										{ return reverse_iterator(end()); } |  | ||||||
| 		inline const_reverse_iterator	rbegin() const									{ return const_reverse_iterator(end()); } |  | ||||||
| 		inline const_reverse_iterator	crbegin() const									{ return rbegin(); } |  | ||||||
| 		inline reverse_iterator			rend()											{ return reverse_iterator(begin()); } |  | ||||||
| 		inline const_reverse_iterator	rend() const									{ return const_reverse_iterator(begin()); } |  | ||||||
| 		inline const_reverse_iterator	crend() const									{ return rend(); } |  | ||||||
| 		inline reference				front()											{ if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; } |  | ||||||
| 		inline const_reference			front() const									{ if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; } |  | ||||||
| 		inline reference				back()											{ if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; } |  | ||||||
| 		inline const_reference			back() const									{ if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; } |  | ||||||
| 
 |  | ||||||
| 	private: |  | ||||||
| 		inline size_type	grow_capacity(size_type sz) const							{ size_type new_capacity = capacity_ ? (capacity_ + capacity_ / 2) : 8; return new_capacity > sz ? new_capacity : sz; } |  | ||||||
| 		inline void			check_offset(const size_type off) const						{ if (off < 0 || off >= size_) throw std::out_of_range("invalid vector position"); } |  | ||||||
| 
 |  | ||||||
| 		inline void			destroy()													{ manager::destroy(data_, size_); manager::deallocate(data_, capacity_); } |  | ||||||
| 	protected: |  | ||||||
| 		size_type	size_; |  | ||||||
| 		size_type	capacity_; |  | ||||||
| 		_Ty*		data_; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, typename _Alloc, typename _Manager> |  | ||||||
| 	void Array<_Ty, _Alloc, _Manager>::resize(size_type new_size, const _Ty& val) |  | ||||||
| 	{ |  | ||||||
| 		if (new_size > size_) |  | ||||||
| 		{ |  | ||||||
| 			if (new_size > capacity_) |  | ||||||
| 			{ |  | ||||||
| 				reserve(grow_capacity(new_size)); |  | ||||||
| 			} |  | ||||||
| 			manager::construct(begin() + size_, new_size - size_, val); |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			manager::destroy(begin() + new_size, size_ - new_size); |  | ||||||
| 		} |  | ||||||
| 		size_ = new_size; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, typename _Alloc, typename _Manager> |  | ||||||
| 	void Array<_Ty, _Alloc, _Manager>::reserve(size_type new_capacity) |  | ||||||
| 	{ |  | ||||||
| 		if (new_capacity <= capacity_) |  | ||||||
| 			return; |  | ||||||
| 
 |  | ||||||
| 		auto new_data = manager::allocate(new_capacity); |  | ||||||
| 		if (data_) |  | ||||||
| 		{ |  | ||||||
| 			manager::construct(new_data, size_/* only construct needed size */); |  | ||||||
| 			manager::copy_data(new_data, data_, size_); |  | ||||||
| 			/* destroy old memory, but not resize */ |  | ||||||
| 			destroy(); |  | ||||||
| 		} |  | ||||||
| 		data_ = new_data; |  | ||||||
| 		capacity_ = new_capacity; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, typename _Alloc, typename _Manager> |  | ||||||
| 	typename Array<_Ty, _Alloc, _Manager>::iterator |  | ||||||
| 		Array<_Ty, _Alloc, _Manager>::erase(const_iterator first, const_iterator last) |  | ||||||
| 	{ |  | ||||||
| 		const auto off = first - begin(); |  | ||||||
| 		const auto count = last - first; |  | ||||||
| 
 |  | ||||||
| 		if (count != 0) |  | ||||||
| 		{ |  | ||||||
| 			check_offset(off); |  | ||||||
| 
 |  | ||||||
| 			manager::move_data(begin() + off, begin() + off + count, size_ - off - count); |  | ||||||
| 			resize(size_ - count);  // do destruction
 |  | ||||||
| 		} |  | ||||||
| 		return begin() + off; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, typename _Alloc, typename _Manager> |  | ||||||
| 	typename Array<_Ty, _Alloc, _Manager>::iterator |  | ||||||
| 		Array<_Ty, _Alloc, _Manager>::insert(const_iterator where, const _Ty& v) |  | ||||||
| 	{ |  | ||||||
| 		const auto off = where - begin(); |  | ||||||
| 		const auto insert_at = begin() + off; |  | ||||||
| 
 |  | ||||||
| 		check_offset(off); |  | ||||||
| 		 |  | ||||||
| 		resize(size_ + 1); |  | ||||||
| 		manager::move_data(insert_at + 1, insert_at, size_ - off - 1); |  | ||||||
| 		data_[off] = v; |  | ||||||
| 		return begin() + off; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	//
 |  | ||||||
| 	// ArrayManager for common type
 |  | ||||||
| 	//
 |  | ||||||
| 	template<typename _Ty, typename _Alloc> |  | ||||||
| 	struct __ArrayManager<_Ty, _Alloc, false> |  | ||||||
| 	{ |  | ||||||
| 		using value_type		= _Ty; |  | ||||||
| 		using size_type			= size_t; |  | ||||||
| 		using allocator_type	= typename _Alloc; |  | ||||||
| 
 |  | ||||||
| 		static void copy_data(value_type* dest, const value_type* src, size_type count)		{ if (src == dest) return; ::memcpy(dest, src, (size_t)count * sizeof(value_type)); } |  | ||||||
| 		static void copy_data(value_type* dest, size_type count, const value_type& val)		{ ::memset(dest, (int)val, (size_t)count * sizeof(value_type)); } |  | ||||||
| 		static void move_data(value_type* dest, const value_type* src, size_type count)		{ if (src == dest) return; ::memmove(dest, src, (size_t)count * sizeof(value_type)); } |  | ||||||
| 
 |  | ||||||
| 		static value_type* allocate(size_type count)										{ return get_allocator().allocate(count); } |  | ||||||
| 		static void deallocate(value_type*& ptr, size_type count)							{ if (ptr) { get_allocator().deallocate(ptr, count); ptr = nullptr; } } |  | ||||||
| 
 |  | ||||||
| 		static void construct(value_type* ptr, size_type count)								{ } |  | ||||||
| 		static void construct(value_type* ptr, size_type count, const value_type& val)		{ while (count) { --count; *(ptr + count) = val; } } |  | ||||||
| 		static void destroy(value_type* ptr, size_type count)								{ } |  | ||||||
| 
 |  | ||||||
| 	private: |  | ||||||
| 		static allocator_type& get_allocator() |  | ||||||
| 		{ |  | ||||||
| 			static allocator_type allocator_; |  | ||||||
| 			return allocator_; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	//
 |  | ||||||
| 	// ArrayManager for class
 |  | ||||||
| 	//
 |  | ||||||
| 	template<typename _Ty, typename _Alloc> |  | ||||||
| 	struct __ArrayManager<_Ty, _Alloc, true> |  | ||||||
| 	{ |  | ||||||
| 		using value_type		= _Ty; |  | ||||||
| 		using size_type			= size_t; |  | ||||||
| 		using allocator_type	= typename _Alloc; |  | ||||||
| 
 |  | ||||||
| 		static void copy_data(value_type* dest, const value_type* src, size_type count)	{ if (src == dest) return; while (count--) (*dest++) = (*src++); } |  | ||||||
| 		static void copy_data(value_type* dest, size_type count, const value_type& val)	{ while (count--) (*dest++) = val; } |  | ||||||
| 		static void move_data(value_type* dest, const value_type* src, size_type count) |  | ||||||
| 		{ |  | ||||||
| 			if (src == dest) return; |  | ||||||
| 			if (dest > src && dest < src + count) |  | ||||||
| 			{ |  | ||||||
| 				src = src + count - 1; |  | ||||||
| 				dest = dest + count - 1; |  | ||||||
| 				while (count--) |  | ||||||
| 					(*dest--) = (*src--); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				while (count--) |  | ||||||
| 					(*dest++) = (*src++); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		static value_type* allocate(size_type count)									{ return get_allocator().allocate(count); } |  | ||||||
| 		static void deallocate(value_type*& ptr, size_type count)						{ if (ptr) { get_allocator().deallocate(ptr, count); ptr = nullptr; } } |  | ||||||
| 
 |  | ||||||
| 		static void construct(value_type* ptr, size_type count)							{ construct(ptr, count, value_type()); } |  | ||||||
| 		static void construct(value_type* ptr, size_type count, const value_type& val)	{ while (count) get_allocator().construct(ptr + (--count), val); } |  | ||||||
| 		static void destroy(value_type* ptr, size_type count)							{ while (count) get_allocator().destroy(ptr + (--count)); } |  | ||||||
| 
 |  | ||||||
| 	private: |  | ||||||
| 		static allocator_type& get_allocator() |  | ||||||
| 		{ |  | ||||||
| 			static allocator_type allocator_; |  | ||||||
| 			return allocator_; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
|  | @ -1,255 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Kiwano - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #pragma once |  | ||||||
| #include "../macros.h" |  | ||||||
| #include <functional> |  | ||||||
| 
 |  | ||||||
| // #define KGE_DEBUG_ENABLE_LIST_CHECK
 |  | ||||||
| 
 |  | ||||||
| #ifdef KGE_DEBUG_ENABLE_LIST_CHECK |  | ||||||
| #	define KGE_DEBUG_CHECK_LIST(list_ptr) list_ptr->Check() |  | ||||||
| #else |  | ||||||
| #	define KGE_DEBUG_CHECK_LIST __noop |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| namespace kiwano |  | ||||||
| { |  | ||||||
| 	template <typename T> class IntrusiveList; |  | ||||||
| 
 |  | ||||||
| 	template <typename T> |  | ||||||
| 	class IntrusiveListItem |  | ||||||
| 	{ |  | ||||||
| 		T prev_; |  | ||||||
| 		T next_; |  | ||||||
| 
 |  | ||||||
| 		template <typename U> |  | ||||||
| 		friend class IntrusiveList; |  | ||||||
| 
 |  | ||||||
| 	public: |  | ||||||
| 		using ItemType = T; |  | ||||||
| 
 |  | ||||||
| 		IntrusiveListItem() : prev_(), next_() {} |  | ||||||
| 
 |  | ||||||
| 		T const& PrevItem() const { return prev_; } |  | ||||||
| 
 |  | ||||||
| 		T& PrevItem() { return prev_; } |  | ||||||
| 
 |  | ||||||
| 		T const& NextItem() const { return next_; } |  | ||||||
| 
 |  | ||||||
| 		T& NextItem() { return next_; } |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	template <typename T> |  | ||||||
| 	class IntrusiveList |  | ||||||
| 	{ |  | ||||||
| 		T first_; |  | ||||||
| 		T last_; |  | ||||||
| 
 |  | ||||||
| 	public: |  | ||||||
| 		using ItemType = T; |  | ||||||
| 
 |  | ||||||
| 		IntrusiveList() : first_(), last_() {} |  | ||||||
| 
 |  | ||||||
| 		~IntrusiveList() { Clear(); } |  | ||||||
| 
 |  | ||||||
| 		T const& First() const { return first_; } |  | ||||||
| 
 |  | ||||||
| 		T& First() { return first_; } |  | ||||||
| 
 |  | ||||||
| 		T const& Last() const { return last_; } |  | ||||||
| 
 |  | ||||||
| 		T& Last() { return last_; } |  | ||||||
| 
 |  | ||||||
| 		bool IsEmpty() const { return !first_; } |  | ||||||
| 
 |  | ||||||
| 		void PushBack(T const& child) |  | ||||||
| 		{ |  | ||||||
| 			if (child->prev_) |  | ||||||
| 				child->prev_->next_ = child->next_; |  | ||||||
| 			if (child->next_) |  | ||||||
| 				child->next_->prev_ = child->prev_; |  | ||||||
| 
 |  | ||||||
| 			child->prev_ = last_; |  | ||||||
| 			child->next_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 			if (first_) |  | ||||||
| 			{ |  | ||||||
| 				last_->next_ = child; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				first_ = child; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			last_ = child; |  | ||||||
| 
 |  | ||||||
| 			KGE_DEBUG_CHECK_LIST(this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		void PushFront(T const& child) |  | ||||||
| 		{ |  | ||||||
| 			if (child->prev_) |  | ||||||
| 				child->prev_->next_ = child->next_; |  | ||||||
| 			if (child->next_) |  | ||||||
| 				child->next_->prev_ = child->prev_; |  | ||||||
| 
 |  | ||||||
| 			child->prev_ = nullptr; |  | ||||||
| 			child->next_ = first_; |  | ||||||
| 
 |  | ||||||
| 			if (first_) |  | ||||||
| 			{ |  | ||||||
| 				first_->prev_ = child; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				last_ = child; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			first_ = child; |  | ||||||
| 
 |  | ||||||
| 			KGE_DEBUG_CHECK_LIST(this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		void InsertBefore(T const& child, T const& before) |  | ||||||
| 		{ |  | ||||||
| 			if (child->prev_) |  | ||||||
| 				child->prev_->next_ = child->next_; |  | ||||||
| 			if (child->next_) |  | ||||||
| 				child->next_->prev_ = child->prev_; |  | ||||||
| 
 |  | ||||||
| 			if (before->prev_) |  | ||||||
| 				before->prev_->next_ = child; |  | ||||||
| 			else |  | ||||||
| 				first_ = child; |  | ||||||
| 
 |  | ||||||
| 			child->prev_ = before->prev_; |  | ||||||
| 			child->next_ = before; |  | ||||||
| 			before->prev_ = child; |  | ||||||
| 
 |  | ||||||
| 			KGE_DEBUG_CHECK_LIST(this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		void InsertAfter(T const& child, T const& after) |  | ||||||
| 		{ |  | ||||||
| 			if (child->prev_) |  | ||||||
| 				child->prev_->next_ = child->next_; |  | ||||||
| 			if (child->next_) |  | ||||||
| 				child->next_->prev_ = child->prev_; |  | ||||||
| 
 |  | ||||||
| 			if (after->next_) |  | ||||||
| 				after->next_->prev_ = child; |  | ||||||
| 			else |  | ||||||
| 				last_ = child; |  | ||||||
| 
 |  | ||||||
| 			child->next_ = after->next_; |  | ||||||
| 			child->prev_ = after; |  | ||||||
| 			after->next_ = child; |  | ||||||
| 
 |  | ||||||
| 			KGE_DEBUG_CHECK_LIST(this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		void Remove(T const& child) |  | ||||||
| 		{ |  | ||||||
| #ifdef KGE_DEBUG_ENABLE_LIST_CHECK |  | ||||||
| 			T tmp = first_; |  | ||||||
| 			while (tmp != child) |  | ||||||
| 			{ |  | ||||||
| 				KGE_ASSERT((tmp != last_) && "The node to be removed is not in this list"); |  | ||||||
| 				tmp = tmp->next_; |  | ||||||
| 			} |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 			if (child->next_) |  | ||||||
| 			{ |  | ||||||
| 				child->next_->prev_ = child->prev_; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				last_ = child->prev_; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (child->prev_) |  | ||||||
| 			{ |  | ||||||
| 				child->prev_->next_ = child->next_; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				first_ = child->next_; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			child->prev_ = nullptr; |  | ||||||
| 			child->next_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 			KGE_DEBUG_CHECK_LIST(this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		void Clear() |  | ||||||
| 		{ |  | ||||||
| 			T p = first_; |  | ||||||
| 			while (p) |  | ||||||
| 			{ |  | ||||||
| 				T tmp = p; |  | ||||||
| 				p = p->next_; |  | ||||||
| 				if (tmp) |  | ||||||
| 				{ |  | ||||||
| 					tmp->next_ = nullptr; |  | ||||||
| 					tmp->prev_ = nullptr; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			first_ = nullptr; |  | ||||||
| 			last_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| #ifdef KGE_DEBUG_ENABLE_LIST_CHECK |  | ||||||
| 
 |  | ||||||
| 	private: |  | ||||||
| 		void Check() |  | ||||||
| 		{ |  | ||||||
| 			if (!first_) |  | ||||||
| 				return; |  | ||||||
| 
 |  | ||||||
| 			int pos = 0; |  | ||||||
| 			T p = first_; |  | ||||||
| 			T tmp = p; |  | ||||||
| 			do |  | ||||||
| 			{ |  | ||||||
| 				tmp = p; |  | ||||||
| 				p = p->next_; |  | ||||||
| 				++pos; |  | ||||||
| 
 |  | ||||||
| 				if (p) |  | ||||||
| 				{ |  | ||||||
| 					KGE_ASSERT(p->prev_ == tmp && "Check list failed"); |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 				{ |  | ||||||
| 					KGE_ASSERT(tmp == last_ && "Check list failed"); |  | ||||||
| 				} |  | ||||||
| 			} while (p); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #undef KGE_DEBUG_CHECK_LIST |  | ||||||
| #undef KGE_DEBUG_ENABLE_LIST_CHECK |  | ||||||
|  | @ -1,212 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Kiwano - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining lhs copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #pragma once |  | ||||||
| #include "../macros.h" |  | ||||||
| #include <utility> |  | ||||||
| #include <type_traits> |  | ||||||
| 
 |  | ||||||
| namespace kiwano |  | ||||||
| { |  | ||||||
| 	template <typename _Ty, typename _Manager> |  | ||||||
| 	class IntrusivePtr |  | ||||||
| 	{ |  | ||||||
| 		_Ty* ptr_{ nullptr }; |  | ||||||
| 
 |  | ||||||
| 	public: |  | ||||||
| 		using Type = _Ty; |  | ||||||
| 
 |  | ||||||
| 		IntrusivePtr() noexcept {} |  | ||||||
| 
 |  | ||||||
| 		IntrusivePtr(nullptr_t) noexcept {} |  | ||||||
| 
 |  | ||||||
| 		IntrusivePtr(Type* p) noexcept : ptr_(p) |  | ||||||
| 		{ |  | ||||||
| 			typename _Manager::AddRef(ptr_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		IntrusivePtr(const Type* p) noexcept : ptr_(p) |  | ||||||
| 		{ |  | ||||||
| 			typename _Manager::AddRef(ptr_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		IntrusivePtr(const IntrusivePtr& other) noexcept |  | ||||||
| 			: ptr_(other.ptr_) |  | ||||||
| 		{ |  | ||||||
| 			typename _Manager::AddRef(ptr_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		template <typename _UTy> |  | ||||||
| 		IntrusivePtr(const IntrusivePtr<_UTy, _Manager>& other) noexcept |  | ||||||
| 			: ptr_(other.Get()) |  | ||||||
| 		{ |  | ||||||
| 			typename _Manager::AddRef(ptr_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		IntrusivePtr(IntrusivePtr&& other) noexcept |  | ||||||
| 		{ |  | ||||||
| 			ptr_ = other.ptr_; |  | ||||||
| 			other.ptr_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		~IntrusivePtr() noexcept |  | ||||||
| 		{ |  | ||||||
| 			typename _Manager::Release(ptr_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline Type* Get() const noexcept { return ptr_; } |  | ||||||
| 
 |  | ||||||
| 		inline void Reset() noexcept |  | ||||||
| 		{ |  | ||||||
| 			IntrusivePtr{}.Swap(*this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline void Swap(IntrusivePtr& other) noexcept |  | ||||||
| 		{ |  | ||||||
| 			std::swap(ptr_, other.ptr_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline Type* operator ->() const |  | ||||||
| 		{ |  | ||||||
| 			KGE_ASSERT(ptr_ != nullptr && "Invalid pointer"); |  | ||||||
| 			return ptr_; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline Type& operator *() const |  | ||||||
| 		{ |  | ||||||
| 			KGE_ASSERT(ptr_ != nullptr && "Invalid pointer"); |  | ||||||
| 			return *ptr_; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline Type** operator &() |  | ||||||
| 		{ |  | ||||||
| 			KGE_ASSERT(ptr_ == nullptr && "Memory leak"); |  | ||||||
| 			return &ptr_; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline operator bool() const noexcept { return ptr_ != nullptr; } |  | ||||||
| 
 |  | ||||||
| 		inline bool operator !() const noexcept { return ptr_ == 0; } |  | ||||||
| 
 |  | ||||||
| 		inline IntrusivePtr& operator =(const IntrusivePtr& other) noexcept |  | ||||||
| 		{ |  | ||||||
| 			if (other.ptr_ != ptr_) |  | ||||||
| 				IntrusivePtr(other).Swap(*this); |  | ||||||
| 			return *this; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline IntrusivePtr& operator =(IntrusivePtr&& other) noexcept |  | ||||||
| 		{ |  | ||||||
| 			typename _Manager::Release(ptr_); |  | ||||||
| 			ptr_ = other.ptr_; |  | ||||||
| 			other.ptr_ = nullptr; |  | ||||||
| 			return *this; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline IntrusivePtr& operator =(Type* p) noexcept |  | ||||||
| 		{ |  | ||||||
| 			if (p != ptr_) |  | ||||||
| 				IntrusivePtr(p).Swap(*this); |  | ||||||
| 			return *this; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline IntrusivePtr& operator =(nullptr_t) noexcept |  | ||||||
| 		{ |  | ||||||
| 			if (nullptr != ptr_) |  | ||||||
| 				IntrusivePtr{}.Swap(*this); |  | ||||||
| 			return *this; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _UTy, class _Manager> |  | ||||||
| 	inline bool operator==(IntrusivePtr<_Ty, _Manager> const& lhs, IntrusivePtr<_UTy, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs.Get() == rhs.Get(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _UTy, class _Manager> |  | ||||||
| 	inline bool operator!=(IntrusivePtr<_Ty, _Manager> const& lhs, IntrusivePtr<_UTy, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs.Get() != rhs.Get(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _UTy, class _Manager> |  | ||||||
| 	inline bool operator<(IntrusivePtr<_Ty, _Manager> const& lhs, IntrusivePtr<_UTy, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs.Get() < rhs.Get(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator==(IntrusivePtr<_Ty, _Manager> const& lhs, _Ty* rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs.Get() == rhs; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator!=(IntrusivePtr<_Ty, _Manager> const& lhs, _Ty* rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs.Get() != rhs; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator==(_Ty* lhs, IntrusivePtr<_Ty, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs == rhs.Get(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator!=(_Ty* lhs, IntrusivePtr<_Ty, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return lhs != rhs.Get(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator==(IntrusivePtr<_Ty, _Manager> const& lhs, nullptr_t) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return !static_cast<bool>(lhs); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator!=(IntrusivePtr<_Ty, _Manager> const& lhs, nullptr_t) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return static_cast<bool>(lhs); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator==(nullptr_t, IntrusivePtr<_Ty, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return !static_cast<bool>(rhs); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline bool operator!=(nullptr_t, IntrusivePtr<_Ty, _Manager> const& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		return static_cast<bool>(rhs); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// template class cannot specialize std::swap,
 |  | ||||||
| 	// so implement a swap function in kiwano namespace
 |  | ||||||
| 	template <class _Ty, class _Manager> |  | ||||||
| 	inline void swap(IntrusivePtr<_Ty, _Manager>& lhs, IntrusivePtr<_Ty, _Manager>& rhs) noexcept |  | ||||||
| 	{ |  | ||||||
| 		lhs.Swap(rhs); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -1,344 +0,0 @@ | ||||||
| // Copyright (c) 2016-2018 Kiwano - Nomango
 |  | ||||||
| // 
 |  | ||||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 |  | ||||||
| // of this software and associated documentation files (the "Software"), to deal
 |  | ||||||
| // in the Software without restriction, including without limitation the rights
 |  | ||||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 |  | ||||||
| // copies of the Software, and to permit persons to whom the Software is
 |  | ||||||
| // furnished to do so, subject to the following conditions:
 |  | ||||||
| // 
 |  | ||||||
| // The above copyright notice and this permission notice shall be included in
 |  | ||||||
| // all copies or substantial portions of the Software.
 |  | ||||||
| // 
 |  | ||||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 |  | ||||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 |  | ||||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 |  | ||||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 |  | ||||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 |  | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 |  | ||||||
| // THE SOFTWARE.
 |  | ||||||
| 
 |  | ||||||
| #pragma once |  | ||||||
| #include <stdexcept> |  | ||||||
| #include <type_traits> |  | ||||||
| 
 |  | ||||||
| namespace kiwano |  | ||||||
| { |  | ||||||
| 	//
 |  | ||||||
| 	// Closure is a light weight std::function<>-like class
 |  | ||||||
| 	//
 |  | ||||||
| 
 |  | ||||||
| 	namespace __closure_detail |  | ||||||
| 	{ |  | ||||||
| 		//
 |  | ||||||
| 		// is_callable
 |  | ||||||
| 		//
 |  | ||||||
| 
 |  | ||||||
| 		namespace __callable_detail |  | ||||||
| 		{ |  | ||||||
| 			template <typename _Ty, typename _Ret, typename... _Args> |  | ||||||
| 			struct helper |  | ||||||
| 			{ |  | ||||||
| 				template <typename _Uty> static int test(...); |  | ||||||
| 
 |  | ||||||
| 				template <typename _Uty, _Ret(_Uty::*)(_Args...)> struct class_mem; |  | ||||||
| 				template <typename _Uty> static char test(class_mem<_Uty, &_Uty::operator()>*); |  | ||||||
| 
 |  | ||||||
| 				template <typename _Uty, _Ret(_Uty::*)(_Args...) const> struct class_const_mem; |  | ||||||
| 				template <typename _Uty> static char test(class_const_mem<_Uty, &_Uty::operator()>*); |  | ||||||
| 
 |  | ||||||
| 				template< |  | ||||||
| 					typename _Uty, |  | ||||||
| 					typename _Uret = typename std::decay<decltype(std::declval<_Uty>().operator()(std::declval<_Args>()...))>::type, |  | ||||||
| 					typename = typename std::enable_if<std::is_convertible<_Ret, _Uret>::value>::type> |  | ||||||
| 				static char test(int); |  | ||||||
| 
 |  | ||||||
| 				static constexpr bool value = sizeof(test<_Ty>(0)) == sizeof(char); |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ty, typename _Ret, typename... _Args> |  | ||||||
| 		struct is_callable |  | ||||||
| 			: public std::bool_constant<__callable_detail::helper<_Ty, _Ret, _Args...>::value> |  | ||||||
| 		{ |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		//
 |  | ||||||
| 		// Callable
 |  | ||||||
| 		//
 |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ret, typename... _Args> |  | ||||||
| 		class Callable |  | ||||||
| 		{ |  | ||||||
| 		public: |  | ||||||
| 			virtual ~Callable() {} |  | ||||||
| 
 |  | ||||||
| 			virtual void AddRef() = 0; |  | ||||||
| 			virtual void Release() = 0; |  | ||||||
| 			virtual _Ret Invoke(_Args... args) const = 0; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ret, typename... _Args> |  | ||||||
| 		class RefCountCallable |  | ||||||
| 			: public Callable<_Ret, _Args...> |  | ||||||
| 		{ |  | ||||||
| 		public: |  | ||||||
| 			RefCountCallable() : ref_count_(0) {} |  | ||||||
| 
 |  | ||||||
| 			virtual void AddRef() override |  | ||||||
| 			{ |  | ||||||
| 				++ref_count_; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			virtual void Release() override |  | ||||||
| 			{ |  | ||||||
| 				--ref_count_; |  | ||||||
| 				if (ref_count_ <= 0) |  | ||||||
| 				{ |  | ||||||
| 					delete this; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		private: |  | ||||||
| 			int ref_count_; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ty, typename _Ret, typename... _Args> |  | ||||||
| 		class ProxyCallable |  | ||||||
| 			: public RefCountCallable<_Ret, _Args...> |  | ||||||
| 		{ |  | ||||||
| 		public: |  | ||||||
| 			ProxyCallable(_Ty&& val) |  | ||||||
| 				: callee_(std::move(val)) |  | ||||||
| 			{ |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			virtual _Ret Invoke(_Args... args) const override |  | ||||||
| 			{ |  | ||||||
| 				return callee_(std::forward<_Args&&>(args)...); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			static inline Callable<_Ret, _Args...>* Make(_Ty&& val) |  | ||||||
| 			{ |  | ||||||
| 				return new (std::nothrow) ProxyCallable<_Ty, _Ret, _Args...>(std::move(val)); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		private: |  | ||||||
| 			_Ty callee_; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ty, typename _Ret, typename... _Args> |  | ||||||
| 		class ProxyMemCallable |  | ||||||
| 			: public RefCountCallable<_Ret, _Args...> |  | ||||||
| 		{ |  | ||||||
| 		public: |  | ||||||
| 			typedef _Ret(_Ty::* _FuncType)(_Args...); |  | ||||||
| 
 |  | ||||||
| 			virtual _Ret Invoke(_Args... args) const override |  | ||||||
| 			{ |  | ||||||
| 				return (static_cast<_Ty*>(ptr_)->*func_)(std::forward<_Args>(args)...); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			static inline Callable<_Ret, _Args...>* Make(void* ptr, _FuncType func) |  | ||||||
| 			{ |  | ||||||
| 				return new (std::nothrow) ProxyMemCallable<_Ty, _Ret, _Args...>(ptr, func); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		protected: |  | ||||||
| 			ProxyMemCallable(void* ptr, _FuncType func) |  | ||||||
| 				: ptr_(ptr) |  | ||||||
| 				, func_(func) |  | ||||||
| 			{ |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		protected: |  | ||||||
| 			void* ptr_; |  | ||||||
| 			_FuncType func_; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ty, typename _Ret, typename... _Args> |  | ||||||
| 		class ProxyConstMemCallable |  | ||||||
| 			: public RefCountCallable<_Ret, _Args...> |  | ||||||
| 		{ |  | ||||||
| 		public: |  | ||||||
| 			typedef _Ret(_Ty::* _FuncType)(_Args...) const; |  | ||||||
| 
 |  | ||||||
| 			virtual _Ret Invoke(_Args... args) const override |  | ||||||
| 			{ |  | ||||||
| 				return (static_cast<_Ty*>(ptr_)->*func_)(std::forward<_Args>(args)...); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			static inline Callable<_Ret, _Args...>* Make(void* ptr, _FuncType func) |  | ||||||
| 			{ |  | ||||||
| 				return new (std::nothrow) ProxyConstMemCallable<_Ty, _Ret, _Args...>(ptr, func); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		protected: |  | ||||||
| 			ProxyConstMemCallable(void* ptr, _FuncType func) |  | ||||||
| 				: ptr_(ptr) |  | ||||||
| 				, func_(func) |  | ||||||
| 			{ |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		protected: |  | ||||||
| 			void* ptr_; |  | ||||||
| 			_FuncType func_; |  | ||||||
| 		}; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	//
 |  | ||||||
| 	// exceptions
 |  | ||||||
| 	//
 |  | ||||||
| 	class bad_function_call : public std::exception |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		bad_function_call() {} |  | ||||||
| 
 |  | ||||||
| 		virtual const char* what() const override |  | ||||||
| 		{ |  | ||||||
| 			return "bad function call"; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	//
 |  | ||||||
| 	// Closure details
 |  | ||||||
| 	//
 |  | ||||||
| 	template<typename _Ty> |  | ||||||
| 	class Closure; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ret, typename... _Args> |  | ||||||
| 	class Closure<_Ret(_Args...)> |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		Closure() |  | ||||||
| 			: callable_(nullptr) |  | ||||||
| 		{ |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		Closure(std::nullptr_t) |  | ||||||
| 			: callable_(nullptr) |  | ||||||
| 		{ |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		Closure(const Closure& rhs) |  | ||||||
| 			: callable_(rhs.callable_) |  | ||||||
| 		{ |  | ||||||
| 			if (callable_) callable_->AddRef(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		Closure(Closure&& rhs) noexcept |  | ||||||
| 			: callable_(rhs.callable_) |  | ||||||
| 		{ |  | ||||||
| 			rhs.callable_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		Closure(_Ret(*func)(_Args...)) |  | ||||||
| 		{ |  | ||||||
| 			callable_ = __closure_detail::ProxyCallable<_Ret(*)(_Args...), _Ret, _Args...>::Make(std::move(func)); |  | ||||||
| 			if (callable_) callable_->AddRef(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		template< |  | ||||||
| 			typename _Ty, |  | ||||||
| 			typename = typename std::enable_if<__closure_detail::is_callable<_Ty, _Ret, _Args...>::value, int>::type> |  | ||||||
| 		Closure(_Ty val) |  | ||||||
| 		{ |  | ||||||
| 			callable_ = __closure_detail::ProxyCallable<_Ty, _Ret, _Args...>::Make(std::move(val)); |  | ||||||
| 			if (callable_) callable_->AddRef(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ty, |  | ||||||
| 			typename _Uty, |  | ||||||
| 			typename = typename std::enable_if<std::is_same<_Ty, _Uty>::value || std::is_base_of<_Ty, _Uty>::value, int>::type> |  | ||||||
| 		Closure(_Uty* ptr, _Ret(_Ty::* func)(_Args...)) |  | ||||||
| 		{ |  | ||||||
| 			callable_ = __closure_detail::ProxyMemCallable<_Ty, _Ret, _Args...>::Make(ptr, func); |  | ||||||
| 			if (callable_) callable_->AddRef(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		template<typename _Ty, |  | ||||||
| 			typename _Uty, |  | ||||||
| 			typename = typename std::enable_if<std::is_same<_Ty, _Uty>::value || std::is_base_of<_Ty, _Uty>::value, int>::type> |  | ||||||
| 		Closure(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const) |  | ||||||
| 		{ |  | ||||||
| 			callable_ = __closure_detail::ProxyConstMemCallable<_Ty, _Ret, _Args...>::Make(ptr, func); |  | ||||||
| 			if (callable_) callable_->AddRef(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		~Closure() |  | ||||||
| 		{ |  | ||||||
| 			tidy(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline void swap(const Closure& rhs) |  | ||||||
| 		{ |  | ||||||
| 			std::swap(callable_, rhs.callable_); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline _Ret operator()(_Args... args) const |  | ||||||
| 		{ |  | ||||||
| 			if (!callable_) |  | ||||||
| 				throw bad_function_call(); |  | ||||||
| 			return callable_->Invoke(std::forward<_Args>(args)...); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline operator bool() const |  | ||||||
| 		{ |  | ||||||
| 			return !!callable_; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline Closure& operator=(const Closure& rhs) |  | ||||||
| 		{ |  | ||||||
| 			tidy(); |  | ||||||
| 			callable_ = rhs.callable_; |  | ||||||
| 			if (callable_) callable_->AddRef(); |  | ||||||
| 			return (*this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		inline Closure& operator=(Closure&& rhs) |  | ||||||
| 		{ |  | ||||||
| 			tidy(); |  | ||||||
| 			callable_ = rhs.callable_; |  | ||||||
| 			rhs.callable_ = nullptr; |  | ||||||
| 			return (*this); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	private: |  | ||||||
| 		inline void tidy() |  | ||||||
| 		{ |  | ||||||
| 			if (callable_) |  | ||||||
| 			{ |  | ||||||
| 				callable_->Release(); |  | ||||||
| 				callable_ = nullptr; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	private: |  | ||||||
| 		__closure_detail::Callable<_Ret, _Args...>* callable_; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, |  | ||||||
| 		typename _Uty, |  | ||||||
| 		typename = typename std::enable_if< |  | ||||||
| 			std::is_same<_Ty, _Uty>::value || std::is_base_of<_Ty, _Uty>::value, int |  | ||||||
| 		>::type, |  | ||||||
| 		typename _Ret, |  | ||||||
| 		typename... _Args> |  | ||||||
| 	inline Closure<_Ret(_Args...)> MakeClosure(_Uty* ptr, _Ret(_Ty::* func)(_Args...)) |  | ||||||
| 	{ |  | ||||||
| 		return Closure<_Ret(_Args...)>(ptr, func); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	template<typename _Ty, |  | ||||||
| 		typename _Uty, |  | ||||||
| 		typename = typename std::enable_if< |  | ||||||
| 			std::is_same<_Ty, _Uty>::value || std::is_base_of<_Ty, _Uty>::value, int |  | ||||||
| 		>::type, |  | ||||||
| 		typename _Ret, |  | ||||||
| 		typename... _Args> |  | ||||||
| 	inline Closure<_Ret(_Args...)> MakeClosure(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const) |  | ||||||
| 	{ |  | ||||||
| 		return Closure<_Ret(_Args...)>(ptr, func); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,90 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "vector.hpp" | ||||||
|  | #include "string.hpp" | ||||||
|  | #include "intrusive_list.hpp" | ||||||
|  | #include "intrusive_ptr.hpp" | ||||||
|  | #include "noncopyable.hpp" | ||||||
|  | #include "singleton.hpp" | ||||||
|  | #include "Function.hpp" | ||||||
|  | #include "basic_json.hpp" | ||||||
|  | #include <set> | ||||||
|  | #include <map> | ||||||
|  | #include <list> | ||||||
|  | #include <queue> | ||||||
|  | #include <unordered_set> | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	using String = kiwano::core::wstring; | ||||||
|  | 
 | ||||||
|  | 	using StringStream = std::wstringstream; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Ty, typename... _Args> | ||||||
|  | 	using Vector = kiwano::core::vector<_Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Ty, typename... _Args> | ||||||
|  | 	using List = std::list<_Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Ty, typename... _Args> | ||||||
|  | 	using Queue = std::queue<_Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Ty, typename... _Args> | ||||||
|  | 	using Set = std::set<_Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Ty1, typename _Ty2> | ||||||
|  | 	using Pair = std::pair<_Ty1, _Ty2>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Ty, typename... _Args> | ||||||
|  | 	using UnorderedSet = std::unordered_set<_Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Kty, typename _Ty, typename... _Args> | ||||||
|  | 	using Map = std::map<_Kty, _Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _Kty, typename _Ty, typename... _Args> | ||||||
|  | 	using UnorderedMap = std::unordered_map<_Kty, _Ty, _Args...>; | ||||||
|  | 
 | ||||||
|  | 	template <typename _FuncTy> | ||||||
|  | 	using Function = kiwano::core::function<_FuncTy>; | ||||||
|  | 
 | ||||||
|  | 	using Json = kiwano::core::basic_json<kiwano::Map, kiwano::Vector, kiwano::String, | ||||||
|  | 		std::int32_t, double, bool, std::allocator>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace std | ||||||
|  | { | ||||||
|  | 	template<> | ||||||
|  | 	struct hash<::kiwano::Json> | ||||||
|  | 	{ | ||||||
|  | 		::std::size_t operator()(const ::kiwano::Json& json) const | ||||||
|  | 		{ | ||||||
|  | 			return hash<::kiwano::Json::string_type>{}(json.dump()); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	template<> | ||||||
|  | 	inline void swap<::kiwano::Json>(::kiwano::Json& lhs, ::kiwano::Json& rhs) noexcept | ||||||
|  | 	{ | ||||||
|  | 		lhs.swap(rhs); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,353 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | inline namespace core | ||||||
|  | { | ||||||
|  | //
 | ||||||
|  | // function is a light weight ::std::function<>-like class
 | ||||||
|  | //
 | ||||||
|  | 
 | ||||||
|  | namespace __function_detail | ||||||
|  | { | ||||||
|  | 	//
 | ||||||
|  | 	// is_callable
 | ||||||
|  | 	//
 | ||||||
|  | 
 | ||||||
|  | 	namespace __callable_detail | ||||||
|  | 	{ | ||||||
|  | 		template <typename _Ty, typename _Ret, typename... _Args> | ||||||
|  | 		struct helper | ||||||
|  | 		{ | ||||||
|  | 			template <typename _Uty> static int test(...); | ||||||
|  | 
 | ||||||
|  | 			template <typename _Uty, _Ret(_Uty::*)(_Args...)> struct class_mem; | ||||||
|  | 			template <typename _Uty> static char test(class_mem<_Uty, &_Uty::operator()>*); | ||||||
|  | 
 | ||||||
|  | 			template <typename _Uty, _Ret(_Uty::*)(_Args...) const> struct class_const_mem; | ||||||
|  | 			template <typename _Uty> static char test(class_const_mem<_Uty, &_Uty::operator()>*); | ||||||
|  | 
 | ||||||
|  | 			template< | ||||||
|  | 				typename _Uty, | ||||||
|  | 				typename _Uret = typename ::std::decay<decltype(::std::declval<_Uty>().operator()(::std::declval<_Args>()...))>::type, | ||||||
|  | 				typename = typename ::std::enable_if<::std::is_convertible<_Ret, _Uret>::value>::type> | ||||||
|  | 			static char test(int); | ||||||
|  | 
 | ||||||
|  | 			static constexpr bool value = sizeof(test<_Ty>(0)) == sizeof(char); | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, typename _Ret, typename... _Args> | ||||||
|  | 	struct is_callable | ||||||
|  | 		: public ::std::bool_constant<__callable_detail::helper<_Ty, _Ret, _Args...>::value> | ||||||
|  | 	{ | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	//
 | ||||||
|  | 	// callable
 | ||||||
|  | 	//
 | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ret, typename... _Args> | ||||||
|  | 	class callable | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		virtual ~callable() {} | ||||||
|  | 
 | ||||||
|  | 		virtual void AddRef() = 0; | ||||||
|  | 		virtual void Release() = 0; | ||||||
|  | 		virtual _Ret Invoke(_Args... args) const = 0; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ret, typename... _Args> | ||||||
|  | 	class ref_count_callable | ||||||
|  | 		: public callable<_Ret, _Args...> | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		ref_count_callable() : ref_count_(0) {} | ||||||
|  | 
 | ||||||
|  | 		virtual void AddRef() override | ||||||
|  | 		{ | ||||||
|  | 			++ref_count_; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		virtual void Release() override | ||||||
|  | 		{ | ||||||
|  | 			--ref_count_; | ||||||
|  | 			if (ref_count_ <= 0) | ||||||
|  | 			{ | ||||||
|  | 				delete this; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		int ref_count_; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, typename _Ret, typename... _Args> | ||||||
|  | 	class proxy_callable | ||||||
|  | 		: public ref_count_callable<_Ret, _Args...> | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		proxy_callable(_Ty&& val) | ||||||
|  | 			: callee_(::std::move(val)) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		virtual _Ret Invoke(_Args... args) const override | ||||||
|  | 		{ | ||||||
|  | 			return callee_(::std::forward<_Args&&>(args)...); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static inline callable<_Ret, _Args...>* Make(_Ty&& val) | ||||||
|  | 		{ | ||||||
|  | 			return new (::std::nothrow) proxy_callable<_Ty, _Ret, _Args...>(::std::move(val)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		_Ty callee_; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, typename _Ret, typename... _Args> | ||||||
|  | 	class proxy_mem_callable | ||||||
|  | 		: public ref_count_callable<_Ret, _Args...> | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		typedef _Ret(_Ty::* _FuncType)(_Args...); | ||||||
|  | 
 | ||||||
|  | 		virtual _Ret Invoke(_Args... args) const override | ||||||
|  | 		{ | ||||||
|  | 			return (static_cast<_Ty*>(ptr_)->*func_)(::std::forward<_Args>(args)...); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static inline callable<_Ret, _Args...>* Make(void* ptr, _FuncType func) | ||||||
|  | 		{ | ||||||
|  | 			return new (::std::nothrow) proxy_mem_callable<_Ty, _Ret, _Args...>(ptr, func); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		proxy_mem_callable(void* ptr, _FuncType func) | ||||||
|  | 			: ptr_(ptr) | ||||||
|  | 			, func_(func) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		void* ptr_; | ||||||
|  | 		_FuncType func_; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, typename _Ret, typename... _Args> | ||||||
|  | 	class proxy_const_mem_callable | ||||||
|  | 		: public ref_count_callable<_Ret, _Args...> | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		typedef _Ret(_Ty::* _FuncType)(_Args...) const; | ||||||
|  | 
 | ||||||
|  | 		virtual _Ret Invoke(_Args... args) const override | ||||||
|  | 		{ | ||||||
|  | 			return (static_cast<_Ty*>(ptr_)->*func_)(::std::forward<_Args>(args)...); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static inline callable<_Ret, _Args...>* Make(void* ptr, _FuncType func) | ||||||
|  | 		{ | ||||||
|  | 			return new (::std::nothrow) proxy_const_mem_callable<_Ty, _Ret, _Args...>(ptr, func); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		proxy_const_mem_callable(void* ptr, _FuncType func) | ||||||
|  | 			: ptr_(ptr) | ||||||
|  | 			, func_(func) | ||||||
|  | 		{ | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		void* ptr_; | ||||||
|  | 		_FuncType func_; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // exceptions
 | ||||||
|  | //
 | ||||||
|  | class bad_function_call : public ::std::exception | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	bad_function_call() {} | ||||||
|  | 
 | ||||||
|  | 	virtual const char* what() const override | ||||||
|  | 	{ | ||||||
|  | 		return "bad function call"; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // function details
 | ||||||
|  | //
 | ||||||
|  | template<typename _Ty> | ||||||
|  | class function; | ||||||
|  | 
 | ||||||
|  | template<typename _Ret, typename... _Args> | ||||||
|  | class function<_Ret(_Args...)> | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	function() | ||||||
|  | 		: callable_(nullptr) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function(::std::nullptr_t) | ||||||
|  | 		: callable_(nullptr) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function(const function& rhs) | ||||||
|  | 		: callable_(rhs.callable_) | ||||||
|  | 	{ | ||||||
|  | 		if (callable_) callable_->AddRef(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function(function&& rhs) noexcept | ||||||
|  | 		: callable_(rhs.callable_) | ||||||
|  | 	{ | ||||||
|  | 		rhs.callable_ = nullptr; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function(_Ret(*func)(_Args...)) | ||||||
|  | 	{ | ||||||
|  | 		callable_ = __function_detail::proxy_callable<_Ret(*)(_Args...), _Ret, _Args...>::Make(::std::move(func)); | ||||||
|  | 		if (callable_) callable_->AddRef(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template< | ||||||
|  | 		typename _Ty, | ||||||
|  | 		typename = typename ::std::enable_if<__function_detail::is_callable<_Ty, _Ret, _Args...>::value, int>::type> | ||||||
|  | 	function(_Ty val) | ||||||
|  | 	{ | ||||||
|  | 		callable_ = __function_detail::proxy_callable<_Ty, _Ret, _Args...>::Make(::std::move(val)); | ||||||
|  | 		if (callable_) callable_->AddRef(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, | ||||||
|  | 		typename _Uty, | ||||||
|  | 		typename = typename ::std::enable_if<::std::is_same<_Ty, _Uty>::value || ::std::is_base_of<_Ty, _Uty>::value, int>::type> | ||||||
|  | 	function(_Uty* ptr, _Ret(_Ty::* func)(_Args...)) | ||||||
|  | 	{ | ||||||
|  | 		callable_ = __function_detail::proxy_mem_callable<_Ty, _Ret, _Args...>::Make(ptr, func); | ||||||
|  | 		if (callable_) callable_->AddRef(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, | ||||||
|  | 		typename _Uty, | ||||||
|  | 		typename = typename ::std::enable_if<::std::is_same<_Ty, _Uty>::value || ::std::is_base_of<_Ty, _Uty>::value, int>::type> | ||||||
|  | 	function(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const) | ||||||
|  | 	{ | ||||||
|  | 		callable_ = __function_detail::proxy_const_mem_callable<_Ty, _Ret, _Args...>::Make(ptr, func); | ||||||
|  | 		if (callable_) callable_->AddRef(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	~function() | ||||||
|  | 	{ | ||||||
|  | 		tidy(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline void swap(const function& rhs) | ||||||
|  | 	{ | ||||||
|  | 		::std::swap(callable_, rhs.callable_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline _Ret operator()(_Args... args) const | ||||||
|  | 	{ | ||||||
|  | 		if (!callable_) | ||||||
|  | 			throw bad_function_call(); | ||||||
|  | 		return callable_->Invoke(::std::forward<_Args>(args)...); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline operator bool() const | ||||||
|  | 	{ | ||||||
|  | 		return !!callable_; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline function& operator=(const function& rhs) | ||||||
|  | 	{ | ||||||
|  | 		tidy(); | ||||||
|  | 		callable_ = rhs.callable_; | ||||||
|  | 		if (callable_) callable_->AddRef(); | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline function& operator=(function&& rhs) | ||||||
|  | 	{ | ||||||
|  | 		tidy(); | ||||||
|  | 		callable_ = rhs.callable_; | ||||||
|  | 		rhs.callable_ = nullptr; | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	inline void tidy() | ||||||
|  | 	{ | ||||||
|  | 		if (callable_) | ||||||
|  | 		{ | ||||||
|  | 			callable_->Release(); | ||||||
|  | 			callable_ = nullptr; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	__function_detail::callable<_Ret, _Args...>* callable_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | }  // inline namespace core
 | ||||||
|  | 
 | ||||||
|  | }  // namespace kiwano
 | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	template<typename _Ty, | ||||||
|  | 		typename _Uty, | ||||||
|  | 		typename = typename std::enable_if< | ||||||
|  | 		std::is_same<_Ty, _Uty>::value || std::is_base_of<_Ty, _Uty>::value, int | ||||||
|  | 		>::type, | ||||||
|  | 		typename _Ret, | ||||||
|  | 		typename... _Args> | ||||||
|  | 		inline function<_Ret(_Args...)> bind_func(_Uty* ptr, _Ret(_Ty::* func)(_Args...)) | ||||||
|  | 	{ | ||||||
|  | 		return function<_Ret(_Args...)>(ptr, func); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename _Ty, | ||||||
|  | 		typename _Uty, | ||||||
|  | 		typename = typename std::enable_if< | ||||||
|  | 		std::is_same<_Ty, _Uty>::value || std::is_base_of<_Ty, _Uty>::value, int | ||||||
|  | 		>::type, | ||||||
|  | 		typename _Ret, | ||||||
|  | 		typename... _Args> | ||||||
|  | 		inline function<_Ret(_Args...)> bind_func(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const) | ||||||
|  | 	{ | ||||||
|  | 		return function<_Ret(_Args...)>(ptr, func); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,261 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "../macros.h" | ||||||
|  | 
 | ||||||
|  | // #define KGE_DEBUG_ENABLE_LIST_CHECK
 | ||||||
|  | 
 | ||||||
|  | #ifdef KGE_DEBUG_ENABLE_LIST_CHECK | ||||||
|  | #	define KGE_DEBUG_CHECK_LIST(list_ptr) list_ptr->check_list() | ||||||
|  | #else | ||||||
|  | #	define KGE_DEBUG_CHECK_LIST __noop | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | inline namespace core | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | template <typename T> class intrusive_list; | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | class intrusive_list_item | ||||||
|  | { | ||||||
|  | 	T prev_; | ||||||
|  | 	T next_; | ||||||
|  | 
 | ||||||
|  | 	template <typename U> | ||||||
|  | 	friend class intrusive_list; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 	using ItemType = T; | ||||||
|  | 
 | ||||||
|  | 	intrusive_list_item() : prev_(), next_() {} | ||||||
|  | 
 | ||||||
|  | 	T const& prev_item() const	{ return prev_; } | ||||||
|  | 
 | ||||||
|  | 	T& prev_item()				{ return prev_; } | ||||||
|  | 
 | ||||||
|  | 	T const& next_item() const	{ return next_; } | ||||||
|  | 
 | ||||||
|  | 	T& next_item()				{ return next_; } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | class intrusive_list | ||||||
|  | { | ||||||
|  | 	T first_; | ||||||
|  | 	T last_; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 	using ItemType = T; | ||||||
|  | 
 | ||||||
|  | 	intrusive_list() : first_(), last_() {} | ||||||
|  | 
 | ||||||
|  | 	~intrusive_list()				{ clear_items(); } | ||||||
|  | 
 | ||||||
|  | 	T const& first_item() const		{ return first_; } | ||||||
|  | 
 | ||||||
|  | 	T& first_item()					{ return first_; } | ||||||
|  | 
 | ||||||
|  | 	T const& last_item() const		{ return last_; } | ||||||
|  | 
 | ||||||
|  | 	T& last_item()					{ return last_; } | ||||||
|  | 
 | ||||||
|  | 	bool is_empty() const			{ return !first_; } | ||||||
|  | 
 | ||||||
|  | 	void push_back_item(T const& child) | ||||||
|  | 	{ | ||||||
|  | 		if (child->prev_) | ||||||
|  | 			child->prev_->next_ = child->next_; | ||||||
|  | 		if (child->next_) | ||||||
|  | 			child->next_->prev_ = child->prev_; | ||||||
|  | 
 | ||||||
|  | 		child->prev_ = last_; | ||||||
|  | 		child->next_ = nullptr; | ||||||
|  | 
 | ||||||
|  | 		if (first_) | ||||||
|  | 		{ | ||||||
|  | 			last_->next_ = child; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			first_ = child; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		last_ = child; | ||||||
|  | 
 | ||||||
|  | 		KGE_DEBUG_CHECK_LIST(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void push_front_item(T const& child) | ||||||
|  | 	{ | ||||||
|  | 		if (child->prev_) | ||||||
|  | 			child->prev_->next_ = child->next_; | ||||||
|  | 		if (child->next_) | ||||||
|  | 			child->next_->prev_ = child->prev_; | ||||||
|  | 
 | ||||||
|  | 		child->prev_ = nullptr; | ||||||
|  | 		child->next_ = first_; | ||||||
|  | 
 | ||||||
|  | 		if (first_) | ||||||
|  | 		{ | ||||||
|  | 			first_->prev_ = child; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			last_ = child; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		first_ = child; | ||||||
|  | 
 | ||||||
|  | 		KGE_DEBUG_CHECK_LIST(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void insert_before(T const& child, T const& before) | ||||||
|  | 	{ | ||||||
|  | 		if (child->prev_) | ||||||
|  | 			child->prev_->next_ = child->next_; | ||||||
|  | 		if (child->next_) | ||||||
|  | 			child->next_->prev_ = child->prev_; | ||||||
|  | 
 | ||||||
|  | 		if (before->prev_) | ||||||
|  | 			before->prev_->next_ = child; | ||||||
|  | 		else | ||||||
|  | 			first_ = child; | ||||||
|  | 
 | ||||||
|  | 		child->prev_ = before->prev_; | ||||||
|  | 		child->next_ = before; | ||||||
|  | 		before->prev_ = child; | ||||||
|  | 
 | ||||||
|  | 		KGE_DEBUG_CHECK_LIST(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void insert_after(T const& child, T const& after) | ||||||
|  | 	{ | ||||||
|  | 		if (child->prev_) | ||||||
|  | 			child->prev_->next_ = child->next_; | ||||||
|  | 		if (child->next_) | ||||||
|  | 			child->next_->prev_ = child->prev_; | ||||||
|  | 
 | ||||||
|  | 		if (after->next_) | ||||||
|  | 			after->next_->prev_ = child; | ||||||
|  | 		else | ||||||
|  | 			last_ = child; | ||||||
|  | 
 | ||||||
|  | 		child->next_ = after->next_; | ||||||
|  | 		child->prev_ = after; | ||||||
|  | 		after->next_ = child; | ||||||
|  | 
 | ||||||
|  | 		KGE_DEBUG_CHECK_LIST(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void remove_item(T const& child) | ||||||
|  | 	{ | ||||||
|  | #ifdef KGE_DEBUG_ENABLE_LIST_CHECK | ||||||
|  | 		T tmp = first_; | ||||||
|  | 		while (tmp != child) | ||||||
|  | 		{ | ||||||
|  | 			KGE_ASSERT((tmp != last_) && "The actor to be removed is not in this list"); | ||||||
|  | 			tmp = tmp->next_; | ||||||
|  | 		} | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 		if (child->next_) | ||||||
|  | 		{ | ||||||
|  | 			child->next_->prev_ = child->prev_; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			last_ = child->prev_; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (child->prev_) | ||||||
|  | 		{ | ||||||
|  | 			child->prev_->next_ = child->next_; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			first_ = child->next_; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		child->prev_ = nullptr; | ||||||
|  | 		child->next_ = nullptr; | ||||||
|  | 
 | ||||||
|  | 		KGE_DEBUG_CHECK_LIST(this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void clear_items() | ||||||
|  | 	{ | ||||||
|  | 		T p = first_; | ||||||
|  | 		while (p) | ||||||
|  | 		{ | ||||||
|  | 			T tmp = p; | ||||||
|  | 			p = p->next_; | ||||||
|  | 			if (tmp) | ||||||
|  | 			{ | ||||||
|  | 				tmp->next_ = nullptr; | ||||||
|  | 				tmp->prev_ = nullptr; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		first_ = nullptr; | ||||||
|  | 		last_ = nullptr; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | #ifdef KGE_DEBUG_ENABLE_LIST_CHECK | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	void check_list() | ||||||
|  | 	{ | ||||||
|  | 		if (!first_) | ||||||
|  | 			return; | ||||||
|  | 
 | ||||||
|  | 		int pos = 0; | ||||||
|  | 		T p = first_; | ||||||
|  | 		T tmp = p; | ||||||
|  | 		do | ||||||
|  | 		{ | ||||||
|  | 			tmp = p; | ||||||
|  | 			p = p->next_; | ||||||
|  | 			++pos; | ||||||
|  | 
 | ||||||
|  | 			if (p) | ||||||
|  | 			{ | ||||||
|  | 				KGE_ASSERT(p->prev_ == tmp && "Check list failed"); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				KGE_ASSERT(tmp == last_ && "Check list failed"); | ||||||
|  | 			} | ||||||
|  | 		} while (p); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | }  // inline namespace core
 | ||||||
|  | 
 | ||||||
|  | }  // namespace kiwano
 | ||||||
|  | 
 | ||||||
|  | #undef KGE_DEBUG_CHECK_LIST | ||||||
|  | #undef KGE_DEBUG_ENABLE_LIST_CHECK | ||||||
|  | @ -0,0 +1,222 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | ||||||
|  | // 
 | ||||||
|  | // Permission is hereby granted, free of charge, to any person obtaining lhs copy
 | ||||||
|  | // of this software and associated documentation files (the "Software"), to deal
 | ||||||
|  | // in the Software without restriction, including without limitation the rights
 | ||||||
|  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | ||||||
|  | // copies of the Software, and to permit persons to whom the Software is
 | ||||||
|  | // furnished to do so, subject to the following conditions:
 | ||||||
|  | // 
 | ||||||
|  | // The above copyright notice and this permission notice shall be included in
 | ||||||
|  | // all copies or substantial portions of the Software.
 | ||||||
|  | // 
 | ||||||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||||||
|  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||||
|  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||||
|  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | ||||||
|  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
|  | // THE SOFTWARE.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "../macros.h" | ||||||
|  | #include <utility> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | inline namespace core | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | template <typename _Ty, typename _ManagerTy> | ||||||
|  | class intrusive_ptr | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	using value_type			= _Ty; | ||||||
|  | 	using pointer_type			= _Ty*; | ||||||
|  | 	using const_pointer_type	= const _Ty*; | ||||||
|  | 	using manager_type			= _ManagerTy; | ||||||
|  | 
 | ||||||
|  | 	intrusive_ptr() noexcept {} | ||||||
|  | 
 | ||||||
|  | 	intrusive_ptr(nullptr_t) noexcept {} | ||||||
|  | 
 | ||||||
|  | 	intrusive_ptr(pointer_type p) noexcept : ptr_(p) | ||||||
|  | 	{ | ||||||
|  | 		typename manager_type::AddRef(ptr_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	intrusive_ptr(const_pointer_type p) noexcept : ptr_(p) | ||||||
|  | 	{ | ||||||
|  | 		typename manager_type::AddRef(ptr_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	intrusive_ptr(const intrusive_ptr& other) noexcept | ||||||
|  | 		: ptr_(other.ptr_) | ||||||
|  | 	{ | ||||||
|  | 		typename manager_type::AddRef(ptr_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	template <typename _UTy> | ||||||
|  | 	intrusive_ptr(const intrusive_ptr<_UTy, manager_type>& other) noexcept | ||||||
|  | 		: ptr_(other.get()) | ||||||
|  | 	{ | ||||||
|  | 		typename manager_type::AddRef(ptr_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	intrusive_ptr(intrusive_ptr&& other) noexcept | ||||||
|  | 	{ | ||||||
|  | 		ptr_ = other.ptr_; | ||||||
|  | 		other.ptr_ = nullptr; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	~intrusive_ptr() noexcept | ||||||
|  | 	{ | ||||||
|  | 		typename manager_type::Release(ptr_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline pointer_type get() const noexcept { return ptr_; } | ||||||
|  | 
 | ||||||
|  | 	inline void reset() noexcept | ||||||
|  | 	{ | ||||||
|  | 		intrusive_ptr{}.swap(*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline void swap(intrusive_ptr& other) noexcept | ||||||
|  | 	{ | ||||||
|  | 		std::swap(ptr_, other.ptr_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline pointer_type operator ->() const | ||||||
|  | 	{ | ||||||
|  | 		KGE_ASSERT(ptr_ != nullptr && "Invalid pointer"); | ||||||
|  | 		return ptr_; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline value_type& operator *() const | ||||||
|  | 	{ | ||||||
|  | 		KGE_ASSERT(ptr_ != nullptr && "Invalid pointer"); | ||||||
|  | 		return *ptr_; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline pointer_type* operator &() | ||||||
|  | 	{ | ||||||
|  | 		KGE_ASSERT(ptr_ == nullptr && "Memory leak"); | ||||||
|  | 		return &ptr_; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline operator bool() const noexcept { return ptr_ != nullptr; } | ||||||
|  | 
 | ||||||
|  | 	inline bool operator !() const noexcept { return ptr_ == 0; } | ||||||
|  | 
 | ||||||
|  | 	inline intrusive_ptr& operator =(const intrusive_ptr& other) noexcept | ||||||
|  | 	{ | ||||||
|  | 		if (other.ptr_ != ptr_) | ||||||
|  | 			intrusive_ptr(other).swap(*this); | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline intrusive_ptr& operator =(intrusive_ptr&& other) noexcept | ||||||
|  | 	{ | ||||||
|  | 		typename manager_type::Release(ptr_); | ||||||
|  | 		ptr_ = other.ptr_; | ||||||
|  | 		other.ptr_ = nullptr; | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline intrusive_ptr& operator =(pointer_type p) noexcept | ||||||
|  | 	{ | ||||||
|  | 		if (p != ptr_) | ||||||
|  | 			intrusive_ptr(p).swap(*this); | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	inline intrusive_ptr& operator =(nullptr_t) noexcept | ||||||
|  | 	{ | ||||||
|  | 		if (nullptr != ptr_) | ||||||
|  | 			intrusive_ptr{}.swap(*this); | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	pointer_type ptr_{ nullptr }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class _UTy, class manager_type> | ||||||
|  | inline bool operator==(intrusive_ptr<_Ty, manager_type> const& lhs, intrusive_ptr<_UTy, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs.get() == rhs.get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class _UTy, class manager_type> | ||||||
|  | inline bool operator!=(intrusive_ptr<_Ty, manager_type> const& lhs, intrusive_ptr<_UTy, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs.get() != rhs.get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class _UTy, class manager_type> | ||||||
|  | inline bool operator<(intrusive_ptr<_Ty, manager_type> const& lhs, intrusive_ptr<_UTy, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs.get() < rhs.get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator==(intrusive_ptr<_Ty, manager_type> const& lhs, _Ty* rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs.get() == rhs; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator!=(intrusive_ptr<_Ty, manager_type> const& lhs, _Ty* rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs.get() != rhs; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator==(_Ty* lhs, intrusive_ptr<_Ty, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs == rhs.get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator!=(_Ty* lhs, intrusive_ptr<_Ty, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return lhs != rhs.get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator==(intrusive_ptr<_Ty, manager_type> const& lhs, nullptr_t) noexcept | ||||||
|  | { | ||||||
|  | 	return !static_cast<bool>(lhs); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator!=(intrusive_ptr<_Ty, manager_type> const& lhs, nullptr_t) noexcept | ||||||
|  | { | ||||||
|  | 	return static_cast<bool>(lhs); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator==(nullptr_t, intrusive_ptr<_Ty, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return !static_cast<bool>(rhs); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline bool operator!=(nullptr_t, intrusive_ptr<_Ty, manager_type> const& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	return static_cast<bool>(rhs); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // template class cannot specialize std::swap,
 | ||||||
|  | // so implement a swap Function in kiwano namespace
 | ||||||
|  | template <class _Ty, class manager_type> | ||||||
|  | inline void swap(intrusive_ptr<_Ty, manager_type>& lhs, intrusive_ptr<_Ty, manager_type>& rhs) noexcept | ||||||
|  | { | ||||||
|  | 	lhs.swap(rhs); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | }  // inline namespace core
 | ||||||
|  | 
 | ||||||
|  | }  // namespace kiwano
 | ||||||
|  | @ -22,14 +22,19 @@ | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 	class Noncopyable | inline namespace core | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class noncopyable | ||||||
| { | { | ||||||
| protected: | protected: | ||||||
| 		Noncopyable() = default; | 	noncopyable() = default; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 		Noncopyable(const Noncopyable&) = delete; | 	noncopyable(const noncopyable&) = delete; | ||||||
| 
 | 
 | ||||||
| 		Noncopyable& operator=(const Noncopyable&) = delete; | 	noncopyable& operator=(const noncopyable&) = delete; | ||||||
| }; | }; | ||||||
| } | 
 | ||||||
|  | }  // inline namespace core
 | ||||||
|  | }  // namespace kiwano
 | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue