[deploy] Merge pull request #47 from KiwanoEngine/dev
Remove tinyxml2 & add pugixml
This commit is contained in:
		
						commit
						3da3cc6022
					
				|  | @ -0,0 +1,108 @@ | |||
| # Clang-format version v9.0.0 | ||||
| --- | ||||
| Language: Cpp | ||||
| BasedOnStyle: Google | ||||
| 
 | ||||
| ColumnLimit: 120 | ||||
| 
 | ||||
| ## | ||||
| ## Indent Style | ||||
| ## | ||||
| 
 | ||||
| IndentWidth: 4 | ||||
| AccessModifierOffset: -4 | ||||
| ConstructorInitializerIndentWidth: 4 | ||||
| ContinuationIndentWidth: 4 | ||||
| TabWidth: 4 | ||||
| UseTab: Never | ||||
| IndentCaseLabels: false | ||||
| NamespaceIndentation: None | ||||
| 
 | ||||
| ## | ||||
| ## Align Style | ||||
| ## | ||||
| 
 | ||||
| AlignAfterOpenBracket: Align | ||||
| AlignConsecutiveAssignments: true | ||||
| AlignConsecutiveDeclarations: true | ||||
| AlignEscapedNewlinesLeft: true | ||||
| AlignOperands: true | ||||
| AlignTrailingComments: true | ||||
| PointerAlignment: Left | ||||
| 
 | ||||
| ## | ||||
| ## SingleLine Style | ||||
| ## | ||||
| 
 | ||||
| AllowAllParametersOfDeclarationOnNextLine: true | ||||
| AllowShortBlocksOnASingleLine: false | ||||
| AllowShortCaseLabelsOnASingleLine: false | ||||
| AllowShortFunctionsOnASingleLine: Empty | ||||
| AllowShortIfStatementsOnASingleLine: false | ||||
| AllowShortLoopsOnASingleLine: false | ||||
| AlwaysBreakAfterDefinitionReturnType: None | ||||
| AlwaysBreakAfterReturnType: None | ||||
| AlwaysBreakBeforeMultilineStrings: false | ||||
| AlwaysBreakTemplateDeclarations: true | ||||
| BinPackArguments: true | ||||
| BinPackParameters: true | ||||
| BreakBeforeBraces: Allman | ||||
| BraceWrapping: | ||||
|   AfterClass: true | ||||
|   AfterControlStatement: true | ||||
|   AfterEnum: true | ||||
|   AfterFunction: true | ||||
|   AfterNamespace: true | ||||
|   AfterObjCDeclaration: true | ||||
|   AfterStruct: true | ||||
|   AfterUnion: true | ||||
|   BeforeCatch: true | ||||
|   BeforeElse: true | ||||
|   IndentBraces: true | ||||
| BreakBeforeBinaryOperators: NonAssignment | ||||
| BreakBeforeTernaryOperators: true | ||||
| CommentPragmas: "^ IWYU pragma:" | ||||
| ConstructorInitializerAllOnOneLineOrOnePerLine: false | ||||
| 
 | ||||
| ## | ||||
| ## Others | ||||
| ## | ||||
| 
 | ||||
| BreakConstructorInitializers: BeforeComma | ||||
| BreakInheritanceList: BeforeComma | ||||
| ReflowComments: true | ||||
| SortIncludes: false | ||||
| Cpp11BracedListStyle: false | ||||
| DerivePointerAlignment: false | ||||
| DisableFormat: false | ||||
| ExperimentalAutoDetectBinPacking: false | ||||
| ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH] | ||||
| IncludeCategories: | ||||
|   - Regex: '^"(llvm|llvm-c|clang|clang-c)/' | ||||
|     Priority: 2 | ||||
|   - Regex: '^(<|"(gtest|isl|json)/)' | ||||
|     Priority: 3 | ||||
|   - Regex: ".*" | ||||
|     Priority: 1 | ||||
| IndentWrappedFunctionNames: false | ||||
| KeepEmptyLinesAtTheStartOfBlocks: true | ||||
| MacroBlockBegin: "" | ||||
| MacroBlockEnd: "" | ||||
| MaxEmptyLinesToKeep: 1 | ||||
| PenaltyBreakBeforeFirstCallParameter: 19 | ||||
| PenaltyBreakComment: 300 | ||||
| PenaltyBreakFirstLessLess: 120 | ||||
| PenaltyBreakString: 1000 | ||||
| PenaltyExcessCharacter: 1000000 | ||||
| PenaltyReturnTypeOnItsOwnLine: 60 | ||||
| SpaceAfterCStyleCast: false | ||||
| SpaceBeforeAssignmentOperators: true | ||||
| SpaceBeforeParens: ControlStatements | ||||
| SpaceInEmptyParentheses: false | ||||
| SpacesBeforeTrailingComments: 2 | ||||
| SpacesInAngles: false | ||||
| SpacesInContainerLiterals: true | ||||
| SpacesInCStyleCastParentheses: false | ||||
| SpacesInParentheses: false | ||||
| SpacesInSquareBrackets: false | ||||
| Standard: Cpp11 | ||||
|  | @ -14,7 +14,7 @@ insert_final_newline = true | |||
| charset = gb2312 | ||||
| 
 | ||||
| # 4 space indentation | ||||
| indent_style = tab | ||||
| indent_style = space | ||||
| indent_size = 4 | ||||
| 
 | ||||
| # Matches the exact files | ||||
|  |  | |||
|  | @ -0,0 +1,66 @@ | |||
|  | ||||
| 
 | ||||
| # Kiwano 游戏引擎 | ||||
| 
 | ||||
| [](https://ci.appveyor.com/project/Nomango/kiwano/branch/master) | ||||
| [](https://github.com/Nomango/Kiwano/releases/latest) | ||||
| [](https://github.com/Nomango/Kiwano/blob/master/LICENSE) | ||||
| 
 | ||||
| [English](./README.md) | 简体中文 | ||||
| 
 | ||||
| ## 介绍 | ||||
| 
 | ||||
| Kiwano 是一个使用 C++ 开发的 2D 游戏引擎,目前仅支持 Windows 平台。 | ||||
| 
 | ||||
| Kiwano-Core 是一个提供了一系列实用工具的游戏无关库,它的目的是简化 C++ 开发过程。 | ||||
| 
 | ||||
| 这个仓库仍处于开发过程中,我创建这个仓库用来学习游戏引擎知识和开发自己的小游戏。 | ||||
| 
 | ||||
| 你可以到 [Kiwano Demos](https://github.com/kiwanogame/KiwanoDemos) 仓库查看和学习如何使用 Kiwano 引擎实现小游戏。 | ||||
| 
 | ||||
| 欢迎您任何形式的贡献。 | ||||
| 
 | ||||
| ## 功能 | ||||
| 
 | ||||
| * 舞台和角色管理 | ||||
| * 舞台过渡动画 | ||||
| * 动作行为 | ||||
| * 按钮等简易UI元素 | ||||
| * 音频支持 | ||||
| * 网络通信支持 | ||||
| * 数据持久化 | ||||
| * 物理引擎 (基于 Box2D) | ||||
| * GUI 引擎 (基于 ImGui) | ||||
| 
 | ||||
| ## 安装 | ||||
| 
 | ||||
| ### 开发环境 | ||||
| 
 | ||||
| - Win8 或更高 (推荐 Win10) | ||||
| - Visual Studio 2015 或更高 | ||||
| 
 | ||||
| ### 通过 NuGet 安装 | ||||
| 
 | ||||
| 1. 打开你的 Visual Studio 解决方案 | ||||
| 2. 在解决方案资源管理器, 右击 `引用` 并选择 `管理 NuGet 程序包` | ||||
| 3. 选择 `浏览` 选项卡, 搜索 `kiwano`, 选中列表中的包然后点击 `安装` | ||||
| 4. 开始使用 Kiwano 进行开发吧! | ||||
| 
 | ||||
| ### 通过源代码安装 | ||||
| 
 | ||||
| 1. 从 Github 仓库克隆或下载源代码 | ||||
| 2. 打开你的 Visual Studio 解决方案, 在解决方案资源管理器中右键你的解决方案, 选择 `添加` => `现有项` | ||||
| 3. 选中源代码目录下 /projects 文件夹中所有的 `.vcxproj` 文件,并确认添加 | ||||
| 4. 右键你的项目,打开 `属性`, 选中 C\C++ => 常规, 并将源代码文件夹下的 src 目录添加到 `附加包含目录` 中 | ||||
| 5. 右键你的项目 `引用` 并选择 `添加引用`, 选中 `kiwano` 项目和其他你需要的项目 | ||||
| 6. 开始使用 Kiwano 进行开发吧! | ||||
| 
 | ||||
| ## 开发计划 | ||||
| 
 | ||||
| * 跨平台支持 | ||||
| * 粒子系统 | ||||
| 
 | ||||
| ## 社交媒体 | ||||
| 
 | ||||
| * 网站: [kiwanoengine.com](https://kiwanoengine.com) | ||||
| * QQ群: 608406540 | ||||
							
								
								
									
										10
									
								
								README.md
								
								
								
								
							
							
						
						
									
										10
									
								
								README.md
								
								
								
								
							|  | @ -6,6 +6,8 @@ | |||
| [](https://github.com/Nomango/Kiwano/releases/latest) | ||||
| [](https://github.com/Nomango/Kiwano/blob/master/LICENSE) | ||||
| 
 | ||||
| English | [简体中文](./README-zh.md) | ||||
| 
 | ||||
| ## Introduction | ||||
| Kiwano is a open-source 2D C++ game engine, only support win32 platform. | ||||
| 
 | ||||
|  | @ -20,12 +22,13 @@ More docs and examples will be added later. | |||
| ## Features | ||||
| * Scene management | ||||
| * Transitions between scenes | ||||
| * Actions behaviours | ||||
| * Action behaviours | ||||
| * Buttons and menus | ||||
| * Texture atlas support | ||||
| * Audio support | ||||
| * Custom data storage | ||||
| * Direct2D based | ||||
| * Physical engine (based on Box2D) | ||||
| * GUI system (based on ImGui) | ||||
| 
 | ||||
| ## Install | ||||
| 
 | ||||
|  | @ -51,8 +54,7 @@ More docs and examples will be added later. | |||
| 6. Now you can build your own applications based on Kiwano source code ! | ||||
| 
 | ||||
| ## Next plan | ||||
| * GUI system | ||||
| * Physical engine | ||||
| * Cross-platform | ||||
| * Particle system | ||||
| 
 | ||||
| ## Contact | ||||
|  |  | |||
							
								
								
									
										19
									
								
								appveyor.yml
								
								
								
								
							
							
						
						
									
										19
									
								
								appveyor.yml
								
								
								
								
							|  | @ -19,7 +19,6 @@ pull_requests: | |||
| environment: | ||||
|   global: | ||||
|     time_out_mins: 5 | ||||
|     job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration) | ||||
|     flag_to_deploy: false | ||||
|     appveyor_api_token: | ||||
|       secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= | ||||
|  | @ -48,11 +47,10 @@ for: | |||
|   environment: | ||||
|     matrix: | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       VS_PLATFORM_TOOLSET: v142 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 | ||||
|       VS_PLATFORM_TOOLSET: v141 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       VS_PLATFORM_TOOLSET: v140 | ||||
|     global: | ||||
|       job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration) | ||||
| - | ||||
|   branches: | ||||
|     except: | ||||
|  | @ -62,7 +60,8 @@ for: | |||
|   environment: | ||||
|     matrix: | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|       VS_PLATFORM_TOOLSET: v142 | ||||
|     global: | ||||
|       job_to_deploy: 2 # 1(images) * 1(platform) * 2(configuration) | ||||
| 
 | ||||
| configuration: | ||||
| - Debug | ||||
|  | @ -90,9 +89,9 @@ after_build: | |||
| 
 | ||||
| artifacts: | ||||
| - path: projects/output/**/*.lib | ||||
|   name: $(appveyor_project_name)-v$(appveyor_build_version)-$(VS_PLATFORM_TOOLSET).$(platform).$(configuration) | ||||
|   name: PublishedLibraries | ||||
| - path: projects/output/**/*.pdb | ||||
|   name: $(appveyor_project_name)-v$(appveyor_build_version)-$(VS_PLATFORM_TOOLSET).$(platform).$(configuration) | ||||
|   name: PublishedSymbols | ||||
| 
 | ||||
| before_deploy: | ||||
| - ps: .\scripts\appveyor\coapp_make.ps1 | ||||
|  | @ -100,9 +99,9 @@ before_deploy: | |||
| deploy: | ||||
| - provider: GitHub | ||||
|   repository: KiwanoEngine/Kiwano | ||||
|   tag: v$(appveyor_build_version) | ||||
|   release: v$(appveyor_build_version) | ||||
|   description: Kiwano-v$(appveyor_build_version) releases. | ||||
|   tag: v$(APPVEYOR_BUILD_VERSION) | ||||
|   release: v$(APPVEYOR_BUILD_VERSION) | ||||
|   description: Kiwano-v$(APPVEYOR_BUILD_VERSION) releases. | ||||
|   auth_token: | ||||
|     secure: pDsK6i03d4qRjtrNXcbhLpAquso/muJWgDSWJHnxP7b6p54kXEvptB67J+1kJOhq | ||||
|   artifact: /.*\.nupkg/ | ||||
|  |  | |||
|  | @ -33,7 +33,6 @@ | |||
|     <ClInclude Include="..\..\..\src\3rd-party\curl\typecheck-gcc.h"> | ||||
|       <Filter>include</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\..\src\3rd-party\curl\tinyxml2.h" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <Library Include="..\..\..\src\3rd-party\curl\libs\libcurl.lib"> | ||||
|  |  | |||
|  | @ -1,97 +0,0 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\..\..\src\3rd-party\tinyxml2\tinyxml2.h" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="..\..\..\src\3rd-party\tinyxml2\tinyxml2.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup Label="ProjectConfigurations"> | ||||
|     <ProjectConfiguration Include="Debug|Win32"> | ||||
|       <Configuration>Debug</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|     <ProjectConfiguration Include="Release|Win32"> | ||||
|       <Configuration>Release</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <ProjectGuid>{AB47E875-85E5-4105-A71E-88930EAAB910}</ProjectGuid> | ||||
|     <RootNamespace>libtinyxml2</RootNamespace> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>true</UseDebugLibraries> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|     <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>false</UseDebugLibraries> | ||||
|     <WholeProgramOptimization>false</WholeProgramOptimization> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|     <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
|   <ImportGroup Label="ExtensionSettings"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="Shared"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <PropertyGroup Label="UserMacros" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <OutDir>$(SolutionDir)\output\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir> | ||||
|     <IntDir>$(SolutionDir)\build\$(PlatformToolset)\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> | ||||
|     <LinkIncremental>true</LinkIncremental> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <OutDir>$(SolutionDir)\output\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir> | ||||
|     <IntDir>$(SolutionDir)\build\$(PlatformToolset)\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> | ||||
|     <LinkIncremental>true</LinkIncremental> | ||||
|   </PropertyGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <Optimization>Disabled</Optimization> | ||||
|       <TreatWarningAsError>true</TreatWarningAsError> | ||||
|       <DebugInformationFormat>None</DebugInformationFormat> | ||||
|       <MultiProcessorCompilation>true</MultiProcessorCompilation> | ||||
|       <AdditionalIncludeDirectories>../../../src/3rd-party;</AdditionalIncludeDirectories> | ||||
|       <MinimalRebuild>false</MinimalRebuild> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <Optimization>MaxSpeed</Optimization> | ||||
|       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||
|       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||
|       <BufferSecurityCheck>false</BufferSecurityCheck> | ||||
|       <TreatWarningAsError>true</TreatWarningAsError> | ||||
|       <DebugInformationFormat>None</DebugInformationFormat> | ||||
|       <MultiProcessorCompilation>true</MultiProcessorCompilation> | ||||
|       <AdditionalIncludeDirectories>../../../src/3rd-party;</AdditionalIncludeDirectories> | ||||
|       <MinimalRebuild>false</MinimalRebuild> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>false</GenerateDebugInformation> | ||||
|       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||
|       <OptimizeReferences>true</OptimizeReferences> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
| </Project> | ||||
|  | @ -1,9 +0,0 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="..\..\..\src\3rd-party\tinyxml2\tinyxml2.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\..\..\src\3rd-party\tinyxml2\tinyxml2.h" /> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
|  | @ -14,8 +14,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano-physics", "kiwano-ph | |||
| EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rd-party", "3rd-party", "{2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}" | ||||
| EndProject | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtinyxml2", "3rd-party\tinyxml2\libtinyxml2.vcxproj", "{AB47E875-85E5-4105-A71E-88930EAAB910}" | ||||
| EndProject | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libimgui", "3rd-party\imgui\libimgui.vcxproj", "{7FA1E56D-62AC-47D1-97D1-40B302724198}" | ||||
| EndProject | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "3rd-party\curl\libcurl.vcxproj", "{A9ABACC7-75A1-46BA-8E48-4105346D9719}" | ||||
|  | @ -49,10 +47,6 @@ Global | |||
| 		{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.ActiveCfg = Release|Win32 | ||||
| 		{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.Build.0 = Release|Win32 | ||||
| 		{AB47E875-85E5-4105-A71E-88930EAAB910}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||
| 		{AB47E875-85E5-4105-A71E-88930EAAB910}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{AB47E875-85E5-4105-A71E-88930EAAB910}.Release|Win32.ActiveCfg = Release|Win32 | ||||
| 		{AB47E875-85E5-4105-A71E-88930EAAB910}.Release|Win32.Build.0 = Release|Win32 | ||||
| 		{7FA1E56D-62AC-47D1-97D1-40B302724198}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||
| 		{7FA1E56D-62AC-47D1-97D1-40B302724198}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{7FA1E56D-62AC-47D1-97D1-40B302724198}.Release|Win32.ActiveCfg = Release|Win32 | ||||
|  | @ -70,7 +64,6 @@ Global | |||
| 		HideSolutionNode = FALSE | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(NestedProjects) = preSolution | ||||
| 		{AB47E875-85E5-4105-A71E-88930EAAB910} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7} | ||||
| 		{7FA1E56D-62AC-47D1-97D1-40B302724198} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7} | ||||
| 		{A9ABACC7-75A1-46BA-8E48-4105346D9719} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7} | ||||
| 		{0CBA9295-F14D-4966-A7C4-1DD68158176C} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7} | ||||
|  |  | |||
|  | @ -9,15 +9,20 @@ | |||
|     <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\Button.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\2d\Frame.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\common.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Common.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Director.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\event\Event.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\event\EventType.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\event\KeyEvent.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\event\MouseEvent.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\event\WindowEvent.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Keys.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Library.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Singleton.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Time.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\kiwano.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\config.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\macros.h" /> | ||||
|  | @ -36,7 +41,6 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\core\Component.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\EventDispatcher.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\EventListener.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\keys.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Logger.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\ObjectBase.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\RefCounter.h" /> | ||||
|  | @ -44,7 +48,6 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\core\SmartPtr.hpp" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Timer.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\TimerManager.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\time.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\math\constants.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\math\ease.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\math\math.h" /> | ||||
|  | @ -54,36 +57,33 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\math\scalar.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\math\Vec2.hpp" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Application.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Director.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\FileSystem.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Input.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\win32\helper.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\win32\libraries.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Window.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Brush.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Color.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Font.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Geometry.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\GeometrySink.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\GifImage.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\StrokeStyle.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Texture.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\TextureCache.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\LayerArea.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Renderer.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\RenderTarget.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\TextLayout.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D3DDeviceResourcesBase.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\helper.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\TextRenderer.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\ui\Button.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\ui\Menu.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Brush.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Color.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D3DDeviceResourcesBase.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\helper.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Font.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Geometry.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\GeometrySink.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\GifImage.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\LayerArea.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\RenderContext.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Renderer.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\StrokeStyle.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\TextLayout.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Texture.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\TextureCache.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\utils\ResourceCache.h" /> | ||||
|     <ClInclude Include="..\..\src\kiwano\utils\UserData.h" /> | ||||
|  | @ -96,6 +96,7 @@ | |||
|     <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\Button.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\DebugActor.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\Frame.cpp" /> | ||||
|  | @ -111,6 +112,7 @@ | |||
|     <ClCompile Include="..\..\src\kiwano\2d\Transition.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\AsyncTask.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Component.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Director.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\EventDispatcher.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\EventListener.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\event\Event.cpp" /> | ||||
|  | @ -122,35 +124,34 @@ | |||
|     <ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Resource.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Time.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Timer.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\TimerManager.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\time.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\Application.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\Director.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\Input.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\win32\StackWalker.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\win32\WindowImpl.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\Window.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Color.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Font.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Geometry.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\GeometrySink.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\GifImage.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Texture.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\TextureCache.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\LayerArea.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Renderer.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\RenderTarget.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\TextLayout.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\TextRenderer.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\ui\Button.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\ui\Menu.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Brush.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Color.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\TextRenderer.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Font.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Geometry.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\GeometrySink.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\GifImage.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\LayerArea.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\RenderContext.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Renderer.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\StrokeStyle.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Texture.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\utils\ResourceCache.cpp" /> | ||||
|     <ClCompile Include="..\..\src\kiwano\utils\UserData.cpp" /> | ||||
|  | @ -165,11 +166,6 @@ | |||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\3rd-party\tinyxml2\libtinyxml2.vcxproj"> | ||||
|       <Project>{ab47e875-85e5-4105-a71e-88930eaab910}</Project> | ||||
|     </ProjectReference> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <ProjectGuid>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid> | ||||
|     <RootNamespace>kiwano</RootNamespace> | ||||
|  |  | |||
|  | @ -7,9 +7,6 @@ | |||
|     <Filter Include="utils"> | ||||
|       <UniqueIdentifier>{68eac919-ee87-4030-a033-c251731928f5}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="ui"> | ||||
|       <UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="platform"> | ||||
|       <UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|  | @ -19,29 +16,23 @@ | |||
|     <Filter Include="core"> | ||||
|       <UniqueIdentifier>{2e18d99a-e906-499a-9e29-4e0783202644}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="renderer"> | ||||
|       <UniqueIdentifier>{7897afce-24cb-42b4-9443-56508e4ec89c}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="2d\action"> | ||||
|       <UniqueIdentifier>{9314f30d-5742-48b6-94e5-e3b4284106f6}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="renderer\win32"> | ||||
|       <UniqueIdentifier>{30333461-e9bc-4709-84bd-ce6e0e1a3079}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="platform\win32"> | ||||
|       <UniqueIdentifier>{e84dcf9a-e650-473e-8c9c-193804ab9e76}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="core\event"> | ||||
|       <UniqueIdentifier>{c629aedd-ffb9-4bc1-82c3-f50e77c82e77}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="render"> | ||||
|       <UniqueIdentifier>{adb44ca9-674a-4b77-993f-d65193d8ab06}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|     <Filter Include="render\DirectX"> | ||||
|       <UniqueIdentifier>{fd281702-0006-46d2-8fd1-28c502464164}</UniqueIdentifier> | ||||
|     </Filter> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\..\src\kiwano\ui\Button.h"> | ||||
|       <Filter>ui</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\ui\Menu.h"> | ||||
|       <Filter>ui</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\2d\Canvas.h"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClInclude> | ||||
|  | @ -66,9 +57,6 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\core\Resource.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\time.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\math\Matrix.hpp"> | ||||
|       <Filter>math</Filter> | ||||
|     </ClInclude> | ||||
|  | @ -156,63 +144,9 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\core\ObjectBase.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Color.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Font.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Geometry.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\GifImage.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\LayerArea.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Renderer.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\TextLayout.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\D3DDeviceResourcesBase.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\TextRenderer.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\RenderTarget.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\2d\Transform.h"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Texture.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\TextureCache.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\StrokeStyle.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\Brush.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\math\constants.h"> | ||||
|       <Filter>math</Filter> | ||||
|     </ClInclude> | ||||
|  | @ -234,36 +168,18 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\platform\FileSystem.h"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\keys.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Input.h"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Window.h"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\Director.h"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\2d\TextActor.h"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\common.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\RefCounter.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\win32\helper.h"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\renderer\GeometrySink.h"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp"> | ||||
|       <Filter>platform\win32</Filter> | ||||
|     </ClInclude> | ||||
|  | @ -288,14 +204,89 @@ | |||
|     <ClInclude Include="..\..\src\kiwano\core\event\WindowEvent.h"> | ||||
|       <Filter>core\event</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\2d\Button.h"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Director.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Singleton.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Common.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Keys.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\core\Time.h"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Brush.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Color.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Font.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Geometry.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\GeometrySink.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\GifImage.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\LayerArea.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\RenderContext.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Renderer.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\StrokeStyle.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\TextLayout.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\Texture.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\TextureCache.h"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\D3DDeviceResourcesBase.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\helper.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="..\..\src\kiwano\ui\Button.cpp"> | ||||
|       <Filter>ui</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\ui\Menu.cpp"> | ||||
|       <Filter>ui</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClCompile> | ||||
|  | @ -317,9 +308,6 @@ | |||
|     <ClCompile Include="..\..\src\kiwano\core\Resource.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\time.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\Application.cpp"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClCompile> | ||||
|  | @ -383,57 +371,9 @@ | |||
|     <ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Color.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Font.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Geometry.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\GifImage.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\LayerArea.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Renderer.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\TextLayout.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.cpp"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.cpp"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.cpp"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.cpp"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\win32\TextRenderer.cpp"> | ||||
|       <Filter>renderer\win32</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\RenderTarget.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\Transform.cpp"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Texture.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\TextureCache.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Component.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|  | @ -455,18 +395,12 @@ | |||
|     <ClCompile Include="..\..\src\kiwano\platform\Window.cpp"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\Director.cpp"> | ||||
|       <Filter>platform</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\renderer\GeometrySink.cpp"> | ||||
|       <Filter>renderer</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp"> | ||||
|       <Filter>platform\win32</Filter> | ||||
|     </ClCompile> | ||||
|  | @ -485,5 +419,71 @@ | |||
|     <ClCompile Include="..\..\src\kiwano\core\event\WindowEvent.cpp"> | ||||
|       <Filter>core\event</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\2d\Button.cpp"> | ||||
|       <Filter>2d</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Director.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\platform\win32\WindowImpl.cpp"> | ||||
|       <Filter>platform\win32</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\core\Time.cpp"> | ||||
|       <Filter>core</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Brush.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Color.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Font.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Geometry.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\GeometrySink.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\GifImage.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\LayerArea.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\RenderContext.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Renderer.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\StrokeStyle.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\Texture.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp"> | ||||
|       <Filter>render</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.cpp"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.cpp"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.cpp"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.cpp"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\kiwano\render\DirectX\TextRenderer.cpp"> | ||||
|       <Filter>render\DirectX</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
|  | @ -0,0 +1,84 @@ | |||
| #!/bin/bash | ||||
| # | ||||
| # clang-format-all: a tool to run clang-format on an entire project | ||||
| # Copyright (C) 2016 Evan Klitzke <evan@eklitzke.org> | ||||
| # | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| function usage { | ||||
|     echo "Usage: $0 DIR..." | ||||
|     exit 1 | ||||
| } | ||||
| 
 | ||||
| if [ $# -eq 0 ]; then | ||||
|     usage | ||||
| fi | ||||
| 
 | ||||
| # Variable that will hold the name of the clang-format command | ||||
| FMT="" | ||||
| 
 | ||||
| # Some distros just call it clang-format. Others (e.g. Ubuntu) are insistent | ||||
| # that the version number be part of the command. We prefer clang-format if | ||||
| # that's present, otherwise we work backwards from highest version to lowest | ||||
| # version. | ||||
| for clangfmt in clang-format{,-{4,3}.{9,8,7,6,5,4,3,2,1,0}}; do | ||||
|     if which "$clangfmt" &>/dev/null; then | ||||
|         FMT="$clangfmt" | ||||
|         break | ||||
|     fi | ||||
| done | ||||
| 
 | ||||
| # Check if we found a working clang-format | ||||
| if [ -z "$FMT" ]; then | ||||
|     echo "failed to find clang-format" | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| # Check all of the arguments first to make sure they're all directories | ||||
| for dir in "$@"; do | ||||
|     if [ ! -d "${dir}" ]; then | ||||
|         echo "${dir} is not a directory" | ||||
|         usage | ||||
|     fi | ||||
| done | ||||
| 
 | ||||
| # Find a dominating file, starting from a given directory and going up. | ||||
| find-dominating-file() { | ||||
|     if [ -r "$1"/"$2" ]; then | ||||
|         return 0 | ||||
|     fi | ||||
|     if [ "$1" = "/" ]; then | ||||
|         return 1 | ||||
|     fi | ||||
|     find-dominating-file "$(realpath "$1"/..)" "$2" | ||||
|     return $? | ||||
| } | ||||
| 
 | ||||
| # Run clang-format -i on all of the things | ||||
| for dir in "$@"; do | ||||
|     pushd "${dir}" &>/dev/null | ||||
|     if ! find-dominating-file . .clang-format; then | ||||
|         echo "Failed to find dominating .clang-format starting at $PWD" | ||||
|         continue | ||||
|     fi | ||||
|     find . \ | ||||
|          \( -name '*.c' \ | ||||
|          -o -name '*.cc' \ | ||||
|          -o -name '*.cpp' \ | ||||
|          -o -name '*.h' \ | ||||
|          -o -name '*.hh' \ | ||||
|          -o -name '*.hpp' \) \ | ||||
|          -exec "${FMT}" -i '{}' \; | ||||
|     popd &>/dev/null | ||||
| done | ||||
|  | @ -115,23 +115,23 @@ public: | |||
| 
 | ||||
| 	virtual _Ret invoke(_Args... args) const override | ||||
| 	{ | ||||
| 		return (static_cast<_Ty*>(ptr_)->*func_)(::std::forward<_Args>(args)...); | ||||
| 		return (ptr_->*func_)(::std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	static inline callable<_Ret, _Args...>* make(void* ptr, _FuncType func) | ||||
| 	static inline callable<_Ret, _Args...>* make(_Ty* ptr, _FuncType func) | ||||
| 	{ | ||||
| 		return new (::std::nothrow) proxy_mem_callable<_Ty, _Ret, _Args...>(ptr, func); | ||||
| 	} | ||||
| 
 | ||||
| protected: | ||||
| 	proxy_mem_callable(void* ptr, _FuncType func) | ||||
| 	proxy_mem_callable(_Ty* ptr, _FuncType func) | ||||
| 		: ptr_(ptr) | ||||
| 		, func_(func) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| protected: | ||||
| 	void* ptr_; | ||||
| 	_Ty* ptr_; | ||||
| 	_FuncType func_; | ||||
| }; | ||||
| 
 | ||||
|  | @ -144,23 +144,23 @@ public: | |||
| 
 | ||||
| 	virtual _Ret invoke(_Args... args) const override | ||||
| 	{ | ||||
| 		return (static_cast<_Ty*>(ptr_)->*func_)(::std::forward<_Args>(args)...); | ||||
| 		return (ptr_->*func_)(::std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	static inline callable<_Ret, _Args...>* make(void* ptr, _FuncType func) | ||||
| 	static inline callable<_Ret, _Args...>* make(_Ty* 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) | ||||
| 	proxy_const_mem_callable(_Ty* ptr, _FuncType func) | ||||
| 		: ptr_(ptr) | ||||
| 		, func_(func) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| protected: | ||||
| 	void* ptr_; | ||||
| 	_Ty* ptr_; | ||||
| 	_FuncType func_; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,20 +16,19 @@ template <typename _Ty, typename _PTy = typename std::pointer_traits<_Ty>::point | |||
| class intrusive_list_item | ||||
| { | ||||
| public: | ||||
| 	using pointer_type			= _PTy; | ||||
| 	using const_pointer_type	= const _PTy; | ||||
| 	using pointer = _PTy; | ||||
| 
 | ||||
| 	intrusive_list_item()				: prev_(nullptr), next_(nullptr) {} | ||||
| 	intrusive_list_item(pointer_type rhs)	: prev_(nullptr), next_(nullptr) { if (rhs) { prev_ = rhs->prev_; next_ = rhs->next_; } } | ||||
| 	intrusive_list_item(pointer rhs)	: prev_(nullptr), next_(nullptr) { if (rhs) { prev_ = rhs->prev_; next_ = rhs->next_; } } | ||||
| 
 | ||||
| 	const_pointer_type	prev_item() const	{ return prev_; } | ||||
| 	pointer_type		prev_item()			{ return prev_; } | ||||
| 	const_pointer_type	next_item() const	{ return next_; } | ||||
| 	pointer_type		next_item()			{ return next_; } | ||||
| 	const pointer	prev_item() const	{ return prev_; } | ||||
| 	pointer			prev_item()			{ return prev_; } | ||||
| 	const pointer	next_item() const	{ return next_; } | ||||
| 	pointer			next_item()			{ return next_; } | ||||
| 
 | ||||
| private: | ||||
| 	pointer_type prev_; | ||||
| 	pointer_type next_; | ||||
| 	pointer prev_; | ||||
| 	pointer next_; | ||||
| 
 | ||||
| 	friend class intrusive_list<_Ty, _PTy>; | ||||
| }; | ||||
|  | @ -39,23 +38,24 @@ template <typename _Ty, typename _PTy> | |||
| class intrusive_list | ||||
| { | ||||
| public: | ||||
| 	using pointer_type			= _PTy; | ||||
| 	using const_pointer_type	= const _PTy; | ||||
| 	using value_type	= typename std::pointer_traits<_PTy>::element_type; | ||||
| 	using pointer		= _PTy; | ||||
| 	using reference		= value_type&; | ||||
| 
 | ||||
| 	intrusive_list()						: first_(), last_() {} | ||||
| 	~intrusive_list()						{ clear(); } | ||||
| 
 | ||||
| 	const_pointer_type	first_item() const		{ return first_; } | ||||
| 	pointer_type		first_item()			{ return first_; } | ||||
| 	const_pointer_type	last_item() const		{ return last_; } | ||||
| 	pointer_type		last_item()				{ return last_; } | ||||
| 	const pointer	first_item() const		{ return first_; } | ||||
| 	pointer			first_item()			{ return first_; } | ||||
| 	const pointer	last_item() const		{ return last_; } | ||||
| 	pointer			last_item()				{ return last_; } | ||||
| 
 | ||||
| 	inline bool empty() const | ||||
| 	{ | ||||
| 		return first_ == nullptr; | ||||
| 	} | ||||
| 
 | ||||
| 	void push_back(pointer_type child) | ||||
| 	void push_back(pointer child) | ||||
| 	{ | ||||
| 		if (child->prev_) | ||||
| 			child->prev_->next_ = child->next_; | ||||
|  | @ -77,7 +77,7 @@ public: | |||
| 		last_ = child; | ||||
| 	} | ||||
| 
 | ||||
| 	void push_front(pointer_type child) | ||||
| 	void push_front(pointer child) | ||||
| 	{ | ||||
| 		if (child->prev_) | ||||
| 			child->prev_->next_ = child->next_; | ||||
|  | @ -99,7 +99,7 @@ public: | |||
| 		first_ = child; | ||||
| 	} | ||||
| 
 | ||||
| 	void insert_before(pointer_type child, pointer_type before) | ||||
| 	void insert_before(pointer child, pointer before) | ||||
| 	{ | ||||
| 		if (child->prev_) | ||||
| 			child->prev_->next_ = child->next_; | ||||
|  | @ -116,7 +116,7 @@ public: | |||
| 		before->prev_ = child; | ||||
| 	} | ||||
| 
 | ||||
| 	void insert_after(pointer_type child, pointer_type after) | ||||
| 	void insert_after(pointer child, pointer after) | ||||
| 	{ | ||||
| 		if (child->prev_) | ||||
| 			child->prev_->next_ = child->next_; | ||||
|  | @ -133,7 +133,7 @@ public: | |||
| 		after->next_ = child; | ||||
| 	} | ||||
| 
 | ||||
| 	void remove(pointer_type child) | ||||
| 	void remove(pointer child) | ||||
| 	{ | ||||
| 		if (child->next_) | ||||
| 		{ | ||||
|  | @ -159,10 +159,10 @@ public: | |||
| 
 | ||||
| 	void clear() | ||||
| 	{ | ||||
| 		pointer_type p = first_; | ||||
| 		pointer p = first_; | ||||
| 		while (p) | ||||
| 		{ | ||||
| 			pointer_type tmp = p; | ||||
| 			pointer tmp = p; | ||||
| 			p = p->next_; | ||||
| 			if (tmp) | ||||
| 			{ | ||||
|  | @ -180,8 +180,8 @@ public: | |||
| 			return; | ||||
| 
 | ||||
| 		int pos = 0; | ||||
| 		pointer_type p = first_; | ||||
| 		pointer_type tmp = p; | ||||
| 		pointer p = first_; | ||||
| 		pointer tmp = p; | ||||
| 		do | ||||
| 		{ | ||||
| 			tmp = p; | ||||
|  | @ -205,15 +205,19 @@ public: | |||
| 	struct iterator_impl | ||||
| 	{ | ||||
| 		using iterator_category		= std::bidirectional_iterator_tag; | ||||
| 		using pointer_type			= _PTy; | ||||
| 		using const_pointer_type	= const _PTy; | ||||
| 		using value_type			= typename std::pointer_traits<_PTy>::element_type; | ||||
| 		using difference_type		= ptrdiff_t; | ||||
| 		using pointer				= _PTy; | ||||
| 		using reference				= value_type&; | ||||
| 
 | ||||
| 		inline iterator_impl(pointer_type ptr = nullptr, bool is_end = false)	: base_(ptr), is_end_(is_end) {} | ||||
| 		inline iterator_impl(pointer ptr = nullptr, bool is_end = false)		: base_(ptr), is_end_(is_end) {} | ||||
| 
 | ||||
| 		inline pointer_type		operator*() const								{ OC_ASSERT(base_ && !is_end_); return base_; } | ||||
| 		inline iterator_impl&	operator++()									{ OC_ASSERT(base_ && !is_end_); pointer_type next = base_->next_item(); if (next) base_ = next; else is_end_ = true; return (*this); } | ||||
| 		inline pointer			base() const									{ OC_ASSERT(!is_end_); return const_cast<pointer&>(base_); } | ||||
| 		inline reference		operator*() const								{ OC_ASSERT(base_ && !is_end_); return const_cast<reference>(*base_); } | ||||
| 		inline pointer			operator->() const								{ OC_ASSERT(base_ && !is_end_); return const_cast<pointer&>(base_); } | ||||
| 		inline iterator_impl&	operator++()									{ OC_ASSERT(base_ && !is_end_); pointer next = base_->next_item(); if (next) base_ = next; else is_end_ = true; return (*this); } | ||||
| 		inline iterator_impl	operator++(int)									{ iterator_impl old = (*this); ++(*this); return old; } | ||||
| 		inline iterator_impl&	operator--()									{ OC_ASSERT(base_); if (is_end_) is_end_ = false; else base_ = pointer_type(base_->prev_item()); return (*this); } | ||||
| 		inline iterator_impl&	operator--()									{ OC_ASSERT(base_); if (is_end_) is_end_ = false; else base_ = pointer(base_->prev_item()); return (*this); } | ||||
| 		inline iterator_impl	operator--(int)									{ iterator_impl old = (*this); --(*this); return old; } | ||||
| 		inline bool				operator==(iterator_impl const& other) const	{ return base_ == other.base_ && is_end_ == other.is_end_; } | ||||
| 		inline bool				operator!=(iterator_impl const& other) const	{ return !(*this == other); } | ||||
|  | @ -221,11 +225,11 @@ public: | |||
| 
 | ||||
| 	private: | ||||
| 		bool is_end_; | ||||
| 		pointer_type base_; | ||||
| 		pointer base_; | ||||
| 	}; | ||||
| 
 | ||||
| 	using iterator					= iterator_impl<pointer_type>; | ||||
| 	using const_iterator			= iterator_impl<const pointer_type>; | ||||
| 	using iterator					= iterator_impl<pointer>; | ||||
| 	using const_iterator			= iterator_impl<const pointer>; | ||||
| 	using reverse_iterator			= std::reverse_iterator<iterator>; | ||||
| 	using const_reverse_iterator	= std::reverse_iterator<const_iterator>; | ||||
| 
 | ||||
|  | @ -241,14 +245,14 @@ public: | |||
| 	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 pointer_type				front()			{ if (empty()) throw std::out_of_range("front() called on empty intrusive_list"); return first_item(); } | ||||
| 	inline const_pointer_type		front() const	{ if (empty()) throw std::out_of_range("front() called on empty intrusive_list"); return first_item(); } | ||||
| 	inline pointer_type				back()			{ if (empty()) throw std::out_of_range("back() called on empty intrusive_list"); return last_item(); } | ||||
| 	inline const_pointer_type		back() const	{ if (empty()) throw std::out_of_range("back() called on empty intrusive_list"); return last_item(); } | ||||
| 	inline pointer					front()			{ if (empty()) throw std::out_of_range("front() called on empty intrusive_list"); return first_item(); } | ||||
| 	inline const pointer			front() const	{ if (empty()) throw std::out_of_range("front() called on empty intrusive_list"); return first_item(); } | ||||
| 	inline pointer					back()			{ if (empty()) throw std::out_of_range("back() called on empty intrusive_list"); return last_item(); } | ||||
| 	inline const pointer			back() const	{ if (empty()) throw std::out_of_range("back() called on empty intrusive_list"); return last_item(); } | ||||
| 
 | ||||
| private: | ||||
| 	pointer_type first_; | ||||
| 	pointer_type last_; | ||||
| 	pointer first_; | ||||
| 	pointer last_; | ||||
| }; | ||||
| 
 | ||||
| }  // namespace oc
 | ||||
|  |  | |||
|  | @ -0,0 +1,74 @@ | |||
| /**
 | ||||
|  * pugixml parser - version 1.10 | ||||
|  * -------------------------------------------------------- | ||||
|  * Copyright (C) 2006-2019, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) | ||||
|  * Report bugs and download new versions at https://pugixml.org/
 | ||||
|  * | ||||
|  * This library is distributed under the MIT License. See notice at the end | ||||
|  * of this file. | ||||
|  * | ||||
|  * This work is based on the pugxml parser, which is: | ||||
|  * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) | ||||
|  */ | ||||
| 
 | ||||
| #ifndef HEADER_PUGICONFIG_HPP | ||||
| #define HEADER_PUGICONFIG_HPP | ||||
| 
 | ||||
| // Uncomment this to enable wchar_t mode
 | ||||
| #define PUGIXML_WCHAR_MODE | ||||
| 
 | ||||
| // Uncomment this to enable compact mode
 | ||||
| // #define PUGIXML_COMPACT
 | ||||
| 
 | ||||
| // Uncomment this to disable XPath
 | ||||
| // #define PUGIXML_NO_XPATH
 | ||||
| 
 | ||||
| // Uncomment this to disable STL
 | ||||
| // #define PUGIXML_NO_STL
 | ||||
| 
 | ||||
| // Uncomment this to disable exceptions
 | ||||
| #define PUGIXML_NO_EXCEPTIONS | ||||
| 
 | ||||
| // Set this to control attributes for public classes/functions, i.e.:
 | ||||
| // #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
 | ||||
| // #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
 | ||||
| // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
 | ||||
| // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
 | ||||
| 
 | ||||
| // Tune these constants to adjust memory-related behavior
 | ||||
| // #define PUGIXML_MEMORY_PAGE_SIZE 32768
 | ||||
| // #define PUGIXML_MEMORY_OUTPUT_STACK 10240
 | ||||
| // #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
 | ||||
| 
 | ||||
| // Uncomment this to switch to header-only version
 | ||||
| #define PUGIXML_HEADER_ONLY | ||||
| 
 | ||||
| // Uncomment this to enable long long support
 | ||||
| // #define PUGIXML_HAS_LONG_LONG
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * Copyright (c) 2006-2019 Arseny Kapoulkine | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -1,18 +0,0 @@ | |||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any | ||||
| damages arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any | ||||
| purpose, including commercial applications, and to alter it and | ||||
| redistribute it freely, subject to the following restrictions: | ||||
| 
 | ||||
| 1. The origin of this software must not be misrepresented; you must | ||||
| not claim that you wrote the original software. If you use this | ||||
| software in a product, an acknowledgment in the product documentation | ||||
| would be appreciated but is not required. | ||||
| 
 | ||||
| 2. Altered source versions must be plainly marked as such, and | ||||
| must not be misrepresented as being the original software. | ||||
| 
 | ||||
| 3. This notice may not be removed or altered from any source | ||||
| distribution. | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -18,27 +18,25 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/platform/win32/helper.h>  // win32::ThrowIfFailed
 | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano-audio/libraries.h> | ||||
| #include <kiwano-audio/AudioEngine.h> | ||||
| #include <kiwano-audio/libraries.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/platform/win32/helper.h>  // win32::ThrowIfFailed
 | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		AudioEngine::AudioEngine() | ||||
| namespace audio | ||||
| { | ||||
| AudioEngine::AudioEngine() | ||||
|     : x_audio2_(nullptr) | ||||
|     , mastering_voice_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		AudioEngine::~AudioEngine() | ||||
| 		{ | ||||
| 		} | ||||
| AudioEngine::~AudioEngine() {} | ||||
| 
 | ||||
| 		void AudioEngine::SetupComponent() | ||||
| 		{ | ||||
| void AudioEngine::SetupComponent() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Creating audio resources"); | ||||
| 
 | ||||
|     HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL); | ||||
|  | @ -54,10 +52,10 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     win32::ThrowIfFailed(hr); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void AudioEngine::DestroyComponent() | ||||
| 		{ | ||||
| void AudioEngine::DestroyComponent() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Destroying audio resources"); | ||||
| 
 | ||||
|     if (mastering_voice_) | ||||
|  | @ -73,10 +71,10 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     dlls::MediaFoundation::Get().MFShutdown(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		bool AudioEngine::CreateSound(Sound& sound, const Transcoder::Buffer& buffer) | ||||
| 		{ | ||||
| bool AudioEngine::CreateSound(Sound& sound, const Transcoder::Buffer& buffer) | ||||
| { | ||||
|     KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!"); | ||||
| 
 | ||||
|     HRESULT hr = S_OK; | ||||
|  | @ -104,22 +102,22 @@ namespace kiwano | |||
| 
 | ||||
|     win32::WarnIfFailed(hr); | ||||
|     return SUCCEEDED(hr); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void AudioEngine::Open() | ||||
| 		{ | ||||
| void AudioEngine::Open() | ||||
| { | ||||
|     KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!"); | ||||
| 
 | ||||
|     if (x_audio2_) | ||||
|         x_audio2_->StartEngine(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void AudioEngine::Close() | ||||
| 		{ | ||||
| void AudioEngine::Close() | ||||
| { | ||||
|     KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!"); | ||||
| 
 | ||||
|     if (x_audio2_) | ||||
|         x_audio2_->StopEngine(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,37 +19,38 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/Component.h> | ||||
| #include <kiwano-audio/Transcoder.h> | ||||
| #include <kiwano-audio/Sound.h> | ||||
| #include <kiwano-audio/Transcoder.h> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/Component.h> | ||||
| #include <xaudio2.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		/**
 | ||||
| namespace audio | ||||
| { | ||||
| 
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * \defgroup Audio 音频引擎 | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Audio | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 音频引擎 | ||||
|  */ | ||||
| 		class KGE_API AudioEngine | ||||
| class KGE_API AudioEngine | ||||
|     : public Singleton<AudioEngine> | ||||
|     , public ComponentBase | ||||
| 		{ | ||||
| { | ||||
|     friend Singleton<AudioEngine>; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 开启音频设备
 | ||||
|     void Open(); | ||||
|  | @ -62,21 +63,22 @@ namespace kiwano | |||
|     /// @brief 从解码器数据缓冲中创建音频对象
 | ||||
|     bool CreateSound(Sound& sound, const Transcoder::Buffer& buffer); | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     void SetupComponent() override; | ||||
| 
 | ||||
|     void DestroyComponent() override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     AudioEngine(); | ||||
| 
 | ||||
|     ~AudioEngine(); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     IXAudio2*               x_audio2_; | ||||
|     IXAudio2MasteringVoice* mastering_voice_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| 	} | ||||
| } | ||||
| /** @} */ | ||||
| 
 | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,31 +18,31 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano-audio/AudioEngine.h> | ||||
| #include <kiwano-audio/Sound.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/platform/FileSystem.h> | ||||
| #include <kiwano-audio/Sound.h> | ||||
| #include <kiwano-audio/AudioEngine.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| namespace audio | ||||
| { | ||||
| 
 | ||||
| 		Sound::Sound() | ||||
| Sound::Sound() | ||||
|     : opened_(false) | ||||
|     , playing_(false) | ||||
|     , voice_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Sound::~Sound() | ||||
| 		{ | ||||
| Sound::~Sound() | ||||
| { | ||||
|     Close(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		bool Sound::Load(String const& file_path) | ||||
| 		{ | ||||
| 			if (!FileSystem::instance().IsFileExists(file_path)) | ||||
| bool Sound::Load(String const& file_path) | ||||
| { | ||||
|     if (!FileSystem::Instance().IsFileExists(file_path)) | ||||
|     { | ||||
|         KGE_WARN(L"Media file '%s' not found", file_path.c_str()); | ||||
|         return false; | ||||
|  | @ -53,7 +53,7 @@ namespace kiwano | |||
|         Close(); | ||||
|     } | ||||
| 
 | ||||
| 			String full_path = FileSystem::instance().GetFullPathForFile(file_path); | ||||
|     String full_path = FileSystem::Instance().GetFullPathForFile(file_path); | ||||
| 
 | ||||
|     HRESULT hr = transcoder_.LoadMediaFile(full_path); | ||||
|     if (FAILED(hr)) | ||||
|  | @ -62,7 +62,7 @@ namespace kiwano | |||
|         return false; | ||||
|     } | ||||
| 
 | ||||
| 			if (!AudioEngine::instance().CreateSound(*this, transcoder_.GetBuffer())) | ||||
|     if (!AudioEngine::Instance().CreateSound(*this, transcoder_.GetBuffer())) | ||||
|     { | ||||
|         Close(); | ||||
|         return false; | ||||
|  | @ -70,10 +70,10 @@ namespace kiwano | |||
| 
 | ||||
|     opened_ = true; | ||||
|     return true; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		bool Sound::Load(Resource const& res) | ||||
| 		{ | ||||
| bool Sound::Load(Resource const& res) | ||||
| { | ||||
|     if (opened_) | ||||
|     { | ||||
|         Close(); | ||||
|  | @ -86,7 +86,7 @@ namespace kiwano | |||
|         return false; | ||||
|     } | ||||
| 
 | ||||
| 			if (!AudioEngine::instance().CreateSound(*this, transcoder_.GetBuffer())) | ||||
|     if (!AudioEngine::Instance().CreateSound(*this, transcoder_.GetBuffer())) | ||||
|     { | ||||
|         Close(); | ||||
|         return false; | ||||
|  | @ -94,15 +94,15 @@ namespace kiwano | |||
| 
 | ||||
|     opened_ = true; | ||||
|     return true; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		bool Sound::IsValid() const | ||||
| 		{ | ||||
| bool Sound::IsValid() const | ||||
| { | ||||
|     return voice_ != nullptr; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Sound::Play(int loop_count) | ||||
| 		{ | ||||
| void Sound::Play(int loop_count) | ||||
| { | ||||
|     if (!opened_) | ||||
|     { | ||||
|         KGE_ERROR(L"Sound must be opened first!"); | ||||
|  | @ -140,26 +140,26 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     playing_ = SUCCEEDED(hr); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Sound::Pause() | ||||
| 		{ | ||||
| void Sound::Pause() | ||||
| { | ||||
|     KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); | ||||
| 
 | ||||
|     if (SUCCEEDED(voice_->Stop())) | ||||
|         playing_ = false; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Sound::Resume() | ||||
| 		{ | ||||
| void Sound::Resume() | ||||
| { | ||||
|     KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); | ||||
| 
 | ||||
|     if (SUCCEEDED(voice_->Start())) | ||||
|         playing_ = true; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Sound::Stop() | ||||
| 		{ | ||||
| void Sound::Stop() | ||||
| { | ||||
|     KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); | ||||
| 
 | ||||
|     HRESULT hr = voice_->Stop(); | ||||
|  | @ -172,10 +172,10 @@ namespace kiwano | |||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|         playing_ = false; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Sound::Close() | ||||
| 		{ | ||||
| void Sound::Close() | ||||
| { | ||||
|     if (voice_) | ||||
|     { | ||||
|         voice_->Stop(); | ||||
|  | @ -188,10 +188,10 @@ namespace kiwano | |||
| 
 | ||||
|     opened_  = false; | ||||
|     playing_ = false; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		bool Sound::IsPlaying() const | ||||
| 		{ | ||||
| bool Sound::IsPlaying() const | ||||
| { | ||||
|     if (opened_) | ||||
|     { | ||||
|         if (!voice_) | ||||
|  | @ -205,23 +205,23 @@ namespace kiwano | |||
|             return true; | ||||
|     } | ||||
|     return false; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float Sound::GetVolume() const | ||||
| 		{ | ||||
| float Sound::GetVolume() const | ||||
| { | ||||
|     KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); | ||||
| 
 | ||||
|     float volume = 0.0f; | ||||
|     voice_->GetVolume(&volume); | ||||
|     return volume; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Sound::SetVolume(float volume) | ||||
| 		{ | ||||
| void Sound::SetVolume(float volume) | ||||
| { | ||||
|     KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); | ||||
| 
 | ||||
|     volume = std::min(std::max(volume, -224.f), 224.f); | ||||
|     voice_->SetVolume(volume); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,35 +19,34 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano-audio/Transcoder.h> | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano/platform/win32/ComPtr.hpp> | ||||
| #include <kiwano-audio/Transcoder.h> | ||||
| #include <xaudio2.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		class AudioEngine; | ||||
| namespace audio | ||||
| { | ||||
| class AudioEngine; | ||||
| 
 | ||||
| 		KGE_DECLARE_SMART_PTR(Sound); | ||||
| KGE_DECLARE_SMART_PTR(Sound); | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Audio | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 音频 | ||||
|  */ | ||||
| 		class KGE_API Sound | ||||
| 			: public ObjectBase | ||||
| 		{ | ||||
| class KGE_API Sound : public virtual ObjectBase | ||||
| { | ||||
|     friend class AudioEngine; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     Sound(); | ||||
| 
 | ||||
|     virtual ~Sound(); | ||||
|  | @ -100,29 +99,28 @@ namespace kiwano | |||
|     /// @param volume 音量大小,1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量
 | ||||
|     void SetVolume(float volume); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     IXAudio2SourceVoice* GetXAudio2Voice() const; | ||||
| 
 | ||||
|     void SetXAudio2Voice(IXAudio2SourceVoice* voice); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     bool                 opened_; | ||||
|     bool                 playing_; | ||||
|     Transcoder           transcoder_; | ||||
|     IXAudio2SourceVoice* voice_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 
 | ||||
| 		inline IXAudio2SourceVoice* Sound::GetXAudio2Voice() const | ||||
| 		{ | ||||
| inline IXAudio2SourceVoice* Sound::GetXAudio2Voice() const | ||||
| { | ||||
|     return voice_; | ||||
| 		} | ||||
| 
 | ||||
| 		inline void Sound::SetXAudio2Voice(IXAudio2SourceVoice* voice) | ||||
| 		{ | ||||
| 			voice_ = voice; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| inline void Sound::SetXAudio2Voice(IXAudio2SourceVoice* voice) | ||||
| { | ||||
|     voice_ = voice; | ||||
| } | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -22,20 +22,20 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		SoundPlayer::SoundPlayer() | ||||
| namespace audio | ||||
| { | ||||
| SoundPlayer::SoundPlayer() | ||||
|     : volume_(1.f) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		SoundPlayer::~SoundPlayer() | ||||
| 		{ | ||||
| SoundPlayer::~SoundPlayer() | ||||
| { | ||||
|     ClearCache(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		size_t SoundPlayer::Load(String const& file_path) | ||||
| 		{ | ||||
| size_t SoundPlayer::Load(String const& file_path) | ||||
| { | ||||
|     int hash_code = static_cast<int>(file_path.hash()); | ||||
|     if (sound_cache_.end() != sound_cache_.find(hash_code)) | ||||
|         return hash_code; | ||||
|  | @ -52,10 +52,10 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return 0; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		size_t SoundPlayer::Load(Resource const& res) | ||||
| 		{ | ||||
| size_t SoundPlayer::Load(Resource const& res) | ||||
| { | ||||
|     size_t hash_code = static_cast<size_t>(res.GetId()); | ||||
|     if (sound_cache_.end() != sound_cache_.find(hash_code)) | ||||
|         return hash_code; | ||||
|  | @ -72,85 +72,85 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return 0; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::Play(size_t id, int loop_count) | ||||
| 		{ | ||||
| void SoundPlayer::Play(size_t id, int loop_count) | ||||
| { | ||||
|     auto iter = sound_cache_.find(id); | ||||
|     if (sound_cache_.end() != iter) | ||||
|         iter->second->Play(loop_count); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::Pause(size_t id) | ||||
| 		{ | ||||
| void SoundPlayer::Pause(size_t id) | ||||
| { | ||||
|     auto iter = sound_cache_.find(id); | ||||
|     if (sound_cache_.end() != iter) | ||||
|         iter->second->Pause(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::Resume(size_t id) | ||||
| 		{ | ||||
| void SoundPlayer::Resume(size_t id) | ||||
| { | ||||
|     auto iter = sound_cache_.find(id); | ||||
|     if (sound_cache_.end() != iter) | ||||
|         iter->second->Resume(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::Stop(size_t id) | ||||
| 		{ | ||||
| void SoundPlayer::Stop(size_t id) | ||||
| { | ||||
|     auto iter = sound_cache_.find(id); | ||||
|     if (sound_cache_.end() != iter) | ||||
|         iter->second->Stop(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		bool SoundPlayer::IsPlaying(size_t id) | ||||
| 		{ | ||||
| bool SoundPlayer::IsPlaying(size_t id) | ||||
| { | ||||
|     auto iter = sound_cache_.find(id); | ||||
|     if (sound_cache_.end() != iter) | ||||
|         return iter->second->IsPlaying(); | ||||
|     return false; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float SoundPlayer::GetVolume() const | ||||
| 		{ | ||||
| float SoundPlayer::GetVolume() const | ||||
| { | ||||
|     return volume_; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::SetVolume(float volume) | ||||
| 		{ | ||||
| void SoundPlayer::SetVolume(float volume) | ||||
| { | ||||
|     volume_ = std::min(std::max(volume, -224.f), 224.f); | ||||
|     for (auto& pair : sound_cache_) | ||||
|     { | ||||
|         pair.second->SetVolume(volume_); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::PauseAll() | ||||
| 		{ | ||||
| void SoundPlayer::PauseAll() | ||||
| { | ||||
|     for (auto& pair : sound_cache_) | ||||
|     { | ||||
|         pair.second->Pause(); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::ResumeAll() | ||||
| 		{ | ||||
| void SoundPlayer::ResumeAll() | ||||
| { | ||||
|     for (auto& pair : sound_cache_) | ||||
|     { | ||||
|         pair.second->Resume(); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void SoundPlayer::StopAll() | ||||
| 		{ | ||||
| void SoundPlayer::StopAll() | ||||
| { | ||||
|     for (auto& pair : sound_cache_) | ||||
|     { | ||||
|         pair.second->Stop(); | ||||
|     } | ||||
| 		} | ||||
| 
 | ||||
| 		void SoundPlayer::ClearCache() | ||||
| 		{ | ||||
| 			sound_cache_.clear(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void SoundPlayer::ClearCache() | ||||
| { | ||||
|     sound_cache_.clear(); | ||||
| } | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,28 +19,27 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano-audio/Sound.h> | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		KGE_DECLARE_SMART_PTR(SoundPlayer); | ||||
| namespace audio | ||||
| { | ||||
| KGE_DECLARE_SMART_PTR(SoundPlayer); | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Audio | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 音频播放器 | ||||
|  */ | ||||
| 		class KGE_API SoundPlayer | ||||
| 			: public ObjectBase | ||||
| 		{ | ||||
| 		public: | ||||
| class KGE_API SoundPlayer : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     SoundPlayer(); | ||||
| 
 | ||||
|     ~SoundPlayer(); | ||||
|  | @ -108,13 +107,13 @@ namespace kiwano | |||
|     /// @brief 清除缓存
 | ||||
|     void ClearCache(); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     float volume_; | ||||
| 
 | ||||
|     using SoundMap = Map<size_t, SoundPtr>; | ||||
|     SoundMap sound_cache_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| 	} | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,42 +19,42 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #ifndef INITGUID | ||||
| #	define INITGUID		// MFAudioFormat_PCM, MF_MT_MAJOR_TYPE, MF_MT_SUBTYPE, MFMediaType_Audio
 | ||||
| #define INITGUID  // MFAudioFormat_PCM, MF_MT_MAJOR_TYPE, MF_MT_SUBTYPE, MFMediaType_Audio
 | ||||
| #endif | ||||
| 
 | ||||
| #include <kiwano/macros.h> | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano-audio/Transcoder.h> | ||||
| #include <kiwano-audio/libraries.h> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano/macros.h> | ||||
| #include <kiwano/platform/win32/ComPtr.hpp> | ||||
| #include <kiwano/platform/win32/libraries.h> | ||||
| #include <kiwano-audio/libraries.h> | ||||
| #include <kiwano-audio/Transcoder.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| namespace audio | ||||
| { | ||||
| 
 | ||||
| 		Transcoder::Transcoder() | ||||
| Transcoder::Transcoder() | ||||
|     : wave_format_(nullptr) | ||||
|     , wave_data_(nullptr) | ||||
|     , wave_size_(0) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Transcoder::~Transcoder() | ||||
| 		{ | ||||
| Transcoder::~Transcoder() | ||||
| { | ||||
|     ClearBuffer(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Transcoder::Buffer Transcoder::GetBuffer() const | ||||
| 		{ | ||||
| Transcoder::Buffer Transcoder::GetBuffer() const | ||||
| { | ||||
|     return Buffer{ wave_data_, wave_size_, wave_format_ }; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Transcoder::ClearBuffer() | ||||
| 		{ | ||||
| void Transcoder::ClearBuffer() | ||||
| { | ||||
|     if (wave_format_) | ||||
|     { | ||||
|         ::CoTaskMemFree(wave_format_); | ||||
|  | @ -68,19 +68,15 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     wave_size_ = 0; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		HRESULT Transcoder::LoadMediaFile(String const& file_path) | ||||
| 		{ | ||||
| HRESULT Transcoder::LoadMediaFile(String const& file_path) | ||||
| { | ||||
|     HRESULT hr = S_OK; | ||||
| 
 | ||||
|     ComPtr<IMFSourceReader> reader; | ||||
| 
 | ||||
| 			hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromURL( | ||||
| 				file_path.c_str(), | ||||
| 				nullptr, | ||||
| 				&reader | ||||
| 			); | ||||
|     hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromURL(file_path.c_str(), nullptr, &reader); | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|  | @ -88,10 +84,10 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     return hr; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		HRESULT Transcoder::LoadMediaResource(Resource const& res) | ||||
| 		{ | ||||
| HRESULT Transcoder::LoadMediaResource(Resource const& res) | ||||
| { | ||||
|     HRESULT hr = S_OK; | ||||
| 
 | ||||
|     ComPtr<IStream>         stream; | ||||
|  | @ -99,12 +95,13 @@ namespace kiwano | |||
|     ComPtr<IMFSourceReader> reader; | ||||
| 
 | ||||
|     Resource::Data data = res.GetData(); | ||||
| 			if (!data) { return E_FAIL; } | ||||
|     if (!data) | ||||
|     { | ||||
|         return E_FAIL; | ||||
|     } | ||||
| 
 | ||||
| 			stream = win32::dlls::Shlwapi::Get().SHCreateMemStream( | ||||
| 				static_cast<const BYTE*>(data.buffer), | ||||
| 				static_cast<uint32_t>(data.size) | ||||
| 			); | ||||
|     stream = win32::dlls::Shlwapi::Get().SHCreateMemStream(static_cast<const BYTE*>(data.buffer), | ||||
|                                                            static_cast<uint32_t>(data.size)); | ||||
| 
 | ||||
|     if (stream == nullptr) | ||||
|     { | ||||
|  | @ -119,11 +116,7 @@ namespace kiwano | |||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
| 				hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromByteStream( | ||||
| 					byte_stream.get(), | ||||
| 					nullptr, | ||||
| 					&reader | ||||
| 				); | ||||
|         hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromByteStream(byte_stream.get(), nullptr, &reader); | ||||
|     } | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|  | @ -132,10 +125,10 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     return hr; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		HRESULT Transcoder::ReadSource(IMFSourceReader* reader) | ||||
| 		{ | ||||
| HRESULT Transcoder::ReadSource(IMFSourceReader* reader) | ||||
| { | ||||
|     HRESULT hr              = S_OK; | ||||
|     DWORD   max_stream_size = 0; | ||||
| 
 | ||||
|  | @ -157,29 +150,19 @@ namespace kiwano | |||
|     // 设置 source reader 的媒体类型,它将使用合适的解码器去解码这个音频
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
| 				hr = reader->SetCurrentMediaType( | ||||
| 					(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | ||||
| 					0, | ||||
| 					partial_type.get() | ||||
| 				); | ||||
|         hr = reader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, partial_type.get()); | ||||
|     } | ||||
| 
 | ||||
|     // 从 IMFMediaType 中获取 WAVEFORMAT 结构
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
| 				hr = reader->GetCurrentMediaType( | ||||
| 					(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | ||||
| 					&uncompressed_type | ||||
| 				); | ||||
|         hr = reader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, &uncompressed_type); | ||||
|     } | ||||
| 
 | ||||
|     // 指定音频流
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
| 				hr = reader->SetStreamSelection( | ||||
| 					(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | ||||
| 					true | ||||
| 				); | ||||
|         hr = reader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, true); | ||||
|     } | ||||
| 
 | ||||
|     // 获取 WAVEFORMAT 数据
 | ||||
|  | @ -187,11 +170,7 @@ namespace kiwano | |||
|     { | ||||
|         uint32_t size = 0; | ||||
|         hr            = dlls::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType( | ||||
| 					uncompressed_type.get(), | ||||
| 					&wave_format_, | ||||
| 					&size, | ||||
| 					(DWORD)MFWaveFormatExConvertFlag_Normal | ||||
| 				); | ||||
|             uncompressed_type.get(), &wave_format_, &size, (DWORD)MFWaveFormatExConvertFlag_Normal); | ||||
|     } | ||||
| 
 | ||||
|     // 估算音频流大小
 | ||||
|  | @ -200,16 +179,10 @@ namespace kiwano | |||
|         PROPVARIANT prop; | ||||
|         PropVariantInit(&prop); | ||||
| 
 | ||||
| 				hr = reader->GetPresentationAttribute( | ||||
| 					(DWORD)MF_SOURCE_READER_MEDIASOURCE, | ||||
| 					MF_PD_DURATION, | ||||
| 					&prop | ||||
| 				); | ||||
|         hr = reader->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &prop); | ||||
| 
 | ||||
|         LONGLONG duration = prop.uhVal.QuadPart; | ||||
| 				max_stream_size = static_cast<DWORD>( | ||||
| 					(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1 | ||||
| 				); | ||||
|         max_stream_size   = static_cast<DWORD>((duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1); | ||||
|         PropVariantClear(&prop); | ||||
|     } | ||||
| 
 | ||||
|  | @ -232,18 +205,18 @@ namespace kiwano | |||
|         { | ||||
|             while (true) | ||||
|             { | ||||
| 						hr = reader->ReadSample( | ||||
| 							(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, | ||||
| 							0, | ||||
| 							nullptr, | ||||
| 							&flags, | ||||
| 							nullptr, | ||||
| 							&sample | ||||
| 						); | ||||
|                 hr = reader->ReadSample((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, nullptr, &flags, nullptr, | ||||
|                                         &sample); | ||||
| 
 | ||||
| 						if (flags & MF_SOURCE_READERF_ENDOFSTREAM) { break; } | ||||
|                 if (flags & MF_SOURCE_READERF_ENDOFSTREAM) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
| 						if (sample == nullptr) { continue; } | ||||
|                 if (sample == nullptr) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 if (SUCCEEDED(hr)) | ||||
|                 { | ||||
|  | @ -254,11 +227,7 @@ namespace kiwano | |||
|                         BYTE* audio_data           = nullptr; | ||||
|                         DWORD sample_buffer_length = 0; | ||||
| 
 | ||||
| 								hr = buffer->Lock( | ||||
| 									&audio_data, | ||||
| 									nullptr, | ||||
| 									&sample_buffer_length | ||||
| 								); | ||||
|                         hr = buffer->Lock(&audio_data, nullptr, &sample_buffer_length); | ||||
| 
 | ||||
|                         if (position + sample_buffer_length >= max_stream_size) | ||||
|                         { | ||||
|  | @ -276,7 +245,10 @@ namespace kiwano | |||
|                 } | ||||
|                 sample = nullptr; | ||||
| 
 | ||||
| 						if (FAILED(hr)) { break; } | ||||
|                 if (FAILED(hr)) | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (SUCCEEDED(hr)) | ||||
|  | @ -293,6 +265,6 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     return hr; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -26,24 +26,24 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		class Sound; | ||||
| namespace audio | ||||
| { | ||||
| class Sound; | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Audio | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 音频解码器 | ||||
|  */ | ||||
| 		class KGE_API Transcoder | ||||
| 		{ | ||||
| class KGE_API Transcoder | ||||
| { | ||||
|     friend class Sound; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 音频数据缓冲 | ||||
|  | @ -67,7 +67,7 @@ namespace kiwano | |||
|     /// @brief 清空数据缓冲
 | ||||
|     void ClearBuffer(); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 解码本地音频文件
 | ||||
|     HRESULT LoadMediaFile(String const& file_path); | ||||
|  | @ -80,12 +80,12 @@ namespace kiwano | |||
|     /// @brief 读取音频源数据
 | ||||
|     HRESULT ReadSource(IMFSourceReader* reader); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     BYTE*         wave_data_; | ||||
|     uint32_t      wave_size_; | ||||
|     WAVEFORMATEX* wave_format_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| 	} | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,21 +18,20 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano-audio/libraries.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		namespace dlls | ||||
| 		{ | ||||
| 			XAudio2::XAudio2() | ||||
| namespace audio | ||||
| { | ||||
| namespace dlls | ||||
| { | ||||
| XAudio2::XAudio2() | ||||
|     : xaudio2() | ||||
|     , XAudio2Create(nullptr) | ||||
| 			{ | ||||
| 				const auto xaudio2_dll_names = | ||||
| 				{ | ||||
| { | ||||
|     const auto xaudio2_dll_names = { | ||||
|         "xaudio2_9.dll",  // for Windows 10
 | ||||
|         "xaudio2_8.dll",  // for Windows 8
 | ||||
|         "xaudio2_7.dll"   // for DirectX SDK
 | ||||
|  | @ -55,9 +54,9 @@ namespace kiwano | |||
|         KGE_ERROR(L"Load xaudio2.dll failed"); | ||||
|         throw std::runtime_error("Load xaudio2.dll failed"); | ||||
|     } | ||||
| 			} | ||||
| } | ||||
| 
 | ||||
| 			MediaFoundation::MediaFoundation() | ||||
| MediaFoundation::MediaFoundation() | ||||
|     : mfplat() | ||||
|     , mfreadwrite() | ||||
|     , MFStartup(nullptr) | ||||
|  | @ -67,14 +66,16 @@ namespace kiwano | |||
|     , MFCreateSourceReaderFromURL(nullptr) | ||||
|     , MFCreateSourceReaderFromByteStream(nullptr) | ||||
|     , MFCreateMFByteStreamOnStream(nullptr) | ||||
| 			{ | ||||
| { | ||||
|     if (mfplat.Load("Mfplat.dll")) | ||||
|     { | ||||
|         MFStartup         = mfplat.GetProcess<PFN_MFStartup>("MFStartup"); | ||||
|         MFShutdown        = mfplat.GetProcess<PFN_MFShutdown>("MFShutdown"); | ||||
|         MFCreateMediaType = mfplat.GetProcess<PFN_MFCreateMediaType>("MFCreateMediaType"); | ||||
| 					MFCreateWaveFormatExFromMFMediaType = mfplat.GetProcess<PFN_MFCreateWaveFormatExFromMFMediaType>("MFCreateWaveFormatExFromMFMediaType"); | ||||
| 					MFCreateMFByteStreamOnStream = mfplat.GetProcess<PFN_MFCreateMFByteStreamOnStream>("MFCreateMFByteStreamOnStream"); | ||||
|         MFCreateWaveFormatExFromMFMediaType = | ||||
|             mfplat.GetProcess<PFN_MFCreateWaveFormatExFromMFMediaType>("MFCreateWaveFormatExFromMFMediaType"); | ||||
|         MFCreateMFByteStreamOnStream = | ||||
|             mfplat.GetProcess<PFN_MFCreateMFByteStreamOnStream>("MFCreateMFByteStreamOnStream"); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|  | @ -84,15 +85,17 @@ namespace kiwano | |||
| 
 | ||||
|     if (mfreadwrite.Load("Mfreadwrite.dll")) | ||||
|     { | ||||
| 					MFCreateSourceReaderFromURL = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromURL>("MFCreateSourceReaderFromURL"); | ||||
| 					MFCreateSourceReaderFromByteStream = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromByteStream>("MFCreateSourceReaderFromByteStream"); | ||||
|         MFCreateSourceReaderFromURL = | ||||
|             mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromURL>("MFCreateSourceReaderFromURL"); | ||||
|         MFCreateSourceReaderFromByteStream = | ||||
|             mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromByteStream>("MFCreateSourceReaderFromByteStream"); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         KGE_ERROR(L"Load Mfreadwrite.dll failed"); | ||||
|         throw std::runtime_error("Load Mfreadwrite.dll failed"); | ||||
|     } | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }  // namespace dlls
 | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,22 +20,22 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/Library.h> | ||||
| #include <xaudio2.h> | ||||
| #include <mfapi.h> | ||||
| #include <mfidl.h> | ||||
| #include <mfreadwrite.h> | ||||
| #include <xaudio2.h> | ||||
| 
 | ||||
| #ifndef KGE_DOXYGEN_DO_NOT_INCLUDE | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace audio | ||||
| 	{ | ||||
| 		namespace dlls | ||||
| 		{ | ||||
| 			class KGE_API XAudio2 | ||||
| 			{ | ||||
| 			public: | ||||
| namespace audio | ||||
| { | ||||
| namespace dlls | ||||
| { | ||||
| class KGE_API XAudio2 | ||||
| { | ||||
| public: | ||||
|     static inline XAudio2& Get() | ||||
|     { | ||||
|         static XAudio2 instance; | ||||
|  | @ -47,19 +47,18 @@ namespace kiwano | |||
| 
 | ||||
|     PFN_XAudio2Create XAudio2Create; | ||||
| 
 | ||||
| 			private: | ||||
| private: | ||||
|     XAudio2(); | ||||
| 
 | ||||
|     XAudio2(const XAudio2&) = delete; | ||||
|     XAudio2& operator=(const XAudio2&) = delete; | ||||
| 
 | ||||
|     Library xaudio2; | ||||
| 			}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 			class KGE_API MediaFoundation | ||||
| 			{ | ||||
| 			public: | ||||
| class KGE_API MediaFoundation | ||||
| { | ||||
| public: | ||||
|     static inline MediaFoundation& Get() | ||||
|     { | ||||
|         static MediaFoundation instance; | ||||
|  | @ -83,7 +82,7 @@ namespace kiwano | |||
|     PFN_MFCreateSourceReaderFromByteStream  MFCreateSourceReaderFromByteStream; | ||||
|     PFN_MFCreateMFByteStreamOnStream        MFCreateMFByteStreamOnStream; | ||||
| 
 | ||||
| 			private: | ||||
| private: | ||||
|     MediaFoundation(); | ||||
| 
 | ||||
|     MediaFoundation(const MediaFoundation&) = delete; | ||||
|  | @ -91,9 +90,9 @@ namespace kiwano | |||
| 
 | ||||
|     Library mfplat; | ||||
|     Library mfreadwrite; | ||||
| 			}; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }; | ||||
| }  // namespace dlls
 | ||||
| }  // namespace audio
 | ||||
| }  // namespace kiwano
 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -22,43 +22,45 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace imgui | ||||
| 	{ | ||||
| 		ImGuiLayer::ImGuiLayer() | ||||
| 		{ | ||||
| namespace imgui | ||||
| { | ||||
| ImGuiLayer::ImGuiLayer() | ||||
| { | ||||
|     SetSwallowEvents(true); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		ImGuiLayer::~ImGuiLayer() | ||||
| 		{ | ||||
| 		} | ||||
| ImGuiLayer::~ImGuiLayer() {} | ||||
| 
 | ||||
| 		void ImGuiLayer::OnRender(RenderTarget* rt) | ||||
| 		{ | ||||
| 			PrepareToRender(rt); | ||||
| void ImGuiLayer::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     for (const auto& pipeline : pipelines_) | ||||
|     { | ||||
|         pipeline.second(); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiLayer::AddItem(ImGuiPipeline const& item, String const& name) | ||||
| 		{ | ||||
| bool ImGuiLayer::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void ImGuiLayer::AddItem(String const& name, ImGuiPipeline const& item) | ||||
| { | ||||
|     pipelines_.insert(std::make_pair(name, item)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiLayer::RemoveItem(String const& name) | ||||
| 		{ | ||||
| void ImGuiLayer::RemoveItem(String const& name) | ||||
| { | ||||
|     auto iter = pipelines_.find(name); | ||||
|     if (iter != pipelines_.end()) | ||||
|     { | ||||
|         pipelines_.erase(iter); | ||||
|     } | ||||
| 		} | ||||
| 
 | ||||
| 		void ImGuiLayer::RemoveAllItems() | ||||
| 		{ | ||||
| 			pipelines_.clear(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ImGuiLayer::RemoveAllItems() | ||||
| { | ||||
|     pipelines_.clear(); | ||||
| } | ||||
| }  // namespace imgui
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,31 +23,30 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace imgui | ||||
| 	{ | ||||
| 		KGE_DECLARE_SMART_PTR(ImGuiLayer); | ||||
| namespace imgui | ||||
| { | ||||
| KGE_DECLARE_SMART_PTR(ImGuiLayer); | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ImGui¹ÜµÀ
 | ||||
| 		using ImGuiPipeline = Function<void()>; | ||||
| /// \~chinese
 | ||||
| /// @brief ImGui¹ÜµÀ
 | ||||
| using ImGuiPipeline = Function<void()>; | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief ImGui图层 | ||||
|  */ | ||||
| 		class ImGuiLayer | ||||
| 			: public Layer | ||||
| 		{ | ||||
| 		public: | ||||
| class ImGuiLayer : public Layer | ||||
| { | ||||
| public: | ||||
|     ImGuiLayer(); | ||||
| 
 | ||||
|     virtual ~ImGuiLayer(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 添加 ImGui 元素
 | ||||
| 			/// @param item ¹ÜµÀ
 | ||||
|     /// @param name 元素名称
 | ||||
| 			void AddItem(ImGuiPipeline const& item, String const& name); | ||||
|     /// @param item ¹ÜµÀ
 | ||||
|     void AddItem(String const& name, ImGuiPipeline const& item); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 移除 ImGui 元素
 | ||||
|  | @ -59,11 +58,13 @@ namespace kiwano | |||
|     /// @brief 移除所有元素
 | ||||
|     void RemoveAllItems(); | ||||
| 
 | ||||
| 		public: | ||||
| 			void OnRender(RenderTarget* rt) override; | ||||
| public: | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
| 		private: | ||||
|     bool CheckVisibility(RenderContext& ctx) const override; | ||||
| 
 | ||||
| private: | ||||
|     Map<String, ImGuiPipeline> pipelines_; | ||||
| 		}; | ||||
| 	} | ||||
| } | ||||
| }; | ||||
| }  // namespace imgui
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -1,234 +1,189 @@ | |||
| // Copyright (C) 2019 Nomango
 | ||||
| 
 | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/platform/Window.h> | ||||
| 
 | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/event/KeyEvent.h> | ||||
| #include <kiwano/core/event/MouseEvent.h> | ||||
| #include <kiwano/platform/Input.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/platform/Window.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <kiwano-imgui/ImGuiModule.h> | ||||
| #include <kiwano-imgui/imgui_impl.h> | ||||
| 
 | ||||
| #include <XInput.h> | ||||
| #pragma comment(lib, "xinput") | ||||
| 
 | ||||
| // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
 | ||||
| #ifndef WM_MOUSEHWHEEL | ||||
| #	define WM_MOUSEHWHEEL 0x020E | ||||
| #endif | ||||
| 
 | ||||
| #ifndef DBT_DEVNODES_CHANGED | ||||
| #	define DBT_DEVNODES_CHANGED 0x0007 | ||||
| #endif | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace imgui | ||||
| 	{ | ||||
| 		ImGuiModule::ImGuiModule() | ||||
| 			: has_gamepad_(false) | ||||
| 			, want_update_has_gamepad_(false) | ||||
| 			, target_window_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| namespace imgui | ||||
| { | ||||
| ImGuiModule::ImGuiModule() | ||||
|     : target_window_(nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::SetupComponent() | ||||
| 		{ | ||||
| void ImGuiModule::SetupComponent() | ||||
| { | ||||
|     // Setup Dear ImGui context
 | ||||
|     IMGUI_CHECKVERSION(); | ||||
|     ImGui::CreateContext(); | ||||
| 			ImGuiIO& io = ImGui::GetIO(); (void)io; | ||||
| 			//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
 | ||||
|     ImGuiIO& io = ImGui::GetIO(); | ||||
|     (void)io; | ||||
| 
 | ||||
|     // Setup Dear ImGui style
 | ||||
|     ImGui::StyleColorsDark(); | ||||
| 			//ImGui::StyleColorsClassic();
 | ||||
| 
 | ||||
|     // Setup Platform/Renderer bindings
 | ||||
| 			Init(Window::instance().GetHandle()); | ||||
|     target_window_ = Renderer::Instance().GetTargetWindow(); | ||||
| 
 | ||||
| 			target_window_ = Renderer::instance().GetTargetWindow(); | ||||
| 		} | ||||
|     io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;  // We can honor GetMouseCursor() values (optional)
 | ||||
|     io.BackendFlags |= | ||||
|         ImGuiBackendFlags_HasSetMousePos;  // We can honor io.WantSetMousePos requests (optional, rarely used)
 | ||||
|     io.BackendPlatformName = "imgui_impl_win32"; | ||||
|     io.ImeWindowHandle     = target_window_; | ||||
| 
 | ||||
| 		void ImGuiModule::DestroyComponent() | ||||
| 		{ | ||||
|     // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during
 | ||||
|     // the application lifetime.
 | ||||
|     io.KeyMap[ImGuiKey_Tab]        = (int)KeyCode::Tab; | ||||
|     io.KeyMap[ImGuiKey_LeftArrow]  = (int)KeyCode::Left; | ||||
|     io.KeyMap[ImGuiKey_RightArrow] = (int)KeyCode::Right; | ||||
|     io.KeyMap[ImGuiKey_UpArrow]    = (int)KeyCode::Up; | ||||
|     io.KeyMap[ImGuiKey_DownArrow]  = (int)KeyCode::Down; | ||||
|     io.KeyMap[ImGuiKey_Delete]     = (int)KeyCode::Delete; | ||||
|     io.KeyMap[ImGuiKey_Backspace]  = (int)KeyCode::Back; | ||||
|     io.KeyMap[ImGuiKey_Space]      = (int)KeyCode::Space; | ||||
|     io.KeyMap[ImGuiKey_Enter]      = (int)KeyCode::Enter; | ||||
|     io.KeyMap[ImGuiKey_Escape]     = (int)KeyCode::Esc; | ||||
|     io.KeyMap[ImGuiKey_A]          = (int)KeyCode::A; | ||||
|     io.KeyMap[ImGuiKey_C]          = (int)KeyCode::C; | ||||
|     io.KeyMap[ImGuiKey_V]          = (int)KeyCode::V; | ||||
|     io.KeyMap[ImGuiKey_X]          = (int)KeyCode::X; | ||||
|     io.KeyMap[ImGuiKey_Y]          = (int)KeyCode::Y; | ||||
|     io.KeyMap[ImGuiKey_Z]          = (int)KeyCode::Z; | ||||
| 
 | ||||
|     ImGui_Impl_Init(Renderer::Instance()); | ||||
| } | ||||
| 
 | ||||
| void ImGuiModule::DestroyComponent() | ||||
| { | ||||
|     ImGui_Impl_Shutdown(); | ||||
|     ImGui::DestroyContext(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::OnUpdate(Duration dt) | ||||
| 		{ | ||||
| void ImGuiModule::OnUpdate(Duration dt) | ||||
| { | ||||
|     ImGuiIO& io = ImGui::GetIO(); | ||||
| 
 | ||||
|     // Setup time step
 | ||||
|     io.DeltaTime = dt.Seconds(); | ||||
| 
 | ||||
|     // Read keyboard modifiers inputs
 | ||||
| 			io.KeyCtrl = Input::instance().IsDown(KeyCode::Ctrl); | ||||
| 			io.KeyShift = Input::instance().IsDown(KeyCode::Shift); | ||||
| 			io.KeyAlt = Input::instance().IsDown(KeyCode::Alt); | ||||
| 			io.KeySuper = false; | ||||
| 			// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
 | ||||
|     io.KeyCtrl  = Input::Instance().IsDown(KeyCode::Ctrl); | ||||
|     io.KeyShift = Input::Instance().IsDown(KeyCode::Shift); | ||||
|     io.KeyAlt   = Input::Instance().IsDown(KeyCode::Alt); | ||||
|     io.KeySuper = Input::Instance().IsDown(KeyCode::Super); | ||||
|     // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the HandleEvent function below.
 | ||||
| 
 | ||||
|     // Update OS mouse position
 | ||||
|     UpdateMousePos(); | ||||
| 
 | ||||
|     // Update OS mouse cursor with the cursor requested by imgui
 | ||||
|     UpdateMouseCursor(); | ||||
| } | ||||
| 
 | ||||
| 			// Update game controllers (if enabled and available)
 | ||||
| 			UpdateGamepads(); | ||||
| 		} | ||||
| 
 | ||||
| 		void ImGuiModule::Init(HWND hwnd) | ||||
| 		{ | ||||
| 			ImGuiIO& io = ImGui::GetIO(); | ||||
| 			io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;         // We can honor GetMouseCursor() values (optional)
 | ||||
| 			io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;          // We can honor io.WantSetMousePos requests (optional, rarely used)
 | ||||
| 			io.BackendPlatformName = "imgui_impl_win32"; | ||||
| 			io.ImeWindowHandle = hwnd; | ||||
| 
 | ||||
| 			// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
 | ||||
| 			io.KeyMap[ImGuiKey_Tab] = KeyCode::Tab; | ||||
| 			io.KeyMap[ImGuiKey_LeftArrow] = KeyCode::Left; | ||||
| 			io.KeyMap[ImGuiKey_RightArrow] = KeyCode::Right; | ||||
| 			io.KeyMap[ImGuiKey_UpArrow] = KeyCode::Up; | ||||
| 			io.KeyMap[ImGuiKey_DownArrow] = KeyCode::Down; | ||||
| 			io.KeyMap[ImGuiKey_Delete] = KeyCode::Delete; | ||||
| 			io.KeyMap[ImGuiKey_Backspace] = KeyCode::Back; | ||||
| 			io.KeyMap[ImGuiKey_Space] = KeyCode::Space; | ||||
| 			io.KeyMap[ImGuiKey_Enter] = KeyCode::Enter; | ||||
| 			io.KeyMap[ImGuiKey_Escape] = KeyCode::Esc; | ||||
| 			io.KeyMap[ImGuiKey_A] = KeyCode::A; | ||||
| 			io.KeyMap[ImGuiKey_C] = KeyCode::C; | ||||
| 			io.KeyMap[ImGuiKey_V] = KeyCode::V; | ||||
| 			io.KeyMap[ImGuiKey_X] = KeyCode::X; | ||||
| 			io.KeyMap[ImGuiKey_Y] = KeyCode::Y; | ||||
| 			io.KeyMap[ImGuiKey_Z] = KeyCode::Z; | ||||
| 
 | ||||
| 			ImGui_Impl_Init(&Renderer::instance()); | ||||
| 		} | ||||
| 
 | ||||
| 		void ImGuiModule::BeforeRender() | ||||
| 		{ | ||||
| void ImGuiModule::BeforeRender() | ||||
| { | ||||
|     NewFrame(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::AfterRender() | ||||
| 		{ | ||||
| void ImGuiModule::AfterRender() | ||||
| { | ||||
|     Render(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) | ||||
| 		{ | ||||
| void ImGuiModule::HandleEvent(Event* evt) | ||||
| { | ||||
|     if (ImGui::GetCurrentContext() == NULL) | ||||
|         return; | ||||
| 
 | ||||
|     ImGuiIO& io = ImGui::GetIO(); | ||||
| 			switch (msg) | ||||
|     if (evt->IsType<MouseEvent>()) | ||||
|     { | ||||
| 			case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: | ||||
| 			case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: | ||||
| 			case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: | ||||
| 			case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: | ||||
|         if (evt->IsType<MouseDownEvent>()) | ||||
|         { | ||||
| 				int button = 0; | ||||
| 				if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } | ||||
| 				if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } | ||||
| 				if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } | ||||
| 				if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; } | ||||
| 				if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) | ||||
| 					::SetCapture(hwnd); | ||||
| 
 | ||||
| 				io.MouseDown[button] = true; | ||||
| 				break; | ||||
|             MouseButton button = dynamic_cast<MouseDownEvent*>(evt)->button; | ||||
|             int         index  = 0; | ||||
|             if (button == MouseButton::Left) | ||||
|                 index = 0; | ||||
|             else if (button == MouseButton::Right) | ||||
|                 index = 1; | ||||
|             else if (button == MouseButton::Middle) | ||||
|                 index = 2; | ||||
|             io.MouseDown[index] = true; | ||||
|         } | ||||
| 			case WM_LBUTTONUP: | ||||
| 			case WM_RBUTTONUP: | ||||
| 			case WM_MBUTTONUP: | ||||
| 			case WM_XBUTTONUP: | ||||
|         else if (evt->IsType<MouseUpEvent>()) | ||||
|         { | ||||
| 				int button = 0; | ||||
| 				if (msg == WM_LBUTTONUP) { button = 0; } | ||||
| 				if (msg == WM_RBUTTONUP) { button = 1; } | ||||
| 				if (msg == WM_MBUTTONUP) { button = 2; } | ||||
| 				if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; } | ||||
| 				io.MouseDown[button] = false; | ||||
| 				if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) | ||||
| 					::ReleaseCapture(); | ||||
| 				break; | ||||
|             MouseButton button = dynamic_cast<MouseUpEvent*>(evt)->button; | ||||
|             int         index  = 0; | ||||
|             if (button == MouseButton::Left) | ||||
|                 index = 0; | ||||
|             else if (button == MouseButton::Right) | ||||
|                 index = 1; | ||||
|             else if (button == MouseButton::Middle) | ||||
|                 index = 2; | ||||
|             io.MouseDown[index] = false; | ||||
|         } | ||||
| 			case WM_MOUSEWHEEL: | ||||
|         else if (evt->IsType<MouseWheelEvent>()) | ||||
|         { | ||||
| 				io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; | ||||
| 				break; | ||||
|             float wheel = dynamic_cast<MouseWheelEvent*>(evt)->wheel; | ||||
|             io.MouseWheel += wheel; | ||||
|         } | ||||
| 			case WM_MOUSEHWHEEL: | ||||
|     } | ||||
|     else if (evt->IsType<KeyEvent>()) | ||||
|     { | ||||
| 				io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; | ||||
| 				break; | ||||
| 			} | ||||
| 			case WM_KEYDOWN: | ||||
| 			case WM_SYSKEYDOWN: | ||||
|         if (evt->IsType<KeyDownEvent>()) | ||||
|         { | ||||
| 				if (wparam < 256) | ||||
| 					io.KeysDown[wparam] = 1; | ||||
| 				break; | ||||
|             KeyCode key           = dynamic_cast<KeyDownEvent*>(evt)->code; | ||||
|             io.KeysDown[(int)key] = true; | ||||
|         } | ||||
| 			case WM_KEYUP: | ||||
| 			case WM_SYSKEYUP: | ||||
|         else if (evt->IsType<KeyUpEvent>()) | ||||
|         { | ||||
| 				if (wparam < 256) | ||||
| 					io.KeysDown[wparam] = 0; | ||||
| 				break; | ||||
|             KeyCode key           = dynamic_cast<KeyUpEvent*>(evt)->code; | ||||
|             io.KeysDown[(int)key] = false; | ||||
|         } | ||||
| 			case WM_CHAR: | ||||
|         else if (evt->IsType<KeyCharEvent>()) | ||||
|         { | ||||
|             // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
 | ||||
| 				io.AddInputCharacter((uint32_t)wparam); | ||||
| 				break; | ||||
| 			} | ||||
| 			case WM_SETCURSOR: | ||||
| 			{ | ||||
| 				if (LOWORD(lparam) == HTCLIENT) | ||||
| 				{ | ||||
| 					UpdateMouseCursor(); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case WM_DEVICECHANGE: | ||||
| 			{ | ||||
| 				if ((uint32_t)wparam == DBT_DEVNODES_CHANGED) | ||||
| 					want_update_has_gamepad_ = true; | ||||
| 				break; | ||||
| 			} | ||||
|             char ch = dynamic_cast<KeyCharEvent*>(evt)->value; | ||||
|             io.AddInputCharacter(static_cast<ImWchar>(ch)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::NewFrame() | ||||
| 		{ | ||||
| void ImGuiModule::NewFrame() | ||||
| { | ||||
|     ImGui_Impl_NewFrame(); | ||||
| 
 | ||||
|     ImGuiIO& io = ImGui::GetIO(); | ||||
|     KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); | ||||
| 
 | ||||
|     // Setup display size (every frame to accommodate for window resizing)
 | ||||
| 			Size display_size = Renderer::instance().GetOutputSize(); | ||||
|     Size display_size = Renderer::Instance().GetOutputSize(); | ||||
|     io.DisplaySize    = ImVec2(display_size.x, display_size.y); | ||||
| 
 | ||||
|     ImGui::NewFrame(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::Render() | ||||
| 		{ | ||||
| void ImGuiModule::Render() | ||||
| { | ||||
|     ImGui::Render(); | ||||
| 
 | ||||
|     ImGui_Impl_RenderDrawData(ImGui::GetDrawData()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::UpdateMousePos() | ||||
| 		{ | ||||
| void ImGuiModule::UpdateMousePos() | ||||
| { | ||||
|     ImGuiIO& io = ImGui::GetIO(); | ||||
| 
 | ||||
| 			// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
 | ||||
|     // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by
 | ||||
|     // user)
 | ||||
|     if (io.WantSetMousePos) | ||||
|     { | ||||
|         POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; | ||||
|  | @ -236,74 +191,46 @@ namespace kiwano | |||
|         ::SetCursorPos(pos.x, pos.y); | ||||
|     } | ||||
| 
 | ||||
| 			Point pos = Input::instance().GetMousePos(); | ||||
|     Point pos   = Input::Instance().GetMousePos(); | ||||
|     io.MousePos = ImVec2(pos.x, pos.y); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ImGuiModule::UpdateMouseCursor() | ||||
| 		{ | ||||
| void ImGuiModule::UpdateMouseCursor() | ||||
| { | ||||
|     if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) | ||||
|         return; | ||||
| 
 | ||||
|     CursorType cursor = CursorType::Arrow; | ||||
|     switch (ImGui::GetMouseCursor()) | ||||
|     { | ||||
| 			case ImGuiMouseCursor_Arrow:        cursor = CursorType::Arrow; break; | ||||
| 			case ImGuiMouseCursor_TextInput:    cursor = CursorType::TextInput; break; | ||||
| 			case ImGuiMouseCursor_ResizeAll:    cursor = CursorType::SizeAll; break; | ||||
| 			case ImGuiMouseCursor_ResizeEW:     cursor = CursorType::SizeWE; break; | ||||
| 			case ImGuiMouseCursor_ResizeNS:     cursor = CursorType::SizeNS; break; | ||||
| 			case ImGuiMouseCursor_ResizeNESW:   cursor = CursorType::SizeNESW; break; | ||||
| 			case ImGuiMouseCursor_ResizeNWSE:   cursor = CursorType::SizeNWSE; break; | ||||
| 			case ImGuiMouseCursor_Hand:         cursor = CursorType::Hand; break; | ||||
|     case ImGuiMouseCursor_Arrow: | ||||
|         cursor = CursorType::Arrow; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_TextInput: | ||||
|         cursor = CursorType::TextInput; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_ResizeAll: | ||||
|         cursor = CursorType::SizeAll; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_ResizeEW: | ||||
|         cursor = CursorType::SizeWE; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_ResizeNS: | ||||
|         cursor = CursorType::SizeNS; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_ResizeNESW: | ||||
|         cursor = CursorType::SizeNESW; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_ResizeNWSE: | ||||
|         cursor = CursorType::SizeNWSE; | ||||
|         break; | ||||
|     case ImGuiMouseCursor_Hand: | ||||
|         cursor = CursorType::Hand; | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
| 			Window::instance().SetCursor(cursor); | ||||
| 		} | ||||
| 		void ImGuiModule::UpdateGamepads() | ||||
| 		{ | ||||
| 			ImGuiIO& io = ImGui::GetIO(); | ||||
| 			memset(io.NavInputs, 0, sizeof(io.NavInputs)); | ||||
| 			if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) | ||||
| 				return; | ||||
| 
 | ||||
| 			// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
 | ||||
| 			// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
 | ||||
| 			if (want_update_has_gamepad_) | ||||
| 			{ | ||||
| 				XINPUT_CAPABILITIES caps; | ||||
| 				has_gamepad_ = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); | ||||
| 				want_update_has_gamepad_ = false; | ||||
| 			} | ||||
| 
 | ||||
| 			XINPUT_STATE xinput_state; | ||||
| 			io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; | ||||
| 			if (has_gamepad_ && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) | ||||
| 			{ | ||||
| 				const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; | ||||
| 				io.BackendFlags |= ImGuiBackendFlags_HasGamepad; | ||||
| 
 | ||||
| #define MAP_BUTTON(NAV_NO, BUTTON_ENUM)     { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } | ||||
| #define MAP_ANALOG(NAV_NO, VALUE, V0, V1)   { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } | ||||
| 				MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A);               // Cross / A
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B);                 // Circle / B
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X);                   // Square / X
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y);                  // Triangle / Y
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);       // D-Pad Left
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);     // D-Pad Right
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP);           // D-Pad Up
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN);       // D-Pad Down
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER);  // L1 / LB
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER);  // L1 / LB
 | ||||
| 				MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
 | ||||
| 				MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); | ||||
| 				MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); | ||||
| 				MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); | ||||
| 				MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); | ||||
| #undef MAP_BUTTON | ||||
| #undef MAP_ANALOG | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|     Window::Instance().SetCursor(cursor); | ||||
| } | ||||
| 
 | ||||
| }  // namespace imgui
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,26 +19,26 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/Component.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace imgui | ||||
| 	{ | ||||
| 		/**
 | ||||
| namespace imgui | ||||
| { | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief ImGuiÄ£¿é | ||||
|  */ | ||||
| 		class ImGuiModule | ||||
| class ImGuiModule | ||||
|     : public Singleton<ImGuiModule> | ||||
|     , public RenderComponent | ||||
|     , public UpdateComponent | ||||
|     , public EventComponent | ||||
| 		{ | ||||
| { | ||||
|     friend Singleton<ImGuiModule>; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     ImGuiModule(); | ||||
| 
 | ||||
|     void SetupComponent() override; | ||||
|  | @ -49,13 +49,11 @@ namespace kiwano | |||
| 
 | ||||
|     void AfterRender() override; | ||||
| 
 | ||||
| 			void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override; | ||||
|     void HandleEvent(Event* evt) override; | ||||
| 
 | ||||
|     void OnUpdate(Duration dt) override; | ||||
| 
 | ||||
| 		private: | ||||
| 			void Init(HWND hwnd); | ||||
| 
 | ||||
| private: | ||||
|     void NewFrame(); | ||||
| 
 | ||||
|     void Render(); | ||||
|  | @ -64,12 +62,8 @@ namespace kiwano | |||
| 
 | ||||
|     void UpdateMouseCursor(); | ||||
| 
 | ||||
| 			void UpdateGamepads(); | ||||
| 
 | ||||
| 		private: | ||||
| 			bool has_gamepad_; | ||||
| 			bool want_update_has_gamepad_; | ||||
| 			HWND target_window_; | ||||
| 		}; | ||||
| 	} | ||||
| } | ||||
| private: | ||||
|     WindowHandle target_window_; | ||||
| }; | ||||
| }  // namespace imgui
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -8,25 +8,62 @@ | |||
| 
 | ||||
| #include <kiwano-imgui/imgui_impl_dx11.h> | ||||
| 
 | ||||
| inline bool     ImGui_Impl_Init(::kiwano::Renderer* renderer)		{ return ImGui_ImplDX11_Init(renderer->GetD3DDeviceResources()->GetDevice(), renderer->GetD3DDeviceResources()->GetDeviceContext()); } | ||||
| inline void     ImGui_Impl_Shutdown()								{ ImGui_ImplDX11_Shutdown(); } | ||||
| inline void     ImGui_Impl_NewFrame()								{ ImGui_ImplDX11_NewFrame(); } | ||||
| inline void     ImGui_Impl_RenderDrawData(ImDrawData* draw_data)	{ ImGui_ImplDX11_RenderDrawData(draw_data); } | ||||
| inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) | ||||
| { | ||||
|     return ImGui_ImplDX11_Init(renderer.GetD3DDeviceResources()->GetDevice(), | ||||
|                                renderer.GetD3DDeviceResources()->GetDeviceContext()); | ||||
| } | ||||
| inline void ImGui_Impl_Shutdown() | ||||
| { | ||||
|     ImGui_ImplDX11_Shutdown(); | ||||
| } | ||||
| inline void ImGui_Impl_NewFrame() | ||||
| { | ||||
|     ImGui_ImplDX11_NewFrame(); | ||||
| } | ||||
| inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) | ||||
| { | ||||
|     ImGui_ImplDX11_RenderDrawData(draw_data); | ||||
| } | ||||
| 
 | ||||
| inline void     ImGui_Impl_InvalidateDeviceObjects()				{ ImGui_ImplDX11_InvalidateDeviceObjects(); } | ||||
| inline bool     ImGui_Impl_CreateDeviceObjects()					{ return ImGui_ImplDX11_CreateDeviceObjects(); } | ||||
| inline void ImGui_Impl_InvalidateDeviceObjects() | ||||
| { | ||||
|     ImGui_ImplDX11_InvalidateDeviceObjects(); | ||||
| } | ||||
| inline bool ImGui_Impl_CreateDeviceObjects() | ||||
| { | ||||
|     return ImGui_ImplDX11_CreateDeviceObjects(); | ||||
| } | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #include <kiwano-imgui/imgui_impl_dx10.h> | ||||
| 
 | ||||
| inline bool     ImGui_Impl_Init(::kiwano::Renderer* renderer)		{ return ImGui_ImplDX10_Init(renderer->GetD3DDeviceResources()->GetDevice()); } | ||||
| inline void     ImGui_Impl_Shutdown()								{ ImGui_ImplDX10_Shutdown(); } | ||||
| inline void     ImGui_Impl_NewFrame()								{ ImGui_ImplDX10_NewFrame(); } | ||||
| inline void     ImGui_Impl_RenderDrawData(ImDrawData* draw_data)	{ ImGui_ImplDX10_RenderDrawData(draw_data); } | ||||
| inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) | ||||
| { | ||||
|     return ImGui_ImplDX10_Init(renderer.GetD3DDeviceResources()->GetDevice()); | ||||
| } | ||||
| inline void ImGui_Impl_Shutdown() | ||||
| { | ||||
|     ImGui_ImplDX10_Shutdown(); | ||||
| } | ||||
| inline void ImGui_Impl_NewFrame() | ||||
| { | ||||
|     ImGui_ImplDX10_NewFrame(); | ||||
| } | ||||
| inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) | ||||
| { | ||||
|     ImGui_ImplDX10_RenderDrawData(draw_data); | ||||
| } | ||||
| 
 | ||||
| inline void     ImGui_Impl_InvalidateDeviceObjects()				{ ImGui_ImplDX10_InvalidateDeviceObjects(); } | ||||
| inline bool     ImGui_Impl_CreateDeviceObjects()					{ return ImGui_ImplDX10_CreateDeviceObjects(); } | ||||
| inline void ImGui_Impl_InvalidateDeviceObjects() | ||||
| { | ||||
|     ImGui_ImplDX10_InvalidateDeviceObjects(); | ||||
| } | ||||
| inline bool ImGui_Impl_CreateDeviceObjects() | ||||
| { | ||||
|     return ImGui_ImplDX10_CreateDeviceObjects(); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,10 +3,10 @@ | |||
| #include <kiwano-imgui/imgui_impl_dx10.h> | ||||
| 
 | ||||
| // DirectX
 | ||||
| #include <stdio.h> | ||||
| #include <d3d10_1.h> | ||||
| #include <d3d10.h> | ||||
| #include <d3dcompiler.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
| #pragma comment(lib, "d3dcompiler")  // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
 | ||||
|  | @ -24,7 +24,7 @@ static ID3D10Buffer*            g_pVertexConstantBuffer = NULL; | |||
| static ID3D10Blob*               g_pPixelShaderBlob      = NULL; | ||||
| static ID3D10PixelShader*        g_pPixelShader          = NULL; | ||||
| static ID3D10SamplerState*       g_pFontSampler          = NULL; | ||||
| static ID3D10ShaderResourceView*g_pFontTextureView = NULL; | ||||
| static ID3D10ShaderResourceView* g_pFontTextureView      = NULL; | ||||
| static ID3D10RasterizerState*    g_pRasterizerState      = NULL; | ||||
| static ID3D10BlendState*         g_pBlendState           = NULL; | ||||
| static ID3D10DepthStencilState*  g_pDepthStencilState    = NULL; | ||||
|  | @ -36,7 +36,8 @@ struct VERTEX_CONSTANT_BUFFER | |||
| }; | ||||
| 
 | ||||
| // 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) | ||||
| { | ||||
|     ID3D10Device* ctx = g_pd3dDevice; | ||||
|  | @ -44,7 +45,11 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
|     // Create and grow vertex/index buffers if needed
 | ||||
|     if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) | ||||
|     { | ||||
|         if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } | ||||
|         if (g_pVB) | ||||
|         { | ||||
|             g_pVB->Release(); | ||||
|             g_pVB = NULL; | ||||
|         } | ||||
|         g_VertexBufferSize = draw_data->TotalVtxCount + 5000; | ||||
|         D3D10_BUFFER_DESC desc; | ||||
|         memset(&desc, 0, sizeof(D3D10_BUFFER_DESC)); | ||||
|  | @ -59,7 +64,11 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
| 
 | ||||
|     if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) | ||||
|     { | ||||
|         if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } | ||||
|         if (g_pIB) | ||||
|         { | ||||
|             g_pIB->Release(); | ||||
|             g_pIB = NULL; | ||||
|         } | ||||
|         g_IndexBufferSize = draw_data->TotalIdxCount + 10000; | ||||
|         D3D10_BUFFER_DESC desc; | ||||
|         memset(&desc, 0, sizeof(D3D10_BUFFER_DESC)); | ||||
|  | @ -88,7 +97,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
|     g_pIB->Unmap(); | ||||
| 
 | ||||
|     // Setup orthographic projection matrix into our constant buffer
 | ||||
|     // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
 | ||||
|     // Our visible imgui space lies from draw_data->DisplayPos (top left) to
 | ||||
|     // draw_data->DisplayPos+data_data->DisplaySize (bottom right).
 | ||||
|     { | ||||
|         void* mapped_resource; | ||||
|         if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) | ||||
|  | @ -98,18 +108,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
|         float                   R               = draw_data->DisplayPos.x + draw_data->DisplaySize.x; | ||||
|         float                   T               = draw_data->DisplayPos.y; | ||||
|         float                   B               = draw_data->DisplayPos.y + draw_data->DisplaySize.y; | ||||
|         float mvp[4][4] = | ||||
|         { | ||||
|             { 2.0f/(R-L),   0.0f,           0.0f,       0.0f }, | ||||
|             { 0.0f,         2.0f/(T-B),     0.0f,       0.0f }, | ||||
|         float                   mvp[4][4]       = { | ||||
|             { 2.0f / (R - L), 0.0f, 0.0f, 0.0f }, | ||||
|             { 0.0f, 2.0f / (T - B), 0.0f, 0.0f }, | ||||
|             { 0.0f, 0.0f, 0.5f, 0.0f }, | ||||
|             { (R+L)/(L-R),  (T+B)/(B-T),    0.5f,       1.0f }, | ||||
|             { (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f }, | ||||
|         }; | ||||
|         memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); | ||||
|         g_pVertexConstantBuffer->Unmap(); | ||||
|     } | ||||
| 
 | ||||
|     // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
 | ||||
|     // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and
 | ||||
|     // verbose. Close your eyes!)
 | ||||
|     struct BACKUP_DX10_STATE | ||||
|     { | ||||
|         UINT                      ScissorRectsCount, ViewportsCount; | ||||
|  | @ -126,7 +136,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
|         ID3D10PixelShader*        PS; | ||||
|         ID3D10VertexShader*       VS; | ||||
|         D3D10_PRIMITIVE_TOPOLOGY  PrimitiveTopology; | ||||
|         ID3D10Buffer*               IndexBuffer, *VertexBuffer, *VSConstantBuffer; | ||||
|         ID3D10Buffer *            IndexBuffer, *VertexBuffer, *VSConstantBuffer; | ||||
|         UINT                      IndexBufferOffset, VertexBufferStride, VertexBufferOffset; | ||||
|         DXGI_FORMAT               IndexBufferFormat; | ||||
|         ID3D10InputLayout*        InputLayout; | ||||
|  | @ -194,7 +204,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
|             else | ||||
|             { | ||||
|                 // Apply scissor/clipping rectangle
 | ||||
|                 const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y)}; | ||||
|                 const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), | ||||
|                                        (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; | ||||
|                 ctx->RSSetScissorRects(1, &r); | ||||
| 
 | ||||
|                 // Bind texture, Draw
 | ||||
|  | @ -210,18 +221,40 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) | |||
|     // Restore modified DX state
 | ||||
|     ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); | ||||
|     ctx->RSSetViewports(old.ViewportsCount, old.Viewports); | ||||
|     ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); | ||||
|     ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); | ||||
|     ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); | ||||
|     ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); | ||||
|     ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); | ||||
|     ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release(); | ||||
|     ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release(); | ||||
|     ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); | ||||
|     ctx->RSSetState(old.RS); | ||||
|     if (old.RS) | ||||
|         old.RS->Release(); | ||||
|     ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); | ||||
|     if (old.BlendState) | ||||
|         old.BlendState->Release(); | ||||
|     ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); | ||||
|     if (old.DepthStencilState) | ||||
|         old.DepthStencilState->Release(); | ||||
|     ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); | ||||
|     if (old.PSShaderResource) | ||||
|         old.PSShaderResource->Release(); | ||||
|     ctx->PSSetSamplers(0, 1, &old.PSSampler); | ||||
|     if (old.PSSampler) | ||||
|         old.PSSampler->Release(); | ||||
|     ctx->PSSetShader(old.PS); | ||||
|     if (old.PS) | ||||
|         old.PS->Release(); | ||||
|     ctx->VSSetShader(old.VS); | ||||
|     if (old.VS) | ||||
|         old.VS->Release(); | ||||
|     ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); | ||||
|     if (old.VSConstantBuffer) | ||||
|         old.VSConstantBuffer->Release(); | ||||
|     ctx->IASetPrimitiveTopology(old.PrimitiveTopology); | ||||
|     ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); | ||||
|     ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); | ||||
|     ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); | ||||
|     ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); | ||||
|     if (old.IndexBuffer) | ||||
|         old.IndexBuffer->Release(); | ||||
|     ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); | ||||
|     if (old.VertexBuffer) | ||||
|         old.VertexBuffer->Release(); | ||||
|     ctx->IASetInputLayout(old.InputLayout); | ||||
|     if (old.InputLayout) | ||||
|         old.InputLayout->Release(); | ||||
| } | ||||
| 
 | ||||
| static void ImGui_ImplDX10_CreateFontsTexture() | ||||
|  | @ -246,7 +279,7 @@ static void ImGui_ImplDX10_CreateFontsTexture() | |||
|         desc.BindFlags        = D3D10_BIND_SHADER_RESOURCE; | ||||
|         desc.CPUAccessFlags   = 0; | ||||
| 
 | ||||
|         ID3D10Texture2D *pTexture = NULL; | ||||
|         ID3D10Texture2D*       pTexture = NULL; | ||||
|         D3D10_SUBRESOURCE_DATA subResource; | ||||
|         subResource.pSysMem          = pixels; | ||||
|         subResource.SysMemPitch      = desc.Width * 4; | ||||
|  | @ -290,16 +323,17 @@ bool    ImGui_ImplDX10_CreateDeviceObjects() | |||
|     if (g_pFontSampler) | ||||
|         ImGui_ImplDX10_InvalidateDeviceObjects(); | ||||
| 
 | ||||
|     // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
 | ||||
|     // If you would like to use this DX10 sample code but remove this dependency you can:
 | ||||
|     //  1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
 | ||||
|     //  2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
 | ||||
|     // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of
 | ||||
|     // d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) If you would like to use this DX10 sample code but remove this
 | ||||
|     // dependency you can:
 | ||||
|     //  1) compile once, save the compiled shader blobs into a file or source code and pass them to
 | ||||
|     //  CreateVertexShader()/CreatePixelShader() [preferred solution] 2) use code to detect any version of the DLL and
 | ||||
|     //  grab a pointer to D3DCompile from the DLL.
 | ||||
|     // See https://github.com/ocornut/imgui/pull/638 for sources and details.
 | ||||
| 
 | ||||
|     // Create the vertex shader
 | ||||
|     { | ||||
|         static const char* vertexShader = | ||||
|             "cbuffer vertexBuffer : register(b0) \
 | ||||
|         static const char* vertexShader = "cbuffer vertexBuffer : register(b0) \
 | ||||
|             {\ | ||||
|             float4x4 ProjectionMatrix; \ | ||||
|             };\ | ||||
|  | @ -326,20 +360,29 @@ bool    ImGui_ImplDX10_CreateDeviceObjects() | |||
|             return output;\ | ||||
|             }"; | ||||
| 
 | ||||
|         D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); | ||||
|         if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|         D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, | ||||
|                    NULL); | ||||
|         if (g_pVertexShaderBlob | ||||
|             == NULL)  // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const
 | ||||
|                       // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|             return false; | ||||
|         if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pVertexShader) != S_OK) | ||||
|         if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), | ||||
|                                              g_pVertexShaderBlob->GetBufferSize(), &g_pVertexShader) | ||||
|             != S_OK) | ||||
|             return false; | ||||
| 
 | ||||
|         // Create the input layout
 | ||||
|         D3D10_INPUT_ELEMENT_DESC local_layout[] = | ||||
|         { | ||||
|             { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT,   0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, | ||||
|             { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,   0, (size_t)(&((ImDrawVert*)0)->uv),  D3D10_INPUT_PER_VERTEX_DATA, 0 }, | ||||
|             { "COLOR",    0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, | ||||
|         D3D10_INPUT_ELEMENT_DESC local_layout[] = { | ||||
|             { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, | ||||
|               0 }, | ||||
|             { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, | ||||
|               0 }, | ||||
|             { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, | ||||
|               0 }, | ||||
|         }; | ||||
|         if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) | ||||
|         if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), | ||||
|                                             g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) | ||||
|             != S_OK) | ||||
|             return false; | ||||
| 
 | ||||
|         // Create the constant buffer
 | ||||
|  | @ -356,8 +399,7 @@ bool    ImGui_ImplDX10_CreateDeviceObjects() | |||
| 
 | ||||
|     // Create the pixel shader
 | ||||
|     { | ||||
|         static const char* pixelShader = | ||||
|             "struct PS_INPUT\
 | ||||
|         static const char* pixelShader = "struct PS_INPUT\
 | ||||
|             {\ | ||||
|             float4 pos : SV_POSITION;\ | ||||
|             float4 col : COLOR0;\ | ||||
|  | @ -372,10 +414,15 @@ bool    ImGui_ImplDX10_CreateDeviceObjects() | |||
|             return out_col; \ | ||||
|             }"; | ||||
| 
 | ||||
|         D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); | ||||
|         if (g_pPixelShaderBlob == NULL)  // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|         D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, | ||||
|                    NULL); | ||||
|         if (g_pPixelShaderBlob | ||||
|             == NULL)  // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const
 | ||||
|                       // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|             return false; | ||||
|         if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), &g_pPixelShader) != S_OK) | ||||
|         if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), | ||||
|                                             g_pPixelShaderBlob->GetBufferSize(), &g_pPixelShader) | ||||
|             != S_OK) | ||||
|             return false; | ||||
|     } | ||||
| 
 | ||||
|  | @ -414,7 +461,8 @@ bool    ImGui_ImplDX10_CreateDeviceObjects() | |||
|         desc.DepthWriteMask          = D3D10_DEPTH_WRITE_MASK_ALL; | ||||
|         desc.DepthFunc               = D3D10_COMPARISON_ALWAYS; | ||||
|         desc.StencilEnable           = false; | ||||
|         desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; | ||||
|         desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = | ||||
|             D3D10_STENCIL_OP_KEEP; | ||||
|         desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; | ||||
|         desc.BackFace              = desc.FrontFace; | ||||
|         g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); | ||||
|  | @ -430,20 +478,73 @@ void    ImGui_ImplDX10_InvalidateDeviceObjects() | |||
|     if (!g_pd3dDevice) | ||||
|         return; | ||||
| 
 | ||||
|     if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } | ||||
|     if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
 | ||||
|     if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } | ||||
|     if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } | ||||
|     if (g_pFontSampler) | ||||
|     { | ||||
|         g_pFontSampler->Release(); | ||||
|         g_pFontSampler = NULL; | ||||
|     } | ||||
|     if (g_pFontTextureView) | ||||
|     { | ||||
|         g_pFontTextureView->Release(); | ||||
|         g_pFontTextureView          = NULL; | ||||
|         ImGui::GetIO().Fonts->TexID = NULL; | ||||
|     }  // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
 | ||||
|     if (g_pIB) | ||||
|     { | ||||
|         g_pIB->Release(); | ||||
|         g_pIB = NULL; | ||||
|     } | ||||
|     if (g_pVB) | ||||
|     { | ||||
|         g_pVB->Release(); | ||||
|         g_pVB = NULL; | ||||
|     } | ||||
| 
 | ||||
|     if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } | ||||
|     if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } | ||||
|     if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } | ||||
|     if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } | ||||
|     if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } | ||||
|     if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } | ||||
|     if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } | ||||
|     if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } | ||||
|     if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } | ||||
|     if (g_pBlendState) | ||||
|     { | ||||
|         g_pBlendState->Release(); | ||||
|         g_pBlendState = NULL; | ||||
|     } | ||||
|     if (g_pDepthStencilState) | ||||
|     { | ||||
|         g_pDepthStencilState->Release(); | ||||
|         g_pDepthStencilState = NULL; | ||||
|     } | ||||
|     if (g_pRasterizerState) | ||||
|     { | ||||
|         g_pRasterizerState->Release(); | ||||
|         g_pRasterizerState = NULL; | ||||
|     } | ||||
|     if (g_pPixelShader) | ||||
|     { | ||||
|         g_pPixelShader->Release(); | ||||
|         g_pPixelShader = NULL; | ||||
|     } | ||||
|     if (g_pPixelShaderBlob) | ||||
|     { | ||||
|         g_pPixelShaderBlob->Release(); | ||||
|         g_pPixelShaderBlob = NULL; | ||||
|     } | ||||
|     if (g_pVertexConstantBuffer) | ||||
|     { | ||||
|         g_pVertexConstantBuffer->Release(); | ||||
|         g_pVertexConstantBuffer = NULL; | ||||
|     } | ||||
|     if (g_pInputLayout) | ||||
|     { | ||||
|         g_pInputLayout->Release(); | ||||
|         g_pInputLayout = NULL; | ||||
|     } | ||||
|     if (g_pVertexShader) | ||||
|     { | ||||
|         g_pVertexShader->Release(); | ||||
|         g_pVertexShader = NULL; | ||||
|     } | ||||
|     if (g_pVertexShaderBlob) | ||||
|     { | ||||
|         g_pVertexShaderBlob->Release(); | ||||
|         g_pVertexShaderBlob = NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool ImGui_ImplDX10_Init(ID3D10Device* device) | ||||
|  | @ -463,8 +564,10 @@ bool    ImGui_ImplDX10_Init(ID3D10Device* device) | |||
|                 g_pd3dDevice = device; | ||||
|                 g_pFactory   = pFactory; | ||||
|             } | ||||
|     if (pDXGIDevice) pDXGIDevice->Release(); | ||||
|     if (pDXGIAdapter) pDXGIAdapter->Release(); | ||||
|     if (pDXGIDevice) | ||||
|         pDXGIDevice->Release(); | ||||
|     if (pDXGIAdapter) | ||||
|         pDXGIAdapter->Release(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
|  | @ -472,7 +575,11 @@ bool    ImGui_ImplDX10_Init(ID3D10Device* device) | |||
| void ImGui_ImplDX10_Shutdown() | ||||
| { | ||||
|     ImGui_ImplDX10_InvalidateDeviceObjects(); | ||||
|     if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } | ||||
|     if (g_pFactory) | ||||
|     { | ||||
|         g_pFactory->Release(); | ||||
|         g_pFactory = NULL; | ||||
|     } | ||||
|     g_pd3dDevice = NULL; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,9 +3,9 @@ | |||
| #include <kiwano-imgui/imgui_impl_dx11.h> | ||||
| 
 | ||||
| // DirectX
 | ||||
| #include <stdio.h> | ||||
| #include <d3d11.h> | ||||
| #include <d3dcompiler.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
| #pragma comment(lib, "d3dcompiler")  // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
 | ||||
|  | @ -24,7 +24,7 @@ static ID3D11Buffer*            g_pVertexConstantBuffer = NULL; | |||
| static ID3D10Blob*               g_pPixelShaderBlob      = NULL; | ||||
| static ID3D11PixelShader*        g_pPixelShader          = NULL; | ||||
| static ID3D11SamplerState*       g_pFontSampler          = NULL; | ||||
| static ID3D11ShaderResourceView*g_pFontTextureView = NULL; | ||||
| static ID3D11ShaderResourceView* g_pFontTextureView      = NULL; | ||||
| static ID3D11RasterizerState*    g_pRasterizerState      = NULL; | ||||
| static ID3D11BlendState*         g_pBlendState           = NULL; | ||||
| static ID3D11DepthStencilState*  g_pDepthStencilState    = NULL; | ||||
|  | @ -36,7 +36,8 @@ struct VERTEX_CONSTANT_BUFFER | |||
| }; | ||||
| 
 | ||||
| // 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) | ||||
| { | ||||
|     ID3D11DeviceContext* ctx = g_pd3dDeviceContext; | ||||
|  | @ -44,7 +45,11 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|     // Create and grow vertex/index buffers if needed
 | ||||
|     if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) | ||||
|     { | ||||
|         if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } | ||||
|         if (g_pVB) | ||||
|         { | ||||
|             g_pVB->Release(); | ||||
|             g_pVB = NULL; | ||||
|         } | ||||
|         g_VertexBufferSize = draw_data->TotalVtxCount + 5000; | ||||
|         D3D11_BUFFER_DESC desc; | ||||
|         memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); | ||||
|  | @ -58,7 +63,11 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|     } | ||||
|     if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) | ||||
|     { | ||||
|         if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } | ||||
|         if (g_pIB) | ||||
|         { | ||||
|             g_pIB->Release(); | ||||
|             g_pIB = NULL; | ||||
|         } | ||||
|         g_IndexBufferSize = draw_data->TotalIdxCount + 10000; | ||||
|         D3D11_BUFFER_DESC desc; | ||||
|         memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); | ||||
|  | @ -90,7 +99,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|     ctx->Unmap(g_pIB, 0); | ||||
| 
 | ||||
|     // Setup orthographic projection matrix into our constant buffer
 | ||||
|     // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
 | ||||
|     // Our visible imgui space lies from draw_data->DisplayPos (top left) to
 | ||||
|     // draw_data->DisplayPos+data_data->DisplaySize (bottom right).
 | ||||
|     { | ||||
|         D3D11_MAPPED_SUBRESOURCE mapped_resource; | ||||
|         if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) | ||||
|  | @ -100,18 +110,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|         float                   R               = draw_data->DisplayPos.x + draw_data->DisplaySize.x; | ||||
|         float                   T               = draw_data->DisplayPos.y; | ||||
|         float                   B               = draw_data->DisplayPos.y + draw_data->DisplaySize.y; | ||||
|         float mvp[4][4] = | ||||
|         { | ||||
|             { 2.0f/(R-L),   0.0f,           0.0f,       0.0f }, | ||||
|             { 0.0f,         2.0f/(T-B),     0.0f,       0.0f }, | ||||
|         float                   mvp[4][4]       = { | ||||
|             { 2.0f / (R - L), 0.0f, 0.0f, 0.0f }, | ||||
|             { 0.0f, 2.0f / (T - B), 0.0f, 0.0f }, | ||||
|             { 0.0f, 0.0f, 0.5f, 0.0f }, | ||||
|             { (R+L)/(L-R),  (T+B)/(B-T),    0.5f,       1.0f }, | ||||
|             { (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f }, | ||||
|         }; | ||||
|         memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); | ||||
|         ctx->Unmap(g_pVertexConstantBuffer, 0); | ||||
|     } | ||||
| 
 | ||||
|     // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
 | ||||
|     // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and
 | ||||
|     // verbose. Close your eyes!)
 | ||||
|     struct BACKUP_DX11_STATE | ||||
|     { | ||||
|         UINT                      ScissorRectsCount, ViewportsCount; | ||||
|  | @ -128,9 +138,9 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|         ID3D11PixelShader*        PS; | ||||
|         ID3D11VertexShader*       VS; | ||||
|         UINT                      PSInstancesCount, VSInstancesCount; | ||||
|         ID3D11ClassInstance*        PSInstances[256], *VSInstances[256];   // 256 is max according to PSSetShader documentation
 | ||||
|         ID3D11ClassInstance *PSInstances[256], *VSInstances[256];  // 256 is max according to PSSetShader documentation
 | ||||
|         D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; | ||||
|         ID3D11Buffer*               IndexBuffer, *VertexBuffer, *VSConstantBuffer; | ||||
|         ID3D11Buffer *           IndexBuffer, *VertexBuffer, *VSConstantBuffer; | ||||
|         UINT                     IndexBufferOffset, VertexBufferStride, VertexBufferOffset; | ||||
|         DXGI_FORMAT              IndexBufferFormat; | ||||
|         ID3D11InputLayout*       InputLayout; | ||||
|  | @ -199,7 +209,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|             else | ||||
|             { | ||||
|                 // Apply scissor/clipping rectangle
 | ||||
|                 const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; | ||||
|                 const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - pos.x), (LONG)(pcmd->ClipRect.y - pos.y), | ||||
|                                        (LONG)(pcmd->ClipRect.z - pos.x), (LONG)(pcmd->ClipRect.w - pos.y) }; | ||||
|                 ctx->RSSetScissorRects(1, &r); | ||||
| 
 | ||||
|                 // Bind texture, Draw
 | ||||
|  | @ -215,20 +226,46 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) | |||
|     // Restore modified DX state
 | ||||
|     ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); | ||||
|     ctx->RSSetViewports(old.ViewportsCount, old.Viewports); | ||||
|     ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); | ||||
|     ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); | ||||
|     ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); | ||||
|     ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); | ||||
|     ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); | ||||
|     ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); | ||||
|     for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); | ||||
|     ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); | ||||
|     ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); | ||||
|     for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); | ||||
|     ctx->RSSetState(old.RS); | ||||
|     if (old.RS) | ||||
|         old.RS->Release(); | ||||
|     ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); | ||||
|     if (old.BlendState) | ||||
|         old.BlendState->Release(); | ||||
|     ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); | ||||
|     if (old.DepthStencilState) | ||||
|         old.DepthStencilState->Release(); | ||||
|     ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); | ||||
|     if (old.PSShaderResource) | ||||
|         old.PSShaderResource->Release(); | ||||
|     ctx->PSSetSamplers(0, 1, &old.PSSampler); | ||||
|     if (old.PSSampler) | ||||
|         old.PSSampler->Release(); | ||||
|     ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); | ||||
|     if (old.PS) | ||||
|         old.PS->Release(); | ||||
|     for (UINT i = 0; i < old.PSInstancesCount; i++) | ||||
|         if (old.PSInstances[i]) | ||||
|             old.PSInstances[i]->Release(); | ||||
|     ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); | ||||
|     if (old.VS) | ||||
|         old.VS->Release(); | ||||
|     ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); | ||||
|     if (old.VSConstantBuffer) | ||||
|         old.VSConstantBuffer->Release(); | ||||
|     for (UINT i = 0; i < old.VSInstancesCount; i++) | ||||
|         if (old.VSInstances[i]) | ||||
|             old.VSInstances[i]->Release(); | ||||
|     ctx->IASetPrimitiveTopology(old.PrimitiveTopology); | ||||
|     ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); | ||||
|     ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); | ||||
|     ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); | ||||
|     ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); | ||||
|     if (old.IndexBuffer) | ||||
|         old.IndexBuffer->Release(); | ||||
|     ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); | ||||
|     if (old.VertexBuffer) | ||||
|         old.VertexBuffer->Release(); | ||||
|     ctx->IASetInputLayout(old.InputLayout); | ||||
|     if (old.InputLayout) | ||||
|         old.InputLayout->Release(); | ||||
| } | ||||
| 
 | ||||
| static void ImGui_ImplDX11_CreateFontsTexture() | ||||
|  | @ -253,7 +290,7 @@ static void ImGui_ImplDX11_CreateFontsTexture() | |||
|         desc.BindFlags        = D3D11_BIND_SHADER_RESOURCE; | ||||
|         desc.CPUAccessFlags   = 0; | ||||
| 
 | ||||
|         ID3D11Texture2D *pTexture = NULL; | ||||
|         ID3D11Texture2D*       pTexture = NULL; | ||||
|         D3D11_SUBRESOURCE_DATA subResource; | ||||
|         subResource.pSysMem          = pixels; | ||||
|         subResource.SysMemPitch      = desc.Width * 4; | ||||
|  | @ -301,16 +338,17 @@ bool    ImGui_ImplDX11_CreateDeviceObjects() | |||
|     if (g_pFontSampler) | ||||
|         ImGui_ImplDX11_InvalidateDeviceObjects(); | ||||
| 
 | ||||
|     // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
 | ||||
|     // If you would like to use this DX11 sample code but remove this dependency you can:
 | ||||
|     //  1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
 | ||||
|     //  2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
 | ||||
|     // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of
 | ||||
|     // d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) If you would like to use this DX11 sample code but remove this
 | ||||
|     // dependency you can:
 | ||||
|     //  1) compile once, save the compiled shader blobs into a file or source code and pass them to
 | ||||
|     //  CreateVertexShader()/CreatePixelShader() [preferred solution] 2) use code to detect any version of the DLL and
 | ||||
|     //  grab a pointer to D3DCompile from the DLL.
 | ||||
|     // See https://github.com/ocornut/imgui/pull/638 for sources and details.
 | ||||
| 
 | ||||
|     // Create the vertex shader
 | ||||
|     { | ||||
|         static const char* vertexShader = | ||||
|             "cbuffer vertexBuffer : register(b0) \
 | ||||
|         static const char* vertexShader = "cbuffer vertexBuffer : register(b0) \
 | ||||
|             {\ | ||||
|             float4x4 ProjectionMatrix; \ | ||||
|             };\ | ||||
|  | @ -337,20 +375,29 @@ bool    ImGui_ImplDX11_CreateDeviceObjects() | |||
|             return output;\ | ||||
|             }"; | ||||
| 
 | ||||
|         D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); | ||||
|         if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|         D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, | ||||
|                    NULL); | ||||
|         if (g_pVertexShaderBlob | ||||
|             == NULL)  // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const
 | ||||
|                       // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|             return false; | ||||
|         if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) | ||||
|         if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), | ||||
|                                              g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) | ||||
|             != S_OK) | ||||
|             return false; | ||||
| 
 | ||||
|         // Create the input layout
 | ||||
|         D3D11_INPUT_ELEMENT_DESC local_layout[] = | ||||
|         { | ||||
|             { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT,   0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, | ||||
|             { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,   0, (size_t)(&((ImDrawVert*)0)->uv),  D3D11_INPUT_PER_VERTEX_DATA, 0 }, | ||||
|             { "COLOR",    0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, | ||||
|         D3D11_INPUT_ELEMENT_DESC local_layout[] = { | ||||
|             { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, | ||||
|               0 }, | ||||
|             { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, | ||||
|               0 }, | ||||
|             { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, | ||||
|               0 }, | ||||
|         }; | ||||
|         if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) | ||||
|         if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), | ||||
|                                             g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) | ||||
|             != S_OK) | ||||
|             return false; | ||||
| 
 | ||||
|         // Create the constant buffer
 | ||||
|  | @ -367,8 +414,7 @@ bool    ImGui_ImplDX11_CreateDeviceObjects() | |||
| 
 | ||||
|     // Create the pixel shader
 | ||||
|     { | ||||
|         static const char* pixelShader = | ||||
|             "struct PS_INPUT\
 | ||||
|         static const char* pixelShader = "struct PS_INPUT\
 | ||||
|             {\ | ||||
|             float4 pos : SV_POSITION;\ | ||||
|             float4 col : COLOR0;\ | ||||
|  | @ -383,10 +429,15 @@ bool    ImGui_ImplDX11_CreateDeviceObjects() | |||
|             return out_col; \ | ||||
|             }"; | ||||
| 
 | ||||
|         D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); | ||||
|         if (g_pPixelShaderBlob == NULL)  // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|         D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, | ||||
|                    NULL); | ||||
|         if (g_pPixelShaderBlob | ||||
|             == NULL)  // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const
 | ||||
|                       // char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
 | ||||
|             return false; | ||||
|         if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) | ||||
|         if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), | ||||
|                                             g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) | ||||
|             != S_OK) | ||||
|             return false; | ||||
|     } | ||||
| 
 | ||||
|  | @ -425,7 +476,8 @@ bool    ImGui_ImplDX11_CreateDeviceObjects() | |||
|         desc.DepthWriteMask          = D3D11_DEPTH_WRITE_MASK_ALL; | ||||
|         desc.DepthFunc               = D3D11_COMPARISON_ALWAYS; | ||||
|         desc.StencilEnable           = false; | ||||
|         desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; | ||||
|         desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = | ||||
|             D3D11_STENCIL_OP_KEEP; | ||||
|         desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; | ||||
|         desc.BackFace              = desc.FrontFace; | ||||
|         g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); | ||||
|  | @ -441,20 +493,73 @@ void    ImGui_ImplDX11_InvalidateDeviceObjects() | |||
|     if (!g_pd3dDevice) | ||||
|         return; | ||||
| 
 | ||||
|     if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } | ||||
|     if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
 | ||||
|     if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } | ||||
|     if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } | ||||
|     if (g_pFontSampler) | ||||
|     { | ||||
|         g_pFontSampler->Release(); | ||||
|         g_pFontSampler = NULL; | ||||
|     } | ||||
|     if (g_pFontTextureView) | ||||
|     { | ||||
|         g_pFontTextureView->Release(); | ||||
|         g_pFontTextureView          = NULL; | ||||
|         ImGui::GetIO().Fonts->TexID = NULL; | ||||
|     }  // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
 | ||||
|     if (g_pIB) | ||||
|     { | ||||
|         g_pIB->Release(); | ||||
|         g_pIB = NULL; | ||||
|     } | ||||
|     if (g_pVB) | ||||
|     { | ||||
|         g_pVB->Release(); | ||||
|         g_pVB = NULL; | ||||
|     } | ||||
| 
 | ||||
|     if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } | ||||
|     if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } | ||||
|     if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } | ||||
|     if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } | ||||
|     if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } | ||||
|     if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } | ||||
|     if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } | ||||
|     if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } | ||||
|     if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } | ||||
|     if (g_pBlendState) | ||||
|     { | ||||
|         g_pBlendState->Release(); | ||||
|         g_pBlendState = NULL; | ||||
|     } | ||||
|     if (g_pDepthStencilState) | ||||
|     { | ||||
|         g_pDepthStencilState->Release(); | ||||
|         g_pDepthStencilState = NULL; | ||||
|     } | ||||
|     if (g_pRasterizerState) | ||||
|     { | ||||
|         g_pRasterizerState->Release(); | ||||
|         g_pRasterizerState = NULL; | ||||
|     } | ||||
|     if (g_pPixelShader) | ||||
|     { | ||||
|         g_pPixelShader->Release(); | ||||
|         g_pPixelShader = NULL; | ||||
|     } | ||||
|     if (g_pPixelShaderBlob) | ||||
|     { | ||||
|         g_pPixelShaderBlob->Release(); | ||||
|         g_pPixelShaderBlob = NULL; | ||||
|     } | ||||
|     if (g_pVertexConstantBuffer) | ||||
|     { | ||||
|         g_pVertexConstantBuffer->Release(); | ||||
|         g_pVertexConstantBuffer = NULL; | ||||
|     } | ||||
|     if (g_pInputLayout) | ||||
|     { | ||||
|         g_pInputLayout->Release(); | ||||
|         g_pInputLayout = NULL; | ||||
|     } | ||||
|     if (g_pVertexShader) | ||||
|     { | ||||
|         g_pVertexShader->Release(); | ||||
|         g_pVertexShader = NULL; | ||||
|     } | ||||
|     if (g_pVertexShaderBlob) | ||||
|     { | ||||
|         g_pVertexShaderBlob->Release(); | ||||
|         g_pVertexShaderBlob = NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) | ||||
|  | @ -475,8 +580,10 @@ bool    ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co | |||
|                 g_pd3dDeviceContext = device_context; | ||||
|                 g_pFactory          = pFactory; | ||||
|             } | ||||
|     if (pDXGIDevice) pDXGIDevice->Release(); | ||||
|     if (pDXGIAdapter) pDXGIAdapter->Release(); | ||||
|     if (pDXGIDevice) | ||||
|         pDXGIDevice->Release(); | ||||
|     if (pDXGIAdapter) | ||||
|         pDXGIAdapter->Release(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
|  | @ -484,7 +591,11 @@ bool    ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co | |||
| void ImGui_ImplDX11_Shutdown() | ||||
| { | ||||
|     ImGui_ImplDX11_InvalidateDeviceObjects(); | ||||
|     if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } | ||||
|     if (g_pFactory) | ||||
|     { | ||||
|         g_pFactory->Release(); | ||||
|         g_pFactory = NULL; | ||||
|     } | ||||
|     g_pd3dDevice        = NULL; | ||||
|     g_pd3dDeviceContext = NULL; | ||||
| } | ||||
|  |  | |||
|  | @ -18,24 +18,22 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <thread> | ||||
| #include <codecvt> | ||||
| 
 | ||||
| #include <thread> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/platform/Application.h> | ||||
| #include <kiwano-network/HttpRequest.h> | ||||
| #include <kiwano-network/HttpResponse.hpp> | ||||
| #include <kiwano-network/HttpClient.h> | ||||
| 
 | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/platform/Application.h> | ||||
| #include <3rd-party/curl/curl.h>  // CURL
 | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| 	using namespace kiwano; | ||||
| 	using namespace kiwano::network; | ||||
| using namespace kiwano; | ||||
| using namespace kiwano::network; | ||||
| 
 | ||||
| 	uint32_t write_data(void* buffer, uint32_t size, uint32_t nmemb, void* userp) | ||||
| 	{ | ||||
| uint32_t write_data(void* buffer, uint32_t size, uint32_t nmemb, void* userp) | ||||
| { | ||||
|     ByteString* recv_buffer = (ByteString*)userp; | ||||
|     uint32_t    total       = size * nmemb; | ||||
| 
 | ||||
|  | @ -44,10 +42,10 @@ namespace | |||
|     recv_buffer->append((char*)buffer, total); | ||||
| 
 | ||||
|     return total; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ByteString convert_to_utf8(String const& str) | ||||
| 	{ | ||||
| ByteString convert_to_utf8(String const& str) | ||||
| { | ||||
|     std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv; | ||||
|     ByteString                                       result; | ||||
| 
 | ||||
|  | @ -61,10 +59,10 @@ namespace | |||
|         result = WideToMultiByte(str); | ||||
|     } | ||||
|     return result; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	String convert_from_utf8(ByteString const& str) | ||||
| 	{ | ||||
| String convert_from_utf8(ByteString const& str) | ||||
| { | ||||
|     oc::string_convert<std::codecvt_utf8<wchar_t>> utf8_conv; | ||||
|     String                                         result; | ||||
| 
 | ||||
|  | @ -78,11 +76,11 @@ namespace | |||
|         result = MultiByteToWide(str); | ||||
|     } | ||||
|     return result; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	class Curl | ||||
| 	{ | ||||
| 	public: | ||||
| class Curl | ||||
| { | ||||
| public: | ||||
|     Curl() | ||||
|         : curl_(curl_easy_init()) | ||||
|         , curl_headers_(nullptr) | ||||
|  | @ -104,7 +102,8 @@ namespace | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| 		bool Init(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, ByteString* response_data, ByteString* response_header, char* error_buffer) | ||||
|     bool Init(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, ByteString* response_data, | ||||
|               ByteString* response_header, char* error_buffer) | ||||
|     { | ||||
|         if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) | ||||
|             return false; | ||||
|  | @ -114,13 +113,15 @@ namespace | |||
|             return false; | ||||
| 
 | ||||
|         const auto ssl_ca_file = wide_to_string(client->GetSSLVerification()); | ||||
| 			if (ssl_ca_file.empty()) { | ||||
|         if (ssl_ca_file.empty()) | ||||
|         { | ||||
|             if (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L)) | ||||
|                 return false; | ||||
|             if (!SetOption(CURLOPT_SSL_VERIFYHOST, 0L)) | ||||
|                 return false; | ||||
|         } | ||||
| 			else { | ||||
|         else | ||||
|         { | ||||
|             if (!SetOption(CURLOPT_SSL_VERIFYPEER, 1L)) | ||||
|                 return false; | ||||
|             if (!SetOption(CURLOPT_SSL_VERIFYHOST, 2L)) | ||||
|  | @ -145,10 +146,8 @@ namespace | |||
|                 return false; | ||||
|         } | ||||
| 
 | ||||
| 			return SetOption(CURLOPT_URL, url.c_str()) | ||||
| 				&& SetOption(CURLOPT_WRITEFUNCTION, write_data) | ||||
| 				&& SetOption(CURLOPT_WRITEDATA, response_data) | ||||
| 				&& SetOption(CURLOPT_HEADERFUNCTION, write_data) | ||||
|         return SetOption(CURLOPT_URL, url.c_str()) && SetOption(CURLOPT_WRITEFUNCTION, write_data) | ||||
|                && SetOption(CURLOPT_WRITEDATA, response_data) && SetOption(CURLOPT_HEADERFUNCTION, write_data) | ||||
|                && SetOption(CURLOPT_HEADERDATA, response_header); | ||||
|     } | ||||
| 
 | ||||
|  | @ -161,111 +160,84 @@ namespace | |||
|         return code == CURLE_OK && (*response_code >= 200 && *response_code < 300); | ||||
|     } | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
|     template <typename... _Args> | ||||
|     bool SetOption(CURLoption option, _Args&&... args) | ||||
|     { | ||||
|         return CURLE_OK == curl_easy_setopt(curl_, option, std::forward<_Args>(args)...); | ||||
|     } | ||||
| 
 | ||||
| 	public: | ||||
| 		static inline bool GetRequest( | ||||
| 			HttpClient* client, | ||||
| 			Vector<ByteString> const& headers, | ||||
| 			ByteString const& url, | ||||
| 			long* response_code, | ||||
| 			ByteString* response_data, | ||||
| 			ByteString* response_header, | ||||
| public: | ||||
|     static inline bool GetRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                   long* response_code, ByteString* response_data, ByteString* response_header, | ||||
|                                   char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | ||||
| 				&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true) | ||||
| 				&& curl.Perform(response_code); | ||||
|                && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.Perform(response_code); | ||||
|     } | ||||
| 
 | ||||
| 		static inline bool PostRequest( | ||||
| 			HttpClient* client, | ||||
| 			Vector<ByteString> const& headers, | ||||
| 			ByteString const& url, | ||||
| 			ByteString const& request_data, | ||||
| 			long* response_code, | ||||
| 			ByteString* response_data, | ||||
| 			ByteString* response_header, | ||||
| 			char* error_buffer) | ||||
|     static inline bool PostRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                    ByteString const& request_data, long* response_code, ByteString* response_data, | ||||
|                                    ByteString* response_header, char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | ||||
| 				&& curl.SetOption(CURLOPT_POST, 1) | ||||
| 				&& curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | ||||
| 				&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) | ||||
| 				&& curl.Perform(response_code); | ||||
|                && curl.SetOption(CURLOPT_POST, 1) && curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | ||||
|                && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code); | ||||
|     } | ||||
| 
 | ||||
| 		static inline bool PutRequest( | ||||
| 			HttpClient* client, | ||||
| 			Vector<ByteString> const& headers, | ||||
| 			ByteString const& url, | ||||
| 			ByteString const& request_data, | ||||
| 			long* response_code, | ||||
| 			ByteString* response_data, | ||||
| 			ByteString* response_header, | ||||
| 			char* error_buffer) | ||||
|     static inline bool PutRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                   ByteString const& request_data, long* response_code, ByteString* response_data, | ||||
|                                   ByteString* response_header, char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | ||||
|                && curl.SetOption(CURLOPT_CUSTOMREQUEST, "PUT") | ||||
|                && curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) | ||||
| 				&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) | ||||
| 				&& curl.Perform(response_code); | ||||
|                && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code); | ||||
|     } | ||||
| 
 | ||||
| 		static inline bool DeleteRequest( | ||||
| 			HttpClient* client, | ||||
| 			Vector<ByteString> const& headers, | ||||
| 			ByteString const& url, | ||||
| 			long* response_code, | ||||
| 			ByteString* response_data, | ||||
| 			ByteString* response_header, | ||||
|     static inline bool DeleteRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, | ||||
|                                      long* response_code, ByteString* response_data, ByteString* response_header, | ||||
|                                      char* error_buffer) | ||||
|     { | ||||
|         Curl curl; | ||||
|         return curl.Init(client, headers, url, response_data, response_header, error_buffer) | ||||
| 				&& curl.SetOption(CURLOPT_CUSTOMREQUEST, "DELETE") | ||||
| 				&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true) | ||||
|                && curl.SetOption(CURLOPT_CUSTOMREQUEST, "DELETE") && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) | ||||
|                && curl.Perform(response_code); | ||||
|     } | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     CURL*       curl_; | ||||
|     curl_slist* curl_headers_; | ||||
| 	}; | ||||
| } | ||||
| }; | ||||
| }  // namespace
 | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace network | ||||
| 	{ | ||||
| 		HttpClient::HttpClient() | ||||
| namespace network | ||||
| { | ||||
| HttpClient::HttpClient() | ||||
|     : timeout_for_connect_(30000 /* 30 seconds */) | ||||
|     , timeout_for_read_(60000 /* 60 seconds */) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		void HttpClient::SetupComponent() | ||||
| 		{ | ||||
| void HttpClient::SetupComponent() | ||||
| { | ||||
|     ::curl_global_init(CURL_GLOBAL_ALL); | ||||
| 
 | ||||
|     std::thread thread(Closure(this, &HttpClient::NetworkThread)); | ||||
|     thread.detach(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void HttpClient::DestroyComponent() | ||||
| 		{ | ||||
| void HttpClient::DestroyComponent() | ||||
| { | ||||
|     ::curl_global_cleanup(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void HttpClient::Send(HttpRequestPtr request) | ||||
| 		{ | ||||
| void HttpClient::Send(HttpRequestPtr request) | ||||
| { | ||||
|     if (!request) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -274,10 +246,10 @@ namespace kiwano | |||
|     request_mutex_.unlock(); | ||||
| 
 | ||||
|     sleep_condition_.notify_one(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void HttpClient::NetworkThread() | ||||
| 		{ | ||||
| void HttpClient::NetworkThread() | ||||
| { | ||||
|     while (true) | ||||
|     { | ||||
|         HttpRequestPtr request; | ||||
|  | @ -300,10 +272,10 @@ namespace kiwano | |||
| 
 | ||||
|         Application::PreformInMainThread(Closure(this, &HttpClient::DispatchResponseCallback)); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response) | ||||
| 		{ | ||||
| void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response) | ||||
| { | ||||
|     bool       ok                 = false; | ||||
|     long       response_code      = 0; | ||||
|     char       error_message[256] = { 0 }; | ||||
|  | @ -326,10 +298,12 @@ namespace kiwano | |||
|         ok = Curl::GetRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); | ||||
|         break; | ||||
|     case HttpRequest::Type::Post: | ||||
| 				ok = Curl::PostRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); | ||||
|         ok = Curl::PostRequest(this, headers, url, data, &response_code, &response_data, &response_header, | ||||
|                                error_message); | ||||
|         break; | ||||
|     case HttpRequest::Type::Put: | ||||
| 				ok = Curl::PutRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); | ||||
|         ok = | ||||
|             Curl::PutRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); | ||||
|         break; | ||||
|     case HttpRequest::Type::Delete: | ||||
|         ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); | ||||
|  | @ -351,10 +325,10 @@ namespace kiwano | |||
|     { | ||||
|         response->SetSucceed(true); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void HttpClient::DispatchResponseCallback() | ||||
| 		{ | ||||
| void HttpClient::DispatchResponseCallback() | ||||
| { | ||||
|     HttpResponsePtr response; | ||||
| 
 | ||||
|     response_mutex_.lock(); | ||||
|  | @ -375,7 +349,7 @@ namespace kiwano | |||
|             callback(request.get(), response.get()); | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| }  // namespace network
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,36 +19,36 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <condition_variable> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/Component.h> | ||||
| #include <mutex> | ||||
| #include <condition_variable> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace network | ||||
| 	{ | ||||
| 		/**
 | ||||
| namespace network | ||||
| { | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * \defgroup Network 网络通信 | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Network | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief HTTP客户端 | ||||
|  */ | ||||
| 		class KGE_API HttpClient | ||||
| class KGE_API HttpClient | ||||
|     : public Singleton<HttpClient> | ||||
|     , public ComponentBase | ||||
| 		{ | ||||
| { | ||||
|     friend Singleton<HttpClient>; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 发送HTTP请求
 | ||||
|     /// @param[in] request HTTP请求
 | ||||
|  | @ -79,12 +79,12 @@ namespace kiwano | |||
|     /// @brief 获取SSL证书地址
 | ||||
|     String const& GetSSLVerification() const; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     virtual void SetupComponent() override; | ||||
| 
 | ||||
|     virtual void DestroyComponent() override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     HttpClient(); | ||||
| 
 | ||||
|     void NetworkThread(); | ||||
|  | @ -93,7 +93,7 @@ namespace kiwano | |||
| 
 | ||||
|     void DispatchResponseCallback(); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     Duration timeout_for_connect_; | ||||
|     Duration timeout_for_read_; | ||||
| 
 | ||||
|  | @ -106,40 +106,39 @@ namespace kiwano | |||
|     Queue<HttpResponsePtr> response_queue_; | ||||
| 
 | ||||
|     std::condition_variable_any sleep_condition_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 
 | ||||
| 		inline void HttpClient::SetTimeoutForConnect(Duration timeout) | ||||
| 		{ | ||||
| inline void HttpClient::SetTimeoutForConnect(Duration timeout) | ||||
| { | ||||
|     timeout_for_connect_ = timeout; | ||||
| 		} | ||||
| 
 | ||||
| 		inline Duration HttpClient::GetTimeoutForConnect() const | ||||
| 		{ | ||||
| 			return timeout_for_connect_; | ||||
| 		} | ||||
| 
 | ||||
| 		inline void HttpClient::SetTimeoutForRead(Duration timeout) | ||||
| 		{ | ||||
| 			timeout_for_read_ = timeout; | ||||
| 		} | ||||
| 
 | ||||
| 		inline Duration HttpClient::GetTimeoutForRead() const | ||||
| 		{ | ||||
| 			return timeout_for_read_; | ||||
| 		} | ||||
| 
 | ||||
| 		inline void HttpClient::SetSSLVerification(String const& root_certificate_path) | ||||
| 		{ | ||||
| 			ssl_verification_ = root_certificate_path; | ||||
| 		} | ||||
| 
 | ||||
| 		inline String const& HttpClient::GetSSLVerification() const | ||||
| 		{ | ||||
| 			return ssl_verification_; | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| inline Duration HttpClient::GetTimeoutForConnect() const | ||||
| { | ||||
|     return timeout_for_connect_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpClient::SetTimeoutForRead(Duration timeout) | ||||
| { | ||||
|     timeout_for_read_ = timeout; | ||||
| } | ||||
| 
 | ||||
| inline Duration HttpClient::GetTimeoutForRead() const | ||||
| { | ||||
|     return timeout_for_read_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpClient::SetSSLVerification(String const& root_certificate_path) | ||||
| { | ||||
|     ssl_verification_ = root_certificate_path; | ||||
| } | ||||
| 
 | ||||
| inline String const& HttpClient::GetSSLVerification() const | ||||
| { | ||||
|     return ssl_verification_; | ||||
| } | ||||
| 
 | ||||
| }  // namespace network
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,12 +23,12 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace network | ||||
| 	{ | ||||
| 		void HttpRequest::SetJsonData(Json const& json) | ||||
| 		{ | ||||
| namespace network | ||||
| { | ||||
| void HttpRequest::SetJsonData(Json const& json) | ||||
| { | ||||
|     SetHeader(L"Content-Type", L"application/json;charset=UTF-8"); | ||||
|     data_ = json.dump(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }  // namespace network
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,31 +19,30 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/core/SmartPtr.hpp> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace network | ||||
| 	{ | ||||
| 		class HttpResponse; | ||||
| namespace network | ||||
| { | ||||
| class HttpResponse; | ||||
| 
 | ||||
| 		KGE_DECLARE_SMART_PTR(HttpRequest); | ||||
| KGE_DECLARE_SMART_PTR(HttpRequest); | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Network | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief HTTP请求 | ||||
|  */ | ||||
| 		class KGE_API HttpRequest | ||||
| 			: public ObjectBase | ||||
| 		{ | ||||
| 		public: | ||||
| class KGE_API HttpRequest : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 响应回调函数
 | ||||
|     using ResponseCallback = Function<void(HttpRequest* /* request */, HttpResponse* /* response */)>; | ||||
|  | @ -115,42 +114,84 @@ namespace kiwano | |||
|     /// @brief 获取响应回调函数
 | ||||
|     ResponseCallback const& GetResponseCallback() const; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     Type                type_; | ||||
|     String              url_; | ||||
|     String              data_; | ||||
|     Map<String, String> headers_; | ||||
|     ResponseCallback    response_cb_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 		inline HttpRequest::HttpRequest()														: type_(Type::Unknown) {} | ||||
| 
 | ||||
| 		inline HttpRequest::HttpRequest(Type type)												: type_(type) {} | ||||
| 
 | ||||
| 		inline void HttpRequest::SetUrl(String const& url)										{ url_ = url; } | ||||
| 
 | ||||
| 		inline String const& HttpRequest::GetUrl() const										{ return url_; } | ||||
| 
 | ||||
| 		inline void HttpRequest::SetType(Type type)												{ type_ = type; } | ||||
| 
 | ||||
| 		inline HttpRequest::Type HttpRequest::GetType() const									{ return type_; } | ||||
| 
 | ||||
| 		inline void HttpRequest::SetData(String const& data)									{ data_ = data; } | ||||
| 
 | ||||
| 		inline String const& HttpRequest::GetData() const										{ return data_; } | ||||
| 
 | ||||
| 		inline void HttpRequest::SetHeaders(Map<String, String> const& headers)					{ headers_ = headers; } | ||||
| 
 | ||||
| 		inline void HttpRequest::SetHeader(String const& field, String const& content)			{ headers_[field] = content; } | ||||
| 
 | ||||
| 		inline Map<String, String>& HttpRequest::GetHeaders()									{ return headers_; } | ||||
| 
 | ||||
| 		inline String const& HttpRequest::GetHeader(String const& header) const					{ return headers_.at(header); } | ||||
| 
 | ||||
| 		inline void HttpRequest::SetResponseCallback(ResponseCallback const& callback)			{ response_cb_ = callback; } | ||||
| 
 | ||||
| 		inline HttpRequest::ResponseCallback const&	HttpRequest::GetResponseCallback() const	{ return response_cb_; } | ||||
| 	} | ||||
| inline HttpRequest::HttpRequest() | ||||
|     : type_(Type::Unknown) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| inline HttpRequest::HttpRequest(Type type) | ||||
|     : type_(type) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| inline void HttpRequest::SetUrl(String const& url) | ||||
| { | ||||
|     url_ = url; | ||||
| } | ||||
| 
 | ||||
| inline String const& HttpRequest::GetUrl() const | ||||
| { | ||||
|     return url_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpRequest::SetType(Type type) | ||||
| { | ||||
|     type_ = type; | ||||
| } | ||||
| 
 | ||||
| inline HttpRequest::Type HttpRequest::GetType() const | ||||
| { | ||||
|     return type_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpRequest::SetData(String const& data) | ||||
| { | ||||
|     data_ = data; | ||||
| } | ||||
| 
 | ||||
| inline String const& HttpRequest::GetData() const | ||||
| { | ||||
|     return data_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpRequest::SetHeaders(Map<String, String> const& headers) | ||||
| { | ||||
|     headers_ = headers; | ||||
| } | ||||
| 
 | ||||
| inline void HttpRequest::SetHeader(String const& field, String const& content) | ||||
| { | ||||
|     headers_[field] = content; | ||||
| } | ||||
| 
 | ||||
| inline Map<String, String>& HttpRequest::GetHeaders() | ||||
| { | ||||
|     return headers_; | ||||
| } | ||||
| 
 | ||||
| inline String const& HttpRequest::GetHeader(String const& header) const | ||||
| { | ||||
|     return headers_.at(header); | ||||
| } | ||||
| 
 | ||||
| inline void HttpRequest::SetResponseCallback(ResponseCallback const& callback) | ||||
| { | ||||
|     response_cb_ = callback; | ||||
| } | ||||
| 
 | ||||
| inline HttpRequest::ResponseCallback const& HttpRequest::GetResponseCallback() const | ||||
| { | ||||
|     return response_cb_; | ||||
| } | ||||
| }  // namespace network
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,23 +23,22 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace network | ||||
| 	{ | ||||
| 		KGE_DECLARE_SMART_PTR(HttpResponse); | ||||
| namespace network | ||||
| { | ||||
| KGE_DECLARE_SMART_PTR(HttpResponse); | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Network | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief HTTP响应 | ||||
|  */ | ||||
| 		class KGE_API HttpResponse | ||||
| 			: public ObjectBase | ||||
| 		{ | ||||
| 		public: | ||||
| class KGE_API HttpResponse : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     HttpResponse(HttpRequestPtr request); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -86,7 +85,7 @@ namespace kiwano | |||
|     /// @brief 设置错误信息
 | ||||
|     void SetError(String const& error_buffer); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     bool           succeed_; | ||||
|     long           response_code_; | ||||
|     HttpRequestPtr request_; | ||||
|  | @ -94,32 +93,70 @@ namespace kiwano | |||
|     String response_header_; | ||||
|     String response_data_; | ||||
|     String error_buffer_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 		inline HttpResponse::HttpResponse(HttpRequestPtr request)						: request_(request), succeed_(false), response_code_(0) {} | ||||
| 
 | ||||
| 		inline HttpRequestPtr	HttpResponse::GetRequest() const						{ return request_; } | ||||
| 
 | ||||
| 		inline void				HttpResponse::SetSucceed(bool succeed)					{ succeed_ = succeed; } | ||||
| 
 | ||||
| 		inline bool				HttpResponse::IsSucceed() const							{ return succeed_; } | ||||
| 
 | ||||
| 		inline void				HttpResponse::SetResponseCode(long response_code)		{ response_code_ = response_code; } | ||||
| 
 | ||||
| 		inline long				HttpResponse::GetResponseCode() const					{ return response_code_; } | ||||
| 
 | ||||
| 		inline void				HttpResponse::SetHeader(String const& response_header)	{ response_header_ = response_header; } | ||||
| 
 | ||||
| 		inline String			HttpResponse::GetHeader() const							{ return response_header_; } | ||||
| 
 | ||||
| 		inline void				HttpResponse::SetData(String const& response_data)		{ response_data_ = response_data; } | ||||
| 
 | ||||
| 		inline String const&	HttpResponse::GetData() const							{ return response_data_; } | ||||
| 
 | ||||
| 		inline void				HttpResponse::SetError(String const& error_buffer)		{ error_buffer_ = error_buffer; } | ||||
| 
 | ||||
| 		inline String const&	HttpResponse::GetError() const							{ return error_buffer_; } | ||||
| 	} | ||||
| inline HttpResponse::HttpResponse(HttpRequestPtr request) | ||||
|     : request_(request) | ||||
|     , succeed_(false) | ||||
|     , response_code_(0) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| inline HttpRequestPtr HttpResponse::GetRequest() const | ||||
| { | ||||
|     return request_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpResponse::SetSucceed(bool succeed) | ||||
| { | ||||
|     succeed_ = succeed; | ||||
| } | ||||
| 
 | ||||
| inline bool HttpResponse::IsSucceed() const | ||||
| { | ||||
|     return succeed_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpResponse::SetResponseCode(long response_code) | ||||
| { | ||||
|     response_code_ = response_code; | ||||
| } | ||||
| 
 | ||||
| inline long HttpResponse::GetResponseCode() const | ||||
| { | ||||
|     return response_code_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpResponse::SetHeader(String const& response_header) | ||||
| { | ||||
|     response_header_ = response_header; | ||||
| } | ||||
| 
 | ||||
| inline String HttpResponse::GetHeader() const | ||||
| { | ||||
|     return response_header_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpResponse::SetData(String const& response_data) | ||||
| { | ||||
|     response_data_ = response_data; | ||||
| } | ||||
| 
 | ||||
| inline String const& HttpResponse::GetData() const | ||||
| { | ||||
|     return response_data_; | ||||
| } | ||||
| 
 | ||||
| inline void HttpResponse::SetError(String const& error_buffer) | ||||
| { | ||||
|     error_buffer_ = error_buffer; | ||||
| } | ||||
| 
 | ||||
| inline String const& HttpResponse::GetError() const | ||||
| { | ||||
|     return error_buffer_; | ||||
| } | ||||
| }  // namespace network
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,6 +20,6 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <kiwano-network/HttpClient.h> | ||||
| #include <kiwano-network/HttpRequest.h> | ||||
| #include <kiwano-network/HttpResponse.hpp> | ||||
| #include <kiwano-network/HttpClient.h> | ||||
|  |  | |||
|  | @ -23,39 +23,26 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| namespace physics | ||||
| { | ||||
| 
 | ||||
| 		Body::Body() | ||||
| Body::Body() | ||||
|     : body_(nullptr) | ||||
|     , actor_(nullptr) | ||||
|     , world_(nullptr) | ||||
|     , category_bits_(0x0001) | ||||
|     , mask_bits_(0xFFFF) | ||||
|     , group_index_(0) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Body::Body(b2Body* body, Actor* actor) | ||||
| 			: Body() | ||||
| 		{ | ||||
| 			SetB2Body(body); | ||||
| 			SetActor(actor); | ||||
| 		} | ||||
| 
 | ||||
| 		Body::Body(World* world, Actor* actor) | ||||
| 			: Body() | ||||
| 		{ | ||||
| 			Init(world, actor); | ||||
| 		} | ||||
| 
 | ||||
| 		Body::~Body() | ||||
| 		{ | ||||
| Body::~Body() | ||||
| { | ||||
|     Destroy(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::Init(World* world, Actor* actor) | ||||
| 		{ | ||||
| bool Body::InitBody(World* world, Actor* actor) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     Destroy(); | ||||
|  | @ -64,52 +51,57 @@ namespace kiwano | |||
|     b2BodyDef def; | ||||
|     b2Body*   b2body = world->GetB2World()->CreateBody(&def); | ||||
| 
 | ||||
|     if (b2body) | ||||
|     { | ||||
|         SetB2Body(b2body); | ||||
|         SetActor(actor); | ||||
|         UpdateFromActor(); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| 		Fixture Body::AddFixture(Shape* shape, const Fixture::Param& param) | ||||
| 		{ | ||||
| Fixture Body::AddFixture(Shape* shape, const Fixture::Param& param) | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     return Fixture(this, shape, param); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Body::AddCircleShape(float radius, float density) | ||||
| 		{ | ||||
| Fixture Body::AddCircleShape(float radius, float density) | ||||
| { | ||||
|     return AddFixture(&CircleShape(radius), Fixture::Param(density)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Body::AddBoxShape(Vec2 const& size, float density) | ||||
| 		{ | ||||
| Fixture Body::AddBoxShape(Vec2 const& size, float density) | ||||
| { | ||||
|     return AddFixture(&BoxShape(size), Fixture::Param(density)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Body::AddPolygonShape(Vector<Point> const& vertexs, float density) | ||||
| 		{ | ||||
| Fixture Body::AddPolygonShape(Vector<Point> const& vertexs, float density) | ||||
| { | ||||
|     return AddFixture(&PolygonShape(vertexs), Fixture::Param(density)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Body::AddEdgeShape(Point const& p1, Point const& p2, float density) | ||||
| 		{ | ||||
| Fixture Body::AddEdgeShape(Point const& p1, Point const& p2, float density) | ||||
| { | ||||
|     return AddFixture(&EdgeShape(p1, p2), Fixture::Param(density)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Body::AddChainShape(Vector<Point> const& vertexs, bool loop, float density) | ||||
| 		{ | ||||
| Fixture Body::AddChainShape(Vector<Point> const& vertexs, bool loop, float density) | ||||
| { | ||||
|     return AddFixture(&ChainShape(vertexs, loop), Fixture::Param(density)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::RemoveFixture(Fixture const& fixture) | ||||
| 		{ | ||||
| void Body::RemoveFixture(Fixture const& fixture) | ||||
| { | ||||
|     if (fixture.GetB2Fixture()) | ||||
|     { | ||||
|         body_->DestroyFixture(fixture.GetB2Fixture()); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::SetCategoryBits(uint16_t category_bits) | ||||
| 		{ | ||||
| void Body::SetCategoryBits(uint16_t category_bits) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
| 
 | ||||
|     if (category_bits != category_bits_) | ||||
|  | @ -123,10 +115,10 @@ namespace kiwano | |||
|             fixture = fixture->GetNext(); | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::SetMaskBits(uint16_t mask_bits) | ||||
| 		{ | ||||
| void Body::SetMaskBits(uint16_t mask_bits) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
| 
 | ||||
|     if (mask_bits != mask_bits_) | ||||
|  | @ -140,10 +132,10 @@ namespace kiwano | |||
|             fixture = fixture->GetNext(); | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::SetGroupIndex(int16_t index) | ||||
| 		{ | ||||
| void Body::SetGroupIndex(int16_t index) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
| 
 | ||||
|     if (index != group_index_) | ||||
|  | @ -157,22 +149,25 @@ namespace kiwano | |||
|             fixture = fixture->GetNext(); | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::GetMassData(float* mass, Point* center, float* inertia) const | ||||
| 		{ | ||||
| void Body::GetMassData(float* mass, Point* center, float* inertia) const | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
| 
 | ||||
|     b2MassData data; | ||||
|     body_->GetMassData(&data); | ||||
| 
 | ||||
| 			if (mass) *mass = data.mass; | ||||
| 			if (center) *center = world_->World2Stage(data.center); | ||||
| 			if (inertia) *inertia = data.I; | ||||
| 		} | ||||
|     if (mass) | ||||
|         *mass = data.mass; | ||||
|     if (center) | ||||
|         *center = world_->World2Stage(data.center); | ||||
|     if (inertia) | ||||
|         *inertia = data.I; | ||||
| } | ||||
| 
 | ||||
| 		void Body::SetMassData(float mass, Point const& center, float inertia) | ||||
| 		{ | ||||
| void Body::SetMassData(float mass, Point const& center, float inertia) | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
| 
 | ||||
|     b2MassData data; | ||||
|  | @ -180,80 +175,80 @@ namespace kiwano | |||
|     data.center = world_->Stage2World(center); | ||||
|     data.I      = inertia; | ||||
|     body_->SetMassData(&data); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::ResetMassData() | ||||
| 		{ | ||||
| void Body::ResetMassData() | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->ResetMassData(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Point Body::GetBodyPosition() const | ||||
| 		{ | ||||
| Point Body::GetBodyPosition() const | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     return world_->World2Stage(body_->GetPosition()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::SetBodyTransform(Point const& pos, float angle) | ||||
| 		{ | ||||
| void Body::SetBodyTransform(Point const& pos, float angle) | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     body_->SetTransform(world_->Stage2World(pos), math::Degree2Radian(angle)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Point Body::GetLocalPoint(Point const& world) const | ||||
| 		{ | ||||
| Point Body::GetLocalPoint(Point const& world) const | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     return world_->World2Stage(body_->GetLocalPoint(world_->Stage2World(world))); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Point Body::GetWorldPoint(Point const& local) const | ||||
| 		{ | ||||
| Point Body::GetWorldPoint(Point const& local) const | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     return world_->World2Stage(body_->GetWorldPoint(world_->Stage2World(local))); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Point Body::GetLocalCenter() const | ||||
| 		{ | ||||
| Point Body::GetLocalCenter() const | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     return world_->World2Stage(body_->GetLocalCenter()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Point Body::GetWorldCenter() const | ||||
| 		{ | ||||
| Point Body::GetWorldCenter() const | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     return world_->World2Stage(body_->GetWorldCenter()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::ApplyForce(Vec2 const& force, Point const& point, bool wake) | ||||
| 		{ | ||||
| void Body::ApplyForce(Vec2 const& force, Point const& point, bool wake) | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     body_->ApplyForce(b2Vec2(force.x, force.y), world_->Stage2World(point), wake); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::ApplyForceToCenter(Vec2 const& force, bool wake) | ||||
| 		{ | ||||
| void Body::ApplyForceToCenter(Vec2 const& force, bool wake) | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     body_->ApplyForceToCenter(b2Vec2(force.x, force.y), wake); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::ApplyTorque(float torque, bool wake) | ||||
| 		{ | ||||
| void Body::ApplyTorque(float torque, bool wake) | ||||
| { | ||||
|     KGE_ASSERT(body_ && world_); | ||||
|     body_->ApplyTorque(torque, wake); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::SetB2Body(b2Body* body) | ||||
| 		{ | ||||
| void Body::SetB2Body(b2Body* body) | ||||
| { | ||||
|     body_ = body; | ||||
|     if (body_) | ||||
|     { | ||||
|         body_->SetUserData(this); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::Destroy() | ||||
| 		{ | ||||
| 			if (world_ && body_) | ||||
| void Body::Destroy() | ||||
| { | ||||
|     if (world_) | ||||
|     { | ||||
|         world_->RemoveBody(this); | ||||
|     } | ||||
|  | @ -261,10 +256,10 @@ namespace kiwano | |||
|     body_  = nullptr; | ||||
|     world_ = nullptr; | ||||
|     actor_ = nullptr; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::UpdateActor() | ||||
| 		{ | ||||
| void Body::UpdateActor() | ||||
| { | ||||
|     if (actor_ && body_) | ||||
|     { | ||||
|         if (world_) | ||||
|  | @ -277,37 +272,31 @@ namespace kiwano | |||
|         } | ||||
|         actor_->SetRotation(math::Radian2Degree(body_->GetAngle())); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Body::UpdateFromActor() | ||||
| 		{ | ||||
| void Body::UpdateFromActor() | ||||
| { | ||||
|     if (actor_ && body_) | ||||
|     { | ||||
|         if (world_) | ||||
|         { | ||||
| 					body_->SetTransform( | ||||
| 						world_->Stage2World(actor_->GetPosition()), | ||||
| 						math::Degree2Radian(actor_->GetRotation()) | ||||
| 					); | ||||
|             body_->SetTransform(world_->Stage2World(actor_->GetPosition()), math::Degree2Radian(actor_->GetRotation())); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
| 					body_->SetTransform( | ||||
| 						Stage2World(actor_->GetPosition()), | ||||
| 						math::Degree2Radian(actor_->GetRotation()) | ||||
| 					); | ||||
| 				} | ||||
|             body_->SetTransform(Stage2World(actor_->GetPosition()), math::Degree2Radian(actor_->GetRotation())); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 		void Body::UpdateFixtureFilter(b2Fixture* fixture) | ||||
| 		{ | ||||
| void Body::UpdateFixtureFilter(b2Fixture* fixture) | ||||
| { | ||||
|     b2Filter filter; | ||||
|     filter.categoryBits = category_bits_; | ||||
|     filter.maskBits     = mask_bits_; | ||||
|     filter.groupIndex   = group_index_; | ||||
|     fixture->SetFilterData(filter); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| } | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,30 +19,29 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano-physics/helper.h> | ||||
| #include <kiwano-physics/Shape.h> | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/ContactEdge.h> | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/Shape.h> | ||||
| #include <kiwano-physics/helper.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		class World; | ||||
| namespace physics | ||||
| { | ||||
| class World; | ||||
| 
 | ||||
| 		KGE_DECLARE_SMART_PTR(Body); | ||||
| KGE_DECLARE_SMART_PTR(Body); | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ÎïÌå
 | ||||
| 		class KGE_API Body | ||||
| 			: public virtual RefCounter | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 物体
 | ||||
| class KGE_API Body : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 物体类型
 | ||||
|     enum class Type | ||||
|  | @ -53,16 +52,20 @@ namespace kiwano | |||
|     }; | ||||
| 
 | ||||
|     Body(); | ||||
| 			Body(b2Body* body, Actor* actor); | ||||
| 			Body(World* world, Actor* actor); | ||||
| 			Body(World* world, ActorPtr actor); | ||||
| 
 | ||||
|     virtual ~Body(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 初始化
 | ||||
|     /// @param[in] world 物理世界
 | ||||
|     /// @param[in] actor 绑定的角色
 | ||||
| 			void Init(World* world, Actor* actor); | ||||
|     bool InitBody(World* world, ActorPtr actor); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 初始化
 | ||||
|     /// @param[in] world 物理世界
 | ||||
|     /// @param[in] actor 绑定的角色
 | ||||
|     bool InitBody(World* world, Actor* actor); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 添加夹具
 | ||||
|  | @ -298,7 +301,7 @@ namespace kiwano | |||
|     b2Body* GetB2Body() const; | ||||
|     void    SetB2Body(b2Body* body); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 销毁物体
 | ||||
|     void UpdateFixtureFilter(b2Fixture* fixture); | ||||
|  | @ -307,7 +310,7 @@ namespace kiwano | |||
|     /// @brief 销毁物体
 | ||||
|     void Destroy(); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     Actor*  actor_; | ||||
|     World*  world_; | ||||
|     b2Body* body_; | ||||
|  | @ -315,66 +318,172 @@ namespace kiwano | |||
|     uint16_t category_bits_; | ||||
|     uint16_t mask_bits_; | ||||
|     int16_t  group_index_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 		inline Body::Body(World* world, ActorPtr actor)			: Body(world, actor.get()) {} | ||||
| 
 | ||||
| 		inline FixtureList Body::GetFixtureList() const			{ KGE_ASSERT(body_); return FixtureList(Fixture(body_->GetFixtureList())); } | ||||
| 
 | ||||
| 		inline ContactEdgeList Body::GetContactList() const		{ KGE_ASSERT(body_); return ContactEdgeList(ContactEdge(body_->GetContactList())); } | ||||
| 
 | ||||
| 		inline uint16_t Body::GetCategoryBits() const			{ return category_bits_; } | ||||
| 
 | ||||
| 		inline uint16_t Body::GetMaskBits() const				{ return mask_bits_; } | ||||
| 
 | ||||
| 		inline int16_t Body::GetGroupIndex() const				{ return group_index_; } | ||||
| 
 | ||||
| 		inline float Body::GetBodyRotation() const				{ KGE_ASSERT(body_); return math::Radian2Degree(body_->GetAngle()); } | ||||
| 
 | ||||
| 		inline void Body::SetBodyRotation(float angle)			{ SetBodyTransform(GetBodyPosition(), angle); } | ||||
| 
 | ||||
| 		inline void Body::SetBodyPosition(Point const& pos)		{ SetBodyTransform(pos, GetBodyRotation()); } | ||||
| 
 | ||||
| 		inline float Body::GetMass() const						{ KGE_ASSERT(body_); return body_->GetMass(); } | ||||
| 
 | ||||
| 		inline float Body::GetInertia() const					{ KGE_ASSERT(body_); return body_->GetInertia(); } | ||||
| 
 | ||||
| 		inline Body::Type Body::GetType() const					{ KGE_ASSERT(body_); return Type(body_->GetType()); } | ||||
| 
 | ||||
| 		inline void Body::SetType(Type type)					{ KGE_ASSERT(body_); body_->SetType(static_cast<b2BodyType>(type)); } | ||||
| 
 | ||||
| 		inline float Body::GetGravityScale() const				{ KGE_ASSERT(body_); return body_->GetGravityScale(); } | ||||
| 
 | ||||
| 		inline void Body::SetGravityScale(float scale)			{ KGE_ASSERT(body_); body_->SetGravityScale(scale); } | ||||
| 
 | ||||
| 		inline bool Body::IsIgnoreRotation() const				{ KGE_ASSERT(body_); return body_->IsFixedRotation(); } | ||||
| 
 | ||||
| 		inline void Body::SetIgnoreRotation(bool flag)			{ KGE_ASSERT(body_); body_->SetFixedRotation(flag); } | ||||
| 
 | ||||
| 		inline bool Body::IsBullet() const						{ KGE_ASSERT(body_); return body_->IsBullet(); } | ||||
| 
 | ||||
| 		inline void Body::SetBullet(bool flag)					{ KGE_ASSERT(body_); body_->SetBullet(flag); } | ||||
| 
 | ||||
| 		inline bool Body::IsAwake() const						{ KGE_ASSERT(body_); return body_->IsAwake(); } | ||||
| 
 | ||||
| 		inline void Body::SetAwake(bool flag)					{ KGE_ASSERT(body_); body_->SetAwake(flag); } | ||||
| 
 | ||||
| 		inline bool Body::IsSleepingAllowed() const				{ KGE_ASSERT(body_); return body_->IsSleepingAllowed(); } | ||||
| 
 | ||||
| 		inline void Body::SetSleepingAllowed(bool flag)			{ KGE_ASSERT(body_); body_->SetSleepingAllowed(flag); } | ||||
| 
 | ||||
| 		inline bool Body::IsActive() const						{ KGE_ASSERT(body_); return body_->IsActive(); } | ||||
| 
 | ||||
| 		inline void Body::SetActive(bool flag)					{ KGE_ASSERT(body_); body_->SetActive(flag); } | ||||
| 
 | ||||
| 		inline Actor* Body::GetActor() const					{ return actor_; } | ||||
| 
 | ||||
| 		inline void Body::SetActor(Actor* actor)				{ actor_ = actor; } | ||||
| 
 | ||||
| 		inline b2Body* Body::GetB2Body() const					{ return body_; } | ||||
| 
 | ||||
| 		inline World* Body::GetWorld() const					{ return world_; } | ||||
| 	} | ||||
| inline bool Body::InitBody(World* world, ActorPtr actor) | ||||
| { | ||||
|     return InitBody(world, actor.get()); | ||||
| } | ||||
| 
 | ||||
| inline FixtureList Body::GetFixtureList() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return FixtureList(Fixture(body_->GetFixtureList())); | ||||
| } | ||||
| 
 | ||||
| inline ContactEdgeList Body::GetContactList() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return ContactEdgeList(ContactEdge(body_->GetContactList())); | ||||
| } | ||||
| 
 | ||||
| inline uint16_t Body::GetCategoryBits() const | ||||
| { | ||||
|     return category_bits_; | ||||
| } | ||||
| 
 | ||||
| inline uint16_t Body::GetMaskBits() const | ||||
| { | ||||
|     return mask_bits_; | ||||
| } | ||||
| 
 | ||||
| inline int16_t Body::GetGroupIndex() const | ||||
| { | ||||
|     return group_index_; | ||||
| } | ||||
| 
 | ||||
| inline float Body::GetBodyRotation() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return math::Radian2Degree(body_->GetAngle()); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetBodyRotation(float angle) | ||||
| { | ||||
|     SetBodyTransform(GetBodyPosition(), angle); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetBodyPosition(Point const& pos) | ||||
| { | ||||
|     SetBodyTransform(pos, GetBodyRotation()); | ||||
| } | ||||
| 
 | ||||
| inline float Body::GetMass() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->GetMass(); | ||||
| } | ||||
| 
 | ||||
| inline float Body::GetInertia() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->GetInertia(); | ||||
| } | ||||
| 
 | ||||
| inline Body::Type Body::GetType() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return Type(body_->GetType()); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetType(Type type) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetType(static_cast<b2BodyType>(type)); | ||||
| } | ||||
| 
 | ||||
| inline float Body::GetGravityScale() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->GetGravityScale(); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetGravityScale(float scale) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetGravityScale(scale); | ||||
| } | ||||
| 
 | ||||
| inline bool Body::IsIgnoreRotation() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->IsFixedRotation(); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetIgnoreRotation(bool flag) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetFixedRotation(flag); | ||||
| } | ||||
| 
 | ||||
| inline bool Body::IsBullet() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->IsBullet(); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetBullet(bool flag) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetBullet(flag); | ||||
| } | ||||
| 
 | ||||
| inline bool Body::IsAwake() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->IsAwake(); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetAwake(bool flag) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetAwake(flag); | ||||
| } | ||||
| 
 | ||||
| inline bool Body::IsSleepingAllowed() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->IsSleepingAllowed(); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetSleepingAllowed(bool flag) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetSleepingAllowed(flag); | ||||
| } | ||||
| 
 | ||||
| inline bool Body::IsActive() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return body_->IsActive(); | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetActive(bool flag) | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     body_->SetActive(flag); | ||||
| } | ||||
| 
 | ||||
| inline Actor* Body::GetActor() const | ||||
| { | ||||
|     return actor_; | ||||
| } | ||||
| 
 | ||||
| inline void Body::SetActor(Actor* actor) | ||||
| { | ||||
|     actor_ = actor; | ||||
| } | ||||
| 
 | ||||
| inline b2Body* Body::GetB2Body() const | ||||
| { | ||||
|     return body_; | ||||
| } | ||||
| 
 | ||||
| inline World* Body::GetWorld() const | ||||
| { | ||||
|     return world_; | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,50 +18,50 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano-physics/Contact.h> | ||||
| #include <kiwano-physics/Body.h> | ||||
| #include <kiwano-physics/Contact.h> | ||||
| #include <kiwano-physics/World.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| namespace physics | ||||
| { | ||||
| 
 | ||||
| 		Contact::Contact() | ||||
| Contact::Contact() | ||||
|     : contact_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Contact::Contact(b2Contact* contact) | ||||
| Contact::Contact(b2Contact* contact) | ||||
|     : Contact() | ||||
| 		{ | ||||
| { | ||||
|     SetB2Contact(contact); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Contact::GetFixtureA() const | ||||
| 		{ | ||||
| Fixture Contact::GetFixtureA() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return Fixture(contact_->GetFixtureA()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture Contact::GetFixtureB() const | ||||
| 		{ | ||||
| Fixture Contact::GetFixtureB() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return Fixture(contact_->GetFixtureB()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Body* Contact::GetBodyA() const | ||||
| 		{ | ||||
| Body* Contact::GetBodyA() const | ||||
| { | ||||
|     return GetFixtureA().GetBody(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Body* Contact::GetBodyB() const | ||||
| 		{ | ||||
| Body* Contact::GetBodyB() const | ||||
| { | ||||
|     return GetFixtureB().GetBody(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Contact::SetTangentSpeed(float speed) | ||||
| 		{ | ||||
| void Contact::SetTangentSpeed(float speed) | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
| 
 | ||||
|     Body* body = GetFixtureA().GetBody(); | ||||
|  | @ -71,10 +71,10 @@ namespace kiwano | |||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     contact_->SetTangentSpeed(world->Stage2World(speed)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float Contact::GetTangentSpeed() const | ||||
| 		{ | ||||
| float Contact::GetTangentSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
| 
 | ||||
|     const Body* body = GetFixtureA().GetBody(); | ||||
|  | @ -84,7 +84,7 @@ namespace kiwano | |||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     return world->World2Stage(contact_->GetTangentSpeed()); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,25 +19,25 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano-physics/helper.h> | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/helper.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		class Body; | ||||
| namespace physics | ||||
| { | ||||
| class Body; | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ÎïÀí½Ó´¥
 | ||||
| 		class KGE_API Contact | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief ÎïÀí½Ó´¥
 | ||||
| class KGE_API Contact | ||||
| { | ||||
| public: | ||||
|     Contact(); | ||||
|     Contact(b2Contact* contact); | ||||
| 
 | ||||
|  | @ -108,22 +108,19 @@ namespace kiwano | |||
|     b2Contact* GetB2Contact() const; | ||||
|     void       SetB2Contact(b2Contact* contact); | ||||
| 
 | ||||
| 			bool operator== (const Contact& rhs) const; | ||||
| 			bool operator!= (const Contact& rhs) const; | ||||
|     bool operator==(const Contact& rhs) const; | ||||
|     bool operator!=(const Contact& rhs) const; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     b2Contact* contact_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ÎïÀí½Ó´¥Áбí
 | ||||
| 		class ContactList | ||||
| 			: public List<Contact> | ||||
| 		{ | ||||
| /// \~chinese
 | ||||
| /// @brief ÎïÀí½Ó´¥Áбí
 | ||||
| class ContactList : public List<Contact> | ||||
| { | ||||
|     template <typename _Ty> | ||||
| 			class IteratorImpl | ||||
| 				: public std::iterator<std::forward_iterator_tag, _Ty> | ||||
|     class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty> | ||||
|     { | ||||
|         using herit = std::iterator<std::forward_iterator_tag, _Ty>; | ||||
| 
 | ||||
|  | @ -156,12 +153,12 @@ namespace kiwano | |||
|             return old; | ||||
|         } | ||||
| 
 | ||||
| 				inline bool operator== (const IteratorImpl& rhs) const | ||||
|         inline bool operator==(const IteratorImpl& rhs) const | ||||
|         { | ||||
|             return elem_ == rhs.elem_; | ||||
|         } | ||||
| 
 | ||||
| 				inline bool operator!= (const IteratorImpl& rhs) const | ||||
|         inline bool operator!=(const IteratorImpl& rhs) const | ||||
|         { | ||||
|             return !operator==(rhs); | ||||
|         } | ||||
|  | @ -170,14 +167,12 @@ namespace kiwano | |||
|         _Ty elem_; | ||||
|     }; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     using value_type     = Contact; | ||||
|     using iterator       = IteratorImpl<value_type>; | ||||
|     using const_iterator = IteratorImpl<const value_type>; | ||||
| 
 | ||||
| 			inline ContactList() | ||||
| 			{ | ||||
| 			} | ||||
|     inline ContactList() {} | ||||
| 
 | ||||
|     inline ContactList(const value_type& first) | ||||
|         : first_(first) | ||||
|  | @ -224,27 +219,77 @@ namespace kiwano | |||
|         return const_iterator(nullptr); | ||||
|     } | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     value_type first_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 
 | ||||
| 		inline bool Contact::IsValid() const						{ return contact_ != nullptr;} | ||||
| 		inline bool Contact::IsTouching() const						{ KGE_ASSERT(contact_); return contact_->IsTouching(); } | ||||
| 		inline void Contact::SetEnabled(bool flag)					{ KGE_ASSERT(contact_); contact_->SetEnabled(flag); } | ||||
| 		inline bool Contact::IsEnabled() const						{ KGE_ASSERT(contact_); return contact_->IsEnabled(); } | ||||
| 		inline void Contact::SetFriction(float friction)			{ KGE_ASSERT(contact_); contact_->SetFriction(friction); } | ||||
| 		inline float Contact::GetFriction() const					{ KGE_ASSERT(contact_); return contact_->GetFriction(); } | ||||
| 		inline void Contact::ResetFriction()						{ KGE_ASSERT(contact_); contact_->ResetFriction(); } | ||||
| 		inline void Contact::SetRestitution(float restitution)		{ KGE_ASSERT(contact_); contact_->SetRestitution(restitution); } | ||||
| 		inline float Contact::GetRestitution() const				{ KGE_ASSERT(contact_); return contact_->GetRestitution(); } | ||||
| 		inline void Contact::ResetRestitution()						{ KGE_ASSERT(contact_); contact_->ResetRestitution(); } | ||||
| 		inline b2Contact* Contact::GetB2Contact() const				{ return contact_; } | ||||
| 		inline void Contact::SetB2Contact(b2Contact* contact)		{ contact_ = contact; } | ||||
| 		inline bool Contact::operator==(const Contact& rhs) const	{ return contact_ == rhs.contact_; } | ||||
| 		inline bool Contact::operator!=(const Contact& rhs) const	{ return contact_ != rhs.contact_; } | ||||
| 
 | ||||
| 	} | ||||
| inline bool Contact::IsValid() const | ||||
| { | ||||
|     return contact_ != nullptr; | ||||
| } | ||||
| inline bool Contact::IsTouching() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return contact_->IsTouching(); | ||||
| } | ||||
| inline void Contact::SetEnabled(bool flag) | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     contact_->SetEnabled(flag); | ||||
| } | ||||
| inline bool Contact::IsEnabled() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return contact_->IsEnabled(); | ||||
| } | ||||
| inline void Contact::SetFriction(float friction) | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     contact_->SetFriction(friction); | ||||
| } | ||||
| inline float Contact::GetFriction() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return contact_->GetFriction(); | ||||
| } | ||||
| inline void Contact::ResetFriction() | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     contact_->ResetFriction(); | ||||
| } | ||||
| inline void Contact::SetRestitution(float restitution) | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     contact_->SetRestitution(restitution); | ||||
| } | ||||
| inline float Contact::GetRestitution() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return contact_->GetRestitution(); | ||||
| } | ||||
| inline void Contact::ResetRestitution() | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     contact_->ResetRestitution(); | ||||
| } | ||||
| inline b2Contact* Contact::GetB2Contact() const | ||||
| { | ||||
|     return contact_; | ||||
| } | ||||
| inline void Contact::SetB2Contact(b2Contact* contact) | ||||
| { | ||||
|     contact_ = contact; | ||||
| } | ||||
| inline bool Contact::operator==(const Contact& rhs) const | ||||
| { | ||||
|     return contact_ == rhs.contact_; | ||||
| } | ||||
| inline bool Contact::operator!=(const Contact& rhs) const | ||||
| { | ||||
|     return contact_ != rhs.contact_; | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -22,19 +22,19 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| namespace physics | ||||
| { | ||||
| 
 | ||||
| 		ContactEdge::ContactEdge() | ||||
| ContactEdge::ContactEdge() | ||||
|     : edge_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		ContactEdge::ContactEdge(b2ContactEdge* edge) | ||||
| 			: ContactEdge() | ||||
| 		{ | ||||
| 			SetB2ContactEdge(edge); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| ContactEdge::ContactEdge(b2ContactEdge* edge) | ||||
|     : ContactEdge() | ||||
| { | ||||
|     SetB2ContactEdge(edge); | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,18 +23,18 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		/**
 | ||||
| namespace physics | ||||
| { | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ½Ó´¥±ß
 | ||||
| 		class KGE_API ContactEdge | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief ½Ó´¥±ß
 | ||||
| class KGE_API ContactEdge | ||||
| { | ||||
| public: | ||||
|     ContactEdge(); | ||||
|     ContactEdge(b2ContactEdge* edge); | ||||
| 
 | ||||
|  | @ -53,21 +53,19 @@ namespace kiwano | |||
|     b2ContactEdge* GetB2ContactEdge() const; | ||||
|     void           SetB2ContactEdge(b2ContactEdge* edge); | ||||
| 
 | ||||
| 			bool operator== (const ContactEdge& rhs) const; | ||||
| 			bool operator!= (const ContactEdge& rhs) const; | ||||
|     bool operator==(const ContactEdge& rhs) const; | ||||
|     bool operator!=(const ContactEdge& rhs) const; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     b2ContactEdge* edge_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ÎïÀí½Ó´¥±ßÁбí
 | ||||
| 		class ContactEdgeList | ||||
| 		{ | ||||
| /// \~chinese
 | ||||
| /// @brief ÎïÀí½Ó´¥±ßÁбí
 | ||||
| class ContactEdgeList | ||||
| { | ||||
|     template <typename _Ty> | ||||
| 			class IteratorImpl | ||||
| 				: public std::iterator<std::forward_iterator_tag, _Ty> | ||||
|     class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty> | ||||
|     { | ||||
|         using herit = std::iterator<std::forward_iterator_tag, _Ty>; | ||||
| 
 | ||||
|  | @ -100,12 +98,12 @@ namespace kiwano | |||
|             return old; | ||||
|         } | ||||
| 
 | ||||
| 				inline bool operator== (const IteratorImpl& rhs) const | ||||
|         inline bool operator==(const IteratorImpl& rhs) const | ||||
|         { | ||||
|             return elem_ == rhs.elem_; | ||||
|         } | ||||
| 
 | ||||
| 				inline bool operator!= (const IteratorImpl& rhs) const | ||||
|         inline bool operator!=(const IteratorImpl& rhs) const | ||||
|         { | ||||
|             return !operator==(rhs); | ||||
|         } | ||||
|  | @ -114,14 +112,12 @@ namespace kiwano | |||
|         _Ty elem_; | ||||
|     }; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     using value_type     = ContactEdge; | ||||
|     using iterator       = IteratorImpl<value_type>; | ||||
|     using const_iterator = IteratorImpl<const value_type>; | ||||
| 
 | ||||
| 			inline ContactEdgeList() | ||||
| 			{ | ||||
| 			} | ||||
|     inline ContactEdgeList() {} | ||||
| 
 | ||||
|     inline ContactEdgeList(const value_type& first) | ||||
|         : first_(first) | ||||
|  | @ -168,19 +164,42 @@ namespace kiwano | |||
|         return const_iterator(nullptr); | ||||
|     } | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     value_type first_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 		inline bool ContactEdge::IsValid() const							{ return edge_ != nullptr; } | ||||
| 		inline Body* ContactEdge::GetOtherBody() const						{ KGE_ASSERT(edge_); return static_cast<Body*>(edge_->other->GetUserData()); } | ||||
| 		inline Contact ContactEdge::GetContact() const						{ KGE_ASSERT(edge_); return Contact(edge_->contact); } | ||||
| 		inline b2ContactEdge* ContactEdge::GetB2ContactEdge() const			{ return edge_; } | ||||
| 		inline void ContactEdge::SetB2ContactEdge(b2ContactEdge* edge)		{ edge_ = edge; } | ||||
| 		inline bool ContactEdge::operator==(const ContactEdge& rhs) const	{ return edge_ == rhs.edge_; } | ||||
| 		inline bool ContactEdge::operator!=(const ContactEdge& rhs) const	{ return edge_ != rhs.edge_; } | ||||
| 
 | ||||
| 	} | ||||
| inline bool ContactEdge::IsValid() const | ||||
| { | ||||
|     return edge_ != nullptr; | ||||
| } | ||||
| inline Body* ContactEdge::GetOtherBody() const | ||||
| { | ||||
|     KGE_ASSERT(edge_); | ||||
|     return static_cast<Body*>(edge_->other->GetUserData()); | ||||
| } | ||||
| inline Contact ContactEdge::GetContact() const | ||||
| { | ||||
|     KGE_ASSERT(edge_); | ||||
|     return Contact(edge_->contact); | ||||
| } | ||||
| inline b2ContactEdge* ContactEdge::GetB2ContactEdge() const | ||||
| { | ||||
|     return edge_; | ||||
| } | ||||
| inline void ContactEdge::SetB2ContactEdge(b2ContactEdge* edge) | ||||
| { | ||||
|     edge_ = edge; | ||||
| } | ||||
| inline bool ContactEdge::operator==(const ContactEdge& rhs) const | ||||
| { | ||||
|     return edge_ == rhs.edge_; | ||||
| } | ||||
| inline bool ContactEdge::operator!=(const ContactEdge& rhs) const | ||||
| { | ||||
|     return edge_ != rhs.edge_; | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -22,29 +22,29 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		ContactBeginEvent::ContactBeginEvent() | ||||
| namespace physics | ||||
| { | ||||
| ContactBeginEvent::ContactBeginEvent() | ||||
|     : Event(KGE_EVENT(ContactBeginEvent)) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		ContactBeginEvent::ContactBeginEvent(Contact const& contact) | ||||
| ContactBeginEvent::ContactBeginEvent(Contact const& contact) | ||||
|     : ContactBeginEvent() | ||||
| 		{ | ||||
| { | ||||
|     this->contact = contact; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		ContactEndEvent::ContactEndEvent() | ||||
| ContactEndEvent::ContactEndEvent() | ||||
|     : Event(KGE_EVENT(ContactEndEvent)) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		ContactEndEvent::ContactEndEvent(Contact const& contact) | ||||
| ContactEndEvent::ContactEndEvent(Contact const& contact) | ||||
|     : ContactEndEvent() | ||||
| 		{ | ||||
| { | ||||
|     this->contact = contact; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| } | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,44 +19,45 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano-physics/Contact.h> | ||||
| #include <kiwano-physics/Body.h> | ||||
| #include <kiwano-physics/Contact.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		/**
 | ||||
| namespace physics | ||||
| { | ||||
| KGE_DECLARE_SMART_PTR(ContactBeginEvent); | ||||
| KGE_DECLARE_SMART_PTR(ContactEndEvent); | ||||
| 
 | ||||
| /**
 | ||||
|  * \addtogroup Events | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 物理接触开始事件
 | ||||
| 		class KGE_API ContactBeginEvent | ||||
| 			: public Event | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 物理接触开始事件
 | ||||
| class KGE_API ContactBeginEvent : public Event | ||||
| { | ||||
| public: | ||||
|     Contact contact;  ///< 产生的接触
 | ||||
| 
 | ||||
|     ContactBeginEvent(); | ||||
| 
 | ||||
|     ContactBeginEvent(Contact const& contact); | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 物理接触结束事件
 | ||||
| 		class KGE_API ContactEndEvent | ||||
| 			: public Event | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 物理接触结束事件
 | ||||
| class KGE_API ContactEndEvent : public Event | ||||
| { | ||||
| public: | ||||
|     Contact contact;  ///< 产生的接触
 | ||||
| 
 | ||||
|     ContactEndEvent(); | ||||
| 
 | ||||
|     ContactEndEvent(Contact const& contact); | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| 	} | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,29 +18,29 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/Body.h> | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/World.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| namespace physics | ||||
| { | ||||
| 
 | ||||
| 		Fixture::Fixture() | ||||
| Fixture::Fixture() | ||||
|     : fixture_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Fixture::Fixture(b2Fixture* fixture) | ||||
| Fixture::Fixture(b2Fixture* fixture) | ||||
|     : Fixture() | ||||
| 		{ | ||||
| { | ||||
|     SetB2Fixture(fixture); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Fixture::Fixture(Body* body, Shape* shape, const Param& param) | ||||
| Fixture::Fixture(Body* body, Shape* shape, const Param& param) | ||||
|     : Fixture() | ||||
| 		{ | ||||
| { | ||||
|     KGE_ASSERT(body); | ||||
| 
 | ||||
|     if (shape) | ||||
|  | @ -56,22 +56,22 @@ namespace kiwano | |||
|         auto fixture   = b2body->CreateFixture(&fd); | ||||
|         SetB2Fixture(fixture); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Body* Fixture::GetBody() const | ||||
| 		{ | ||||
| Body* Fixture::GetBody() const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return static_cast<Body*>(fixture_->GetBody()->GetUserData()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Shape Fixture::GetShape() const | ||||
| 		{ | ||||
| Shape Fixture::GetShape() const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return Shape(fixture_->GetShape()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Fixture::GetMassData(float* mass, Point* center, float* inertia) const | ||||
| 		{ | ||||
| void Fixture::GetMassData(float* mass, Point* center, float* inertia) const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
| 
 | ||||
|     const Body* body = GetBody(); | ||||
|  | @ -83,13 +83,16 @@ namespace kiwano | |||
|     b2MassData data; | ||||
|     fixture_->GetMassData(&data); | ||||
| 
 | ||||
| 			if (mass) *mass = data.mass; | ||||
| 			if (center) *center = world->World2Stage(data.center); | ||||
| 			if (inertia) *inertia = data.I; | ||||
| 		} | ||||
|     if (mass) | ||||
|         *mass = data.mass; | ||||
|     if (center) | ||||
|         *center = world->World2Stage(data.center); | ||||
|     if (inertia) | ||||
|         *inertia = data.I; | ||||
| } | ||||
| 
 | ||||
| 		bool Fixture::TestPoint(const Point& p) const | ||||
| 		{ | ||||
| bool Fixture::TestPoint(const Point& p) const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
| 
 | ||||
|     const Body* body = GetBody(); | ||||
|  | @ -99,7 +102,7 @@ namespace kiwano | |||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     return fixture_->TestPoint(world->Stage2World(p)); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,25 +19,25 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano-physics/helper.h> | ||||
| #include <kiwano-physics/Shape.h> | ||||
| #include <kiwano-physics/helper.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		class Body; | ||||
| namespace physics | ||||
| { | ||||
| class Body; | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ÎïÀí¼Ð¾ß
 | ||||
| 		class Fixture | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief ÎïÀí¼Ð¾ß
 | ||||
| class Fixture | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief ¼Ð¾ß²ÎÊý
 | ||||
|     struct Param | ||||
|  | @ -54,7 +54,8 @@ namespace kiwano | |||
|             , friction(friction) | ||||
|             , restitution(restitution) | ||||
|             , is_sensor(is_sensor) | ||||
| 				{} | ||||
|         { | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     Fixture(); | ||||
|  | @ -117,21 +118,19 @@ namespace kiwano | |||
|     b2Fixture* GetB2Fixture() const; | ||||
|     void       SetB2Fixture(b2Fixture* fixture); | ||||
| 
 | ||||
| 			bool operator== (const Fixture& rhs) const; | ||||
| 			bool operator!= (const Fixture& rhs) const; | ||||
|     bool operator==(const Fixture& rhs) const; | ||||
|     bool operator!=(const Fixture& rhs) const; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     b2Fixture* fixture_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief ÎïÀí¼Ð¾ßÁбí
 | ||||
| 		class FixtureList | ||||
| 			: public List<Fixture> | ||||
| 		{ | ||||
| /// \~chinese
 | ||||
| /// @brief ÎïÀí¼Ð¾ßÁбí
 | ||||
| class FixtureList : public List<Fixture> | ||||
| { | ||||
|     template <typename _Ty> | ||||
| 			class IteratorImpl | ||||
| 				: public std::iterator<std::forward_iterator_tag, _Ty> | ||||
|     class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty> | ||||
|     { | ||||
|         using herit = std::iterator<std::forward_iterator_tag, _Ty>; | ||||
| 
 | ||||
|  | @ -164,12 +163,12 @@ namespace kiwano | |||
|             return old; | ||||
|         } | ||||
| 
 | ||||
| 				inline bool operator== (const IteratorImpl& rhs) const | ||||
|         inline bool operator==(const IteratorImpl& rhs) const | ||||
|         { | ||||
|             return elem_ == rhs.elem_; | ||||
|         } | ||||
| 
 | ||||
| 				inline bool operator!= (const IteratorImpl& rhs) const | ||||
|         inline bool operator!=(const IteratorImpl& rhs) const | ||||
|         { | ||||
|             return !operator==(rhs); | ||||
|         } | ||||
|  | @ -178,14 +177,12 @@ namespace kiwano | |||
|         _Ty elem_; | ||||
|     }; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     using value_type     = Fixture; | ||||
|     using iterator       = IteratorImpl<value_type>; | ||||
|     using const_iterator = IteratorImpl<const value_type>; | ||||
| 
 | ||||
| 			inline FixtureList() | ||||
| 			{ | ||||
| 			} | ||||
|     inline FixtureList() {} | ||||
| 
 | ||||
|     inline FixtureList(const value_type& first) | ||||
|         : first_(first) | ||||
|  | @ -232,24 +229,71 @@ namespace kiwano | |||
|         return const_iterator(nullptr); | ||||
|     } | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     value_type first_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 		inline bool Fixture::IsSensor() const						{ KGE_ASSERT(fixture_); return fixture_->IsSensor(); } | ||||
| 		inline void Fixture::SetSensor(bool sensor)					{ KGE_ASSERT(fixture_); fixture_->SetSensor(sensor); } | ||||
| 		inline float Fixture::GetDensity() const					{ KGE_ASSERT(fixture_); return fixture_->GetDensity(); } | ||||
| 		inline void Fixture::SetDensity(float density)				{ KGE_ASSERT(fixture_); fixture_->SetDensity(density); } | ||||
| 		inline float Fixture::GetFriction() const					{ KGE_ASSERT(fixture_); return fixture_->GetFriction(); } | ||||
| 		inline void Fixture::SetFriction(float friction)			{ KGE_ASSERT(fixture_); fixture_->SetFriction(friction); } | ||||
| 		inline float Fixture::GetRestitution() const				{ KGE_ASSERT(fixture_); return fixture_->GetRestitution(); } | ||||
| 		inline void Fixture::SetRestitution(float restitution)		{ KGE_ASSERT(fixture_); fixture_->SetRestitution(restitution); } | ||||
| 		inline bool Fixture::IsValid() const						{ return fixture_ != nullptr; } | ||||
| 		inline b2Fixture* Fixture::GetB2Fixture() const				{ return fixture_; } | ||||
| 		inline void Fixture::SetB2Fixture(b2Fixture* fixture)		{ fixture_ = fixture; } | ||||
| 		inline bool Fixture::operator==(const Fixture& rhs) const	{ return fixture_ == rhs.fixture_; } | ||||
| 		inline bool Fixture::operator!=(const Fixture& rhs) const	{ return fixture_ != rhs.fixture_; } | ||||
| 	} | ||||
| inline bool Fixture::IsSensor() const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return fixture_->IsSensor(); | ||||
| } | ||||
| inline void Fixture::SetSensor(bool sensor) | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     fixture_->SetSensor(sensor); | ||||
| } | ||||
| inline float Fixture::GetDensity() const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return fixture_->GetDensity(); | ||||
| } | ||||
| inline void Fixture::SetDensity(float density) | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     fixture_->SetDensity(density); | ||||
| } | ||||
| inline float Fixture::GetFriction() const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return fixture_->GetFriction(); | ||||
| } | ||||
| inline void Fixture::SetFriction(float friction) | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     fixture_->SetFriction(friction); | ||||
| } | ||||
| inline float Fixture::GetRestitution() const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return fixture_->GetRestitution(); | ||||
| } | ||||
| inline void Fixture::SetRestitution(float restitution) | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     fixture_->SetRestitution(restitution); | ||||
| } | ||||
| inline bool Fixture::IsValid() const | ||||
| { | ||||
|     return fixture_ != nullptr; | ||||
| } | ||||
| inline b2Fixture* Fixture::GetB2Fixture() const | ||||
| { | ||||
|     return fixture_; | ||||
| } | ||||
| inline void Fixture::SetB2Fixture(b2Fixture* fixture) | ||||
| { | ||||
|     fixture_ = fixture; | ||||
| } | ||||
| inline bool Fixture::operator==(const Fixture& rhs) const | ||||
| { | ||||
|     return fixture_ == rhs.fixture_; | ||||
| } | ||||
| inline bool Fixture::operator!=(const Fixture& rhs) const | ||||
| { | ||||
|     return fixture_ != rhs.fixture_; | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,41 +23,30 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		//
 | ||||
| 		// Joint
 | ||||
| 		//
 | ||||
| namespace physics | ||||
| { | ||||
| //
 | ||||
| // Joint
 | ||||
| //
 | ||||
| 
 | ||||
| 		Joint::Joint() | ||||
| Joint::Joint() | ||||
|     : joint_(nullptr) | ||||
|     , world_(nullptr) | ||||
|     , type_(Type::Unknown) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Joint::Joint(b2Joint* joint) | ||||
| 			: Joint() | ||||
| 		{ | ||||
| 			SetB2Joint(joint); | ||||
| 		} | ||||
| Joint::~Joint() | ||||
| { | ||||
|     Destroy(); | ||||
| } | ||||
| 
 | ||||
| 		Joint::Joint(World* world, b2JointDef* joint_def) | ||||
| 			: Joint() | ||||
| 		{ | ||||
| 			Init(world, joint_def); | ||||
| 		} | ||||
| bool Joint::InitJoint(World* world, b2JointDef* joint_def) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
| 		Joint::~Joint() | ||||
| 		{ | ||||
| 			if (world_) | ||||
| 			{ | ||||
| 				world_->RemoveJoint(this); | ||||
| 			} | ||||
| 		} | ||||
|     Destroy(); | ||||
| 
 | ||||
| 		void Joint::Init(World* world, b2JointDef* joint_def) | ||||
| 		{ | ||||
|     world_ = world; | ||||
|     if (world_) | ||||
|     { | ||||
|  | @ -65,97 +54,94 @@ namespace kiwano | |||
| 
 | ||||
|         b2Joint* joint = world_->GetB2World()->CreateJoint(joint_def); | ||||
|         SetB2Joint(joint); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		BodyPtr Joint::GetBodyA() const | ||||
| 		{ | ||||
|         return joint != nullptr; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| BodyPtr Joint::GetBodyA() const | ||||
| { | ||||
|     KGE_ASSERT(joint_); | ||||
| 
 | ||||
|     b2Body* body = joint_->GetBodyA(); | ||||
|     return BodyPtr(static_cast<Body*>(body->GetUserData())); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		BodyPtr Joint::GetBodyB() const | ||||
| 		{ | ||||
| BodyPtr Joint::GetBodyB() const | ||||
| { | ||||
|     KGE_ASSERT(joint_); | ||||
| 
 | ||||
|     b2Body* body = joint_->GetBodyB(); | ||||
|     return BodyPtr(static_cast<Body*>(body->GetUserData())); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Joint::SetB2Joint(b2Joint* joint) | ||||
| 		{ | ||||
| void Joint::SetB2Joint(b2Joint* joint) | ||||
| { | ||||
|     joint_ = joint; | ||||
|     if (joint_) | ||||
|     { | ||||
|         type_ = Joint::Type(joint_->GetType()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Joint::Destroy() | ||||
| { | ||||
|     if (world_) | ||||
|     { | ||||
|         world_->RemoveJoint(this); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// DistanceJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // DistanceJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		DistanceJoint::DistanceJoint() | ||||
| DistanceJoint::DistanceJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		DistanceJoint::DistanceJoint(World* world, b2DistanceJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		DistanceJoint::DistanceJoint(World* world, DistanceJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool DistanceJoint::InitJoint(World* world, DistanceJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2DistanceJointDef def; | ||||
| 			def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor_a), world->Stage2World(param.anchor_b)); | ||||
|     def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor_a), | ||||
|                    world->Stage2World(param.anchor_b)); | ||||
|     def.frequencyHz  = param.frequency_hz; | ||||
|     def.dampingRatio = param.damping_ratio; | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2DistanceJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		void DistanceJoint::SetLength(float length) | ||||
| 		{ | ||||
| void DistanceJoint::SetLength(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetLength(GetWorld()->Stage2World(length)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float DistanceJoint::GetLength() const | ||||
| 		{ | ||||
| float DistanceJoint::GetLength() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetLength()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// FrictionJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // FrictionJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		FrictionJoint::FrictionJoint() | ||||
| FrictionJoint::FrictionJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		FrictionJoint::FrictionJoint(World* world, b2FrictionJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		FrictionJoint::FrictionJoint(World* world, FrictionJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool FrictionJoint::InitJoint(World* world, FrictionJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2FrictionJointDef def; | ||||
|  | @ -163,54 +149,47 @@ namespace kiwano | |||
|     def.maxForce  = param.max_force; | ||||
|     def.maxTorque = world->Stage2World(param.max_torque); | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		void FrictionJoint::SetMaxForce(float length) | ||||
| 		{ | ||||
| void FrictionJoint::SetMaxForce(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxForce(length); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float FrictionJoint::GetMaxForce() const | ||||
| 		{ | ||||
| float FrictionJoint::GetMaxForce() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return raw_joint_->GetMaxForce(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void FrictionJoint::SetMaxTorque(float length) | ||||
| 		{ | ||||
| void FrictionJoint::SetMaxTorque(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetMaxTorque(GetWorld()->Stage2World(length)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float FrictionJoint::GetMaxTorque() const | ||||
| 		{ | ||||
| float FrictionJoint::GetMaxTorque() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetMaxTorque()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// GearJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // GearJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		GearJoint::GearJoint() | ||||
| GearJoint::GearJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		GearJoint::GearJoint(World* world, b2GearJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		GearJoint::GearJoint(World* world, GearJoint::Param param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool GearJoint::InitJoint(World* world, GearJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.joint_a && param.joint_b); | ||||
| 
 | ||||
|     b2GearJointDef def; | ||||
|  | @ -218,42 +197,35 @@ namespace kiwano | |||
|     def.joint2 = param.joint_b->GetB2Joint(); | ||||
|     def.ratio  = param.ratio; | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2GearJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		void GearJoint::SetRatio(float ratio) | ||||
| 		{ | ||||
| void GearJoint::SetRatio(float ratio) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetRatio(ratio); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float GearJoint::GetRatio() const | ||||
| 		{ | ||||
| float GearJoint::GetRatio() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return raw_joint_->GetRatio(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// MotorJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // MotorJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		MotorJoint::MotorJoint() | ||||
| MotorJoint::MotorJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		MotorJoint::MotorJoint(World* world, b2MotorJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		MotorJoint::MotorJoint(World* world, MotorJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool MotorJoint::InitJoint(World* world, MotorJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2MotorJointDef def; | ||||
|  | @ -262,58 +234,52 @@ namespace kiwano | |||
|     def.maxTorque        = world->Stage2World(param.max_torque); | ||||
|     def.correctionFactor = param.correction_factor; | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2MotorJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		void MotorJoint::SetMaxForce(float length) | ||||
| 		{ | ||||
| void MotorJoint::SetMaxForce(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxForce(length); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float MotorJoint::GetMaxForce() const | ||||
| 		{ | ||||
| float MotorJoint::GetMaxForce() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return raw_joint_->GetMaxForce(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void MotorJoint::SetMaxTorque(float length) | ||||
| 		{ | ||||
| void MotorJoint::SetMaxTorque(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetMaxTorque(GetWorld()->Stage2World(length)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float MotorJoint::GetMaxTorque() const | ||||
| 		{ | ||||
| float MotorJoint::GetMaxTorque() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetMaxTorque()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// PrismaticJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // PrismaticJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		PrismaticJoint::PrismaticJoint() | ||||
| PrismaticJoint::PrismaticJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		PrismaticJoint::PrismaticJoint(World* world, b2PrismaticJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		PrismaticJoint::PrismaticJoint(World* world, PrismaticJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool PrismaticJoint::InitJoint(World* world, PrismaticJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2PrismaticJointDef def; | ||||
| 			def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), Stage2World(param.axis)); | ||||
|     def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), | ||||
|                    Stage2World(param.axis)); | ||||
|     def.enableLimit      = param.enable_limit; | ||||
|     def.lowerTranslation = world->Stage2World(param.lower_translation); | ||||
|     def.upperTranslation = world->Stage2World(param.upper_translation); | ||||
|  | @ -321,132 +287,119 @@ namespace kiwano | |||
|     def.maxMotorForce    = param.max_motor_force; | ||||
|     def.motorSpeed       = world->Stage2World(param.motor_speed); | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		float PrismaticJoint::GetJointTranslation() const | ||||
| 		{ | ||||
| float PrismaticJoint::GetJointTranslation() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetJointTranslation()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PrismaticJoint::GetJointSpeed() const | ||||
| 		{ | ||||
| float PrismaticJoint::GetJointSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetJointSpeed()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PrismaticJoint::GetLowerLimit() const | ||||
| 		{ | ||||
| float PrismaticJoint::GetLowerLimit() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetLowerLimit()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PrismaticJoint::GetUpperLimit() const | ||||
| 		{ | ||||
| float PrismaticJoint::GetUpperLimit() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetUpperLimit()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void PrismaticJoint::SetLimits(float lower, float upper) | ||||
| 		{ | ||||
| void PrismaticJoint::SetLimits(float lower, float upper) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetLimits(GetWorld()->Stage2World(lower), GetWorld()->Stage2World(upper)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// PulleyJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // PulleyJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		PulleyJoint::PulleyJoint() | ||||
| PulleyJoint::PulleyJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		PulleyJoint::PulleyJoint(World* world, b2PulleyJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		PulleyJoint::PulleyJoint(World* world, PulleyJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool PulleyJoint::InitJoint(World* world, PulleyJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2PulleyJointDef def; | ||||
| 			def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.ground_anchor_a), world->Stage2World(param.ground_anchor_b), | ||||
| 				world->Stage2World(param.anchor_a), world->Stage2World(param.anchor_b), param.ratio); | ||||
|     def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.ground_anchor_a), | ||||
|                    world->Stage2World(param.ground_anchor_b), world->Stage2World(param.anchor_a), | ||||
|                    world->Stage2World(param.anchor_b), param.ratio); | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		Point PulleyJoint::GetGroundAnchorA() const | ||||
| 		{ | ||||
| Point PulleyJoint::GetGroundAnchorA() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetGroundAnchorA()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Point PulleyJoint::GetGroundAnchorB() const | ||||
| 		{ | ||||
| Point PulleyJoint::GetGroundAnchorB() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetGroundAnchorB()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PulleyJoint::GetRatio() const | ||||
| 		{ | ||||
| float PulleyJoint::GetRatio() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return raw_joint_->GetRatio(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PulleyJoint::GetLengthA() const | ||||
| 		{ | ||||
| float PulleyJoint::GetLengthA() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetLengthA()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PulleyJoint::GetLengthB() const | ||||
| 		{ | ||||
| float PulleyJoint::GetLengthB() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetLengthB()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PulleyJoint::GetCurrentLengthA() const | ||||
| 		{ | ||||
| float PulleyJoint::GetCurrentLengthA() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetCurrentLengthA()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float PulleyJoint::GetCurrentLengthB() const | ||||
| 		{ | ||||
| float PulleyJoint::GetCurrentLengthB() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetCurrentLengthB()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// RevoluteJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // RevoluteJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		RevoluteJoint::RevoluteJoint() | ||||
| RevoluteJoint::RevoluteJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		RevoluteJoint::RevoluteJoint(World* world, b2RevoluteJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		RevoluteJoint::RevoluteJoint(World* world, RevoluteJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool RevoluteJoint::InitJoint(World* world, RevoluteJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2RevoluteJointDef def; | ||||
|  | @ -458,72 +411,65 @@ namespace kiwano | |||
|     def.maxMotorTorque = world->Stage2World(param.max_motor_torque); | ||||
|     def.motorSpeed     = math::Degree2Radian(param.motor_speed); | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2RevoluteJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		float RevoluteJoint::GetJointAngle() const | ||||
| 		{ | ||||
| float RevoluteJoint::GetJointAngle() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return math::Radian2Degree(raw_joint_->GetJointAngle()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float RevoluteJoint::GetJointSpeed() const | ||||
| 		{ | ||||
| float RevoluteJoint::GetJointSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return math::Radian2Degree(raw_joint_->GetJointSpeed()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float RevoluteJoint::GetLowerLimit() const | ||||
| 		{ | ||||
| float RevoluteJoint::GetLowerLimit() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return math::Radian2Degree(raw_joint_->GetLowerLimit()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float RevoluteJoint::GetUpperLimit() const | ||||
| 		{ | ||||
| float RevoluteJoint::GetUpperLimit() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return math::Radian2Degree(raw_joint_->GetUpperLimit()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void RevoluteJoint::SetLimits(float lower, float upper) | ||||
| 		{ | ||||
| void RevoluteJoint::SetLimits(float lower, float upper) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetLimits(math::Degree2Radian(lower), math::Degree2Radian(upper)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void RevoluteJoint::SetMaxMotorTorque(float torque) | ||||
| 		{ | ||||
| void RevoluteJoint::SetMaxMotorTorque(float torque) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetMaxMotorTorque(GetWorld()->Stage2World(torque)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float RevoluteJoint::GetMaxMotorTorque() const | ||||
| 		{ | ||||
| float RevoluteJoint::GetMaxMotorTorque() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetMaxMotorTorque()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// RopeJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // RopeJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		RopeJoint::RopeJoint() | ||||
| RopeJoint::RopeJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		RopeJoint::RopeJoint(World* world, b2RopeJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		RopeJoint::RopeJoint(World* world, RopeJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool RopeJoint::InitJoint(World* world, RopeJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2RopeJointDef def; | ||||
|  | @ -533,42 +479,35 @@ namespace kiwano | |||
|     def.localAnchorB = world->Stage2World(param.local_anchor_b); | ||||
|     def.maxLength    = world->Stage2World(param.max_length); | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		void RopeJoint::SetMaxLength(float length) | ||||
| 		{ | ||||
| void RopeJoint::SetMaxLength(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetMaxLength(GetWorld()->Stage2World(length)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float RopeJoint::GetMaxLength() const | ||||
| 		{ | ||||
| float RopeJoint::GetMaxLength() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetMaxLength()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// WeldJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // WeldJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		WeldJoint::WeldJoint() | ||||
| WeldJoint::WeldJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		WeldJoint::WeldJoint(World* world, b2WeldJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		WeldJoint::WeldJoint(World* world, WeldJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool WeldJoint::InitJoint(World* world, WeldJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2WeldJointDef def; | ||||
|  | @ -576,89 +515,75 @@ namespace kiwano | |||
|     def.frequencyHz  = param.frequency_hz; | ||||
|     def.dampingRatio = param.damping_ratio; | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2WeldJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| //
 | ||||
| // WheelJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		//
 | ||||
| 		// WheelJoint
 | ||||
| 		//
 | ||||
| 
 | ||||
| 		WheelJoint::WheelJoint() | ||||
| WheelJoint::WheelJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		WheelJoint::WheelJoint(World* world, b2WheelJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		WheelJoint::WheelJoint(World* world, WheelJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool WheelJoint::InitJoint(World* world, WheelJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2WheelJointDef def; | ||||
| 			def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), Stage2World(param.axis)); | ||||
|     def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), | ||||
|                    Stage2World(param.axis)); | ||||
|     def.enableMotor    = param.enable_motor; | ||||
|     def.maxMotorTorque = world->Stage2World(param.max_motor_torque); | ||||
|     def.motorSpeed     = world->Stage2World(param.motor_speed); | ||||
|     def.frequencyHz    = param.frequency_hz; | ||||
|     def.dampingRatio   = param.damping_ratio; | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2WheelJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		float WheelJoint::GetJointTranslation() const | ||||
| 		{ | ||||
| float WheelJoint::GetJointTranslation() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetJointTranslation()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float WheelJoint::GetJointLinearSpeed() const | ||||
| 		{ | ||||
| float WheelJoint::GetJointLinearSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetJointLinearSpeed()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void WheelJoint::SetMaxMotorTorque(float torque) | ||||
| 		{ | ||||
| void WheelJoint::SetMaxMotorTorque(float torque) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     raw_joint_->SetMaxMotorTorque(GetWorld()->Stage2World(torque)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float WheelJoint::GetMaxMotorTorque() const | ||||
| 		{ | ||||
| float WheelJoint::GetMaxMotorTorque() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_ && GetWorld()); | ||||
|     return GetWorld()->World2Stage(raw_joint_->GetMaxMotorTorque()); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// MouseJoint
 | ||||
| 		//
 | ||||
| //
 | ||||
| // MouseJoint
 | ||||
| //
 | ||||
| 
 | ||||
| 		MouseJoint::MouseJoint() | ||||
| MouseJoint::MouseJoint() | ||||
|     : Joint() | ||||
|     , raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		MouseJoint::MouseJoint(World* world, b2MouseJointDef* def) | ||||
| 			: Joint(world, def) | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		MouseJoint::MouseJoint(World* world, MouseJoint::Param const& param) | ||||
| 			: Joint() | ||||
| 			, raw_joint_(nullptr) | ||||
| 		{ | ||||
| bool MouseJoint::InitJoint(World* world, MouseJoint::Param const& param) | ||||
| { | ||||
|     KGE_ASSERT(param.body_a && param.body_b); | ||||
| 
 | ||||
|     b2MouseJointDef def; | ||||
|  | @ -669,21 +594,22 @@ namespace kiwano | |||
|     def.frequencyHz  = param.frequency_hz; | ||||
|     def.dampingRatio = param.damping_ratio; | ||||
| 
 | ||||
| 			Init(world, &def); | ||||
|     Joint::InitJoint(world, &def); | ||||
|     raw_joint_ = static_cast<b2MouseJoint*>(GetB2Joint()); | ||||
| 		} | ||||
|     return raw_joint_ != nullptr; | ||||
| } | ||||
| 
 | ||||
| 		void MouseJoint::SetMaxForce(float length) | ||||
| 		{ | ||||
| void MouseJoint::SetMaxForce(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxForce(length); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		float MouseJoint::GetMaxForce() const | ||||
| 		{ | ||||
| float MouseJoint::GetMaxForce() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return raw_joint_->GetMaxForce(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| } | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -23,114 +23,114 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		Shape::Shape() | ||||
| namespace physics | ||||
| { | ||||
| Shape::Shape() | ||||
|     : shape_(nullptr) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		Shape::Shape(b2Shape* shape) | ||||
| Shape::Shape(b2Shape* shape) | ||||
|     : shape_(shape) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		b2Shape* Shape::GetB2Shape() const | ||||
| 		{ | ||||
| b2Shape* Shape::GetB2Shape() const | ||||
| { | ||||
|     return shape_; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void Shape::SetB2Shape(b2Shape* shape) | ||||
| 		{ | ||||
| void Shape::SetB2Shape(b2Shape* shape) | ||||
| { | ||||
|     shape_ = shape; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// CircleShape
 | ||||
| 		//
 | ||||
| //
 | ||||
| // CircleShape
 | ||||
| //
 | ||||
| 
 | ||||
| 		CircleShape::CircleShape() | ||||
| CircleShape::CircleShape() | ||||
|     : Shape(&circle_) | ||||
|     , circle_() | ||||
|     , radius_(0.f) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		CircleShape::CircleShape(float radius, Point const& offset) | ||||
| CircleShape::CircleShape(float radius, Point const& offset) | ||||
|     : CircleShape() | ||||
| 		{ | ||||
| { | ||||
|     Set(radius, offset); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void CircleShape::Set(float radius, Point const& offset) | ||||
| 		{ | ||||
| void CircleShape::Set(float radius, Point const& offset) | ||||
| { | ||||
|     radius_ = radius; | ||||
|     offset_ = offset; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void CircleShape::FitWorld(World* world) | ||||
| 		{ | ||||
| void CircleShape::FitWorld(World* world) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
|     circle_.m_radius = world->Stage2World(radius_); | ||||
|     circle_.m_p      = world->Stage2World(offset_); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// BoxShape
 | ||||
| 		//
 | ||||
| //
 | ||||
| // BoxShape
 | ||||
| //
 | ||||
| 
 | ||||
| 		BoxShape::BoxShape() | ||||
| BoxShape::BoxShape() | ||||
|     : Shape(&polygon_) | ||||
|     , polygon_() | ||||
|     , rotation_(0.f) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		BoxShape::BoxShape(Vec2 const& size, Point const& offset, float rotation) | ||||
| BoxShape::BoxShape(Vec2 const& size, Point const& offset, float rotation) | ||||
|     : BoxShape() | ||||
| 		{ | ||||
| { | ||||
|     Set(size, offset, rotation); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void BoxShape::Set(Vec2 const& size, Point const& offset, float rotation) | ||||
| 		{ | ||||
| void BoxShape::Set(Vec2 const& size, Point const& offset, float rotation) | ||||
| { | ||||
|     box_size_ = size; | ||||
|     offset_   = offset; | ||||
|     rotation_ = rotation; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void BoxShape::FitWorld(World* world) | ||||
| 		{ | ||||
| void BoxShape::FitWorld(World* world) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     b2Vec2 box    = world->Stage2World(box_size_); | ||||
|     b2Vec2 offset = world->Stage2World(offset_); | ||||
|     polygon_.SetAsBox(box.x / 2, box.y / 2, offset, rotation_); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// PolygonShape
 | ||||
| 		//
 | ||||
| //
 | ||||
| // PolygonShape
 | ||||
| //
 | ||||
| 
 | ||||
| 		PolygonShape::PolygonShape() | ||||
| PolygonShape::PolygonShape() | ||||
|     : Shape(&polygon_) | ||||
|     , polygon_() | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		PolygonShape::PolygonShape(Vector<Point> const& vertexs) | ||||
| PolygonShape::PolygonShape(Vector<Point> const& vertexs) | ||||
|     : PolygonShape() | ||||
| 		{ | ||||
| { | ||||
|     Set(vertexs); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void PolygonShape::Set(Vector<Point> const& vertexs) | ||||
| 		{ | ||||
| void PolygonShape::Set(Vector<Point> const& vertexs) | ||||
| { | ||||
|     vertexs_ = vertexs; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void PolygonShape::FitWorld(World* world) | ||||
| 		{ | ||||
| void PolygonShape::FitWorld(World* world) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     Vector<b2Vec2> b2vertexs; | ||||
|  | @ -141,64 +141,64 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     polygon_.Set(&b2vertexs[0], static_cast<int32>(b2vertexs.size())); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// EdgeShape
 | ||||
| 		//
 | ||||
| //
 | ||||
| // EdgeShape
 | ||||
| //
 | ||||
| 
 | ||||
| 		EdgeShape::EdgeShape() | ||||
| EdgeShape::EdgeShape() | ||||
|     : Shape(&edge_) | ||||
|     , edge_() | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		EdgeShape::EdgeShape(Point const& p1, Point const& p2) | ||||
| EdgeShape::EdgeShape(Point const& p1, Point const& p2) | ||||
|     : EdgeShape() | ||||
| 		{ | ||||
| { | ||||
|     Set(p1, p2); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void EdgeShape::Set(Point const& p1, Point const& p2) | ||||
| 		{ | ||||
| void EdgeShape::Set(Point const& p1, Point const& p2) | ||||
| { | ||||
|     p_[0] = p1; | ||||
|     p_[1] = p2; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void EdgeShape::FitWorld(World* world) | ||||
| 		{ | ||||
| void EdgeShape::FitWorld(World* world) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     b2Vec2 p1 = world->Stage2World(p_[0]); | ||||
|     b2Vec2 p2 = world->Stage2World(p_[1]); | ||||
|     edge_.Set(p1, p2); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		//
 | ||||
| 		// ChainShape
 | ||||
| 		//
 | ||||
| //
 | ||||
| // ChainShape
 | ||||
| //
 | ||||
| 
 | ||||
| 		ChainShape::ChainShape() | ||||
| ChainShape::ChainShape() | ||||
|     : Shape(&chain_) | ||||
|     , chain_() | ||||
|     , loop_(false) | ||||
| 		{ | ||||
| 		} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 		ChainShape::ChainShape(Vector<Point> const& vertexs, bool loop) | ||||
| ChainShape::ChainShape(Vector<Point> const& vertexs, bool loop) | ||||
|     : ChainShape() | ||||
| 		{ | ||||
| { | ||||
|     Set(vertexs, loop); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ChainShape::Set(Vector<Point> const& vertexs, bool loop) | ||||
| 		{ | ||||
| void ChainShape::Set(Vector<Point> const& vertexs, bool loop) | ||||
| { | ||||
|     vertexs_ = vertexs; | ||||
|     loop_    = loop; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void ChainShape::FitWorld(World* world) | ||||
| 		{ | ||||
| void ChainShape::FitWorld(World* world) | ||||
| { | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     Vector<b2Vec2> b2vertexs; | ||||
|  | @ -216,7 +216,7 @@ namespace kiwano | |||
|     { | ||||
|         chain_.CreateChain(&b2vertexs[0], static_cast<int32>(b2vertexs.size())); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| } | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,140 +23,135 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		class World; | ||||
| 		class Fixture; | ||||
| namespace physics | ||||
| { | ||||
| class World; | ||||
| class Fixture; | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 形状基类
 | ||||
| 		class KGE_API Shape | ||||
| 		{ | ||||
| /// \~chinese
 | ||||
| /// @brief 形状基类
 | ||||
| class KGE_API Shape | ||||
| { | ||||
|     friend class Fixture; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     Shape(); | ||||
|     Shape(b2Shape* shape); | ||||
| 
 | ||||
|     b2Shape* GetB2Shape() const; | ||||
|     void     SetB2Shape(b2Shape* shape); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     virtual void FitWorld(World* world) {} | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     b2Shape* shape_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 圆形形状
 | ||||
| 		class KGE_API CircleShape | ||||
| 			: public Shape | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 圆形形状
 | ||||
| class KGE_API CircleShape : public Shape | ||||
| { | ||||
| public: | ||||
|     CircleShape(); | ||||
| 
 | ||||
|     CircleShape(float radius, Point const& offset = Point()); | ||||
| 
 | ||||
|     void Set(float radius, Point const& offset = Point()); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     void FitWorld(World* world) override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     float         radius_; | ||||
|     Point         offset_; | ||||
|     b2CircleShape circle_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 盒子形状
 | ||||
| 		class KGE_API BoxShape | ||||
| 			: public Shape | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 盒子形状
 | ||||
| class KGE_API BoxShape : public Shape | ||||
| { | ||||
| public: | ||||
|     BoxShape(); | ||||
| 
 | ||||
|     BoxShape(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f); | ||||
| 
 | ||||
|     void Set(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     void FitWorld(World* world) override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     float          rotation_; | ||||
|     Vec2           box_size_; | ||||
|     Point          offset_; | ||||
|     b2PolygonShape polygon_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 多边形形状
 | ||||
| 		class KGE_API PolygonShape | ||||
| 			: public Shape | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 多边形形状
 | ||||
| class KGE_API PolygonShape : public Shape | ||||
| { | ||||
| public: | ||||
|     PolygonShape(); | ||||
| 
 | ||||
|     PolygonShape(Vector<Point> const& vertexs); | ||||
| 
 | ||||
|     void Set(Vector<Point> const& vertexs); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     void FitWorld(World* world) override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     Vector<Point>  vertexs_; | ||||
|     b2PolygonShape polygon_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 线段形状, 用于表示一条边
 | ||||
| 		class KGE_API EdgeShape | ||||
| 			: public Shape | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 线段形状, 用于表示一条边
 | ||||
| class KGE_API EdgeShape : public Shape | ||||
| { | ||||
| public: | ||||
|     EdgeShape(); | ||||
| 
 | ||||
|     EdgeShape(Point const& p1, Point const& p2); | ||||
| 
 | ||||
|     void Set(Point const& p1, Point const& p2); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     void FitWorld(World* world) override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     Point       p_[2]; | ||||
|     b2EdgeShape edge_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 链式形状
 | ||||
| 		class KGE_API ChainShape | ||||
| 			: public Shape | ||||
| 		{ | ||||
| 		public: | ||||
| /// \~chinese
 | ||||
| /// @brief 链式形状
 | ||||
| class KGE_API ChainShape : public Shape | ||||
| { | ||||
| public: | ||||
|     ChainShape(); | ||||
| 
 | ||||
|     ChainShape(Vector<Point> const& vertexs, bool loop = false); | ||||
| 
 | ||||
|     void Set(Vector<Point> const& vertexs, bool loop = false); | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     void FitWorld(World* world) override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     bool          loop_; | ||||
|     Vector<Point> vertexs_; | ||||
|     b2ChainShape  chain_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| 		/** @} */ | ||||
| 	} | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,22 +19,23 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include "World.h" | ||||
| 
 | ||||
| #include <kiwano-physics/ContactEvent.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		namespace | ||||
| 		{ | ||||
| 			const float default_global_scale = 100.f;		// 100 pixels per meters
 | ||||
| 		} | ||||
| namespace physics | ||||
| { | ||||
| namespace | ||||
| { | ||||
| const float default_global_scale = 100.f;  // 100 pixels per meters
 | ||||
| } | ||||
| 
 | ||||
| 		class World::DestructionListener : public b2DestructionListener | ||||
| 		{ | ||||
| class World::DestructionListener : public b2DestructionListener | ||||
| { | ||||
|     World* world_; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     DestructionListener(World* world) | ||||
|         : world_(world) | ||||
|     { | ||||
|  | @ -48,18 +49,14 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| 			void SayGoodbye(b2Fixture* fixture) override | ||||
| 			{ | ||||
|     void SayGoodbye(b2Fixture* fixture) override {} | ||||
| }; | ||||
| 
 | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		class World::ContactListener | ||||
| 			: public b2ContactListener | ||||
| 		{ | ||||
| class World::ContactListener : public b2ContactListener | ||||
| { | ||||
|     World* world_; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     ContactListener(World* world) | ||||
|         : world_(world) | ||||
|     { | ||||
|  | @ -67,21 +64,29 @@ namespace kiwano | |||
| 
 | ||||
|     void BeginContact(b2Contact* contact) override | ||||
|     { | ||||
| 				ContactBeginEvent evt(contact); | ||||
| 				world_->Dispatch(evt); | ||||
|         ContactBeginEventPtr evt = new ContactBeginEvent(contact); | ||||
|         world_->DispatchEvent(evt.get()); | ||||
|     } | ||||
| 
 | ||||
|     void EndContact(b2Contact* contact) override | ||||
|     { | ||||
| 				ContactEndEvent evt(contact); | ||||
| 				world_->Dispatch(evt); | ||||
|         ContactEndEventPtr evt = new ContactEndEvent(contact); | ||||
|         world_->DispatchEvent(evt.get()); | ||||
|     } | ||||
| 
 | ||||
| 			void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override		{ KGE_NOT_USED(contact); KGE_NOT_USED(oldManifold); } | ||||
| 			void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override	{ KGE_NOT_USED(contact); KGE_NOT_USED(impulse); } | ||||
| 		}; | ||||
|     void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override | ||||
|     { | ||||
|         KGE_NOT_USED(contact); | ||||
|         KGE_NOT_USED(oldManifold); | ||||
|     } | ||||
|     void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override | ||||
|     { | ||||
|         KGE_NOT_USED(contact); | ||||
|         KGE_NOT_USED(impulse); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 		World::World() | ||||
| World::World() | ||||
|     : world_(b2Vec2(0, 10.0f)) | ||||
|     , vel_iter_(6) | ||||
|     , pos_iter_(2) | ||||
|  | @ -89,16 +94,16 @@ namespace kiwano | |||
|     , destruction_listener_(nullptr) | ||||
|     , contact_listener_(nullptr) | ||||
|     , removing_joint_(false) | ||||
| 		{ | ||||
| { | ||||
|     destruction_listener_ = new DestructionListener(this); | ||||
|     world_.SetDestructionListener(destruction_listener_); | ||||
| 
 | ||||
|     contact_listener_ = new ContactListener(this); | ||||
|     world_.SetContactListener(contact_listener_); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		World::~World() | ||||
| 		{ | ||||
| World::~World() | ||||
| { | ||||
|     world_.SetDestructionListener(nullptr); | ||||
|     if (destruction_listener_) | ||||
|     { | ||||
|  | @ -117,18 +122,18 @@ namespace kiwano | |||
|     RemoveAllChildren(); | ||||
|     RemoveAllBodies(); | ||||
|     RemoveAllJoints(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::RemoveBody(Body* body) | ||||
| 		{ | ||||
| void World::RemoveBody(Body* body) | ||||
| { | ||||
|     if (body && body->GetB2Body()) | ||||
|     { | ||||
|         world_.DestroyBody(body->GetB2Body()); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::RemoveAllBodies() | ||||
| 		{ | ||||
| void World::RemoveAllBodies() | ||||
| { | ||||
|     if (world_.GetBodyCount()) | ||||
|     { | ||||
|         b2Body* body = world_.GetBodyList(); | ||||
|  | @ -139,18 +144,18 @@ namespace kiwano | |||
|             body = next; | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::AddJoint(Joint* joint) | ||||
| 		{ | ||||
| void World::AddJoint(Joint* joint) | ||||
| { | ||||
|     if (joint) | ||||
|     { | ||||
|         joints_.push_back(joint); | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::RemoveJoint(Joint* joint) | ||||
| 		{ | ||||
| void World::RemoveJoint(Joint* joint) | ||||
| { | ||||
|     if (joint) | ||||
|     { | ||||
|         auto iter = std::find(joints_.begin(), joints_.end(), joint); | ||||
|  | @ -166,10 +171,10 @@ namespace kiwano | |||
|             } | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::RemoveAllJoints() | ||||
| 		{ | ||||
| void World::RemoveAllJoints() | ||||
| { | ||||
|     if (world_.GetJointCount()) | ||||
|     { | ||||
|         removing_joint_ = true; | ||||
|  | @ -185,53 +190,50 @@ namespace kiwano | |||
|         removing_joint_ = false; | ||||
|     } | ||||
|     joints_.clear(); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::JointRemoved(b2Joint* joint) | ||||
| 		{ | ||||
| void World::JointRemoved(b2Joint* joint) | ||||
| { | ||||
|     if (!removing_joint_ && joint) | ||||
|     { | ||||
| 				auto iter = std::find_if( | ||||
| 					joints_.begin(), | ||||
| 					joints_.end(), | ||||
| 					[joint](Joint* j) -> bool { return j->GetB2Joint() == joint; } | ||||
| 				); | ||||
|         auto iter = std::find_if(joints_.begin(), joints_.end(), | ||||
|                                  [joint](Joint* j) -> bool { return j->GetB2Joint() == joint; }); | ||||
| 
 | ||||
|         if (iter != joints_.end()) | ||||
|         { | ||||
|             joints_.erase(iter); | ||||
|         } | ||||
|     } | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		b2World* World::GetB2World() | ||||
| 		{ | ||||
| b2World* World::GetB2World() | ||||
| { | ||||
|     return &world_; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		const b2World* World::GetB2World() const | ||||
| 		{ | ||||
| const b2World* World::GetB2World() const | ||||
| { | ||||
|     return &world_; | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		Vec2 World::GetGravity() const | ||||
| 		{ | ||||
| Vec2 World::GetGravity() const | ||||
| { | ||||
|     b2Vec2 g = world_.GetGravity(); | ||||
|     return Vec2(g.x, g.y); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::SetGravity(Vec2 gravity) | ||||
| 		{ | ||||
| void World::SetGravity(Vec2 gravity) | ||||
| { | ||||
|     world_.SetGravity(b2Vec2(gravity.x, gravity.y)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		ContactList World::GetContactList() | ||||
| 		{ | ||||
| ContactList World::GetContactList() | ||||
| { | ||||
|     return ContactList(Contact(world_.GetContactList())); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| 		void World::Update(Duration dt) | ||||
| 		{ | ||||
| void World::Update(Duration dt) | ||||
| { | ||||
|     world_.Step(dt.Seconds(), vel_iter_, pos_iter_); | ||||
| 
 | ||||
|     b2Body* b2body = world_.GetBodyList(); | ||||
|  | @ -247,7 +249,7 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     Stage::Update(dt); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -24,31 +24,30 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		KGE_DECLARE_SMART_PTR(World); | ||||
| namespace physics | ||||
| { | ||||
| KGE_DECLARE_SMART_PTR(World); | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * \defgroup Physics 物理引擎 | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 		/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 物理世界 | ||||
|  */ | ||||
| 		class KGE_API World | ||||
| 			: public Stage | ||||
| 		{ | ||||
| class KGE_API World : public Stage | ||||
| { | ||||
|     friend class Body; | ||||
|     friend class Joint; | ||||
| 
 | ||||
| 		public: | ||||
| public: | ||||
|     World(); | ||||
| 
 | ||||
|     virtual ~World(); | ||||
|  | @ -107,7 +106,7 @@ namespace kiwano | |||
| 
 | ||||
|     const b2World* GetB2World() const; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 移除物体
 | ||||
|     void RemoveBody(Body* body); | ||||
|  | @ -132,10 +131,10 @@ namespace kiwano | |||
|     /// @brief 关节被移除
 | ||||
|     void JointRemoved(b2Joint* joint); | ||||
| 
 | ||||
| 		protected: | ||||
| protected: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
| 		private: | ||||
| private: | ||||
|     b2World world_; | ||||
|     int     vel_iter_; | ||||
|     int     pos_iter_; | ||||
|  | @ -151,49 +150,48 @@ namespace kiwano | |||
| 
 | ||||
|     bool           removing_joint_; | ||||
|     Vector<Joint*> joints_; | ||||
| 		}; | ||||
| }; | ||||
| 
 | ||||
| /** @} */ | ||||
| 
 | ||||
| 		/** @} */ | ||||
| 
 | ||||
| 		inline float World::GetGlobalScale() const | ||||
| 		{ | ||||
| inline float World::GetGlobalScale() const | ||||
| { | ||||
|     return global_scale_; | ||||
| 		} | ||||
| 
 | ||||
| 		inline void World::SetGlobalScale(float scale) | ||||
| 		{ | ||||
| 			global_scale_ = scale; | ||||
| 		} | ||||
| 
 | ||||
| 		inline float World::World2Stage(float value) const | ||||
| 		{ | ||||
| 			return value * GetGlobalScale(); | ||||
| 		} | ||||
| 
 | ||||
| 		inline Vec2 World::World2Stage(const b2Vec2& pos) const | ||||
| 		{ | ||||
| 			return Point(World2Stage(pos.x), World2Stage(pos.y)); | ||||
| 		} | ||||
| 
 | ||||
| 		inline float World::Stage2World(float value) const | ||||
| 		{ | ||||
| 			return value / GetGlobalScale(); | ||||
| 		} | ||||
| 
 | ||||
| 		inline b2Vec2 World::Stage2World(const Vec2& pos) const | ||||
| 		{ | ||||
| 			return b2Vec2(Stage2World(pos.x), Stage2World(pos.y)); | ||||
| 		} | ||||
| 
 | ||||
| 		inline void World::SetVelocityIterations(int vel_iter) | ||||
| 		{ | ||||
| 			vel_iter_ = vel_iter; | ||||
| 		} | ||||
| 
 | ||||
| 		inline void World::SetPositionIterations(int pos_iter) | ||||
| 		{ | ||||
| 			pos_iter_ = pos_iter; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| inline void World::SetGlobalScale(float scale) | ||||
| { | ||||
|     global_scale_ = scale; | ||||
| } | ||||
| 
 | ||||
| inline float World::World2Stage(float value) const | ||||
| { | ||||
|     return value * GetGlobalScale(); | ||||
| } | ||||
| 
 | ||||
| inline Vec2 World::World2Stage(const b2Vec2& pos) const | ||||
| { | ||||
|     return Point(World2Stage(pos.x), World2Stage(pos.y)); | ||||
| } | ||||
| 
 | ||||
| inline float World::Stage2World(float value) const | ||||
| { | ||||
|     return value / GetGlobalScale(); | ||||
| } | ||||
| 
 | ||||
| inline b2Vec2 World::Stage2World(const Vec2& pos) const | ||||
| { | ||||
|     return b2Vec2(Stage2World(pos.x), Stage2World(pos.y)); | ||||
| } | ||||
| 
 | ||||
| inline void World::SetVelocityIterations(int vel_iter) | ||||
| { | ||||
|     vel_iter_ = vel_iter; | ||||
| } | ||||
| 
 | ||||
| inline void World::SetPositionIterations(int pos_iter) | ||||
| { | ||||
|     pos_iter_ = pos_iter; | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -26,9 +26,15 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace physics | ||||
| 	{ | ||||
| 		inline b2Vec2	Stage2World(const Vec2& pos)	{ return b2Vec2(pos.x, pos.y); } | ||||
| 		inline Vec2		World2Stage(const b2Vec2& pos)	{ return Vec2(pos.x, pos.y); } | ||||
| 	} | ||||
| namespace physics | ||||
| { | ||||
| inline b2Vec2 Stage2World(const Vec2& pos) | ||||
| { | ||||
|     return b2Vec2(pos.x, pos.y); | ||||
| } | ||||
| inline Vec2 World2Stage(const b2Vec2& pos) | ||||
| { | ||||
|     return Vec2(pos.x, pos.y); | ||||
| } | ||||
| }  // namespace physics
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,10 +20,10 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <kiwano-physics/Shape.h> | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/Body.h> | ||||
| #include <kiwano-physics/Contact.h> | ||||
| #include <kiwano-physics/ContactEvent.h> | ||||
| #include <kiwano-physics/Body.h> | ||||
| #include <kiwano-physics/Fixture.h> | ||||
| #include <kiwano-physics/Joint.h> | ||||
| #include <kiwano-physics/Shape.h> | ||||
| #include <kiwano-physics/World.h> | ||||
|  |  | |||
|  | @ -21,23 +21,23 @@ | |||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/Stage.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace | ||||
| 	{ | ||||
| 		float default_anchor_x = 0.f; | ||||
| 		float default_anchor_y = 0.f; | ||||
| 	} | ||||
| namespace | ||||
| { | ||||
| float default_anchor_x = 0.f; | ||||
| float default_anchor_y = 0.f; | ||||
| }  // namespace
 | ||||
| 
 | ||||
| 	void Actor::SetDefaultAnchor(float anchor_x, float anchor_y) | ||||
| 	{ | ||||
| void Actor::SetDefaultAnchor(float anchor_x, float anchor_y) | ||||
| { | ||||
|     default_anchor_x = anchor_x; | ||||
|     default_anchor_y = anchor_y; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Actor::Actor() | ||||
| Actor::Actor() | ||||
|     : visible_(true) | ||||
|     , visible_in_rt_(true) | ||||
|     , update_pausing_(false) | ||||
|  | @ -57,11 +57,13 @@ namespace kiwano | |||
|     , opacity_(1.f) | ||||
|     , displayed_opacity_(1.f) | ||||
|     , anchor_(default_anchor_x, default_anchor_y) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void Actor::Update(Duration dt) | ||||
| 	{ | ||||
| Actor::~Actor() {} | ||||
| 
 | ||||
| void Actor::Update(Duration dt) | ||||
| { | ||||
|     UpdateActions(this, dt); | ||||
|     UpdateTimers(dt); | ||||
| 
 | ||||
|  | @ -82,10 +84,10 @@ namespace kiwano | |||
|             child->Update(dt); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::Render(RenderTarget* rt) | ||||
| 	{ | ||||
| void Actor::Render(RenderContext& ctx) | ||||
| { | ||||
|     if (!visible_) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -93,10 +95,10 @@ namespace kiwano | |||
| 
 | ||||
|     if (children_.empty()) | ||||
|     { | ||||
| 			if (CheckVisibilty(rt)) | ||||
|         if (CheckVisibility(ctx)) | ||||
|         { | ||||
| 				PrepareToRender(rt); | ||||
| 				OnRender(rt); | ||||
|             PrepareToRender(ctx); | ||||
|             OnRender(ctx); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|  | @ -108,53 +110,53 @@ namespace kiwano | |||
|             if (child->GetZOrder() >= 0) | ||||
|                 break; | ||||
| 
 | ||||
| 				child->Render(rt); | ||||
|             child->Render(ctx); | ||||
|             child = child->next_item().get(); | ||||
|         } | ||||
| 
 | ||||
| 			if (CheckVisibilty(rt)) | ||||
|         if (CheckVisibility(ctx)) | ||||
|         { | ||||
| 				PrepareToRender(rt); | ||||
| 				OnRender(rt); | ||||
|             PrepareToRender(ctx); | ||||
|             OnRender(ctx); | ||||
|         } | ||||
| 
 | ||||
|         while (child) | ||||
|         { | ||||
| 				child->Render(rt); | ||||
|             child->Render(ctx); | ||||
|             child = child->next_item().get(); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::PrepareToRender(RenderTarget* rt) | ||||
| 	{ | ||||
| 		rt->SetTransform(transform_matrix_); | ||||
| 		rt->SetBrushOpacity(GetDisplayedOpacity()); | ||||
| 	} | ||||
| void Actor::PrepareToRender(RenderContext& ctx) | ||||
| { | ||||
|     ctx.SetTransform(transform_matrix_); | ||||
|     ctx.SetBrushOpacity(GetDisplayedOpacity()); | ||||
| } | ||||
| 
 | ||||
| 	void Actor::RenderBorder(RenderTarget* rt) | ||||
| 	{ | ||||
| void Actor::RenderBorder(RenderContext& ctx) | ||||
| { | ||||
|     if (show_border_ && !size_.IsOrigin()) | ||||
|     { | ||||
|         Rect bounds = GetBounds(); | ||||
| 
 | ||||
| 			rt->SetTransform(transform_matrix_); | ||||
|         ctx.SetTransform(transform_matrix_); | ||||
| 
 | ||||
| 			rt->SetCurrentBrush(GetStage()->GetBorderFillBrush()); | ||||
| 			rt->FillRectangle(bounds); | ||||
|         ctx.SetCurrentBrush(GetStage()->GetBorderFillBrush()); | ||||
|         ctx.FillRectangle(bounds); | ||||
| 
 | ||||
| 			rt->SetCurrentBrush(GetStage()->GetBorderStrokeBrush()); | ||||
| 			rt->DrawRectangle(bounds, 2.f); | ||||
|         ctx.SetCurrentBrush(GetStage()->GetBorderStrokeBrush()); | ||||
|         ctx.DrawRectangle(bounds, 2.f); | ||||
|     } | ||||
| 
 | ||||
|     for (auto child = children_.first_item(); child; child = child->next_item()) | ||||
|     { | ||||
| 			child->RenderBorder(rt); | ||||
| 		} | ||||
|         child->RenderBorder(ctx); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 	bool Actor::CheckVisibilty(RenderTarget* rt) const | ||||
| 	{ | ||||
| bool Actor::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     if (dirty_visibility_) | ||||
|     { | ||||
|         dirty_visibility_ = false; | ||||
|  | @ -165,93 +167,99 @@ namespace kiwano | |||
|         } | ||||
|         else | ||||
|         { | ||||
| 				visible_in_rt_ = rt->CheckVisibility(GetBounds(), GetTransformMatrix()); | ||||
|             visible_in_rt_ = ctx.CheckVisibility(GetBounds(), GetTransformMatrix()); | ||||
|         } | ||||
|     } | ||||
|     return visible_in_rt_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::Dispatch(Event& evt) | ||||
| 	{ | ||||
| bool Actor::DispatchEvent(Event* evt) | ||||
| { | ||||
|     if (!visible_) | ||||
| 			return; | ||||
|         return true; | ||||
| 
 | ||||
| 		ActorPtr prev; | ||||
| 		for (auto child = children_.last_item(); child; child = prev) | ||||
|     // Dispatch to children those are greater than 0 in Z-Order
 | ||||
|     Actor* child = children_.last_item().get(); | ||||
|     while (child) | ||||
|     { | ||||
| 			prev = child->prev_item(); | ||||
| 			child->Dispatch(evt); | ||||
|         if (child->GetZOrder() < 0) | ||||
|             break; | ||||
| 
 | ||||
|         if (!child->DispatchEvent(evt)) | ||||
|             return false; | ||||
| 
 | ||||
|         child = child->prev_item().get(); | ||||
|     } | ||||
| 
 | ||||
|     if (!EventDispatcher::DispatchEvent(evt)) | ||||
|         return false; | ||||
| 
 | ||||
|     HandleEvent(evt); | ||||
| 
 | ||||
|     while (child) | ||||
|     { | ||||
|         if (!child->DispatchEvent(evt)) | ||||
|             return false; | ||||
| 
 | ||||
|         child = child->prev_item().get(); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void Actor::HandleEvent(Event* evt) | ||||
| { | ||||
|     if (responsible_) | ||||
|     { | ||||
| 			if (evt.IsType<MouseMoveEvent>()) | ||||
|         if (evt->IsType<MouseMoveEvent>()) | ||||
|         { | ||||
| 				auto& mouse_evt = evt.SafeCast<MouseMoveEvent>(); | ||||
| 				if (!mouse_evt.target && ContainsPoint(mouse_evt.pos)) | ||||
| 				{ | ||||
| 					mouse_evt.target = this; | ||||
| 
 | ||||
| 					if (!hover_) | ||||
|             auto mouse_evt = dynamic_cast<MouseMoveEvent*>(evt); | ||||
|             bool contains  = ContainsPoint(mouse_evt->pos); | ||||
|             if (!hover_ && contains) | ||||
|             { | ||||
|                 hover_ = true; | ||||
| 
 | ||||
| 						MouseHoverEvent hover; | ||||
| 						hover.pos = mouse_evt.pos; | ||||
| 						hover.left_btn_down = mouse_evt.left_btn_down; | ||||
| 						hover.right_btn_down = mouse_evt.right_btn_down; | ||||
| 						hover.target = this; | ||||
| 						EventDispatcher::Dispatch(hover); | ||||
|                 MouseHoverEventPtr hover = new MouseHoverEvent; | ||||
|                 hover->pos               = mouse_evt->pos; | ||||
|                 EventDispatcher::DispatchEvent(hover.get()); | ||||
|             } | ||||
| 				} | ||||
| 				else if (hover_) | ||||
|             else if (hover_ && !contains) | ||||
|             { | ||||
|                 hover_   = false; | ||||
|                 pressed_ = false; | ||||
| 
 | ||||
| 					MouseOutEvent out; | ||||
| 					out.pos = mouse_evt.pos; | ||||
| 					out.left_btn_down = mouse_evt.left_btn_down; | ||||
| 					out.right_btn_down = mouse_evt.right_btn_down; | ||||
| 					out.target = this; | ||||
| 					EventDispatcher::Dispatch(out); | ||||
|                 MouseOutEventPtr out = new MouseOutEvent; | ||||
|                 out->pos             = mouse_evt->pos; | ||||
|                 EventDispatcher::DispatchEvent(out.get()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 			if (evt.IsType<MouseDownEvent>() && hover_) | ||||
|         if (evt->IsType<MouseDownEvent>() && hover_) | ||||
|         { | ||||
|             pressed_ = true; | ||||
| 				evt.SafeCast<MouseDownEvent>().target = this; | ||||
|         } | ||||
| 
 | ||||
| 			if (evt.IsType<MouseUpEvent>() && pressed_) | ||||
|         if (evt->IsType<MouseUpEvent>() && pressed_) | ||||
|         { | ||||
|             pressed_ = false; | ||||
| 
 | ||||
| 				auto mouse_up_evt = evt.SafeCast<MouseUpEvent>(); | ||||
| 				mouse_up_evt.target = this; | ||||
|             auto mouse_up_evt = dynamic_cast<MouseUpEvent*>(evt); | ||||
| 
 | ||||
| 				MouseClickEvent click; | ||||
| 				click.pos = mouse_up_evt.pos; | ||||
| 				click.left_btn_down = mouse_up_evt.left_btn_down; | ||||
| 				click.right_btn_down = mouse_up_evt.right_btn_down; | ||||
| 				click.target = this; | ||||
| 				click.button = mouse_up_evt.button; | ||||
| 				EventDispatcher::Dispatch(click); | ||||
|             MouseClickEventPtr click = new MouseClickEvent; | ||||
|             click->pos               = mouse_up_evt->pos; | ||||
|             click->button            = mouse_up_evt->button; | ||||
|             EventDispatcher::DispatchEvent(click.get()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 		EventDispatcher::Dispatch(evt); | ||||
| 	} | ||||
| 
 | ||||
| 	Matrix3x2 const & Actor::GetTransformMatrix()  const | ||||
| 	{ | ||||
| Matrix3x2 const& Actor::GetTransformMatrix() const | ||||
| { | ||||
|     UpdateTransform(); | ||||
|     return transform_matrix_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Matrix3x2 const & Actor::GetTransformInverseMatrix()  const | ||||
| 	{ | ||||
| Matrix3x2 const& Actor::GetTransformInverseMatrix() const | ||||
| { | ||||
|     UpdateTransform(); | ||||
|     if (dirty_transform_inverse_) | ||||
|     { | ||||
|  | @ -259,10 +267,10 @@ namespace kiwano | |||
|         dirty_transform_inverse_  = false; | ||||
|     } | ||||
|     return transform_matrix_inverse_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::UpdateTransform() const | ||||
| 	{ | ||||
| void Actor::UpdateTransform() const | ||||
| { | ||||
|     if (!dirty_transform_) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -290,10 +298,10 @@ namespace kiwano | |||
|     // update children's transform
 | ||||
|     for (auto child = children_.first_item().get(); child; child = child->next_item().get()) | ||||
|         child->dirty_transform_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::UpdateOpacity() | ||||
| 	{ | ||||
| void Actor::UpdateOpacity() | ||||
| { | ||||
|     if (parent_ && parent_->IsCascadeOpacityEnabled()) | ||||
|     { | ||||
|         displayed_opacity_ = opacity_ * parent_->displayed_opacity_; | ||||
|  | @ -307,10 +315,10 @@ namespace kiwano | |||
|     { | ||||
|         child->UpdateOpacity(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetStage(Stage* stage) | ||||
| 	{ | ||||
| void Actor::SetStage(Stage* stage) | ||||
| { | ||||
|     if (stage_ != stage) | ||||
|     { | ||||
|         stage_ = stage; | ||||
|  | @ -319,10 +327,10 @@ namespace kiwano | |||
|             child->stage_ = stage; | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::Reorder() | ||||
| 	{ | ||||
| void Actor::Reorder() | ||||
| { | ||||
|     if (parent_) | ||||
|     { | ||||
|         ActorPtr me = this; | ||||
|  | @ -351,140 +359,140 @@ namespace kiwano | |||
|             parent_->children_.push_front(me); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetZOrder(int zorder) | ||||
| 	{ | ||||
| void Actor::SetZOrder(int zorder) | ||||
| { | ||||
|     if (z_order_ != zorder) | ||||
|     { | ||||
|         z_order_ = zorder; | ||||
|         Reorder(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetOpacity(float opacity) | ||||
| 	{ | ||||
| void Actor::SetOpacity(float opacity) | ||||
| { | ||||
|     if (opacity_ == opacity) | ||||
|         return; | ||||
| 
 | ||||
|     displayed_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f); | ||||
|     UpdateOpacity(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetCascadeOpacityEnabled(bool enabled) | ||||
| 	{ | ||||
| void Actor::SetCascadeOpacityEnabled(bool enabled) | ||||
| { | ||||
|     if (cascade_opacity_ == enabled) | ||||
|         return; | ||||
| 
 | ||||
|     cascade_opacity_ = enabled; | ||||
|     UpdateOpacity(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetAnchor(Vec2 const& anchor) | ||||
| 	{ | ||||
| void Actor::SetAnchor(Vec2 const& anchor) | ||||
| { | ||||
|     if (anchor_ == anchor) | ||||
|         return; | ||||
| 
 | ||||
|     anchor_          = anchor; | ||||
|     dirty_transform_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetWidth(float width) | ||||
| 	{ | ||||
| void Actor::SetWidth(float width) | ||||
| { | ||||
|     SetSize(Size{ width, size_.y }); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetHeight(float height) | ||||
| 	{ | ||||
| void Actor::SetHeight(float height) | ||||
| { | ||||
|     SetSize(Size{ size_.x, height }); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetSize(Size const& size) | ||||
| 	{ | ||||
| void Actor::SetSize(Size const& size) | ||||
| { | ||||
|     if (size_ == size) | ||||
|         return; | ||||
| 
 | ||||
|     size_            = size; | ||||
|     dirty_transform_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetTransform(Transform const& transform) | ||||
| 	{ | ||||
| void Actor::SetTransform(Transform const& transform) | ||||
| { | ||||
|     transform_         = transform; | ||||
|     dirty_transform_   = true; | ||||
|     is_fast_transform_ = false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetVisible(bool val) | ||||
| 	{ | ||||
| void Actor::SetVisible(bool val) | ||||
| { | ||||
|     visible_ = val; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetName(String const& name) | ||||
| 	{ | ||||
| void Actor::SetName(String const& name) | ||||
| { | ||||
|     if (!IsName(name)) | ||||
|     { | ||||
|         ObjectBase::SetName(name); | ||||
|         hash_name_ = std::hash<String>{}(name); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetPosition(const Point & pos) | ||||
| 	{ | ||||
| void Actor::SetPosition(const Point& pos) | ||||
| { | ||||
|     if (transform_.position == pos) | ||||
|         return; | ||||
| 
 | ||||
|     transform_.position = pos; | ||||
|     dirty_transform_    = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetPositionX(float x) | ||||
| 	{ | ||||
| void Actor::SetPositionX(float x) | ||||
| { | ||||
|     SetPosition(Point{ x, transform_.position.y }); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetPositionY(float y) | ||||
| 	{ | ||||
| void Actor::SetPositionY(float y) | ||||
| { | ||||
|     SetPosition(Point{ transform_.position.x, y }); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::Move(Vec2 const& v) | ||||
| 	{ | ||||
| void Actor::Move(Vec2 const& v) | ||||
| { | ||||
|     this->SetPosition(Point{ transform_.position.x + v.x, transform_.position.y + v.y }); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetScale(Vec2 const& scale) | ||||
| 	{ | ||||
| void Actor::SetScale(Vec2 const& scale) | ||||
| { | ||||
|     if (transform_.scale == scale) | ||||
|         return; | ||||
| 
 | ||||
|     transform_.scale   = scale; | ||||
|     dirty_transform_   = true; | ||||
|     is_fast_transform_ = false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetSkew(Vec2 const& skew) | ||||
| 	{ | ||||
| void Actor::SetSkew(Vec2 const& skew) | ||||
| { | ||||
|     if (transform_.skew == skew) | ||||
|         return; | ||||
| 
 | ||||
|     transform_.skew    = skew; | ||||
|     dirty_transform_   = true; | ||||
|     is_fast_transform_ = false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetRotation(float angle) | ||||
| 	{ | ||||
| void Actor::SetRotation(float angle) | ||||
| { | ||||
|     if (transform_.rotation == angle) | ||||
|         return; | ||||
| 
 | ||||
|     transform_.rotation = angle; | ||||
|     dirty_transform_    = true; | ||||
|     is_fast_transform_  = false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::AddChild(Actor* child, int zorder) | ||||
| 	{ | ||||
| void Actor::AddChild(Actor* child, int zorder) | ||||
| { | ||||
|     KGE_ASSERT(child && "Actor::AddChild failed, NULL pointer exception"); | ||||
| 
 | ||||
|     if (child) | ||||
|  | @ -513,33 +521,33 @@ namespace kiwano | |||
|         child->Reorder(); | ||||
|         child->UpdateOpacity(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::AddChild(ActorPtr child, int zorder) | ||||
| 	{ | ||||
| void Actor::AddChild(ActorPtr child, int zorder) | ||||
| { | ||||
|     AddChild(child.get()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::AddChildren(Vector<ActorPtr> const& children) | ||||
| 	{ | ||||
| void Actor::AddChildren(Vector<ActorPtr> const& children) | ||||
| { | ||||
|     for (const auto& actor : children) | ||||
|     { | ||||
|         this->AddChild(actor); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Rect Actor::GetBounds() const | ||||
| 	{ | ||||
| Rect Actor::GetBounds() const | ||||
| { | ||||
|     return Rect{ Point{}, size_ }; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Rect Actor::GetBoundingBox() const | ||||
| 	{ | ||||
| Rect Actor::GetBoundingBox() const | ||||
| { | ||||
|     return GetTransformMatrix().Transform(GetBounds()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Vector<ActorPtr> Actor::GetChildren(String const& name) const | ||||
| 	{ | ||||
| Vector<ActorPtr> Actor::GetChildren(String const& name) const | ||||
| { | ||||
|     Vector<ActorPtr> children; | ||||
|     size_t           hash_code = std::hash<String>{}(name); | ||||
| 
 | ||||
|  | @ -551,10 +559,10 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return children; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Actor* Actor::GetChild(String const& name) const | ||||
| 	{ | ||||
| Actor* Actor::GetChild(String const& name) const | ||||
| { | ||||
|     size_t hash_code = std::hash<String>{}(name); | ||||
| 
 | ||||
|     for (auto child = children_.first_item().get(); child; child = child->next_item().get()) | ||||
|  | @ -565,33 +573,33 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return nullptr; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Actor::Children& Actor::GetAllChildren() | ||||
| 	{ | ||||
| Actor::Children& Actor::GetAllChildren() | ||||
| { | ||||
|     return children_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Actor::Children const & Actor::GetAllChildren() const | ||||
| 	{ | ||||
| Actor::Children const& Actor::GetAllChildren() const | ||||
| { | ||||
|     return children_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::RemoveFromParent() | ||||
| 	{ | ||||
| void Actor::RemoveFromParent() | ||||
| { | ||||
|     if (parent_) | ||||
|     { | ||||
|         parent_->RemoveChild(this); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::RemoveChild(ActorPtr child) | ||||
| 	{ | ||||
| void Actor::RemoveChild(ActorPtr child) | ||||
| { | ||||
|     RemoveChild(child.get()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::RemoveChild(Actor * child) | ||||
| 	{ | ||||
| void Actor::RemoveChild(Actor* child) | ||||
| { | ||||
|     KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception"); | ||||
| 
 | ||||
|     if (children_.empty()) | ||||
|  | @ -600,13 +608,14 @@ namespace kiwano | |||
|     if (child) | ||||
|     { | ||||
|         child->parent_ = nullptr; | ||||
| 			if (child->stage_) child->SetStage(nullptr); | ||||
|         if (child->stage_) | ||||
|             child->SetStage(nullptr); | ||||
|         children_.remove(ActorPtr(child)); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::RemoveChildren(String const& child_name) | ||||
| 	{ | ||||
| void Actor::RemoveChildren(String const& child_name) | ||||
| { | ||||
|     if (children_.empty()) | ||||
|     { | ||||
|         return; | ||||
|  | @ -624,25 +633,25 @@ namespace kiwano | |||
|             RemoveChild(child); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::RemoveAllChildren() | ||||
| 	{ | ||||
| void Actor::RemoveAllChildren() | ||||
| { | ||||
|     children_.clear(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Actor::SetResponsible(bool enable) | ||||
| 	{ | ||||
| void Actor::SetResponsible(bool enable) | ||||
| { | ||||
|     responsible_ = enable; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool Actor::ContainsPoint(const Point& point) const | ||||
| 	{ | ||||
| bool Actor::ContainsPoint(const Point& point) const | ||||
| { | ||||
|     if (size_.x == 0.f || size_.y == 0.f) | ||||
|         return false; | ||||
| 
 | ||||
|     Point local = GetTransformInverseMatrix().Transform(point); | ||||
|     return GetBounds().ContainsPoint(local); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,50 +19,50 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/time.h> | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/math/math.h> | ||||
| #include <kiwano/2d/Transform.h> | ||||
| #include <kiwano/2d/action/ActionManager.h> | ||||
| #include <kiwano/core/TimerManager.h> | ||||
| #include <kiwano/core/EventDispatcher.h> | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/core/Time.h> | ||||
| #include <kiwano/core/TimerManager.h> | ||||
| #include <kiwano/math/math.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	class Stage; | ||||
| 	class Director; | ||||
| 	class RenderTarget; | ||||
| class Stage; | ||||
| class Director; | ||||
| class RenderContext; | ||||
| 
 | ||||
| 	KGE_DECLARE_SMART_PTR(Actor); | ||||
| KGE_DECLARE_SMART_PTR(Actor); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * \defgroup Actors 基础角色 | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 角色 | ||||
| 	* @details 角色是舞台上最基本的元素,是完成渲染、更新、事件分发等功能的最小单位,也是动画、定时器、事件监听等功能的载体 | ||||
|  * @details | ||||
|  * 角色是舞台上最基本的元素,是完成渲染、更新、事件分发等功能的最小单位,也是动画、定时器、事件监听等功能的载体 | ||||
|  */ | ||||
| 	class KGE_API Actor | ||||
| 		: public ObjectBase | ||||
| class KGE_API Actor | ||||
|     : public virtual ObjectBase | ||||
|     , public TimerManager | ||||
|     , public ActionManager | ||||
|     , public EventDispatcher | ||||
| 		, public IntrusiveListItem<ActorPtr> | ||||
| 	{ | ||||
|     , protected IntrusiveListItem<ActorPtr> | ||||
| { | ||||
|     friend class Director; | ||||
|     friend class Transition; | ||||
|     friend IntrusiveList<ActorPtr>; | ||||
| 
 | ||||
| 	public: | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 子成员列表
 | ||||
|     using Children = IntrusiveList<ActorPtr>; | ||||
|  | @ -73,6 +73,8 @@ namespace kiwano | |||
| 
 | ||||
|     Actor(); | ||||
| 
 | ||||
|     virtual ~Actor(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 更新角色
 | ||||
|     /// @details 每帧画面刷新前调用该函数,重载该函数以实现角色的更新处理
 | ||||
|  | @ -81,9 +83,10 @@ namespace kiwano | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 渲染角色
 | ||||
| 		/// @details 每帧画面刷新时调用该函数,默认不进行渲染,重载该函数以实现具体渲染过程
 | ||||
| 		/// @param rt 渲染目标
 | ||||
| 		virtual void OnRender(RenderTarget* rt); | ||||
|     /// @details
 | ||||
|     /// 每帧画面刷新时调用该函数,默认不进行渲染,重载该函数以实现具体渲染过程
 | ||||
|     /// @param ctx 渲染上下文
 | ||||
|     virtual void OnRender(RenderContext& ctx); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取显示状态
 | ||||
|  | @ -117,34 +120,6 @@ namespace kiwano | |||
|     /// @brief 获取 y 坐标
 | ||||
|     float GetPositionY() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取缩放比例
 | ||||
| 		Point const& GetScale() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取横向缩放比例
 | ||||
| 		float GetScaleX() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取纵向缩放比例
 | ||||
| 		float GetScaleY() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取错切角度
 | ||||
| 		Point const& GetSkew() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取横向错切角度
 | ||||
| 		float GetSkewX() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取纵向错切角度
 | ||||
| 		float GetSkewY() const; | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取旋转角度
 | ||||
| 		float GetRotation() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取宽度
 | ||||
|     float GetWidth() const; | ||||
|  | @ -189,6 +164,34 @@ namespace kiwano | |||
|     /// @brief 获取显示透明度
 | ||||
|     float GetDisplayedOpacity() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取旋转角度
 | ||||
|     float GetRotation() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取缩放比例
 | ||||
|     Point const& GetScale() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取横向缩放比例
 | ||||
|     float GetScaleX() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取纵向缩放比例
 | ||||
|     float GetScaleY() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取错切角度
 | ||||
|     Point const& GetSkew() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取横向错切角度
 | ||||
|     float GetSkewX() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取纵向错切角度
 | ||||
|     float GetSkewY() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取变换
 | ||||
|     Transform GetTransform() const; | ||||
|  | @ -362,10 +365,6 @@ namespace kiwano | |||
|     /// @brief 从父角色移除
 | ||||
|     void RemoveFromParent(); | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 判断点是否在角色内
 | ||||
| 		virtual bool ContainsPoint(const Point& point) const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 暂停角色更新
 | ||||
|     void PauseUpdating(); | ||||
|  | @ -386,38 +385,44 @@ namespace kiwano | |||
|     /// @brief 获取更新时的回调函数
 | ||||
|     UpdateCallback GetCallbackOnUpdate() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 判断点是否在角色内
 | ||||
|     virtual bool ContainsPoint(const Point& point) const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 渲染角色边界
 | ||||
|     void ShowBorder(bool show); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 分发事件
 | ||||
| 		void Dispatch(Event& evt) override; | ||||
|     /// @param evt 事件
 | ||||
|     /// @return 是否继续分发该事件
 | ||||
|     virtual bool DispatchEvent(Event* evt); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置默认锚点
 | ||||
|     static void SetDefaultAnchor(float anchor_x, float anchor_y); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 更新自身和所有子角色
 | ||||
|     virtual void Update(Duration dt); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 渲染自身和所有子角色
 | ||||
| 		virtual void Render(RenderTarget* rt); | ||||
|     virtual void Render(RenderContext& ctx); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 绘制自身和所有子角色的边界
 | ||||
| 		virtual void RenderBorder(RenderTarget* rt); | ||||
|     virtual void RenderBorder(RenderContext& ctx); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
| 		/// @brief 检查是否在渲染目标的视区内
 | ||||
| 		virtual bool CheckVisibilty(RenderTarget* rt) const; | ||||
|     /// @brief 检查是否在渲染上下文的视区内
 | ||||
|     virtual bool CheckVisibility(RenderContext& ctx) const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
| 		/// @brief 渲染前初始化渲染目标状态,仅当 CheckVisibilty 返回真时调用该函数
 | ||||
| 		virtual void PrepareToRender(RenderTarget* rt); | ||||
|     /// @brief 渲染前初始化渲染上下文状态,仅当 CheckVisibility 返回真时调用该函数
 | ||||
|     virtual void PrepareToRender(RenderContext& ctx); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 更新自己的二维变换,并通知所有子角色
 | ||||
|  | @ -435,7 +440,11 @@ namespace kiwano | |||
|     /// @brief 设置节点所在舞台
 | ||||
|     void SetStage(Stage* stage); | ||||
| 
 | ||||
| 	private: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 处理事件
 | ||||
|     void HandleEvent(Event* evt); | ||||
| 
 | ||||
| private: | ||||
|     bool           visible_; | ||||
|     bool           update_pausing_; | ||||
|     bool           cascade_opacity_; | ||||
|  | @ -462,224 +471,222 @@ namespace kiwano | |||
|     mutable bool      dirty_transform_inverse_; | ||||
|     mutable Matrix3x2 transform_matrix_; | ||||
|     mutable Matrix3x2 transform_matrix_inverse_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 
 | ||||
| 	inline void Actor::OnUpdate(Duration dt) | ||||
| 	{ | ||||
| inline void Actor::OnUpdate(Duration dt) | ||||
| { | ||||
|     KGE_NOT_USED(dt); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::OnRender(RenderTarget* rt) | ||||
| 	{ | ||||
| 		KGE_NOT_USED(rt); | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Actor::IsVisible() const | ||||
| 	{ | ||||
| 		return visible_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Actor::IsResponsible() const | ||||
| 	{ | ||||
| 		return responsible_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Actor::IsCascadeOpacityEnabled() const | ||||
| 	{ | ||||
| 		return cascade_opacity_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline size_t Actor::GetHashName() const | ||||
| 	{ | ||||
| 		return hash_name_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline int Actor::GetZOrder() const | ||||
| 	{ | ||||
| 		return z_order_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Point const& Actor::GetPosition() const | ||||
| 	{ | ||||
| 		return transform_.position; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetPositionX() const | ||||
| 	{ | ||||
| 		return GetPosition().x; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetPositionY() const | ||||
| 	{ | ||||
| 		return GetPosition().y; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Point const& Actor::GetScale() const | ||||
| 	{ | ||||
| 		return transform_.scale; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetScaleX() const | ||||
| 	{ | ||||
| 		return GetScale().x; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetScaleY() const | ||||
| 	{ | ||||
| 		return GetScale().y; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Point const& Actor::GetSkew() const | ||||
| 	{ | ||||
| 		return transform_.skew; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetSkewX() const | ||||
| 	{ | ||||
| 		return GetSkew().x; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetSkewY() const | ||||
| 	{ | ||||
| 		return GetSkew().y; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetRotation() const | ||||
| 	{ | ||||
| 		return transform_.rotation; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetWidth() const | ||||
| 	{ | ||||
| 		return GetSize().x; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetHeight() const | ||||
| 	{ | ||||
| 		return GetSize().y; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Size const& Actor::GetSize() const | ||||
| 	{ | ||||
| 		return size_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetScaledWidth() const | ||||
| 	{ | ||||
| 		return GetWidth() * GetScaleX(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetScaledHeight() const | ||||
| 	{ | ||||
| 		return GetHeight() * GetScaleY(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline Size Actor::GetScaledSize() const | ||||
| 	{ | ||||
| 		return Size{ GetScaledWidth(), GetScaledHeight() }; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Point const& Actor::GetAnchor() const | ||||
| 	{ | ||||
| 		return anchor_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetAnchorX() const | ||||
| 	{ | ||||
| 		return GetAnchor().x; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetAnchorY() const | ||||
| 	{ | ||||
| 		return GetAnchor().y; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetOpacity() const | ||||
| 	{ | ||||
| 		return opacity_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline float Actor::GetDisplayedOpacity() const | ||||
| 	{ | ||||
| 		return displayed_opacity_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Transform Actor::GetTransform() const | ||||
| 	{ | ||||
| 		return transform_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Actor* Actor::GetParent() const | ||||
| 	{ | ||||
| 		return parent_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Stage* Actor::GetStage() const | ||||
| 	{ | ||||
| 		return stage_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::PauseUpdating() | ||||
| 	{ | ||||
| 		update_pausing_ = true; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::ResumeUpdating() | ||||
| 	{ | ||||
| 		update_pausing_ = false; | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Actor::IsUpdatePausing() const | ||||
| 	{ | ||||
| 		return update_pausing_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::SetCallbackOnUpdate(UpdateCallback const& cb) | ||||
| 	{ | ||||
| 		cb_update_ = cb; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Actor::UpdateCallback Actor::GetCallbackOnUpdate() const | ||||
| 	{ | ||||
| 		return cb_update_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::ShowBorder(bool show) | ||||
| 	{ | ||||
| 		show_border_ = show; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::SetPosition(float x, float y) | ||||
| 	{ | ||||
| 		SetPosition(Point{ x, y }); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::Move(float vx, float vy) | ||||
| 	{ | ||||
| 		Move(Vec2{ vx, vy }); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::SetScale(float scalex, float scaley) | ||||
| 	{ | ||||
| 		SetScale(Vec2{ scalex, scaley }); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::SetAnchor(float anchorx, float anchory) | ||||
| 	{ | ||||
| 		SetAnchor(Vec2{ anchorx, anchory }); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::SetSize(float width, float height) | ||||
| 	{ | ||||
| 		SetSize(Size{ width, height }); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Actor::SetSkew(float skewx, float skewy) | ||||
| 	{ | ||||
| 		SetSkew(Vec2{ skewx, skewy }); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| inline void Actor::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     KGE_NOT_USED(ctx); | ||||
| } | ||||
| 
 | ||||
| inline bool Actor::IsVisible() const | ||||
| { | ||||
|     return visible_; | ||||
| } | ||||
| 
 | ||||
| inline bool Actor::IsResponsible() const | ||||
| { | ||||
|     return responsible_; | ||||
| } | ||||
| 
 | ||||
| inline bool Actor::IsCascadeOpacityEnabled() const | ||||
| { | ||||
|     return cascade_opacity_; | ||||
| } | ||||
| 
 | ||||
| inline size_t Actor::GetHashName() const | ||||
| { | ||||
|     return hash_name_; | ||||
| } | ||||
| 
 | ||||
| inline int Actor::GetZOrder() const | ||||
| { | ||||
|     return z_order_; | ||||
| } | ||||
| 
 | ||||
| inline Point const& Actor::GetPosition() const | ||||
| { | ||||
|     return transform_.position; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetPositionX() const | ||||
| { | ||||
|     return GetPosition().x; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetPositionY() const | ||||
| { | ||||
|     return GetPosition().y; | ||||
| } | ||||
| 
 | ||||
| inline Point const& Actor::GetScale() const | ||||
| { | ||||
|     return transform_.scale; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetScaleX() const | ||||
| { | ||||
|     return GetScale().x; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetScaleY() const | ||||
| { | ||||
|     return GetScale().y; | ||||
| } | ||||
| 
 | ||||
| inline Point const& Actor::GetSkew() const | ||||
| { | ||||
|     return transform_.skew; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetSkewX() const | ||||
| { | ||||
|     return GetSkew().x; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetSkewY() const | ||||
| { | ||||
|     return GetSkew().y; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetRotation() const | ||||
| { | ||||
|     return transform_.rotation; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetWidth() const | ||||
| { | ||||
|     return GetSize().x; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetHeight() const | ||||
| { | ||||
|     return GetSize().y; | ||||
| } | ||||
| 
 | ||||
| inline Size const& Actor::GetSize() const | ||||
| { | ||||
|     return size_; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetScaledWidth() const | ||||
| { | ||||
|     return GetWidth() * GetScaleX(); | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetScaledHeight() const | ||||
| { | ||||
|     return GetHeight() * GetScaleY(); | ||||
| } | ||||
| 
 | ||||
| inline Size Actor::GetScaledSize() const | ||||
| { | ||||
|     return Size{ GetScaledWidth(), GetScaledHeight() }; | ||||
| } | ||||
| 
 | ||||
| inline Point const& Actor::GetAnchor() const | ||||
| { | ||||
|     return anchor_; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetAnchorX() const | ||||
| { | ||||
|     return GetAnchor().x; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetAnchorY() const | ||||
| { | ||||
|     return GetAnchor().y; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetOpacity() const | ||||
| { | ||||
|     return opacity_; | ||||
| } | ||||
| 
 | ||||
| inline float Actor::GetDisplayedOpacity() const | ||||
| { | ||||
|     return displayed_opacity_; | ||||
| } | ||||
| 
 | ||||
| inline Transform Actor::GetTransform() const | ||||
| { | ||||
|     return transform_; | ||||
| } | ||||
| 
 | ||||
| inline Actor* Actor::GetParent() const | ||||
| { | ||||
|     return parent_; | ||||
| } | ||||
| 
 | ||||
| inline Stage* Actor::GetStage() const | ||||
| { | ||||
|     return stage_; | ||||
| } | ||||
| 
 | ||||
| inline void Actor::PauseUpdating() | ||||
| { | ||||
|     update_pausing_ = true; | ||||
| } | ||||
| 
 | ||||
| inline void Actor::ResumeUpdating() | ||||
| { | ||||
|     update_pausing_ = false; | ||||
| } | ||||
| 
 | ||||
| inline bool Actor::IsUpdatePausing() const | ||||
| { | ||||
|     return update_pausing_; | ||||
| } | ||||
| 
 | ||||
| inline void Actor::SetCallbackOnUpdate(UpdateCallback const& cb) | ||||
| { | ||||
|     cb_update_ = cb; | ||||
| } | ||||
| 
 | ||||
| inline Actor::UpdateCallback Actor::GetCallbackOnUpdate() const | ||||
| { | ||||
|     return cb_update_; | ||||
| } | ||||
| 
 | ||||
| inline void Actor::ShowBorder(bool show) | ||||
| { | ||||
|     show_border_ = show; | ||||
| } | ||||
| 
 | ||||
| inline void Actor::SetPosition(float x, float y) | ||||
| { | ||||
|     SetPosition(Point{ x, y }); | ||||
| } | ||||
| 
 | ||||
| inline void Actor::Move(float vx, float vy) | ||||
| { | ||||
|     Move(Vec2{ vx, vy }); | ||||
| } | ||||
| 
 | ||||
| inline void Actor::SetScale(float scalex, float scaley) | ||||
| { | ||||
|     SetScale(Vec2{ scalex, scaley }); | ||||
| } | ||||
| 
 | ||||
| inline void Actor::SetAnchor(float anchorx, float anchory) | ||||
| { | ||||
|     SetAnchor(Vec2{ anchorx, anchory }); | ||||
| } | ||||
| 
 | ||||
| inline void Actor::SetSize(float width, float height) | ||||
| { | ||||
|     SetSize(Size{ width, height }); | ||||
| } | ||||
| 
 | ||||
| inline void Actor::SetSkew(float skewx, float skewy) | ||||
| { | ||||
|     SetSkew(Vec2{ skewx, skewy }); | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -0,0 +1,207 @@ | |||
| // 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 <kiwano/2d/Button.h> | ||||
| #include <kiwano/2d/Stage.h> | ||||
| #include <kiwano/platform/Window.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| Button::Button() | ||||
|     : enabled_(true) | ||||
|     , status_(Status::Normal) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| Button::Button(const Callback& click) | ||||
|     : Button() | ||||
| { | ||||
|     this->SetClickCallback(click); | ||||
| } | ||||
| 
 | ||||
| Button::Button(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out) | ||||
|     : Button() | ||||
| { | ||||
|     this->SetClickCallback(click); | ||||
|     this->SetPressedCallback(pressed); | ||||
|     this->SetMouseOverCallback(mouse_over); | ||||
|     this->SetMouseOutCallback(mouse_out); | ||||
| } | ||||
| 
 | ||||
| Button::~Button() {} | ||||
| 
 | ||||
| bool Button::IsEnable() const | ||||
| { | ||||
|     return enabled_; | ||||
| } | ||||
| 
 | ||||
| void Button::SetEnabled(bool enabled) | ||||
| { | ||||
|     if (enabled_ != enabled) | ||||
|     { | ||||
|         enabled_ = enabled; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Button::SetClickCallback(const Callback& func) | ||||
| { | ||||
|     click_callback_ = func; | ||||
| } | ||||
| 
 | ||||
| void Button::SetPressedCallback(const Callback& func) | ||||
| { | ||||
|     pressed_callback_ = func; | ||||
| } | ||||
| 
 | ||||
| void Button::SetReleasedCallback(const Callback& func) | ||||
| { | ||||
|     released_callback_ = func; | ||||
| } | ||||
| 
 | ||||
| void Button::SetMouseOverCallback(const Callback& func) | ||||
| { | ||||
|     mouse_over_callback_ = func; | ||||
| } | ||||
| 
 | ||||
| void Button::SetMouseOutCallback(const Callback& func) | ||||
| { | ||||
|     mouse_out_callback_ = func; | ||||
| } | ||||
| 
 | ||||
| void Button::SetStatus(Status status) | ||||
| { | ||||
|     if (status_ != status) | ||||
|     { | ||||
|         Status old_status = status_; | ||||
| 
 | ||||
|         if (status == Status::Normal) | ||||
|         { | ||||
|             Window::Instance().SetCursor(CursorType::Arrow); | ||||
| 
 | ||||
|             if (mouse_out_callback_) | ||||
|                 mouse_out_callback_(this); | ||||
|         } | ||||
|         else if (status == Status::Hover) | ||||
|         { | ||||
|             Window::Instance().SetCursor(CursorType::Hand); | ||||
| 
 | ||||
|             if (old_status == Status::Pressed) | ||||
|             { | ||||
|                 if (released_callback_) | ||||
|                     released_callback_(this); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (mouse_over_callback_) | ||||
|                     mouse_over_callback_(this); | ||||
|             } | ||||
|         } | ||||
|         else if (status == Status::Pressed) | ||||
|         { | ||||
|             if (pressed_callback_) | ||||
|                 pressed_callback_(this); | ||||
|         } | ||||
| 
 | ||||
|         status_ = status; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Button::Status Button::GetStatus() const | ||||
| { | ||||
|     return status_; | ||||
| } | ||||
| 
 | ||||
| void Button::UpdateStatus(Event* evt) | ||||
| { | ||||
|     if (!enabled_) | ||||
|         return; | ||||
| 
 | ||||
|     if (evt->IsType<MouseHoverEvent>()) | ||||
|     { | ||||
|         SetStatus(Status::Hover); | ||||
|     } | ||||
|     else if (evt->IsType<MouseOutEvent>()) | ||||
|     { | ||||
|         SetStatus(Status::Normal); | ||||
|     } | ||||
|     else if (evt->IsType<MouseDownEvent>() && status_ == Status::Hover) | ||||
|     { | ||||
|         SetStatus(Status::Pressed); | ||||
|     } | ||||
|     else if (evt->IsType<MouseUpEvent>() && status_ == Status::Pressed) | ||||
|     { | ||||
|         SetStatus(Status::Hover); | ||||
|     } | ||||
|     else if (evt->IsType<MouseClickEvent>()) | ||||
|     { | ||||
|         if (click_callback_) | ||||
|             click_callback_(this); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| SpriteButton::SpriteButton() | ||||
|     : SpriteButton(nullptr, nullptr, nullptr, nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| SpriteButton::SpriteButton(Callback const& click) | ||||
|     : SpriteButton(click, nullptr, nullptr, nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| SpriteButton::SpriteButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, | ||||
|                            Callback const& mouse_out) | ||||
|     : Button(click, pressed, mouse_over, mouse_out) | ||||
| { | ||||
|     SetResponsible(true); | ||||
| 
 | ||||
|     EventListener::Callback handler = Closure(this, &SpriteButton::UpdateStatus); | ||||
|     AddListener<MouseHoverEvent>(handler); | ||||
|     AddListener<MouseOutEvent>(handler); | ||||
|     AddListener<MouseDownEvent>(handler); | ||||
|     AddListener<MouseUpEvent>(handler); | ||||
|     AddListener<MouseClickEvent>(handler); | ||||
| } | ||||
| 
 | ||||
| TextButton::TextButton() | ||||
|     : TextButton(nullptr, nullptr, nullptr, nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| TextButton::TextButton(Callback const& click) | ||||
|     : TextButton(click, nullptr, nullptr, nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| TextButton::TextButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, | ||||
|                        Callback const& mouse_out) | ||||
|     : Button(click, pressed, mouse_over, mouse_out) | ||||
| { | ||||
|     SetResponsible(true); | ||||
| 
 | ||||
|     EventListener::Callback handler = Closure(this, &TextButton::UpdateStatus); | ||||
|     AddListener<MouseHoverEvent>(handler); | ||||
|     AddListener<MouseOutEvent>(handler); | ||||
|     AddListener<MouseDownEvent>(handler); | ||||
|     AddListener<MouseUpEvent>(handler); | ||||
|     AddListener<MouseClickEvent>(handler); | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  | @ -0,0 +1,164 @@ | |||
| // 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 <kiwano/2d/Sprite.h> | ||||
| #include <kiwano/2d/TextActor.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| KGE_DECLARE_SMART_PTR(Button); | ||||
| KGE_DECLARE_SMART_PTR(SpriteButton); | ||||
| KGE_DECLARE_SMART_PTR(TextButton); | ||||
| 
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 按钮 | ||||
|  */ | ||||
| class KGE_API Button : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 按钮回调函数
 | ||||
|     using Callback = Function<void(Button* /* self */)>; | ||||
| 
 | ||||
|     Button(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造按钮
 | ||||
|     /// @param click 按钮点击回调函数
 | ||||
|     explicit Button(Callback const& click); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造按钮
 | ||||
|     /// @param click 按钮点击回调函数
 | ||||
|     /// @param pressed 按钮按下回调函数
 | ||||
|     /// @param mouse_over 按钮移入回调函数
 | ||||
|     /// @param mouse_out 按钮移出回调函数
 | ||||
|     Button(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); | ||||
| 
 | ||||
|     virtual ~Button(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取按钮状态是启用还是禁用
 | ||||
|     bool IsEnable() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置按钮启用或禁用
 | ||||
|     void SetEnabled(bool enabled); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置按钮点击后的回调函数
 | ||||
|     void SetClickCallback(const Callback& func); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置按钮被按下时的回调函数
 | ||||
|     void SetPressedCallback(const Callback& func); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置按钮被抬起时的回调函数
 | ||||
|     void SetReleasedCallback(const Callback& func); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置鼠标移入按钮时的回调函数
 | ||||
|     void SetMouseOverCallback(const Callback& func); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置鼠标移出按钮时的回调函数
 | ||||
|     void SetMouseOutCallback(const Callback& func); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 按钮状态
 | ||||
|     enum class Status | ||||
|     { | ||||
|         Normal,  ///< 普通
 | ||||
|         Hover,   ///< 鼠标在按钮内
 | ||||
|         Pressed  ///< 被按下
 | ||||
|     }; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置按钮状态
 | ||||
|     void SetStatus(Status status); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取按钮状态
 | ||||
|     Status GetStatus() const; | ||||
| 
 | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 更新按钮状态
 | ||||
|     void UpdateStatus(Event* evt); | ||||
| 
 | ||||
| private: | ||||
|     bool     enabled_; | ||||
|     Status   status_; | ||||
|     Callback click_callback_; | ||||
|     Callback pressed_callback_; | ||||
|     Callback released_callback_; | ||||
|     Callback mouse_over_callback_; | ||||
|     Callback mouse_out_callback_; | ||||
| }; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 精灵按钮
 | ||||
| class SpriteButton | ||||
|     : public Sprite | ||||
|     , public Button | ||||
| { | ||||
| public: | ||||
|     SpriteButton(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造精灵按钮
 | ||||
|     /// @param click 按钮点击回调函数
 | ||||
|     explicit SpriteButton(Callback const& click); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造精灵按钮
 | ||||
|     /// @param click 按钮点击回调函数
 | ||||
|     /// @param pressed 按钮按下回调函数
 | ||||
|     /// @param mouse_over 按钮移入回调函数
 | ||||
|     /// @param mouse_out 按钮移出回调函数
 | ||||
|     SpriteButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); | ||||
| }; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 文字按钮
 | ||||
| class TextButton | ||||
|     : public TextActor | ||||
|     , public Button | ||||
| { | ||||
| public: | ||||
|     TextButton(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造文字按钮
 | ||||
|     /// @param click 按钮点击回调函数
 | ||||
|     explicit TextButton(Callback const& click); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造文字按钮
 | ||||
|     /// @param click 按钮点击回调函数
 | ||||
|     /// @param pressed 按钮按下回调函数
 | ||||
|     /// @param mouse_over 按钮移入回调函数
 | ||||
|     /// @param mouse_out 按钮移出回调函数
 | ||||
|     TextButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); | ||||
| }; | ||||
| }  // namespace kiwano
 | ||||
|  | @ -20,213 +20,176 @@ | |||
| 
 | ||||
| #include <kiwano/2d/Canvas.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Canvas::Canvas() | ||||
| Canvas::Canvas() | ||||
|     : cache_expired_(false) | ||||
|     , stroke_width_(1.0f) | ||||
| 		, stroke_style_(StrokeStyle::Miter) | ||||
| 	{ | ||||
| 	} | ||||
|     , stroke_style_() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	Canvas::~Canvas() | ||||
| 	{ | ||||
| 	} | ||||
| Canvas::~Canvas() {} | ||||
| 
 | ||||
| 	void Canvas::BeginDraw() | ||||
| 	{ | ||||
| void Canvas::BeginDraw() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->BeginDraw(); | ||||
| 	} | ||||
|     ctx_->BeginDraw(); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::EndDraw() | ||||
| 	{ | ||||
| void Canvas::EndDraw() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->EndDraw(); | ||||
|     ctx_->EndDraw(); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::OnRender(RenderTarget* rt) | ||||
| 	{ | ||||
| void Canvas::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     UpdateCache(); | ||||
| 
 | ||||
|     if (texture_cached_ && texture_cached_->IsValid()) | ||||
|     { | ||||
| 			PrepareToRender(rt); | ||||
|         PrepareToRender(ctx); | ||||
| 
 | ||||
|         Rect bitmap_rect(0.f, 0.f, texture_cached_->GetWidth(), texture_cached_->GetHeight()); | ||||
| 			rt->DrawTexture(*texture_cached_, bitmap_rect, bitmap_rect); | ||||
| 		} | ||||
|         ctx.DrawTexture(*texture_cached_, bitmap_rect, bitmap_rect); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::SetBrush(BrushPtr brush) | ||||
| 	{ | ||||
| void Canvas::SetBrush(BrushPtr brush) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(brush); | ||||
| 	} | ||||
|     ctx_->SetCurrentBrush(brush); | ||||
| } | ||||
| 
 | ||||
| 	float Canvas::GetStrokeWidth() const | ||||
| 	{ | ||||
| float Canvas::GetStrokeWidth() const | ||||
| { | ||||
|     return stroke_width_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::SetBrushTransform(Transform const& transform) | ||||
| 	{ | ||||
| void Canvas::SetBrushTransform(Transform const& transform) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetTransform(transform.ToMatrix()); | ||||
| 	} | ||||
|     ctx_->SetTransform(transform.ToMatrix()); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::SetBrushTransform(Matrix3x2 const & transform) | ||||
| 	{ | ||||
| void Canvas::SetBrushTransform(Matrix3x2 const& transform) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetTransform(transform); | ||||
| 	} | ||||
|     ctx_->SetTransform(transform); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::PushLayerArea(LayerArea& area) | ||||
| 	{ | ||||
| void Canvas::PushLayerArea(LayerArea& area) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->PushLayer(area); | ||||
| 	} | ||||
|     ctx_->PushLayer(area); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::PopLayerArea() | ||||
| 	{ | ||||
| void Canvas::PopLayerArea() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->PopLayer(); | ||||
| 	} | ||||
|     ctx_->PopLayer(); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::PushClipRect(Rect const& clip_rect) | ||||
| 	{ | ||||
| void Canvas::PushClipRect(Rect const& clip_rect) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->PushClipRect(clip_rect); | ||||
| 	} | ||||
|     ctx_->PushClipRect(clip_rect); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::PopClipRect() | ||||
| 	{ | ||||
| void Canvas::PopClipRect() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->PopClipRect(); | ||||
| 	} | ||||
|     ctx_->PopClipRect(); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawLine(Point const& begin, Point const& end) | ||||
| 	{ | ||||
| void Canvas::DrawLine(Point const& begin, Point const& end) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(stroke_brush_); | ||||
| 		rt_->DrawLine( | ||||
| 			begin, | ||||
| 			end, | ||||
| 			stroke_width_, | ||||
| 			stroke_style_ | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(stroke_brush_); | ||||
|     ctx_->DrawLine(begin, end, stroke_width_, stroke_style_); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawCircle(Point const& center, float radius) | ||||
| 	{ | ||||
| void Canvas::DrawCircle(Point const& center, float radius) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(stroke_brush_); | ||||
| 		rt_->DrawEllipse( | ||||
| 			center, | ||||
| 			Vec2(radius, radius), | ||||
| 			stroke_width_, | ||||
| 			stroke_style_ | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(stroke_brush_); | ||||
|     ctx_->DrawEllipse(center, Vec2(radius, radius), stroke_width_, stroke_style_); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawEllipse(Point const& center, Vec2 const& radius) | ||||
| 	{ | ||||
| void Canvas::DrawEllipse(Point const& center, Vec2 const& radius) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(stroke_brush_); | ||||
| 		rt_->DrawEllipse( | ||||
| 			center, | ||||
| 			radius, | ||||
| 			stroke_width_, | ||||
| 			stroke_style_ | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(stroke_brush_); | ||||
|     ctx_->DrawEllipse(center, radius, stroke_width_, stroke_style_); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawRect(Rect const& rect) | ||||
| 	{ | ||||
| void Canvas::DrawRect(Rect const& rect) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(stroke_brush_); | ||||
| 		rt_->DrawRectangle( | ||||
| 			rect, | ||||
| 			stroke_width_, | ||||
| 			stroke_style_ | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(stroke_brush_); | ||||
|     ctx_->DrawRectangle(rect, stroke_width_, stroke_style_); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius) | ||||
| 	{ | ||||
| void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(stroke_brush_); | ||||
| 		rt_->DrawRoundedRectangle( | ||||
| 			rect, | ||||
| 			radius, | ||||
| 			stroke_width_, | ||||
| 			stroke_style_ | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(stroke_brush_); | ||||
|     ctx_->DrawRoundedRectangle(rect, radius, stroke_width_, stroke_style_); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::FillCircle(Point const& center, float radius) | ||||
| 	{ | ||||
| void Canvas::FillCircle(Point const& center, float radius) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(fill_brush_); | ||||
| 		rt_->FillEllipse( | ||||
| 			center, | ||||
| 			Vec2(radius, radius) | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(fill_brush_); | ||||
|     ctx_->FillEllipse(center, Vec2(radius, radius)); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::FillEllipse(Point const& center, Vec2 const& radius) | ||||
| 	{ | ||||
| void Canvas::FillEllipse(Point const& center, Vec2 const& radius) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(fill_brush_); | ||||
| 		rt_->FillEllipse( | ||||
| 			center, | ||||
| 			radius | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(fill_brush_); | ||||
|     ctx_->FillEllipse(center, radius); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::FillRect(Rect const& rect) | ||||
| 	{ | ||||
| void Canvas::FillRect(Rect const& rect) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(fill_brush_); | ||||
| 		rt_->FillRectangle( | ||||
| 			rect | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(fill_brush_); | ||||
|     ctx_->FillRectangle(rect); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius) | ||||
| 	{ | ||||
| void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(fill_brush_); | ||||
| 		rt_->FillRoundedRectangle( | ||||
| 			rect, | ||||
| 			radius | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(fill_brush_); | ||||
|     ctx_->FillRoundedRectangle(rect, radius); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawTexture(TexturePtr texture, const Rect* src_rect, const Rect* dest_rect) | ||||
| 	{ | ||||
| void Canvas::DrawTexture(TexturePtr texture, const Rect* src_rect, const Rect* dest_rect) | ||||
| { | ||||
|     if (texture) | ||||
|     { | ||||
|         InitRenderTargetAndBrushs(); | ||||
| 			rt_->DrawTexture(*texture, src_rect, dest_rect); | ||||
|         ctx_->DrawTexture(*texture, src_rect, dest_rect); | ||||
|         cache_expired_ = true; | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawTextLayout(String const& text, Point const& point) | ||||
| 	{ | ||||
| void Canvas::DrawTextLayout(String const& text, Point const& point) | ||||
| { | ||||
|     if (text.empty()) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -234,91 +197,85 @@ namespace kiwano | |||
|     layout.SetStyle(text_style_); | ||||
|     layout.SetText(text); | ||||
|     DrawTextLayout(layout, point); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point) | ||||
| 	{ | ||||
| void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->DrawTextLayout(layout, point); | ||||
| 	} | ||||
|     ctx_->DrawTextLayout(layout, point); | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::BeginPath(Point const& begin_pos) | ||||
| 	{ | ||||
| void Canvas::BeginPath(Point const& begin_pos) | ||||
| { | ||||
|     geo_sink_.BeginPath(begin_pos); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::EndPath(bool closed) | ||||
| 	{ | ||||
| void Canvas::EndPath(bool closed) | ||||
| { | ||||
|     geo_sink_.EndPath(closed); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::AddLine(Point const & point) | ||||
| 	{ | ||||
| void Canvas::AddLine(Point const& point) | ||||
| { | ||||
|     geo_sink_.AddLine(point); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::AddLines(Vector<Point> const& points) | ||||
| 	{ | ||||
| void Canvas::AddLines(Vector<Point> const& points) | ||||
| { | ||||
|     geo_sink_.AddLines(points); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::AddBezier(Point const & point1, Point const & point2, Point const & point3) | ||||
| 	{ | ||||
| void Canvas::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||
| { | ||||
|     geo_sink_.AddBezier(point1, point2, point3); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::AddArc(Point const & point, Size const & radius, float rotation, bool clockwise, bool is_small) | ||||
| 	{ | ||||
| void Canvas::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||
| { | ||||
|     geo_sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::StrokePath() | ||||
| 	{ | ||||
| void Canvas::StrokePath() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(stroke_brush_); | ||||
| 		rt_->DrawGeometry( | ||||
| 			geo_sink_.GetGeometry(), | ||||
| 			stroke_width_, | ||||
| 			stroke_style_ | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(stroke_brush_); | ||||
|     ctx_->DrawGeometry(geo_sink_.GetGeometry(), stroke_width_, stroke_style_); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::FillPath() | ||||
| 	{ | ||||
| void Canvas::FillPath() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->SetCurrentBrush(fill_brush_); | ||||
| 		rt_->FillGeometry( | ||||
| 			geo_sink_.GetGeometry() | ||||
| 		); | ||||
|     ctx_->SetCurrentBrush(fill_brush_); | ||||
|     ctx_->FillGeometry(geo_sink_.GetGeometry()); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::Clear() | ||||
| 	{ | ||||
| void Canvas::Clear() | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->Clear(); | ||||
|     ctx_->Clear(); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::Clear(Color const& clear_color) | ||||
| 	{ | ||||
| void Canvas::Clear(Color const& clear_color) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
| 		rt_->Clear(clear_color); | ||||
|     ctx_->Clear(clear_color); | ||||
|     cache_expired_ = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	TexturePtr Canvas::ExportToTexture() const | ||||
| 	{ | ||||
| TexturePtr Canvas::ExportToTexture() const | ||||
| { | ||||
|     UpdateCache(); | ||||
|     return texture_cached_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::InitRenderTargetAndBrushs() | ||||
| void Canvas::InitRenderTargetAndBrushs() | ||||
| { | ||||
|     if (!ctx_) | ||||
|     { | ||||
| 		if (!rt_) | ||||
| 		{ | ||||
| 			Renderer::instance().CreateTextureRenderTarget(rt_); | ||||
|         Renderer::Instance().CreateTextureRenderTarget(ctx_); | ||||
|     } | ||||
| 
 | ||||
|     if (!stroke_brush_) | ||||
|  | @ -332,22 +289,22 @@ namespace kiwano | |||
|         fill_brush_ = new Brush; | ||||
|         fill_brush_->SetColor(Color::White); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Canvas::UpdateCache() const | ||||
| 	{ | ||||
| 		if (cache_expired_ && rt_) | ||||
| void Canvas::UpdateCache() const | ||||
| { | ||||
|     if (cache_expired_ && ctx_) | ||||
|     { | ||||
|         if (!texture_cached_) | ||||
|         { | ||||
|             texture_cached_ = new Texture; | ||||
|         } | ||||
| 
 | ||||
| 			if (rt_->GetOutput(*texture_cached_)) | ||||
|         if (ctx_->GetOutput(*texture_cached_)) | ||||
|         { | ||||
|             cache_expired_ = false; | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,26 +20,25 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/renderer/RenderTarget.h> | ||||
| #include <kiwano/renderer/GeometrySink.h> | ||||
| #include <kiwano/render/GeometrySink.h> | ||||
| #include <kiwano/render/RenderContext.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(Canvas); | ||||
| KGE_DECLARE_SMART_PTR(Canvas); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 画布,用于绘制图元 | ||||
|  */ | ||||
| 	class KGE_API Canvas | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API Canvas : public Actor | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构建空画布
 | ||||
|     Canvas(); | ||||
|  | @ -206,7 +205,7 @@ namespace kiwano | |||
|     /// \~chinese
 | ||||
|     /// @brief 设置轮廓样式
 | ||||
|     /// @param stroke_style 轮廓样式
 | ||||
| 		void SetStrokeStyle(StrokeStyle stroke_style); | ||||
|     void SetStrokeStyle(const StrokeStyle& stroke_style); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置文字画刷样式
 | ||||
|  | @ -262,14 +261,14 @@ namespace kiwano | |||
|     /// @brief 导出纹理
 | ||||
|     TexturePtr ExportToTexture() const; | ||||
| 
 | ||||
| 		void OnRender(RenderTarget* rt) override; | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     void InitRenderTargetAndBrushs(); | ||||
| 
 | ||||
|     void UpdateCache() const; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     float        stroke_width_; | ||||
|     TextStyle    text_style_; | ||||
|     StrokeStyle  stroke_style_; | ||||
|  | @ -279,56 +278,55 @@ namespace kiwano | |||
| 
 | ||||
|     mutable bool                    cache_expired_; | ||||
|     mutable TexturePtr              texture_cached_; | ||||
| 		mutable TextureRenderTargetPtr	rt_; | ||||
| 	}; | ||||
|     mutable TextureRenderContextPtr ctx_; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 	inline void Canvas::SetStrokeWidth(float width) | ||||
| 	{ | ||||
| inline void Canvas::SetStrokeWidth(float width) | ||||
| { | ||||
|     stroke_width_ = std::max(width, 0.f); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	inline void Canvas::SetStrokeStyle(StrokeStyle stroke_style) | ||||
| 	{ | ||||
| inline void Canvas::SetStrokeStyle(const StrokeStyle& stroke_style) | ||||
| { | ||||
|     stroke_style_ = stroke_style; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	inline void Canvas::SetTextStyle(TextStyle const& text_style) | ||||
| 	{ | ||||
| inline void Canvas::SetTextStyle(TextStyle const& text_style) | ||||
| { | ||||
|     text_style_ = text_style; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	inline void Canvas::SetStrokeColor(Color const& color) | ||||
| 	{ | ||||
| inline void Canvas::SetStrokeColor(Color const& color) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
|     stroke_brush_->SetColor(color); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	inline void Canvas::SetFillColor(Color const& color) | ||||
| 	{ | ||||
| inline void Canvas::SetFillColor(Color const& color) | ||||
| { | ||||
|     InitRenderTargetAndBrushs(); | ||||
|     fill_brush_->SetColor(color); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Canvas::SetFillBrush(BrushPtr brush) | ||||
| 	{ | ||||
| 		fill_brush_ = brush; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Canvas::SetStrokeBrush(BrushPtr brush) | ||||
| 	{ | ||||
| 		stroke_brush_ = brush; | ||||
| 	} | ||||
| 
 | ||||
| 	inline BrushPtr Canvas::GetFillBrush() const | ||||
| 	{ | ||||
| 		return fill_brush_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline BrushPtr Canvas::GetStrokeBrush() const | ||||
| 	{ | ||||
| 		return stroke_brush_; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| inline void Canvas::SetFillBrush(BrushPtr brush) | ||||
| { | ||||
|     fill_brush_ = brush; | ||||
| } | ||||
| 
 | ||||
| inline void Canvas::SetStrokeBrush(BrushPtr brush) | ||||
| { | ||||
|     stroke_brush_ = brush; | ||||
| } | ||||
| 
 | ||||
| inline BrushPtr Canvas::GetFillBrush() const | ||||
| { | ||||
|     return fill_brush_; | ||||
| } | ||||
| 
 | ||||
| inline BrushPtr Canvas::GetStrokeBrush() const | ||||
| { | ||||
|     return stroke_brush_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,19 +19,19 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/DebugActor.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <psapi.h> | ||||
| 
 | ||||
| #pragma comment(lib, "psapi.lib") | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace | ||||
| 	{ | ||||
| 		class comma_numpunct : public std::numpunct<wchar_t> | ||||
| 		{ | ||||
| 		private: | ||||
| namespace | ||||
| { | ||||
| class comma_numpunct : public std::numpunct<wchar_t> | ||||
| { | ||||
| private: | ||||
|     virtual wchar_t do_thousands_sep() const override | ||||
|     { | ||||
|         return L','; | ||||
|  | @ -41,49 +41,47 @@ namespace kiwano | |||
|     { | ||||
|         return "\03"; | ||||
|     } | ||||
| 		}; | ||||
| }; | ||||
| }  // namespace
 | ||||
| 
 | ||||
| 		std::locale comma_locale(std::locale(), new comma_numpunct); | ||||
| 	} | ||||
| 
 | ||||
| 	DebugActor::DebugActor() | ||||
| 	{ | ||||
| DebugActor::DebugActor() | ||||
| { | ||||
|     SetName(L"kiwano-debug-actor"); | ||||
|     SetPosition(Point{ 10, 10 }); | ||||
|     SetResponsible(true); | ||||
|     SetCascadeOpacityEnabled(true); | ||||
| 
 | ||||
|     comma_locale_ = std::locale(std::locale(), new comma_numpunct); | ||||
| 
 | ||||
|     background_brush_ = new Brush; | ||||
|     background_brush_->SetColor(Color(0.0f, 0.0f, 0.0f, 0.7f)); | ||||
| 
 | ||||
| 		debug_text_ = new TextActor; | ||||
| 		debug_text_->SetPosition(Point{ 10, 10 }); | ||||
| 		this->AddChild(debug_text_); | ||||
|     BrushPtr fill_brush = new Brush; | ||||
|     fill_brush->SetColor(Color::White); | ||||
| 
 | ||||
|     TextStyle style; | ||||
|     style.font_family  = L"Arial"; | ||||
|     style.font_size    = 16.f; | ||||
|     style.font_weight  = FontWeight::Normal; | ||||
|     style.line_spacing = 20.f; | ||||
| 		debug_text_->SetStyle(style); | ||||
| 		debug_text_->SetFillColor(Color::White); | ||||
|     style.fill_brush   = fill_brush; | ||||
|     debug_text_.SetStyle(style); | ||||
| 
 | ||||
| 		AddListener<MouseHoverEvent>([=](Event&) { SetOpacity(0.4f); }); | ||||
| 		AddListener<MouseOutEvent>([=](Event&) { SetOpacity(1.f); }); | ||||
| 	} | ||||
|     AddListener<MouseHoverEvent>([=](Event*) { SetOpacity(0.4f); }); | ||||
|     AddListener<MouseOutEvent>([=](Event*) { SetOpacity(1.f); }); | ||||
| } | ||||
| 
 | ||||
| 	DebugActor::~DebugActor() | ||||
| 	{ | ||||
| 	} | ||||
| DebugActor::~DebugActor() {} | ||||
| 
 | ||||
| 	void DebugActor::OnRender(RenderTarget* rt) | ||||
| 	{ | ||||
| 		rt->SetCurrentBrush(background_brush_); | ||||
| 		rt->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }); | ||||
| 	} | ||||
| void DebugActor::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     ctx.SetCurrentBrush(background_brush_); | ||||
|     ctx.FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }); | ||||
|     ctx.DrawTextLayout(debug_text_, Point(10, 10)); | ||||
| } | ||||
| 
 | ||||
| 	void DebugActor::OnUpdate(Duration dt) | ||||
| 	{ | ||||
| void DebugActor::OnUpdate(Duration dt) | ||||
| { | ||||
|     KGE_NOT_USED(dt); | ||||
| 
 | ||||
|     frame_time_.push_back(Time::Now()); | ||||
|  | @ -95,7 +93,7 @@ namespace kiwano | |||
|     StringStream ss; | ||||
| 
 | ||||
|     // For formatting integers with commas
 | ||||
| 		(void)ss.imbue(comma_locale); | ||||
|     (void)ss.imbue(comma_locale_); | ||||
| 
 | ||||
|     ss << "Fps: " << frame_time_.size() << std::endl; | ||||
| 
 | ||||
|  | @ -106,9 +104,10 @@ namespace kiwano | |||
|     } | ||||
| #endif | ||||
| 
 | ||||
| 		ss << "Render: " << Renderer::instance().GetStatus().duration.Milliseconds() << "ms" << std::endl; | ||||
|     ss << "Render: " << Renderer::Instance().GetStatus().duration.Milliseconds() << "ms" << std::endl; | ||||
| 
 | ||||
| 		ss << "Primitives / sec: " << std::fixed << Renderer::instance().GetStatus().primitives * frame_time_.size() << std::endl; | ||||
|     ss << "Primitives / sec: " << std::fixed << Renderer::Instance().GetStatus().primitives * frame_time_.size() | ||||
|        << std::endl; | ||||
| 
 | ||||
|     ss << "Memory: "; | ||||
|     { | ||||
|  | @ -124,22 +123,24 @@ namespace kiwano | |||
|         ss << pmc.PrivateUsage / 1024 << "Kb"; | ||||
|     } | ||||
| 
 | ||||
| 		debug_text_->SetText(ss.str()); | ||||
|     debug_text_.SetText(ss.str()); | ||||
|     debug_text_.Update(); | ||||
| 
 | ||||
| 		if (debug_text_->GetWidth() > GetWidth() - 20) | ||||
|     Size layout_size = debug_text_.GetLayoutSize(); | ||||
|     if (layout_size.x > GetWidth() - 20) | ||||
|     { | ||||
| 			SetWidth(20 + debug_text_->GetWidth()); | ||||
|         SetWidth(20 + layout_size.x); | ||||
|     } | ||||
| 
 | ||||
| 		if (debug_text_->GetHeight() > GetHeight() - 20) | ||||
|     if (layout_size.y > GetHeight() - 20) | ||||
|     { | ||||
| 			SetHeight(20 + debug_text_->GetHeight()); | ||||
|         SetHeight(20 + layout_size.y); | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
| 	bool DebugActor::CheckVisibilty(RenderTarget* rt) const | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| bool DebugActor::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,42 +20,39 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/TextActor.h> | ||||
| #include <kiwano/renderer/Color.h> | ||||
| #include <kiwano/renderer/Brush.h> | ||||
| #include <kiwano/render/TextLayout.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 调试节点 | ||||
|  */ | ||||
| 	class KGE_API DebugActor | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API DebugActor : public Actor | ||||
| { | ||||
| public: | ||||
|     DebugActor(); | ||||
| 
 | ||||
|     virtual ~DebugActor(); | ||||
| 
 | ||||
| 		void OnRender(RenderTarget* rt) override; | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
|     void OnUpdate(Duration dt) override; | ||||
| 
 | ||||
| 	protected: | ||||
| 		bool CheckVisibilty(RenderTarget* rt) const override; | ||||
| protected: | ||||
|     bool CheckVisibility(RenderContext& ctx) const override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     std::locale  comma_locale_; | ||||
|     BrushPtr     background_brush_; | ||||
| 		TextActorPtr	debug_text_; | ||||
|     TextLayout   debug_text_; | ||||
|     Vector<Time> frame_time_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| 
 | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,38 +19,36 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/Frame.h> | ||||
| #include <kiwano/renderer/TextureCache.h> | ||||
| #include <kiwano/render/TextureCache.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Frame::Frame() | ||||
| 	{ | ||||
| 	} | ||||
| Frame::Frame() {} | ||||
| 
 | ||||
| 	bool Frame::Load(String const& file_path) | ||||
| 	{ | ||||
| 		TexturePtr texture = TextureCache::instance().AddOrGetTexture(file_path); | ||||
| bool Frame::Load(String const& file_path) | ||||
| { | ||||
|     TexturePtr texture = TextureCache::Instance().AddOrGetTexture(file_path); | ||||
|     if (texture->IsValid()) | ||||
|     { | ||||
|         SetTexture(texture); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool Frame::Load(Resource const& res) | ||||
| 	{ | ||||
| 		TexturePtr texture = TextureCache::instance().AddOrGetTexture(res); | ||||
| bool Frame::Load(Resource const& res) | ||||
| { | ||||
|     TexturePtr texture = TextureCache::Instance().AddOrGetTexture(res); | ||||
|     if (texture->IsValid()) | ||||
|     { | ||||
|         SetTexture(texture); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Frame::SetCropRect(Rect const& crop_rect) | ||||
| 	{ | ||||
| void Frame::SetCropRect(Rect const& crop_rect) | ||||
| { | ||||
|     if (texture_->IsValid()) | ||||
|     { | ||||
|         auto bitmap_size          = texture_->GetSize(); | ||||
|  | @ -59,10 +57,10 @@ namespace kiwano | |||
|         crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x); | ||||
|         crop_rect_.right_bottom.y = std::min(std::max(crop_rect.right_bottom.y, 0.f), bitmap_size.y); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Frame::SetTexture(TexturePtr texture) | ||||
| 	{ | ||||
| void Frame::SetTexture(TexturePtr texture) | ||||
| { | ||||
|     texture_ = texture; | ||||
|     if (texture_->IsValid()) | ||||
|     { | ||||
|  | @ -70,5 +68,5 @@ namespace kiwano | |||
|         crop_rect_.right_bottom.x                     = texture_->GetWidth(); | ||||
|         crop_rect_.right_bottom.y                     = texture_->GetHeight(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,20 +20,19 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/renderer/Texture.h> | ||||
| #include <kiwano/render/Texture.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(Frame); | ||||
| KGE_DECLARE_SMART_PTR(Frame); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 图像帧 | ||||
|  */ | ||||
| 	class KGE_API Frame | ||||
| 		: public ObjectBase | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API Frame : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构建空图像帧
 | ||||
|     Frame(); | ||||
|  | @ -86,16 +85,37 @@ namespace kiwano | |||
|     /// @brief 获取纹理
 | ||||
|     TexturePtr GetTexture() const; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     TexturePtr texture_; | ||||
|     Rect       crop_rect_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	inline bool				Frame::IsValid() const		{ return texture_ && texture_->IsValid(); } | ||||
| 	inline float			Frame::GetWidth() const		{ return crop_rect_.GetWidth(); } | ||||
| 	inline float			Frame::GetHeight() const	{ return crop_rect_.GetHeight(); } | ||||
| 	inline Size				Frame::GetSize() const		{ return crop_rect_.GetSize(); } | ||||
| 	inline Point			Frame::GetCropPoint() const { return crop_rect_.GetLeftTop(); } | ||||
| 	inline Rect const&		Frame::GetCropRect() const	{ return crop_rect_; } | ||||
| 	inline TexturePtr		Frame::GetTexture() const	{ return texture_; } | ||||
| inline bool Frame::IsValid() const | ||||
| { | ||||
|     return texture_ && texture_->IsValid(); | ||||
| } | ||||
| inline float Frame::GetWidth() const | ||||
| { | ||||
|     return crop_rect_.GetWidth(); | ||||
| } | ||||
| inline float Frame::GetHeight() const | ||||
| { | ||||
|     return crop_rect_.GetHeight(); | ||||
| } | ||||
| inline Size Frame::GetSize() const | ||||
| { | ||||
|     return crop_rect_.GetSize(); | ||||
| } | ||||
| inline Point Frame::GetCropPoint() const | ||||
| { | ||||
|     return crop_rect_.GetLeftTop(); | ||||
| } | ||||
| inline Rect const& Frame::GetCropRect() const | ||||
| { | ||||
|     return crop_rect_; | ||||
| } | ||||
| inline TexturePtr Frame::GetTexture() const | ||||
| { | ||||
|     return texture_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,31 +23,27 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	FrameSequence::FrameSequence() | ||||
| 	{ | ||||
| 	} | ||||
| FrameSequence::FrameSequence() {} | ||||
| 
 | ||||
| 	FrameSequence::FrameSequence(Vector<FramePtr> const& frames) | ||||
| 	{ | ||||
| FrameSequence::FrameSequence(Vector<FramePtr> const& frames) | ||||
| { | ||||
|     this->AddFrames(frames); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	FrameSequence::~FrameSequence() | ||||
| 	{ | ||||
| 	} | ||||
| FrameSequence::~FrameSequence() {} | ||||
| 
 | ||||
| 	void FrameSequence::AddFrame(FramePtr frame) | ||||
| 	{ | ||||
| void FrameSequence::AddFrame(FramePtr frame) | ||||
| { | ||||
|     KGE_ASSERT(frame && "FrameSequence::Add failed, NULL pointer exception"); | ||||
| 
 | ||||
|     if (frame) | ||||
|     { | ||||
|         frames_.push_back(frame); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void FrameSequence::AddFrames(Vector<FramePtr> const& frames) | ||||
| 	{ | ||||
| void FrameSequence::AddFrames(Vector<FramePtr> const& frames) | ||||
| { | ||||
|     if (frames_.empty()) | ||||
|         frames_ = frames; | ||||
|     else | ||||
|  | @ -56,36 +52,36 @@ namespace kiwano | |||
|         for (const auto& texture : frames) | ||||
|             AddFrame(texture); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	FramePtr FrameSequence::GetFrame(size_t index) const | ||||
| 	{ | ||||
| FramePtr FrameSequence::GetFrame(size_t index) const | ||||
| { | ||||
|     KGE_ASSERT(index < frames_.size()); | ||||
|     return frames_[index]; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Vector<FramePtr> const& FrameSequence::GetFrames() const | ||||
| 	{ | ||||
| Vector<FramePtr> const& FrameSequence::GetFrames() const | ||||
| { | ||||
|     return frames_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	size_t FrameSequence::GetFramesCount() const | ||||
| 	{ | ||||
| size_t FrameSequence::GetFramesCount() const | ||||
| { | ||||
|     return frames_.size(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	FrameSequencePtr FrameSequence::Clone() const | ||||
| 	{ | ||||
| FrameSequencePtr FrameSequence::Clone() const | ||||
| { | ||||
|     auto frame_seq = new (std::nothrow) FrameSequence; | ||||
|     if (frame_seq) | ||||
|     { | ||||
|         frame_seq->AddFrames(frames_); | ||||
|     } | ||||
|     return frame_seq; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	FrameSequencePtr FrameSequence::Reverse() const | ||||
| 	{ | ||||
| FrameSequencePtr FrameSequence::Reverse() const | ||||
| { | ||||
|     auto frame_seq = new (std::nothrow) FrameSequence; | ||||
|     if (!frames_.empty()) | ||||
|     { | ||||
|  | @ -96,6 +92,6 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return frame_seq; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,22 +19,21 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/time.h> | ||||
| #include <kiwano/2d/Frame.h> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/Time.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(FrameSequence); | ||||
| KGE_DECLARE_SMART_PTR(FrameSequence); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 序列帧 | ||||
|  */ | ||||
| 	class KGE_API FrameSequence | ||||
| 		: public ObjectBase | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API FrameSequence : public virtual ObjectBase | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构建空序列帧
 | ||||
|     FrameSequence(); | ||||
|  | @ -77,7 +76,7 @@ namespace kiwano | |||
|     /// @brief 获取序列帧的倒转
 | ||||
|     FrameSequencePtr Reverse() const; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Vector<FramePtr> frames_; | ||||
| 	}; | ||||
| } | ||||
| }; | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,33 +19,33 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/GifSprite.h> | ||||
| #include <kiwano/renderer/TextureCache.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <kiwano/render/TextureCache.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	GifSprite::GifSprite() | ||||
| GifSprite::GifSprite() | ||||
|     : animating_(false) | ||||
|     , next_index_(0) | ||||
|     , total_loop_count_(1) | ||||
|     , loop_count_(0) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	bool GifSprite::Load(String const& file_path) | ||||
| 	{ | ||||
| 		GifImagePtr image = TextureCache::instance().AddOrGetGifImage(file_path); | ||||
| bool GifSprite::Load(String const& file_path) | ||||
| { | ||||
|     GifImagePtr image = TextureCache::Instance().AddOrGetGifImage(file_path); | ||||
|     return Load(image); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool GifSprite::Load(Resource const& res) | ||||
| 	{ | ||||
| 		GifImagePtr image = TextureCache::instance().AddOrGetGifImage(res); | ||||
| bool GifSprite::Load(Resource const& res) | ||||
| { | ||||
|     GifImagePtr image = TextureCache::Instance().AddOrGetGifImage(res); | ||||
|     return Load(image); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool GifSprite::Load(GifImagePtr gif) | ||||
| 	{ | ||||
| bool GifSprite::Load(GifImagePtr gif) | ||||
| { | ||||
|     if (gif && gif->IsValid()) | ||||
|     { | ||||
|         gif_ = gif; | ||||
|  | @ -58,7 +58,7 @@ namespace kiwano | |||
| 
 | ||||
|         if (!frame_rt_) | ||||
|         { | ||||
| 				Renderer::instance().CreateTextureRenderTarget(frame_rt_); | ||||
|             Renderer::Instance().CreateTextureRenderTarget(frame_rt_); | ||||
|         } | ||||
| 
 | ||||
|         if (gif_->GetFramesCount() > 0) | ||||
|  | @ -68,20 +68,20 @@ namespace kiwano | |||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::OnRender(RenderTarget* rt) | ||||
| void GifSprite::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     if (frame_to_render_ && CheckVisibility(ctx)) | ||||
|     { | ||||
| 		if (frame_to_render_ && CheckVisibilty(rt)) | ||||
| 		{ | ||||
| 			PrepareToRender(rt); | ||||
|         PrepareToRender(ctx); | ||||
| 
 | ||||
| 			rt->DrawTexture(*frame_to_render_, &frame_.rect, nullptr); | ||||
| 		} | ||||
|         ctx.DrawTexture(*frame_to_render_, &frame_.rect, nullptr); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::Update(Duration dt) | ||||
| 	{ | ||||
| void GifSprite::Update(Duration dt) | ||||
| { | ||||
|     Actor::Update(dt); | ||||
| 
 | ||||
|     if (gif_ && gif_->IsValid() && animating_) | ||||
|  | @ -94,24 +94,24 @@ namespace kiwano | |||
|             ComposeNextFrame(); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::SetGifImage(GifImagePtr gif) | ||||
| 	{ | ||||
| void GifSprite::SetGifImage(GifImagePtr gif) | ||||
| { | ||||
|     gif_ = gif; | ||||
|     RestartAnimation(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::RestartAnimation() | ||||
| 	{ | ||||
| void GifSprite::RestartAnimation() | ||||
| { | ||||
|     animating_           = true; | ||||
|     next_index_          = 0; | ||||
|     loop_count_          = 0; | ||||
|     frame_.disposal_type = GifImage::DisposalType::None; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::ComposeNextFrame() | ||||
| 	{ | ||||
| void GifSprite::ComposeNextFrame() | ||||
| { | ||||
|     KGE_ASSERT(frame_rt_); | ||||
|     KGE_ASSERT(gif_); | ||||
| 
 | ||||
|  | @ -125,10 +125,10 @@ namespace kiwano | |||
| 
 | ||||
|         animating_ = (!EndOfAnimation() && gif_->GetFramesCount() > 1); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::DisposeCurrentFrame() | ||||
| 	{ | ||||
| void GifSprite::DisposeCurrentFrame() | ||||
| { | ||||
|     switch (frame_.disposal_type) | ||||
|     { | ||||
|     case GifImage::DisposalType::Unknown: | ||||
|  | @ -143,10 +143,10 @@ namespace kiwano | |||
|         RestoreSavedFrame(); | ||||
|         break; | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::OverlayNextFrame() | ||||
| 	{ | ||||
| void GifSprite::OverlayNextFrame() | ||||
| { | ||||
|     KGE_ASSERT(frame_rt_); | ||||
|     KGE_ASSERT(gif_ && gif_->IsValid()); | ||||
| 
 | ||||
|  | @ -193,10 +193,10 @@ namespace kiwano | |||
|     { | ||||
|         done_cb_(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::SaveComposedFrame() | ||||
| 	{ | ||||
| void GifSprite::SaveComposedFrame() | ||||
| { | ||||
|     KGE_ASSERT(frame_rt_); | ||||
| 
 | ||||
|     TexturePtr frame_to_be_saved = new Texture; | ||||
|  | @ -206,15 +206,16 @@ namespace kiwano | |||
|         if (!saved_frame_) | ||||
|         { | ||||
|             saved_frame_ = new Texture; | ||||
| 				frame_rt_->CreateTexture(*saved_frame_, frame_to_be_saved->GetSizeInPixels(), frame_to_be_saved->GetPixelFormat()); | ||||
|             frame_rt_->CreateTexture(*saved_frame_, frame_to_be_saved->GetSizeInPixels(), | ||||
|                                      frame_to_be_saved->GetPixelFormat()); | ||||
|         } | ||||
| 
 | ||||
|         saved_frame_->CopyFrom(frame_to_be_saved); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::RestoreSavedFrame() | ||||
| 	{ | ||||
| void GifSprite::RestoreSavedFrame() | ||||
| { | ||||
|     KGE_ASSERT(frame_rt_); | ||||
| 
 | ||||
|     if (saved_frame_) | ||||
|  | @ -226,10 +227,10 @@ namespace kiwano | |||
|             frame_to_copy_to->CopyFrom(saved_frame_); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void GifSprite::ClearCurrentFrameArea() | ||||
| 	{ | ||||
| void GifSprite::ClearCurrentFrameArea() | ||||
| { | ||||
|     KGE_ASSERT(frame_rt_); | ||||
|     frame_rt_->BeginDraw(); | ||||
| 
 | ||||
|  | @ -238,6 +239,6 @@ namespace kiwano | |||
|     frame_rt_->PopClipRect(); | ||||
| 
 | ||||
|     return frame_rt_->EndDraw(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -21,26 +21,25 @@ | |||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/core/Resource.h> | ||||
| #include <kiwano/renderer/RenderTarget.h> | ||||
| #include <kiwano/renderer/GifImage.h> | ||||
| #include <kiwano/render/GifImage.h> | ||||
| #include <kiwano/render/RenderContext.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(GifSprite); | ||||
| KGE_DECLARE_SMART_PTR(GifSprite); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief GIF 精灵 | ||||
|  */ | ||||
| 	class KGE_API GifSprite | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API GifSprite : public Actor | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief GIF播放循环结束回调
 | ||||
|     using LoopDoneCallback = Function<void(int /* times */)>; | ||||
|  | @ -98,9 +97,9 @@ namespace kiwano | |||
|     /// @brief 获取 GIF 图片
 | ||||
|     GifImagePtr GetGifImage() const; | ||||
| 
 | ||||
| 		void OnRender(RenderTarget* rt) override; | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -135,7 +134,7 @@ namespace kiwano | |||
|     /// @brief 清空当前图像区域
 | ||||
|     void ClearCurrentFrameArea(); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     bool                    animating_; | ||||
|     int                     total_loop_count_; | ||||
|     int                     loop_count_; | ||||
|  | @ -147,24 +146,48 @@ namespace kiwano | |||
|     GifImage::Frame         frame_; | ||||
|     TexturePtr              saved_frame_; | ||||
|     TexturePtr              frame_to_render_; | ||||
| 		TextureRenderTargetPtr	frame_rt_; | ||||
| 	}; | ||||
|     TextureRenderContextPtr frame_rt_; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 	inline void							GifSprite::SetLoopCount(int loops)							{ total_loop_count_ = loops; } | ||||
| 
 | ||||
| 	inline void							GifSprite::SetLoopDoneCallback(LoopDoneCallback const& cb)	{ loop_cb_ = cb; } | ||||
| 
 | ||||
| 	inline void							GifSprite::SetDoneCallback(DoneCallback const& cb)			{ done_cb_ = cb; } | ||||
| 
 | ||||
| 	inline GifSprite::LoopDoneCallback	GifSprite::GetLoopDoneCallback() const						{ return loop_cb_; } | ||||
| 
 | ||||
| 	inline GifSprite::DoneCallback		GifSprite::GetDoneCallback() const							{ return done_cb_; } | ||||
| 
 | ||||
| 	inline GifImagePtr					GifSprite::GetGifImage() const								{ return gif_; } | ||||
| 
 | ||||
| 	inline bool							GifSprite::IsLastFrame() const								{ return (next_index_ == 0); } | ||||
| 
 | ||||
| 	inline bool							GifSprite::EndOfAnimation() const							{ return IsLastFrame() && loop_count_ == total_loop_count_ + 1; } | ||||
| inline void GifSprite::SetLoopCount(int loops) | ||||
| { | ||||
|     total_loop_count_ = loops; | ||||
| } | ||||
| 
 | ||||
| inline void GifSprite::SetLoopDoneCallback(LoopDoneCallback const& cb) | ||||
| { | ||||
|     loop_cb_ = cb; | ||||
| } | ||||
| 
 | ||||
| inline void GifSprite::SetDoneCallback(DoneCallback const& cb) | ||||
| { | ||||
|     done_cb_ = cb; | ||||
| } | ||||
| 
 | ||||
| inline GifSprite::LoopDoneCallback GifSprite::GetLoopDoneCallback() const | ||||
| { | ||||
|     return loop_cb_; | ||||
| } | ||||
| 
 | ||||
| inline GifSprite::DoneCallback GifSprite::GetDoneCallback() const | ||||
| { | ||||
|     return done_cb_; | ||||
| } | ||||
| 
 | ||||
| inline GifImagePtr GifSprite::GetGifImage() const | ||||
| { | ||||
|     return gif_; | ||||
| } | ||||
| 
 | ||||
| inline bool GifSprite::IsLastFrame() const | ||||
| { | ||||
|     return (next_index_ == 0); | ||||
| } | ||||
| 
 | ||||
| inline bool GifSprite::EndOfAnimation() const | ||||
| { | ||||
|     return IsLastFrame() && loop_count_ == total_loop_count_ + 1; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,71 +20,63 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Layer.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Layer::Layer() | ||||
| Layer::Layer() | ||||
|     : swallow_(false) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	Layer::~Layer() | ||||
| 	{ | ||||
| 	} | ||||
| Layer::~Layer() {} | ||||
| 
 | ||||
| 	void Layer::SetClipRect(Rect const& clip_rect) | ||||
| 	{ | ||||
| void Layer::SetClipRect(Rect const& clip_rect) | ||||
| { | ||||
|     area_.SetAreaRect(clip_rect); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Layer::SetOpacity(float opacity) | ||||
| 	{ | ||||
| void Layer::SetOpacity(float opacity) | ||||
| { | ||||
|     // Actor::SetOpacity(opacity);
 | ||||
|     area_.SetOpacity(opacity); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Layer::SetMaskGeometry(Geometry const& mask) | ||||
| 	{ | ||||
| void Layer::SetMaskGeometry(Geometry const& mask) | ||||
| { | ||||
|     area_.SetMaskGeometry(mask); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Layer::SetMaskTransform(Matrix3x2 const& transform) | ||||
| 	{ | ||||
| void Layer::SetMaskTransform(Matrix3x2 const& transform) | ||||
| { | ||||
|     area_.SetMaskTransform(transform); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Layer::Dispatch(Event& evt) | ||||
| 	{ | ||||
| bool Layer::DispatchEvent(Event* evt) | ||||
| { | ||||
|     if (!IsVisible()) | ||||
| 			return; | ||||
|         return true; | ||||
| 
 | ||||
| 		if (!swallow_) | ||||
|     if (swallow_) | ||||
|     { | ||||
| 			ActorPtr prev; | ||||
| 			for (auto child = GetAllChildren().last_item(); child; child = prev) | ||||
| 			{ | ||||
| 				prev = child->prev_item(); | ||||
| 				child->Dispatch(evt); | ||||
| 			} | ||||
|         return EventDispatcher::DispatchEvent(evt); | ||||
|     } | ||||
|     return Actor::DispatchEvent(evt); | ||||
| } | ||||
| 
 | ||||
| 		EventDispatcher::Dispatch(evt); | ||||
| 	} | ||||
| void Layer::Render(RenderContext& ctx) | ||||
| { | ||||
|     ctx.PushLayer(area_); | ||||
| 
 | ||||
| 	void Layer::Render(RenderTarget* rt) | ||||
| 	{ | ||||
| 		rt->PushLayer(area_); | ||||
|     Actor::Render(ctx); | ||||
| 
 | ||||
| 		Actor::Render(rt); | ||||
|     ctx.PopLayer(); | ||||
| } | ||||
| 
 | ||||
| 		rt->PopLayer(); | ||||
| 	} | ||||
| 
 | ||||
| 	bool Layer::CheckVisibilty(RenderTarget* rt) const | ||||
| 	{ | ||||
| bool Layer::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     // Do not need to render Layer
 | ||||
|     return false; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,26 +20,25 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/renderer/LayerArea.h> | ||||
| #include <kiwano/renderer/RenderTarget.h> | ||||
| #include <kiwano/render/LayerArea.h> | ||||
| #include <kiwano/render/RenderContext.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(Layer); | ||||
| KGE_DECLARE_SMART_PTR(Layer); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 图层 | ||||
|  */ | ||||
| 	class KGE_API Layer | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API Layer : public Actor | ||||
| { | ||||
| public: | ||||
|     Layer(); | ||||
| 
 | ||||
|     virtual ~Layer(); | ||||
|  | @ -82,26 +81,37 @@ namespace kiwano | |||
|     /// @brief 获取图层区域
 | ||||
|     LayerArea const& GetArea() const; | ||||
| 
 | ||||
| 		void Dispatch(Event& evt) override; | ||||
|     bool DispatchEvent(Event* evt) override; | ||||
| 
 | ||||
| 	protected: | ||||
| 		void Render(RenderTarget* rt) override; | ||||
| protected: | ||||
|     void Render(RenderContext& ctx) override; | ||||
| 
 | ||||
| 		bool CheckVisibilty(RenderTarget* rt) const override; | ||||
|     bool CheckVisibility(RenderContext& ctx) const override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     bool      swallow_; | ||||
|     LayerArea area_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| 
 | ||||
| 	inline bool				Layer::IsSwallowEventsEnabled() const	{ return swallow_; } | ||||
| 
 | ||||
| 	inline void				Layer::SetSwallowEvents(bool enabled)	{ swallow_ = enabled; } | ||||
| 
 | ||||
| 	inline void				Layer::SetArea(LayerArea const& area)	{ area_ = area; } | ||||
| 
 | ||||
| 	inline LayerArea const&	Layer::GetArea() const					{ return area_; } | ||||
| /** @} */ | ||||
| 
 | ||||
| inline bool Layer::IsSwallowEventsEnabled() const | ||||
| { | ||||
|     return swallow_; | ||||
| } | ||||
| 
 | ||||
| inline void Layer::SetSwallowEvents(bool enabled) | ||||
| { | ||||
|     swallow_ = enabled; | ||||
| } | ||||
| 
 | ||||
| inline void Layer::SetArea(LayerArea const& area) | ||||
| { | ||||
|     area_ = area; | ||||
| } | ||||
| 
 | ||||
| inline LayerArea const& Layer::GetArea() const | ||||
| { | ||||
|     return area_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,50 +20,48 @@ | |||
| 
 | ||||
| #include <kiwano/2d/ShapeActor.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	ShapeActor::ShapeActor() | ||||
| ShapeActor::ShapeActor() | ||||
|     : stroke_width_(1.f) | ||||
| 		, stroke_style_(StrokeStyle::Miter) | ||||
| 	{ | ||||
| 	} | ||||
|     , stroke_style_() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ShapeActor::~ShapeActor() | ||||
| 	{ | ||||
| 	} | ||||
| ShapeActor::~ShapeActor() {} | ||||
| 
 | ||||
| 	Rect ShapeActor::GetBounds() const | ||||
| 	{ | ||||
| Rect ShapeActor::GetBounds() const | ||||
| { | ||||
|     return bounds_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Rect ShapeActor::GetBoundingBox() const | ||||
| 	{ | ||||
| Rect ShapeActor::GetBoundingBox() const | ||||
| { | ||||
|     if (!geo_.IsValid()) | ||||
|         return Rect{}; | ||||
| 
 | ||||
|     return geo_.GetBoundingBox(GetTransformMatrix()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool ShapeActor::ContainsPoint(const Point& point) const | ||||
| 	{ | ||||
| bool ShapeActor::ContainsPoint(const Point& point) const | ||||
| { | ||||
|     return geo_.ContainsPoint(point, &GetTransformMatrix()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ShapeActor::SetStrokeWidth(float width) | ||||
| 	{ | ||||
| void ShapeActor::SetStrokeWidth(float width) | ||||
| { | ||||
|     stroke_width_ = std::max(width, 0.f); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ShapeActor::SetStrokeStyle(StrokeStyle stroke_style) | ||||
| 	{ | ||||
| void ShapeActor::SetStrokeStyle(const StrokeStyle& stroke_style) | ||||
| { | ||||
|     stroke_style_ = stroke_style; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ShapeActor::SetGeometry(Geometry const& geometry) | ||||
| 	{ | ||||
| void ShapeActor::SetGeometry(Geometry const& geometry) | ||||
| { | ||||
|     geo_ = geometry; | ||||
|     if (geo_.IsValid()) | ||||
|     { | ||||
|  | @ -75,10 +73,10 @@ namespace kiwano | |||
|         bounds_ = Rect{}; | ||||
|         SetSize(0.f, 0.f); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ShapeActor::OnRender(RenderTarget* rt) | ||||
| 	{ | ||||
| void ShapeActor::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     // Create default brush
 | ||||
|     if (!fill_brush_) | ||||
|     { | ||||
|  | @ -92,187 +90,150 @@ namespace kiwano | |||
|         stroke_brush_->SetColor(Color::Transparent); | ||||
|     } | ||||
| 
 | ||||
| 		rt->SetCurrentBrush(stroke_brush_); | ||||
| 		rt->DrawGeometry(geo_, stroke_width_ * 2 /* twice width for widening */, stroke_style_); | ||||
|     ctx.SetCurrentBrush(stroke_brush_); | ||||
|     ctx.DrawGeometry(geo_, stroke_width_ * 2 /* twice width for widening */, stroke_style_); | ||||
| 
 | ||||
| 		rt->SetCurrentBrush(fill_brush_); | ||||
| 		rt->FillGeometry(geo_); | ||||
| 	} | ||||
|     ctx.SetCurrentBrush(fill_brush_); | ||||
|     ctx.FillGeometry(geo_); | ||||
| } | ||||
| 
 | ||||
| 	bool ShapeActor::CheckVisibilty(RenderTarget* rt) const | ||||
| 	{ | ||||
| 		return geo_.IsValid() && Actor::CheckVisibilty(rt); | ||||
| 	} | ||||
| bool ShapeActor::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     return geo_.IsValid() && Actor::CheckVisibility(ctx); | ||||
| } | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// LineActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // LineActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	LineActor::LineActor() | ||||
| 	{ | ||||
| 	} | ||||
| LineActor::LineActor() {} | ||||
| 
 | ||||
| 	LineActor::~LineActor() | ||||
| 	{ | ||||
| 	} | ||||
| LineActor::~LineActor() {} | ||||
| 
 | ||||
| 	void LineActor::SetLine(Point const& begin, Point const& end) | ||||
| 	{ | ||||
| void LineActor::SetLine(Point const& begin, Point const& end) | ||||
| { | ||||
|     if (begin_ != begin || end_ != end) | ||||
|     { | ||||
|         begin_ = begin; | ||||
|         end_   = end; | ||||
|         SetGeometry(Geometry::CreateLine(begin, end)); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // RectActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// RectActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| RectActor::RectActor() {} | ||||
| 
 | ||||
| 	RectActor::RectActor() | ||||
| 	{ | ||||
| 	} | ||||
| RectActor::~RectActor() {} | ||||
| 
 | ||||
| 	RectActor::~RectActor() | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	void RectActor::SetRectSize(Size const& size) | ||||
| 	{ | ||||
| void RectActor::SetRectSize(Size const& size) | ||||
| { | ||||
|     if (size != rect_size_) | ||||
|     { | ||||
|         rect_size_ = size; | ||||
|         SetGeometry(Geometry::CreateRect(Rect{ Point{}, size })); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // RoundRectActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// RoundRectActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| RoundRectActor::RoundRectActor() {} | ||||
| 
 | ||||
| 	RoundRectActor::RoundRectActor() | ||||
| 	{ | ||||
| 	} | ||||
| RoundRectActor::~RoundRectActor() {} | ||||
| 
 | ||||
| 	RoundRectActor::~RoundRectActor() | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	void RoundRectActor::SetRadius(Vec2 const& radius) | ||||
| 	{ | ||||
| void RoundRectActor::SetRadius(Vec2 const& radius) | ||||
| { | ||||
|     SetRoundedRect(GetSize(), radius); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void RoundRectActor::SetRectSize(Size const& size) | ||||
| 	{ | ||||
| void RoundRectActor::SetRectSize(Size const& size) | ||||
| { | ||||
|     SetRoundedRect(size, radius_); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) | ||||
| 	{ | ||||
| void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) | ||||
| { | ||||
|     if (rect_size_ != size || radius_ != radius) | ||||
|     { | ||||
|         rect_size_ = size; | ||||
|         radius_    = radius; | ||||
|         SetGeometry(Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius)); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // CircleActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// CircleActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	CircleActor::CircleActor() | ||||
| CircleActor::CircleActor() | ||||
|     : radius_(0.f) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	CircleActor::~CircleActor() | ||||
| 	{ | ||||
| 	} | ||||
| CircleActor::~CircleActor() {} | ||||
| 
 | ||||
| 	void CircleActor::SetRadius(float radius) | ||||
| 	{ | ||||
| void CircleActor::SetRadius(float radius) | ||||
| { | ||||
|     if (radius_ != radius) | ||||
|     { | ||||
|         radius_ = radius; | ||||
|         SetGeometry(Geometry::CreateCircle(Point{ radius, radius }, radius)); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // EllipseActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// EllipseActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| EllipseActor::EllipseActor() {} | ||||
| 
 | ||||
| 	EllipseActor::EllipseActor() | ||||
| 	{ | ||||
| 	} | ||||
| EllipseActor::~EllipseActor() {} | ||||
| 
 | ||||
| 	EllipseActor::~EllipseActor() | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	void EllipseActor::SetRadius(Vec2 const& radius) | ||||
| 	{ | ||||
| void EllipseActor::SetRadius(Vec2 const& radius) | ||||
| { | ||||
|     if (radius_ != radius) | ||||
|     { | ||||
|         radius_ = radius; | ||||
|         SetGeometry(Geometry::CreateEllipse(radius, radius)); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // PolygonActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// PolygonActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| PolygonActor::PolygonActor() {} | ||||
| 
 | ||||
| 	PolygonActor::PolygonActor() | ||||
| 	{ | ||||
| 	} | ||||
| PolygonActor::~PolygonActor() {} | ||||
| 
 | ||||
| 	PolygonActor::~PolygonActor() | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	void PolygonActor::SetVertices(Vector<Point> const& points) | ||||
| 	{ | ||||
| void PolygonActor::SetVertices(Vector<Point> const& points) | ||||
| { | ||||
|     if (points.size() > 1) | ||||
|     { | ||||
|         SetGeometry( | ||||
| 				GeometrySink() | ||||
| 				.BeginPath(points[0]) | ||||
| 				.AddLines(&points[1], points.size() - 1) | ||||
| 				.EndPath(true) | ||||
| 				.GetGeometry() | ||||
| 			); | ||||
| 		} | ||||
|             GeometrySink().BeginPath(points[0]).AddLines(&points[1], points.size() - 1).EndPath(true).GetGeometry()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // PathShapeActor
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// PathShapeActor
 | ||||
| 	//-------------------------------------------------------
 | ||||
| PathShapeActor::PathShapeActor() {} | ||||
| 
 | ||||
| 	PathShapeActor::PathShapeActor() | ||||
| 	{ | ||||
| 	} | ||||
| PathShapeActor::~PathShapeActor() {} | ||||
| 
 | ||||
| 	PathShapeActor::~PathShapeActor() | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	void PathShapeActor::BeginPath(Point const& begin_pos) | ||||
| 	{ | ||||
| void PathShapeActor::BeginPath(Point const& begin_pos) | ||||
| { | ||||
|     sink_.BeginPath(begin_pos); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void PathShapeActor::EndPath(bool closed) | ||||
| 	{ | ||||
| void PathShapeActor::EndPath(bool closed) | ||||
| { | ||||
|     sink_.EndPath(closed); | ||||
|     Geometry geo = sink_.GetGeometry(); | ||||
| 
 | ||||
|  | @ -280,31 +241,31 @@ namespace kiwano | |||
|     { | ||||
|         SetGeometry(geo); | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
| 	void PathShapeActor::AddLine(Point const& point) | ||||
| 	{ | ||||
| 		sink_.AddLine(point); | ||||
| 	} | ||||
| 
 | ||||
| 	void PathShapeActor::AddLines(Vector<Point> const& points) | ||||
| 	{ | ||||
| 		sink_.AddLines(points); | ||||
| 	} | ||||
| 
 | ||||
| 	void PathShapeActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||
| 	{ | ||||
| 		sink_.AddBezier(point1, point2, point3); | ||||
| 	} | ||||
| 
 | ||||
| 	void PathShapeActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||
| 	{ | ||||
| 		sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||
| 	} | ||||
| 
 | ||||
| 	void PathShapeActor::ClearPath() | ||||
| 	{ | ||||
| 		SetGeometry(Geometry()); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void PathShapeActor::AddLine(Point const& point) | ||||
| { | ||||
|     sink_.AddLine(point); | ||||
| } | ||||
| 
 | ||||
| void PathShapeActor::AddLines(Vector<Point> const& points) | ||||
| { | ||||
|     sink_.AddLines(points); | ||||
| } | ||||
| 
 | ||||
| void PathShapeActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||
| { | ||||
|     sink_.AddBezier(point1, point2, point3); | ||||
| } | ||||
| 
 | ||||
| void PathShapeActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||
| { | ||||
|     sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||
| } | ||||
| 
 | ||||
| void PathShapeActor::ClearPath() | ||||
| { | ||||
|     SetGeometry(Geometry()); | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,35 +20,34 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/renderer/Brush.h> | ||||
| #include <kiwano/renderer/Geometry.h> | ||||
| #include <kiwano/renderer/GeometrySink.h> | ||||
| #include <kiwano/renderer/StrokeStyle.h> | ||||
| #include <kiwano/render/Brush.h> | ||||
| #include <kiwano/render/Geometry.h> | ||||
| #include <kiwano/render/GeometrySink.h> | ||||
| #include <kiwano/render/StrokeStyle.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(ShapeActor); | ||||
| 	KGE_DECLARE_SMART_PTR(LineActor); | ||||
| 	KGE_DECLARE_SMART_PTR(RectActor); | ||||
| 	KGE_DECLARE_SMART_PTR(RoundRectActor); | ||||
| 	KGE_DECLARE_SMART_PTR(CircleActor); | ||||
| 	KGE_DECLARE_SMART_PTR(EllipseActor); | ||||
| 	KGE_DECLARE_SMART_PTR(PolygonActor); | ||||
| 	KGE_DECLARE_SMART_PTR(PathShapeActor); | ||||
| KGE_DECLARE_SMART_PTR(ShapeActor); | ||||
| KGE_DECLARE_SMART_PTR(LineActor); | ||||
| KGE_DECLARE_SMART_PTR(RectActor); | ||||
| KGE_DECLARE_SMART_PTR(RoundRectActor); | ||||
| KGE_DECLARE_SMART_PTR(CircleActor); | ||||
| KGE_DECLARE_SMART_PTR(EllipseActor); | ||||
| KGE_DECLARE_SMART_PTR(PolygonActor); | ||||
| KGE_DECLARE_SMART_PTR(PathShapeActor); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 二维形状角色 | ||||
|  */ | ||||
| 	class KGE_API ShapeActor | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API ShapeActor : public Actor | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造二维形状角色
 | ||||
|     ShapeActor(); | ||||
|  | @ -69,7 +68,7 @@ namespace kiwano | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取线条样式
 | ||||
| 		StrokeStyle SetStrokeStyle() const; | ||||
|     const StrokeStyle& GetStrokeStyle() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取形状
 | ||||
|  | @ -113,33 +112,31 @@ namespace kiwano | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置线条样式
 | ||||
| 		void SetStrokeStyle(StrokeStyle stroke_style); | ||||
|     void SetStrokeStyle(const StrokeStyle& stroke_style); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置几何形状
 | ||||
|     void SetGeometry(Geometry const& geometry); | ||||
| 
 | ||||
| 		void OnRender(RenderTarget* rt) override; | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
| 	protected: | ||||
| 		bool CheckVisibilty(RenderTarget* rt) const override; | ||||
| protected: | ||||
|     bool CheckVisibility(RenderContext& ctx) const override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     BrushPtr    fill_brush_; | ||||
|     BrushPtr    stroke_brush_; | ||||
|     float       stroke_width_; | ||||
|     StrokeStyle stroke_style_; | ||||
|     Rect        bounds_; | ||||
|     Geometry    geo_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 线段图形角色
 | ||||
| 	class KGE_API LineActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 线段图形角色
 | ||||
| class KGE_API LineActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     LineActor(); | ||||
| 
 | ||||
|     virtual ~LineActor(); | ||||
|  | @ -168,18 +165,16 @@ namespace kiwano | |||
|     /// @param end 线段终点
 | ||||
|     void SetLine(Point const& begin, Point const& end); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Point begin_; | ||||
|     Point end_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 矩形角色
 | ||||
| 	class KGE_API RectActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 矩形角色
 | ||||
| class KGE_API RectActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     RectActor(); | ||||
| 
 | ||||
|     virtual ~RectActor(); | ||||
|  | @ -193,18 +188,15 @@ namespace kiwano | |||
|     /// @param size 矩形大小
 | ||||
|     void SetRectSize(Size const& size); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Size rect_size_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 圆角矩形角色
 | ||||
| 	class KGE_API RoundRectActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 圆角矩形角色
 | ||||
| class KGE_API RoundRectActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     RoundRectActor(); | ||||
| 
 | ||||
|     virtual ~RoundRectActor(); | ||||
|  | @ -233,18 +225,16 @@ namespace kiwano | |||
|     /// @param radius 圆角半径
 | ||||
|     void SetRoundedRect(Size const& size, Vec2 const& radius); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Size rect_size_; | ||||
|     Vec2 radius_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 圆形角色
 | ||||
| 	class KGE_API CircleActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 圆形角色
 | ||||
| class KGE_API CircleActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     CircleActor(); | ||||
| 
 | ||||
|     virtual ~CircleActor(); | ||||
|  | @ -258,17 +248,15 @@ namespace kiwano | |||
|     /// @param radius 圆形半径
 | ||||
|     void SetRadius(float radius); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     float radius_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 椭圆角色
 | ||||
| 	class KGE_API EllipseActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 椭圆角色
 | ||||
| class KGE_API EllipseActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     EllipseActor(); | ||||
| 
 | ||||
|     virtual ~EllipseActor(); | ||||
|  | @ -282,17 +270,15 @@ namespace kiwano | |||
|     /// @param radius 椭圆半径
 | ||||
|     void SetRadius(Vec2 const& radius); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Vec2 radius_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 多边形角色
 | ||||
| 	class KGE_API PolygonActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 多边形角色
 | ||||
| class KGE_API PolygonActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     PolygonActor(); | ||||
| 
 | ||||
|     virtual ~PolygonActor(); | ||||
|  | @ -301,15 +287,13 @@ namespace kiwano | |||
|     /// @brief 设置多边形端点
 | ||||
|     /// @param points 多边形端点集合
 | ||||
|     void SetVertices(Vector<Point> const& points); | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 路径图形角色
 | ||||
| 	class KGE_API PathShapeActor | ||||
| 		: public ShapeActor | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 路径图形角色
 | ||||
| class KGE_API PathShapeActor : public ShapeActor | ||||
| { | ||||
| public: | ||||
|     PathShapeActor(); | ||||
| 
 | ||||
|     virtual ~PathShapeActor(); | ||||
|  | @ -354,49 +338,97 @@ namespace kiwano | |||
|     /// @brief 清除路径
 | ||||
|     void ClearPath(); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     GeometrySink sink_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 	inline void ShapeActor::SetStrokeColor(Color const& color) | ||||
| 	{ | ||||
| inline void ShapeActor::SetStrokeColor(Color const& color) | ||||
| { | ||||
|     if (!stroke_brush_) | ||||
|     { | ||||
|         stroke_brush_ = new Brush; | ||||
|     } | ||||
|     stroke_brush_->SetColor(color); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	inline void ShapeActor::SetFillColor(Color const& color) | ||||
| 	{ | ||||
| inline void ShapeActor::SetFillColor(Color const& color) | ||||
| { | ||||
|     if (!fill_brush_) | ||||
|     { | ||||
|         fill_brush_ = new Brush; | ||||
|     } | ||||
|     fill_brush_->SetColor(color); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void			ShapeActor::SetFillBrush(BrushPtr brush)		{ fill_brush_ = brush; } | ||||
| 	inline void			ShapeActor::SetStrokeBrush(BrushPtr brush)		{ stroke_brush_ = brush; } | ||||
| 	inline BrushPtr		ShapeActor::GetFillBrush() const				{ return fill_brush_; } | ||||
| 	inline BrushPtr		ShapeActor::GetStrokeBrush() const				{ return stroke_brush_; } | ||||
| 	inline float		ShapeActor::GetStrokeWidth() const				{ return stroke_width_; } | ||||
| 	inline StrokeStyle	ShapeActor::SetStrokeStyle() const				{ return stroke_style_; } | ||||
| 	inline Geometry		ShapeActor::GetGeometry() const					{ return geo_; } | ||||
| 
 | ||||
| 	inline Point const& LineActor::GetBeginPoint() const				{ return begin_; } | ||||
| 	inline Point const& LineActor::GetEndPoint() const					{ return end_; } | ||||
| 	inline void			LineActor::SetBeginPoint(Point const& begin)	{ SetLine(begin, end_); } | ||||
| 	inline void			LineActor::SetEndPoint(Point const& end)		{ SetLine(begin_, end); } | ||||
| 
 | ||||
| 	inline Size const&	RectActor::GetRectSize() const					{ return rect_size_; } | ||||
| 
 | ||||
| 	inline Vec2			RoundRectActor::GetRadius() const				{ return radius_; } | ||||
| 	inline Size			RoundRectActor::GetRectSize() const				{ return GetSize(); } | ||||
| 
 | ||||
| 	inline float		CircleActor::GetRadius() const					{ return radius_; } | ||||
| 
 | ||||
| 	inline Vec2			EllipseActor::GetRadius() const					{ return radius_; } | ||||
| } | ||||
| 
 | ||||
| inline void ShapeActor::SetFillBrush(BrushPtr brush) | ||||
| { | ||||
|     fill_brush_ = brush; | ||||
| } | ||||
| inline void ShapeActor::SetStrokeBrush(BrushPtr brush) | ||||
| { | ||||
|     stroke_brush_ = brush; | ||||
| } | ||||
| inline BrushPtr ShapeActor::GetFillBrush() const | ||||
| { | ||||
|     return fill_brush_; | ||||
| } | ||||
| inline BrushPtr ShapeActor::GetStrokeBrush() const | ||||
| { | ||||
|     return stroke_brush_; | ||||
| } | ||||
| inline float ShapeActor::GetStrokeWidth() const | ||||
| { | ||||
|     return stroke_width_; | ||||
| } | ||||
| inline const StrokeStyle& ShapeActor::GetStrokeStyle() const | ||||
| { | ||||
|     return stroke_style_; | ||||
| } | ||||
| inline Geometry ShapeActor::GetGeometry() const | ||||
| { | ||||
|     return geo_; | ||||
| } | ||||
| 
 | ||||
| inline Point const& LineActor::GetBeginPoint() const | ||||
| { | ||||
|     return begin_; | ||||
| } | ||||
| inline Point const& LineActor::GetEndPoint() const | ||||
| { | ||||
|     return end_; | ||||
| } | ||||
| inline void LineActor::SetBeginPoint(Point const& begin) | ||||
| { | ||||
|     SetLine(begin, end_); | ||||
| } | ||||
| inline void LineActor::SetEndPoint(Point const& end) | ||||
| { | ||||
|     SetLine(begin_, end); | ||||
| } | ||||
| 
 | ||||
| inline Size const& RectActor::GetRectSize() const | ||||
| { | ||||
|     return rect_size_; | ||||
| } | ||||
| 
 | ||||
| inline Vec2 RoundRectActor::GetRadius() const | ||||
| { | ||||
|     return radius_; | ||||
| } | ||||
| inline Size RoundRectActor::GetRectSize() const | ||||
| { | ||||
|     return GetSize(); | ||||
| } | ||||
| 
 | ||||
| inline float CircleActor::GetRadius() const | ||||
| { | ||||
|     return radius_; | ||||
| } | ||||
| 
 | ||||
| inline Vec2 EllipseActor::GetRadius() const | ||||
| { | ||||
|     return radius_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,20 +19,16 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/Sprite.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Sprite::Sprite() | ||||
| 	{ | ||||
| 	} | ||||
| Sprite::Sprite() {} | ||||
| 
 | ||||
| 	Sprite::~Sprite() | ||||
| 	{ | ||||
| 	} | ||||
| Sprite::~Sprite() {} | ||||
| 
 | ||||
| 	bool Sprite::Load(String const& file_path) | ||||
| 	{ | ||||
| bool Sprite::Load(String const& file_path) | ||||
| { | ||||
|     FramePtr frame = new (std::nothrow) Frame; | ||||
|     if (frame->Load(file_path)) | ||||
|     { | ||||
|  | @ -40,10 +36,10 @@ namespace kiwano | |||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool Sprite::Load(Resource const& res) | ||||
| 	{ | ||||
| bool Sprite::Load(Resource const& res) | ||||
| { | ||||
|     FramePtr frame = new (std::nothrow) Frame; | ||||
|     if (frame->Load(res)) | ||||
|     { | ||||
|  | @ -51,19 +47,19 @@ namespace kiwano | |||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Sprite::SetCropRect(const Rect& crop_rect) | ||||
| 	{ | ||||
| void Sprite::SetCropRect(const Rect& crop_rect) | ||||
| { | ||||
|     if (frame_) | ||||
|     { | ||||
|         frame_->SetCropRect(crop_rect); | ||||
|         SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() }); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Sprite::SetFrame(FramePtr frame) | ||||
| 	{ | ||||
| void Sprite::SetFrame(FramePtr frame) | ||||
| { | ||||
|     if (frame_ != frame) | ||||
|     { | ||||
|         frame_ = frame; | ||||
|  | @ -72,15 +68,15 @@ namespace kiwano | |||
|             SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() }); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
| 	void Sprite::OnRender(RenderTarget* rt) | ||||
| 	{ | ||||
| 		rt->DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds()); | ||||
| 	} | ||||
| 
 | ||||
| 	bool Sprite::CheckVisibilty(RenderTarget* rt) const | ||||
| 	{ | ||||
| 		return frame_ && frame_->IsValid() && Actor::CheckVisibilty(rt); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void Sprite::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds()); | ||||
| } | ||||
| 
 | ||||
| bool Sprite::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     return frame_ && frame_->IsValid() && Actor::CheckVisibility(ctx); | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -24,21 +24,20 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(Sprite); | ||||
| KGE_DECLARE_SMART_PTR(Sprite); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief ¾«Áé | ||||
|  */ | ||||
| 	class KGE_API Sprite | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API Sprite : public Actor | ||||
| { | ||||
| public: | ||||
|     Sprite(); | ||||
| 
 | ||||
|     virtual ~Sprite(); | ||||
|  | @ -67,17 +66,19 @@ namespace kiwano | |||
|     /// @param[in] frame ͼÏñÖ¡
 | ||||
|     void SetFrame(FramePtr frame); | ||||
| 
 | ||||
| 		void OnRender(RenderTarget* rt) override; | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
| 	protected: | ||||
| 		bool CheckVisibilty(RenderTarget* rt) const override; | ||||
| protected: | ||||
|     bool CheckVisibility(RenderContext& ctx) const override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     FramePtr frame_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| 
 | ||||
| 	inline FramePtr Sprite::GetFrame() const { return frame_; } | ||||
| /** @} */ | ||||
| 
 | ||||
| inline FramePtr Sprite::GetFrame() const | ||||
| { | ||||
|     return frame_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,35 +20,33 @@ | |||
| 
 | ||||
| #include <kiwano/2d/Stage.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Stage::Stage() | ||||
| 	{ | ||||
| Stage::Stage() | ||||
| { | ||||
|     SetStage(this); | ||||
| 
 | ||||
|     SetAnchor(Vec2{ 0, 0 }); | ||||
| 		SetSize(Renderer::instance().GetOutputSize()); | ||||
| 	} | ||||
|     SetSize(Renderer::Instance().GetOutputSize()); | ||||
| } | ||||
| 
 | ||||
| 	Stage::~Stage() | ||||
| 	{ | ||||
| 	} | ||||
| Stage::~Stage() {} | ||||
| 
 | ||||
| 	void Stage::OnEnter() | ||||
| 	{ | ||||
| void Stage::OnEnter() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Stage entered"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Stage::OnExit() | ||||
| 	{ | ||||
| void Stage::OnExit() | ||||
| { | ||||
|     KGE_SYS_LOG(L"Stage exited"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Stage::RenderBorder(RenderTarget* rt) | ||||
| 	{ | ||||
| 		rt->SetBrushOpacity(1.0f); | ||||
| void Stage::RenderBorder(RenderContext& ctx) | ||||
| { | ||||
|     ctx.SetBrushOpacity(GetDisplayedOpacity()); | ||||
| 
 | ||||
|     if (!border_fill_brush_) | ||||
|     { | ||||
|  | @ -62,7 +60,7 @@ namespace kiwano | |||
|         border_stroke_brush_->SetColor(Color(Color::Red, .8f)); | ||||
|     } | ||||
| 
 | ||||
| 		Actor::RenderBorder(rt); | ||||
| 	} | ||||
| 
 | ||||
|     Actor::RenderBorder(ctx); | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,30 +20,29 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/renderer/Brush.h> | ||||
| #include <kiwano/render/Brush.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(Stage); | ||||
| KGE_DECLARE_SMART_PTR(Stage); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 舞台 | ||||
|  * @details 舞台是所有角色的载体,是导演直接控制的对象 | ||||
|  * @see kiwano::Actor kiwano::Director | ||||
|  */ | ||||
| 	class KGE_API Stage | ||||
| 		: public Actor | ||||
| 	{ | ||||
| class KGE_API Stage : public Actor | ||||
| { | ||||
|     friend class Transition; | ||||
|     friend class Director; | ||||
| 
 | ||||
| 	public: | ||||
| public: | ||||
|     Stage(); | ||||
| 
 | ||||
|     virtual ~Stage(); | ||||
|  | @ -74,36 +73,35 @@ namespace kiwano | |||
|     /// @brief 设置角色边界轮廓画刷
 | ||||
|     void SetBorderStrokeBrush(BrushPtr brush); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 绘制所有子角色的边界
 | ||||
| 		void RenderBorder(RenderTarget* rt) override; | ||||
|     void RenderBorder(RenderContext& ctx) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     BrushPtr border_fill_brush_; | ||||
|     BrushPtr border_stroke_brush_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 	inline BrushPtr Stage::GetBorderFillBrush() const | ||||
| 	{ | ||||
| inline BrushPtr Stage::GetBorderFillBrush() const | ||||
| { | ||||
|     return border_fill_brush_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline BrushPtr Stage::GetBorderStrokeBrush() const | ||||
| 	{ | ||||
| 		return border_stroke_brush_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Stage::SetBorderFillBrush(BrushPtr brush) | ||||
| 	{ | ||||
| 		border_fill_brush_ = brush; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Stage::SetBorderStrokeBrush(BrushPtr brush) | ||||
| 	{ | ||||
| 		border_stroke_brush_ = brush; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| inline BrushPtr Stage::GetBorderStrokeBrush() const | ||||
| { | ||||
|     return border_stroke_brush_; | ||||
| } | ||||
| 
 | ||||
| inline void Stage::SetBorderFillBrush(BrushPtr brush) | ||||
| { | ||||
|     border_fill_brush_ = brush; | ||||
| } | ||||
| 
 | ||||
| inline void Stage::SetBorderStrokeBrush(BrushPtr brush) | ||||
| { | ||||
|     border_stroke_brush_ = brush; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,16 +20,16 @@ | |||
| 
 | ||||
| #include <kiwano/2d/TextActor.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	namespace | ||||
| 	{ | ||||
| 		TextStyle text_default_style; | ||||
| namespace | ||||
| { | ||||
| TextStyle text_default_style; | ||||
| 
 | ||||
| 		void InitDefaultTextStyle() | ||||
| 		{ | ||||
| void InitDefaultTextStyle() | ||||
| { | ||||
|     static bool inited = false; | ||||
|     if (!inited) | ||||
|     { | ||||
|  | @ -39,58 +39,60 @@ namespace kiwano | |||
|         text_default_style.fill_brush = new Brush; | ||||
|         text_default_style.fill_brush->SetColor(Color::White); | ||||
|     } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| }  // namespace
 | ||||
| 
 | ||||
| 	void TextActor::SetDefaultStyle(TextStyle const & style) | ||||
| 	{ | ||||
| void TextActor::SetDefaultStyle(TextStyle const& style) | ||||
| { | ||||
|     text_default_style = style; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	const TextStyle& TextActor::GetDefaultStyle() | ||||
| 	{ | ||||
| const TextStyle& TextActor::GetDefaultStyle() | ||||
| { | ||||
|     InitDefaultTextStyle(); | ||||
|     return text_default_style; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	TextActor::TextActor() | ||||
| TextActor::TextActor() | ||||
|     : TextActor(String()) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	TextActor::TextActor(String const& text) | ||||
| 		: TextActor(text, text_default_style) | ||||
| 	{ | ||||
| 	} | ||||
| TextActor::TextActor(String const& text) | ||||
|     : TextActor(text, GetDefaultStyle()) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	TextActor::TextActor(String const& text, const TextStyle& style) | ||||
| TextActor::TextActor(String const& text, const TextStyle& style) | ||||
|     : show_underline_(false) | ||||
|     , show_strikethrough_(false) | ||||
| 	{ | ||||
| 		InitDefaultTextStyle(); | ||||
| 
 | ||||
| { | ||||
|     SetText(text); | ||||
|     SetStyle(style); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	TextActor::~TextActor() | ||||
| 	{ | ||||
| 	} | ||||
| TextActor::~TextActor() {} | ||||
| 
 | ||||
| 	void TextActor::OnRender(RenderTarget* rt) | ||||
| 	{ | ||||
| 		rt->DrawTextLayout(text_layout_); | ||||
| 	} | ||||
| void TextActor::OnRender(RenderContext& ctx) | ||||
| { | ||||
|     ctx.DrawTextLayout(text_layout_); | ||||
| } | ||||
| 
 | ||||
| 	void TextActor::OnUpdate(Duration dt) | ||||
| 	{ | ||||
| void TextActor::OnUpdate(Duration dt) | ||||
| { | ||||
|     UpdateLayout(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void TextActor::UpdateLayout() | ||||
| 	{ | ||||
| void TextActor::UpdateLayout() | ||||
| { | ||||
|     if (text_layout_.IsDirty()) | ||||
|     { | ||||
|         text_layout_.Update(); | ||||
|     } | ||||
| 
 | ||||
|     if (text_layout_.GetDirtyFlag() & TextLayout::DirtyFlag::Updated) | ||||
|     { | ||||
|         text_layout_.SetDirtyFlag(TextLayout::DirtyFlag::Clean); | ||||
| 
 | ||||
|         if (show_underline_) | ||||
|             text_layout_.SetUnderline(true, 0, text_layout_.GetText().length()); | ||||
|  | @ -100,30 +102,31 @@ namespace kiwano | |||
| 
 | ||||
|         SetSize(text_layout_.GetLayoutSize()); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	bool TextActor::CheckVisibilty(RenderTarget* rt) const | ||||
| 	{ | ||||
| 		return text_layout_.IsValid() && Actor::CheckVisibilty(rt); | ||||
| 	} | ||||
| bool TextActor::CheckVisibility(RenderContext& ctx) const | ||||
| { | ||||
|     return text_layout_.IsValid() && Actor::CheckVisibility(ctx); | ||||
| } | ||||
| 
 | ||||
| 	void TextActor::SetFillColor(Color const& color) | ||||
| 	{ | ||||
| 		if (!text_layout_.GetFillBrush()) | ||||
| void TextActor::SetFillColor(Color const& color) | ||||
| { | ||||
|     if (!text_layout_.GetFillBrush() || text_layout_.GetFillBrush() == GetDefaultStyle().fill_brush) | ||||
|     { | ||||
|         BrushPtr brush = new Brush; | ||||
|         text_layout_.SetFillBrush(brush); | ||||
|     } | ||||
|     text_layout_.GetFillBrush()->SetColor(color); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void TextActor::SetOutlineColor(Color const& outline_color) | ||||
| 	{ | ||||
| 		if (!text_layout_.GetOutlineBrush()) | ||||
| void TextActor::SetOutlineColor(Color const& outline_color) | ||||
| { | ||||
|     if (!text_layout_.GetOutlineBrush() || text_layout_.GetOutlineBrush() == GetDefaultStyle().outline_brush) | ||||
|     { | ||||
|         BrushPtr brush = new Brush; | ||||
|         text_layout_.SetOutlineBrush(brush); | ||||
|     } | ||||
|     text_layout_.GetOutlineBrush()->SetColor(outline_color); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,26 +20,25 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/renderer/Color.h> | ||||
| #include <kiwano/renderer/TextLayout.h> | ||||
| #include <kiwano/render/Color.h> | ||||
| #include <kiwano/render/TextLayout.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(TextActor); | ||||
| KGE_DECLARE_SMART_PTR(TextActor); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actors | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 文本角色 | ||||
|  */ | ||||
| 	class KGE_API TextActor | ||||
| 		: public Actor | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API TextActor : public Actor | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构建空的文本角色
 | ||||
|     TextActor(); | ||||
|  | @ -69,6 +68,10 @@ namespace kiwano | |||
|     /// @brief 获取文本布局
 | ||||
|     const TextLayout& GetLayout() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief »ñÈ¡Îı¾²¼¾Ö´óС
 | ||||
|     Size GetLayoutSize() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取填充画刷
 | ||||
|     BrushPtr GetFillBrush() const; | ||||
|  | @ -143,7 +146,7 @@ namespace kiwano | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置文字描边线相交样式
 | ||||
| 		void SetOutlineStroke(StrokeStyle outline_stroke); | ||||
|     void SetOutlineStroke(const StrokeStyle& outline_stroke); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置是否显示下划线(默认值为 false)
 | ||||
|  | @ -166,129 +169,133 @@ namespace kiwano | |||
|     /// @brief 获取默认文字样式
 | ||||
|     static const TextStyle& GetDefaultStyle(); | ||||
| 
 | ||||
| 		void OnRender(RenderTarget* rt) override; | ||||
|     void OnRender(RenderContext& ctx) override; | ||||
| 
 | ||||
|     void OnUpdate(Duration dt) override; | ||||
| 
 | ||||
| 	protected: | ||||
| 		bool CheckVisibilty(RenderTarget* rt) const override; | ||||
| protected: | ||||
|     bool CheckVisibility(RenderContext& ctx) const override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     bool       show_underline_; | ||||
|     bool       show_strikethrough_; | ||||
|     TextLayout text_layout_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 	inline const String& TextActor::GetText() const | ||||
| 	{ | ||||
| inline const String& TextActor::GetText() const | ||||
| { | ||||
|     return text_layout_.GetText(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline FontPtr TextActor::GetFont() const | ||||
| 	{ | ||||
| 		return text_layout_.GetStyle().font; | ||||
| 	} | ||||
| 
 | ||||
| 	inline const TextStyle& TextActor::GetStyle() const | ||||
| 	{ | ||||
| 		return text_layout_.GetStyle(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline const TextLayout& TextActor::GetLayout() const | ||||
| 	{ | ||||
| 		return text_layout_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline BrushPtr TextActor::GetFillBrush() const | ||||
| 	{ | ||||
| 		return text_layout_.GetFillBrush(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline BrushPtr TextActor::GetOutlineBrush() const | ||||
| 	{ | ||||
| 		return text_layout_.GetOutlineBrush(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetText(String const& text) | ||||
| 	{ | ||||
| 		text_layout_.SetText(text); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetStyle(const TextStyle& style) | ||||
| 	{ | ||||
| 		text_layout_.SetStyle(style); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetFont(FontPtr font) | ||||
| 	{ | ||||
| 		text_layout_.SetFont(font); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetFontFamily(String const& family) | ||||
| 	{ | ||||
| 		text_layout_.SetFontFamily(family); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetFontSize(float size) | ||||
| 	{ | ||||
| 		text_layout_.SetFontSize(size); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetFontWeight(uint32_t weight) | ||||
| 	{ | ||||
| 		text_layout_.SetFontWeight(weight); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetItalic(bool italic) | ||||
| 	{ | ||||
| 		text_layout_.SetItalic(italic); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetWrapWidth(float wrap_width) | ||||
| 	{ | ||||
| 		text_layout_.SetWrapWidth(wrap_width); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetLineSpacing(float line_spacing) | ||||
| 	{ | ||||
| 		text_layout_.SetLineSpacing(line_spacing); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetAlignment(TextAlign align) | ||||
| 	{ | ||||
| 		text_layout_.SetAlignment(align); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetUnderline(bool enable) | ||||
| 	{ | ||||
| 		show_underline_ = enable; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetStrikethrough(bool enable) | ||||
| 	{ | ||||
| 		show_strikethrough_ = enable; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetFillBrush(BrushPtr brush) | ||||
| 	{ | ||||
| 		text_layout_.SetFillBrush(brush); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetOutlineBrush(BrushPtr brush) | ||||
| 	{ | ||||
| 		text_layout_.SetOutlineBrush(brush); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetOutlineWidth(float outline_width) | ||||
| 	{ | ||||
| 		text_layout_.SetOutlineWidth(outline_width); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void TextActor::SetOutlineStroke(StrokeStyle outline_stroke) | ||||
| 	{ | ||||
| 		text_layout_.SetOutlineStroke(outline_stroke); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| inline FontPtr TextActor::GetFont() const | ||||
| { | ||||
|     return text_layout_.GetStyle().font; | ||||
| } | ||||
| 
 | ||||
| inline const TextStyle& TextActor::GetStyle() const | ||||
| { | ||||
|     return text_layout_.GetStyle(); | ||||
| } | ||||
| 
 | ||||
| inline const TextLayout& TextActor::GetLayout() const | ||||
| { | ||||
|     return text_layout_; | ||||
| } | ||||
| 
 | ||||
| inline Size TextActor::GetLayoutSize() const | ||||
| { | ||||
|     return text_layout_.GetLayoutSize(); | ||||
| } | ||||
| 
 | ||||
| inline BrushPtr TextActor::GetFillBrush() const | ||||
| { | ||||
|     return text_layout_.GetFillBrush(); | ||||
| } | ||||
| 
 | ||||
| inline BrushPtr TextActor::GetOutlineBrush() const | ||||
| { | ||||
|     return text_layout_.GetOutlineBrush(); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetText(String const& text) | ||||
| { | ||||
|     text_layout_.SetText(text); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetStyle(const TextStyle& style) | ||||
| { | ||||
|     text_layout_.SetStyle(style); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetFont(FontPtr font) | ||||
| { | ||||
|     text_layout_.SetFont(font); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetFontFamily(String const& family) | ||||
| { | ||||
|     text_layout_.SetFontFamily(family); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetFontSize(float size) | ||||
| { | ||||
|     text_layout_.SetFontSize(size); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetFontWeight(uint32_t weight) | ||||
| { | ||||
|     text_layout_.SetFontWeight(weight); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetItalic(bool italic) | ||||
| { | ||||
|     text_layout_.SetItalic(italic); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetWrapWidth(float wrap_width) | ||||
| { | ||||
|     text_layout_.SetWrapWidth(wrap_width); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetLineSpacing(float line_spacing) | ||||
| { | ||||
|     text_layout_.SetLineSpacing(line_spacing); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetAlignment(TextAlign align) | ||||
| { | ||||
|     text_layout_.SetAlignment(align); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetUnderline(bool enable) | ||||
| { | ||||
|     show_underline_ = enable; | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetStrikethrough(bool enable) | ||||
| { | ||||
|     show_strikethrough_ = enable; | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetFillBrush(BrushPtr brush) | ||||
| { | ||||
|     text_layout_.SetFillBrush(brush); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetOutlineBrush(BrushPtr brush) | ||||
| { | ||||
|     text_layout_.SetOutlineBrush(brush); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetOutlineWidth(float outline_width) | ||||
| { | ||||
|     text_layout_.SetOutlineWidth(outline_width); | ||||
| } | ||||
| 
 | ||||
| inline void TextActor::SetOutlineStroke(const StrokeStyle& outline_stroke) | ||||
| { | ||||
|     text_layout_.SetOutlineStroke(outline_stroke); | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -22,28 +22,25 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Transform::Transform() | ||||
| Transform::Transform() | ||||
|     : position() | ||||
|     , rotation(0.f) | ||||
|     , scale(1.f, 1.f) | ||||
|     , skew(0.f, 0.f) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	Matrix3x2 Transform::ToMatrix() const | ||||
| 	{ | ||||
| Matrix3x2 Transform::ToMatrix() const | ||||
| { | ||||
|     if (!skew.IsOrigin()) | ||||
|     { | ||||
|         return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation); | ||||
|     } | ||||
|     return Matrix3x2::SRT(position, scale, rotation); | ||||
| 	} | ||||
| 
 | ||||
| 	bool Transform::operator== (Transform const& rhs) const | ||||
| 	{ | ||||
| 		return position == rhs.position && | ||||
| 			rotation == rhs.rotation && | ||||
| 			scale == rhs.scale && | ||||
| 			skew == rhs.skew; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool Transform::operator==(Transform const& rhs) const | ||||
| { | ||||
|     return position == rhs.position && rotation == rhs.rotation && scale == rhs.scale && skew == rhs.skew; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,25 +23,25 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 二维放射变换 | ||||
|  */ | ||||
| 	class Transform | ||||
| 	{ | ||||
| 	public: | ||||
| class Transform | ||||
| { | ||||
| public: | ||||
|     float rotation;  ///< 旋转
 | ||||
|     Point position;  ///< 坐标
 | ||||
|     Point scale;     ///< 缩放
 | ||||
|     Point skew;      ///< 错切角度
 | ||||
| 
 | ||||
| 	public: | ||||
| public: | ||||
|     Transform(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 将二维放射变换转换为矩阵
 | ||||
|     Matrix3x2 ToMatrix() const; | ||||
| 
 | ||||
| 		bool operator== (const Transform& rhs) const; | ||||
| 	}; | ||||
| } | ||||
|     bool operator==(const Transform& rhs) const; | ||||
| }; | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,20 +18,20 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/Transition.h> | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/Stage.h> | ||||
| #include <kiwano/platform/Window.h> | ||||
| #include <kiwano/2d/Transition.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| #include <kiwano/renderer/Renderer.h> | ||||
| #include <kiwano/platform/Window.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Transition
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // Transition
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	Transition::Transition(Duration duration) | ||||
| Transition::Transition(Duration duration) | ||||
|     : done_(false) | ||||
|     , duration_(duration) | ||||
|     , delta_() | ||||
|  | @ -41,26 +41,24 @@ namespace kiwano | |||
|     , in_stage_(nullptr) | ||||
|     , out_layer_() | ||||
|     , in_layer_() | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	Transition::~Transition() | ||||
| 	{ | ||||
| 	} | ||||
| Transition::~Transition() {} | ||||
| 
 | ||||
| 	bool Transition::IsDone() | ||||
| 	{ | ||||
| bool Transition::IsDone() | ||||
| { | ||||
|     return done_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Transition::Init(StagePtr prev, StagePtr next) | ||||
| 	{ | ||||
| void Transition::Init(StagePtr prev, StagePtr next) | ||||
| { | ||||
|     process_ = 0; | ||||
|     delta_   = Duration{}; | ||||
| 
 | ||||
|     out_stage_   = prev; | ||||
|     in_stage_    = next; | ||||
| 		window_size_ = Renderer::instance().GetOutputSize(); | ||||
|     window_size_ = Renderer::Instance().GetOutputSize(); | ||||
| 
 | ||||
|     if (in_stage_) | ||||
|     { | ||||
|  | @ -71,10 +69,10 @@ namespace kiwano | |||
|     { | ||||
|         out_layer_.SetAreaRect(Rect{ Point(), window_size_ }); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Transition::Update(Duration dt) | ||||
| 	{ | ||||
| void Transition::Update(Duration dt) | ||||
| { | ||||
|     if (duration_.IsZero()) | ||||
|     { | ||||
|         process_ = 1; | ||||
|  | @ -89,131 +87,119 @@ namespace kiwano | |||
|     { | ||||
|         this->Stop(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Transition::Render(RenderTarget* rt) | ||||
| 	{ | ||||
| void Transition::Render(RenderContext& ctx) | ||||
| { | ||||
|     if (out_stage_) | ||||
|     { | ||||
| 			out_stage_->PrepareToRender(rt); | ||||
| 			rt->PushClipRect(Rect{ Point{}, window_size_ }); | ||||
| 			rt->PushLayer(out_layer_); | ||||
|         out_stage_->PrepareToRender(ctx); | ||||
|         ctx.PushClipRect(Rect{ Point{}, window_size_ }); | ||||
|         ctx.PushLayer(out_layer_); | ||||
| 
 | ||||
| 			out_stage_->Render(rt); | ||||
|         out_stage_->Render(ctx); | ||||
| 
 | ||||
| 			rt->PopLayer(); | ||||
| 			rt->PopClipRect(); | ||||
|         ctx.PopLayer(); | ||||
|         ctx.PopClipRect(); | ||||
|     } | ||||
| 
 | ||||
|     if (in_stage_) | ||||
|     { | ||||
| 			in_stage_->PrepareToRender(rt); | ||||
| 			rt->PushClipRect(Rect{ Point{}, window_size_ }); | ||||
| 			rt->PushLayer(in_layer_); | ||||
|         in_stage_->PrepareToRender(ctx); | ||||
|         ctx.PushClipRect(Rect{ Point{}, window_size_ }); | ||||
|         ctx.PushLayer(in_layer_); | ||||
| 
 | ||||
| 			in_stage_->Render(rt); | ||||
|         in_stage_->Render(ctx); | ||||
| 
 | ||||
| 			rt->PopLayer(); | ||||
| 			rt->PopClipRect(); | ||||
| 		} | ||||
|         ctx.PopLayer(); | ||||
|         ctx.PopClipRect(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 	void Transition::Stop() | ||||
| 	{ | ||||
| void Transition::Stop() | ||||
| { | ||||
|     done_ = true; | ||||
|     Reset(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// BoxTransition
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // BoxTransition
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	BoxTransition::BoxTransition(Duration duration) | ||||
| BoxTransition::BoxTransition(Duration duration) | ||||
|     : Transition(duration) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void BoxTransition::Init(StagePtr prev, StagePtr next) | ||||
| 	{ | ||||
| void BoxTransition::Init(StagePtr prev, StagePtr next) | ||||
| { | ||||
|     Transition::Init(prev, next); | ||||
| 
 | ||||
|     in_layer_.SetOpacity(0.f); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void BoxTransition::Update(Duration dt) | ||||
| 	{ | ||||
| void BoxTransition::Update(Duration dt) | ||||
| { | ||||
|     Transition::Update(dt); | ||||
| 
 | ||||
|     if (process_ < .5f) | ||||
|     { | ||||
| 			out_layer_.SetAreaRect( | ||||
| 				Rect( | ||||
| 					window_size_.x * process_, | ||||
| 					window_size_.y * process_, | ||||
| 					window_size_.x * (1 - process_), | ||||
| 					window_size_.y * (1 - process_) | ||||
| 				) | ||||
| 			); | ||||
|         out_layer_.SetAreaRect(Rect(window_size_.x * process_, window_size_.y * process_, | ||||
|                                     window_size_.x * (1 - process_), window_size_.y * (1 - process_))); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         out_layer_.SetOpacity(0.f); | ||||
|         in_layer_.SetOpacity(1.f); | ||||
| 			in_layer_.SetAreaRect( | ||||
| 				Rect( | ||||
| 					window_size_.x * (1 - process_), | ||||
| 					window_size_.y * (1 - process_), | ||||
| 					window_size_.x * process_, | ||||
| 					window_size_.y * process_ | ||||
| 				) | ||||
| 			); | ||||
| 		} | ||||
|         in_layer_.SetAreaRect(Rect(window_size_.x * (1 - process_), window_size_.y * (1 - process_), | ||||
|                                    window_size_.x * process_, window_size_.y * process_)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// EmergeTransition
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // EmergeTransition
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	EmergeTransition::EmergeTransition(Duration duration) | ||||
| EmergeTransition::EmergeTransition(Duration duration) | ||||
|     : Transition(duration) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void EmergeTransition::Init(StagePtr prev, StagePtr next) | ||||
| 	{ | ||||
| void EmergeTransition::Init(StagePtr prev, StagePtr next) | ||||
| { | ||||
|     Transition::Init(prev, next); | ||||
| 
 | ||||
|     out_layer_.SetOpacity(1.f); | ||||
|     in_layer_.SetOpacity(0.f); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void EmergeTransition::Update(Duration dt) | ||||
| 	{ | ||||
| void EmergeTransition::Update(Duration dt) | ||||
| { | ||||
|     Transition::Update(dt); | ||||
| 
 | ||||
|     out_layer_.SetOpacity(1 - process_); | ||||
|     in_layer_.SetOpacity(process_); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// FadeTransition
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // FadeTransition
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	FadeTransition::FadeTransition(Duration duration) | ||||
| FadeTransition::FadeTransition(Duration duration) | ||||
|     : Transition(duration) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void FadeTransition::Init(StagePtr prev, StagePtr next) | ||||
| 	{ | ||||
| void FadeTransition::Init(StagePtr prev, StagePtr next) | ||||
| { | ||||
|     Transition::Init(prev, next); | ||||
| 
 | ||||
|     out_layer_.SetOpacity(1.f); | ||||
|     in_layer_.SetOpacity(0.f); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void FadeTransition::Update(Duration dt) | ||||
| 	{ | ||||
| void FadeTransition::Update(Duration dt) | ||||
| { | ||||
|     Transition::Update(dt); | ||||
| 
 | ||||
|     if (process_ < 0.5) | ||||
|  | @ -226,20 +212,20 @@ namespace kiwano | |||
|         out_layer_.SetOpacity(0.f); | ||||
|         in_layer_.SetOpacity((process_ - 0.5f) * 2); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// MoveTransition
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // MoveTransition
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	MoveTransition::MoveTransition(Duration duration, Type type) | ||||
| MoveTransition::MoveTransition(Duration duration, Type type) | ||||
|     : Transition(duration) | ||||
|     , type_(type) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void MoveTransition::Init(StagePtr prev, StagePtr next) | ||||
| 	{ | ||||
| void MoveTransition::Init(StagePtr prev, StagePtr next) | ||||
| { | ||||
|     Transition::Init(prev, next); | ||||
| 
 | ||||
|     switch (type_) | ||||
|  | @ -273,10 +259,10 @@ namespace kiwano | |||
|         transform.position = start_pos_; | ||||
|         in_stage_->SetTransform(transform); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void MoveTransition::Update(Duration dt) | ||||
| 	{ | ||||
| void MoveTransition::Update(Duration dt) | ||||
| { | ||||
|     Transition::Update(dt); | ||||
| 
 | ||||
|     if (out_stage_) | ||||
|  | @ -292,10 +278,10 @@ namespace kiwano | |||
|         transform.position = start_pos_ + pos_delta_ * process_; | ||||
|         in_stage_->SetTransform(transform); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void MoveTransition::Reset() | ||||
| 	{ | ||||
| void MoveTransition::Reset() | ||||
| { | ||||
|     if (out_stage_) | ||||
|     { | ||||
|         out_stage_->SetTransform(Transform{}); | ||||
|  | @ -305,20 +291,20 @@ namespace kiwano | |||
|     { | ||||
|         in_stage_->SetTransform(Transform{}); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// RotationTransition
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // RotationTransition
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	RotationTransition::RotationTransition(Duration duration, float rotation) | ||||
| RotationTransition::RotationTransition(Duration duration, float rotation) | ||||
|     : Transition(duration) | ||||
|     , rotation_(rotation) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void RotationTransition::Init(StagePtr prev, StagePtr next) | ||||
| 	{ | ||||
| void RotationTransition::Init(StagePtr prev, StagePtr next) | ||||
| { | ||||
|     Transition::Init(prev, next); | ||||
| 
 | ||||
|     auto transform     = Transform{}; | ||||
|  | @ -337,10 +323,10 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     in_layer_.SetOpacity(0.f); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void RotationTransition::Update(Duration dt) | ||||
| 	{ | ||||
| void RotationTransition::Update(Duration dt) | ||||
| { | ||||
|     Transition::Update(dt); | ||||
| 
 | ||||
|     if (process_ < .5f) | ||||
|  | @ -367,10 +353,10 @@ namespace kiwano | |||
|             in_stage_->SetTransform(transform); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void RotationTransition::Reset() | ||||
| 	{ | ||||
| void RotationTransition::Reset() | ||||
| { | ||||
|     if (out_stage_) | ||||
|     { | ||||
|         out_stage_->SetTransform(Transform{}); | ||||
|  | @ -382,5 +368,5 @@ namespace kiwano | |||
|         in_stage_->SetTransform(Transform{}); | ||||
|         in_stage_->SetAnchor(Vec2{ 0.f, 0.f }); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -20,38 +20,35 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/Stage.h> | ||||
| #include <kiwano/renderer/LayerArea.h> | ||||
| #include <kiwano/render/LayerArea.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	class Director; | ||||
| 	class RenderTarget; | ||||
| class Director; | ||||
| class RenderContext; | ||||
| 
 | ||||
| 	KGE_DECLARE_SMART_PTR(Transition); | ||||
| 	KGE_DECLARE_SMART_PTR(FadeTransition); | ||||
| 	KGE_DECLARE_SMART_PTR(EmergeTransition); | ||||
| 	KGE_DECLARE_SMART_PTR(BoxTransition); | ||||
| 	KGE_DECLARE_SMART_PTR(MoveTransition); | ||||
| 	KGE_DECLARE_SMART_PTR(RotationTransition); | ||||
| KGE_DECLARE_SMART_PTR(Transition); | ||||
| KGE_DECLARE_SMART_PTR(FadeTransition); | ||||
| KGE_DECLARE_SMART_PTR(EmergeTransition); | ||||
| KGE_DECLARE_SMART_PTR(BoxTransition); | ||||
| KGE_DECLARE_SMART_PTR(MoveTransition); | ||||
| KGE_DECLARE_SMART_PTR(RotationTransition); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 舞台过渡动画 | ||||
|  */ | ||||
| 	class KGE_API Transition | ||||
| 		: public ObjectBase | ||||
| 	{ | ||||
| class KGE_API Transition : public virtual ObjectBase | ||||
| { | ||||
|     friend class Director; | ||||
| 
 | ||||
| 	public: | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 构建空的场景过渡动画 | ||||
|      * @param duration 动画时长 | ||||
|      */ | ||||
| 		explicit Transition( | ||||
| 			Duration duration | ||||
| 		); | ||||
|     explicit Transition(Duration duration); | ||||
| 
 | ||||
|     virtual ~Transition(); | ||||
| 
 | ||||
|  | @ -61,17 +58,14 @@ namespace kiwano | |||
|      */ | ||||
|     bool IsDone(); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 初始化场景过渡动画 | ||||
|      * @param[in] prev 转出场景 | ||||
|      * @param[in] next 转入场景 | ||||
|      */ | ||||
| 		virtual void Init( | ||||
| 			StagePtr prev, | ||||
| 			StagePtr next | ||||
| 		); | ||||
|     virtual void Init(StagePtr prev, StagePtr next); | ||||
| 
 | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|  | @ -83,9 +77,9 @@ namespace kiwano | |||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 渲染过度动画 | ||||
| 		* @param[in] rt äÖȾĿ±ê | ||||
|      * @param[in] ctx äÖȾÉÏÏÂÎÄ | ||||
|      */ | ||||
| 		virtual void Render(RenderTarget* rt); | ||||
|     virtual void Render(RenderContext& ctx); | ||||
| 
 | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|  | @ -99,7 +93,7 @@ namespace kiwano | |||
|      */ | ||||
|     virtual void Reset() {} | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     bool      done_; | ||||
|     float     process_; | ||||
|     Duration  duration_; | ||||
|  | @ -109,102 +103,79 @@ namespace kiwano | |||
|     StagePtr  in_stage_; | ||||
|     LayerArea out_layer_; | ||||
|     LayerArea in_layer_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 淡入淡出过渡动画 | ||||
|  * @details 前一场景淡出动画结束后,后一场景淡入 | ||||
|  */ | ||||
| 	class FadeTransition | ||||
| 		: public Transition | ||||
| 	{ | ||||
| 	public: | ||||
| class FadeTransition : public Transition | ||||
| { | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 构建淡入淡出过渡动画 | ||||
|      * @param duration 动画时长 | ||||
|      */ | ||||
| 		explicit FadeTransition( | ||||
| 			Duration duration | ||||
| 		); | ||||
|     explicit FadeTransition(Duration duration); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
| 		virtual void Init( | ||||
| 			StagePtr prev, | ||||
| 			StagePtr next | ||||
| 		) override; | ||||
| 	}; | ||||
|     virtual void Init(StagePtr prev, StagePtr next) override; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 渐变过渡动画 | ||||
|  * @details 前一场景淡出动画的同时,后一场景淡入 | ||||
|  */ | ||||
| 	class EmergeTransition | ||||
| 		: public Transition | ||||
| 	{ | ||||
| 	public: | ||||
| class EmergeTransition : public Transition | ||||
| { | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 构建渐变过渡动画 | ||||
|      * @param duration 动画时长 | ||||
|      */ | ||||
| 		explicit EmergeTransition( | ||||
| 			Duration duration | ||||
| 		); | ||||
|     explicit EmergeTransition(Duration duration); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
| 		virtual void Init( | ||||
| 			StagePtr prev, | ||||
| 			StagePtr next | ||||
| 		) override; | ||||
| 	}; | ||||
|     virtual void Init(StagePtr prev, StagePtr next) override; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 盒状过渡动画 | ||||
|  * @details 前一场景以盒状收缩至消失,后一场景以盒状扩大 | ||||
|  */ | ||||
| 	class BoxTransition | ||||
| 		: public Transition | ||||
| 	{ | ||||
| 	public: | ||||
| class BoxTransition : public Transition | ||||
| { | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 构建盒状过渡动画 | ||||
|      * @param duration 动画时长 | ||||
|      */ | ||||
| 		explicit BoxTransition( | ||||
| 			Duration duration | ||||
| 		); | ||||
|     explicit BoxTransition(Duration duration); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
| 		virtual void Init( | ||||
| 			StagePtr prev, | ||||
| 			StagePtr next | ||||
| 		) override; | ||||
| 	}; | ||||
|     virtual void Init(StagePtr prev, StagePtr next) override; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 位移过渡动画 | ||||
|  * @details 两场景以位移的方式切换 | ||||
|  */ | ||||
| 	class MoveTransition | ||||
| 		: public Transition | ||||
| 	{ | ||||
| 	public: | ||||
| class MoveTransition : public Transition | ||||
| { | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 位移方式 | ||||
|  | @ -223,59 +194,45 @@ namespace kiwano | |||
|      * @param duration 动画时长 | ||||
|      * @param type 位移方式 | ||||
|      */ | ||||
| 		explicit MoveTransition( | ||||
| 			Duration duration, | ||||
| 			Type type | ||||
| 		); | ||||
|     explicit MoveTransition(Duration duration, Type type); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
| 		virtual void Init( | ||||
| 			StagePtr prev, | ||||
| 			StagePtr next | ||||
| 		) override; | ||||
|     virtual void Init(StagePtr prev, StagePtr next) override; | ||||
| 
 | ||||
|     void Reset() override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Type  type_; | ||||
|     Point pos_delta_; | ||||
|     Point start_pos_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 旋转过渡动画 | ||||
|  * @details 前一场景以旋转方式收缩至消失,后一场景以旋转方式扩大 | ||||
|  */ | ||||
| 	class RotationTransition | ||||
| 		: public Transition | ||||
| 	{ | ||||
| 	public: | ||||
| class RotationTransition : public Transition | ||||
| { | ||||
| public: | ||||
|     /**
 | ||||
|      * \~chinese | ||||
|      * @brief 构建旋转过渡动画 | ||||
|      * @param duration 动画时长 | ||||
|      * @param rotation 旋转度数 | ||||
|      */ | ||||
| 		explicit RotationTransition( | ||||
| 			Duration duration, | ||||
| 			float rotation = 360 | ||||
| 		); | ||||
|     explicit RotationTransition(Duration duration, float rotation = 360); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Update(Duration dt) override; | ||||
| 
 | ||||
| 		virtual void Init( | ||||
| 			StagePtr prev, | ||||
| 			StagePtr next | ||||
| 		) override; | ||||
|     virtual void Init(StagePtr prev, StagePtr next) override; | ||||
| 
 | ||||
|     void Reset() override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     float rotation_; | ||||
| 	}; | ||||
| } | ||||
| }; | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,35 +18,31 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/action/Action.h> | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/action/Action.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	Action::Action() | ||||
| Action::Action() | ||||
|     : running_(true) | ||||
|     , detach_target_(false) | ||||
|     , loops_done_(0) | ||||
|     , loops_(0) | ||||
|     , status_(Status::NotStarted) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	Action::~Action() | ||||
| 	{ | ||||
| 	} | ||||
| Action::~Action() {} | ||||
| 
 | ||||
| 	void Action::Init(Actor* target) | ||||
| 	{ | ||||
| 	} | ||||
| void Action::Init(Actor* target) {} | ||||
| 
 | ||||
| 	void Action::Update(Actor* target, Duration dt) | ||||
| 	{ | ||||
| void Action::Update(Actor* target, Duration dt) | ||||
| { | ||||
|     Complete(target); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Action::UpdateStep(Actor* target, Duration dt) | ||||
| 	{ | ||||
| void Action::UpdateStep(Actor* target, Duration dt) | ||||
| { | ||||
|     KGE_ASSERT(target != nullptr && "Action target should NOT be nullptr!"); | ||||
| 
 | ||||
|     elapsed_ += dt; | ||||
|  | @ -81,15 +77,14 @@ namespace kiwano | |||
| 
 | ||||
|         status_ = Status::Removeable; | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Action::Complete(Actor* target) | ||||
| 	{ | ||||
| void Action::Complete(Actor* target) | ||||
| { | ||||
|     if (cb_loop_done_) | ||||
|         cb_loop_done_(target); | ||||
| 
 | ||||
| 		if (loops_ >= 0 | ||||
| 			&& loops_done_ >= loops_) | ||||
|     if (loops_ >= 0 && loops_done_ >= loops_) | ||||
|     { | ||||
|         Done(); | ||||
|     } | ||||
|  | @ -99,15 +94,15 @@ namespace kiwano | |||
|     } | ||||
| 
 | ||||
|     ++loops_done_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void Action::Restart(Actor* target) | ||||
| 	{ | ||||
| void Action::Restart(Actor* target) | ||||
| { | ||||
|     status_     = Status::NotStarted; | ||||
|     elapsed_    = 0; | ||||
|     loops_done_ = 0; | ||||
| 
 | ||||
|     Init(target); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,40 +19,40 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/core/common.h> | ||||
| #include <kiwano/core/time.h> | ||||
| #include <kiwano/core/SmartPtr.hpp> | ||||
| #include <kiwano/core/Common.h> | ||||
| #include <kiwano/core/ObjectBase.h> | ||||
| #include <kiwano/core/SmartPtr.hpp> | ||||
| #include <kiwano/core/Time.h> | ||||
| #include <kiwano/math/math.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	class Actor; | ||||
| 	class ActionManager; | ||||
| class Actor; | ||||
| class ActionManager; | ||||
| 
 | ||||
| 	KGE_DECLARE_SMART_PTR(Action); | ||||
| KGE_DECLARE_SMART_PTR(Action); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * \defgroup Actions 动画 | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actions | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief ¶¯»
 | ||||
| 	class KGE_API Action | ||||
| 		: public ObjectBase | ||||
| /// \~chinese
 | ||||
| /// @brief ¶¯»
 | ||||
| class KGE_API Action | ||||
|     : public virtual ObjectBase | ||||
|     , protected IntrusiveListItem<ActionPtr> | ||||
| 	{ | ||||
| { | ||||
|     friend class ActionManager; | ||||
|     friend class ActionGroup; | ||||
|     friend IntrusiveList<ActionPtr>; | ||||
| 
 | ||||
| 	public: | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 动画结束时的回调函数
 | ||||
|     using DoneCallback = Function<void(Actor* /* target */)>; | ||||
|  | @ -122,7 +122,7 @@ namespace kiwano | |||
|     /// @brief 获取动画循环结束时的回调函数
 | ||||
|     DoneCallback GetLoopDoneCallback() const; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 初始化动画
 | ||||
|     virtual void Init(Actor* target); | ||||
|  | @ -178,7 +178,7 @@ namespace kiwano | |||
|     /// @brief 是否可移除
 | ||||
|     bool IsRemoveable() const; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Status       status_; | ||||
|     bool         running_; | ||||
|     bool         detach_target_; | ||||
|  | @ -188,103 +188,102 @@ namespace kiwano | |||
|     Duration     elapsed_; | ||||
|     DoneCallback cb_done_; | ||||
|     DoneCallback cb_loop_done_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| 
 | ||||
| 	inline void Action::Resume() | ||||
| 	{ | ||||
| inline void Action::Resume() | ||||
| { | ||||
|     running_ = true; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::Pause() | ||||
| 	{ | ||||
| 		running_ = false; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::Stop() | ||||
| 	{ | ||||
| 		Done(); | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::SetDelay(Duration delay) | ||||
| 	{ | ||||
| 		delay_ = delay; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::SetLoops(int loops) | ||||
| 	{ | ||||
| 		loops_ = loops; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::RemoveTargetWhenDone() | ||||
| 	{ | ||||
| 		detach_target_ = true; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::SetDoneCallback(DoneCallback const& cb) | ||||
| 	{ | ||||
| 		cb_done_ = cb; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::SetLoopDoneCallback(DoneCallback const& cb) | ||||
| 	{ | ||||
| 		cb_loop_done_ = cb; | ||||
| 	} | ||||
| 
 | ||||
| 	inline void Action::Done() | ||||
| 	{ | ||||
| 		status_ = Status::Done; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Action::Status Action::GetStatus() const | ||||
| 	{ | ||||
| 		return status_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Action::IsRunning() const | ||||
| 	{ | ||||
| 		return running_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Action::IsDone() const | ||||
| 	{ | ||||
| 		return status_ == Status::Done || status_ == Status::Removeable; | ||||
| 	} | ||||
| 
 | ||||
| 	inline bool Action::IsRemoveable() const | ||||
| 	{ | ||||
| 		return status_ == Status::Removeable; | ||||
| 	} | ||||
| 
 | ||||
| 	inline int Action::GetLoops() const | ||||
| 	{ | ||||
| 		return loops_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Duration Action::GetDelay() const | ||||
| 	{ | ||||
| 		return delay_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Duration Action::GetElapsed() const | ||||
| 	{ | ||||
| 		return elapsed_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline int Action::GetLoopsDone() const | ||||
| 	{ | ||||
| 		return loops_done_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Action::DoneCallback Action::GetDoneCallback() const | ||||
| 	{ | ||||
| 		return cb_done_; | ||||
| 	} | ||||
| 
 | ||||
| 	inline Action::DoneCallback Action::GetLoopDoneCallback() const | ||||
| 	{ | ||||
| 		return cb_loop_done_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| inline void Action::Pause() | ||||
| { | ||||
|     running_ = false; | ||||
| } | ||||
| 
 | ||||
| inline void Action::Stop() | ||||
| { | ||||
|     Done(); | ||||
| } | ||||
| 
 | ||||
| inline void Action::SetDelay(Duration delay) | ||||
| { | ||||
|     delay_ = delay; | ||||
| } | ||||
| 
 | ||||
| inline void Action::SetLoops(int loops) | ||||
| { | ||||
|     loops_ = loops; | ||||
| } | ||||
| 
 | ||||
| inline void Action::RemoveTargetWhenDone() | ||||
| { | ||||
|     detach_target_ = true; | ||||
| } | ||||
| 
 | ||||
| inline void Action::SetDoneCallback(DoneCallback const& cb) | ||||
| { | ||||
|     cb_done_ = cb; | ||||
| } | ||||
| 
 | ||||
| inline void Action::SetLoopDoneCallback(DoneCallback const& cb) | ||||
| { | ||||
|     cb_loop_done_ = cb; | ||||
| } | ||||
| 
 | ||||
| inline void Action::Done() | ||||
| { | ||||
|     status_ = Status::Done; | ||||
| } | ||||
| 
 | ||||
| inline Action::Status Action::GetStatus() const | ||||
| { | ||||
|     return status_; | ||||
| } | ||||
| 
 | ||||
| inline bool Action::IsRunning() const | ||||
| { | ||||
|     return running_; | ||||
| } | ||||
| 
 | ||||
| inline bool Action::IsDone() const | ||||
| { | ||||
|     return status_ == Status::Done || status_ == Status::Removeable; | ||||
| } | ||||
| 
 | ||||
| inline bool Action::IsRemoveable() const | ||||
| { | ||||
|     return status_ == Status::Removeable; | ||||
| } | ||||
| 
 | ||||
| inline int Action::GetLoops() const | ||||
| { | ||||
|     return loops_; | ||||
| } | ||||
| 
 | ||||
| inline Duration Action::GetDelay() const | ||||
| { | ||||
|     return delay_; | ||||
| } | ||||
| 
 | ||||
| inline Duration Action::GetElapsed() const | ||||
| { | ||||
|     return elapsed_; | ||||
| } | ||||
| 
 | ||||
| inline int Action::GetLoopsDone() const | ||||
| { | ||||
|     return loops_done_; | ||||
| } | ||||
| 
 | ||||
| inline Action::DoneCallback Action::GetDoneCallback() const | ||||
| { | ||||
|     return cb_done_; | ||||
| } | ||||
| 
 | ||||
| inline Action::DoneCallback Action::GetLoopDoneCallback() const | ||||
| { | ||||
|     return cb_loop_done_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -22,19 +22,19 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	ActionDelay::ActionDelay(Duration delay) | ||||
| 	{ | ||||
| ActionDelay::ActionDelay(Duration delay) | ||||
| { | ||||
|     SetDelay(delay); | ||||
| 	} | ||||
| 
 | ||||
| 	ActionPtr ActionDelay::Clone() const | ||||
| 	{ | ||||
| 		return new ActionDelay(GetDelay()); | ||||
| 	} | ||||
| 
 | ||||
| 	ActionPtr ActionDelay::Reverse() const | ||||
| 	{ | ||||
| 		return new ActionDelay(GetDelay()); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| ActionPtr ActionDelay::Clone() const | ||||
| { | ||||
|     return new ActionDelay(GetDelay()); | ||||
| } | ||||
| 
 | ||||
| ActionPtr ActionDelay::Reverse() const | ||||
| { | ||||
|     return new ActionDelay(GetDelay()); | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,23 +23,20 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actions | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 延时动画
 | ||||
| 	class KGE_API ActionDelay | ||||
| 		: public Action | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 延时动画
 | ||||
| class KGE_API ActionDelay : public Action | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构建延时动画
 | ||||
|     /// @param delay 延时时长
 | ||||
| 		ActionDelay( | ||||
| 			Duration delay | ||||
| 		); | ||||
|     ActionDelay(Duration delay); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取该动画的拷贝对象
 | ||||
|  | @ -48,7 +45,7 @@ namespace kiwano | |||
|     /// \~chinese
 | ||||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,33 +18,31 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/action/ActionGroup.h> | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/action/ActionGroup.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// ActionGroup
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // ActionGroup
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionGroup::ActionGroup() | ||||
| ActionGroup::ActionGroup() | ||||
|     : sequence_(true) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ActionGroup::ActionGroup(Vector<ActionPtr> const& actions, bool sequence) | ||||
| ActionGroup::ActionGroup(Vector<ActionPtr> const& actions, bool sequence) | ||||
|     : sequence_(sequence) | ||||
| 	{ | ||||
| { | ||||
|     this->Add(actions); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionGroup::~ActionGroup() | ||||
| 	{ | ||||
| 	} | ||||
| ActionGroup::~ActionGroup() {} | ||||
| 
 | ||||
| 	void ActionGroup::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionGroup::Init(Actor* target) | ||||
| { | ||||
|     if (actions_.empty()) | ||||
|     { | ||||
|         Done(); | ||||
|  | @ -62,10 +60,10 @@ namespace kiwano | |||
|             current_->Restart(target); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionGroup::Update(Actor* target, Duration dt) | ||||
| 	{ | ||||
| void ActionGroup::Update(Actor* target, Duration dt) | ||||
| { | ||||
|     if (sequence_) | ||||
|     { | ||||
|         if (current_) | ||||
|  | @ -100,24 +98,24 @@ namespace kiwano | |||
|             Complete(target); | ||||
|         } | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionGroup::Add(ActionPtr action) | ||||
| 	{ | ||||
| void ActionGroup::Add(ActionPtr action) | ||||
| { | ||||
|     if (action) | ||||
|     { | ||||
|         actions_.push_back(action); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionGroup::Add(Vector<ActionPtr> const& actions) | ||||
| 	{ | ||||
| void ActionGroup::Add(Vector<ActionPtr> const& actions) | ||||
| { | ||||
|     for (const auto& action : actions) | ||||
|         Add(action); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionGroup::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionGroup::Clone() const | ||||
| { | ||||
|     auto group = new (std::nothrow) ActionGroup(); | ||||
|     if (group) | ||||
|     { | ||||
|  | @ -130,10 +128,10 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return group; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionGroup::Reverse() const | ||||
| 	{ | ||||
| ActionPtr ActionGroup::Reverse() const | ||||
| { | ||||
|     auto group = new (std::nothrow) ActionGroup(); | ||||
|     if (group && !actions_.empty()) | ||||
|     { | ||||
|  | @ -143,6 +141,6 @@ namespace kiwano | |||
|         } | ||||
|     } | ||||
|     return group; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,19 +23,18 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	KGE_DECLARE_SMART_PTR(ActionGroup); | ||||
| KGE_DECLARE_SMART_PTR(ActionGroup); | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actions | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 动画组合
 | ||||
| 	class KGE_API ActionGroup | ||||
| 		: public Action | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 动画组合
 | ||||
| class KGE_API ActionGroup : public Action | ||||
| { | ||||
| public: | ||||
|     using ActionList = IntrusiveList<ActionPtr>; | ||||
| 
 | ||||
|     ActionGroup(); | ||||
|  | @ -70,19 +69,22 @@ namespace kiwano | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void Update(Actor* target, Duration dt) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     bool       sequence_; | ||||
|     ActionPtr  current_; | ||||
|     ActionList actions_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| 
 | ||||
| 	inline ActionGroup::ActionList const& ActionGroup::GetActions() const { return actions_; } | ||||
| /** @} */ | ||||
| 
 | ||||
| inline ActionGroup::ActionList const& ActionGroup::GetActions() const | ||||
| { | ||||
|     return actions_; | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,124 +19,200 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <kiwano/2d/action/ActionTween.h> | ||||
| #include <kiwano/2d/action/ActionWalk.h> | ||||
| #include <kiwano/2d/action/ActionDelay.h> | ||||
| #include <kiwano/2d/action/ActionGroup.h> | ||||
| #include <kiwano/2d/action/ActionTween.h> | ||||
| #include <kiwano/2d/action/ActionWalk.h> | ||||
| #include <kiwano/2d/action/Animation.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actions | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 动画辅助类
 | ||||
| 	struct ActionHelper | ||||
| 	{ | ||||
| /// \~chinese
 | ||||
| /// @brief 动画辅助类
 | ||||
| struct ActionHelper | ||||
| { | ||||
|     using DoneCallback = Action::DoneCallback; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置循环次数
 | ||||
| 		inline ActionHelper& SetLoops(int loops)							{ core->SetLoops(loops); return (*this); } | ||||
|     inline ActionHelper& SetLoops(int loops) | ||||
|     { | ||||
|         core->SetLoops(loops); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画延迟
 | ||||
| 		inline ActionHelper& SetDelay(Duration delay)						{ core->SetDelay(delay); return (*this); } | ||||
|     inline ActionHelper& SetDelay(Duration delay) | ||||
|     { | ||||
|         core->SetDelay(delay); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画结束回调函数
 | ||||
| 		inline ActionHelper& SetDoneCallback(DoneCallback const& cb)		{ core->SetDoneCallback(cb); return (*this); } | ||||
|     inline ActionHelper& SetDoneCallback(DoneCallback const& cb) | ||||
|     { | ||||
|         core->SetDoneCallback(cb); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画循环结束时的回调函数
 | ||||
| 		inline ActionHelper& SetLoopDoneCallback(DoneCallback const& cb)	{ core->SetLoopDoneCallback(cb); return (*this); } | ||||
|     inline ActionHelper& SetLoopDoneCallback(DoneCallback const& cb) | ||||
|     { | ||||
|         core->SetLoopDoneCallback(cb); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 动画结束时移除目标角色
 | ||||
| 		inline ActionHelper& RemoveTargetWhenDone()							{ core->RemoveTargetWhenDone(); return (*this); } | ||||
|     inline ActionHelper& RemoveTargetWhenDone() | ||||
|     { | ||||
|         core->RemoveTargetWhenDone(); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置名称
 | ||||
| 		inline ActionHelper& SetName(String const& name)					{ core->SetName(name); return (*this); } | ||||
|     inline ActionHelper& SetName(String const& name) | ||||
|     { | ||||
|         core->SetName(name); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取指针
 | ||||
| 		inline ActionPtr Get() const										{ return core; } | ||||
| 
 | ||||
| 		inline ActionHelper(ActionPtr core)									: core(core) {} | ||||
| 
 | ||||
| 		inline operator ActionPtr() const									{ return core; } | ||||
| 
 | ||||
| 	private: | ||||
| 		ActionPtr core; | ||||
| 	}; | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 补间动画辅助类
 | ||||
| 	struct TweenHelper | ||||
|     inline ActionPtr Get() const | ||||
|     { | ||||
|         return core; | ||||
|     } | ||||
| 
 | ||||
|     inline ActionHelper(ActionPtr core) | ||||
|         : core(core) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     inline operator ActionPtr() const | ||||
|     { | ||||
|         return core; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     ActionPtr core; | ||||
| }; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 补间动画辅助类
 | ||||
| struct TweenHelper | ||||
| { | ||||
|     using DoneCallback = Action::DoneCallback; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画持续时长
 | ||||
| 		inline TweenHelper& SetDuration(Duration dur)						{ core->SetDuration(dur); return (*this); } | ||||
|     inline TweenHelper& SetDuration(Duration dur) | ||||
|     { | ||||
|         core->SetDuration(dur); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置循环次数
 | ||||
| 		inline TweenHelper& SetLoops(int loops)								{ core->SetLoops(loops); return (*this); } | ||||
|     inline TweenHelper& SetLoops(int loops) | ||||
|     { | ||||
|         core->SetLoops(loops); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置缓动函数
 | ||||
| 		inline TweenHelper& SetEaseFunc(EaseFunc ease)						{ core->SetEaseFunc(ease); return (*this); } | ||||
|     inline TweenHelper& SetEaseFunc(EaseFunc ease) | ||||
|     { | ||||
|         core->SetEaseFunc(ease); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画延迟
 | ||||
| 		inline TweenHelper& SetDelay(Duration delay)						{ core->SetDelay(delay); return (*this); } | ||||
|     inline TweenHelper& SetDelay(Duration delay) | ||||
|     { | ||||
|         core->SetDelay(delay); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画结束回调函数
 | ||||
| 		inline TweenHelper& SetDoneCallback(DoneCallback const& cb)			{ core->SetDoneCallback(cb); return (*this); } | ||||
|     inline TweenHelper& SetDoneCallback(DoneCallback const& cb) | ||||
|     { | ||||
|         core->SetDoneCallback(cb); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置动画循环结束时的回调函数
 | ||||
| 		inline TweenHelper& SetLoopDoneCallback(DoneCallback const& cb)		{ core->SetLoopDoneCallback(cb); return (*this); } | ||||
|     inline TweenHelper& SetLoopDoneCallback(DoneCallback const& cb) | ||||
|     { | ||||
|         core->SetLoopDoneCallback(cb); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 动画结束时移除目标角色
 | ||||
| 		inline TweenHelper& RemoveTargetWhenDone()							{ core->RemoveTargetWhenDone(); return (*this); } | ||||
|     inline TweenHelper& RemoveTargetWhenDone() | ||||
|     { | ||||
|         core->RemoveTargetWhenDone(); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置名称
 | ||||
| 		inline TweenHelper& SetName(String const& name)						{ core->SetName(name); return (*this); } | ||||
|     inline TweenHelper& SetName(String const& name) | ||||
|     { | ||||
|         core->SetName(name); | ||||
|         return (*this); | ||||
|     } | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取指针
 | ||||
| 		inline ActionTweenPtr Get() const									{ return core; } | ||||
| 		 | ||||
| 		inline TweenHelper(ActionTweenPtr core)								: core(core) {} | ||||
| 
 | ||||
| 		inline operator ActionPtr() const									{ return core; } | ||||
| 
 | ||||
| 		inline operator ActionTweenPtr() const								{ return core; } | ||||
| 
 | ||||
| 	private: | ||||
| 		ActionTweenPtr core; | ||||
| 	}; | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 动画构造器
 | ||||
| 	struct Tween | ||||
|     inline ActionTweenPtr Get() const | ||||
|     { | ||||
| 	public: | ||||
|         return core; | ||||
|     } | ||||
| 
 | ||||
|     inline TweenHelper(ActionTweenPtr core) | ||||
|         : core(core) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     inline operator ActionPtr() const | ||||
|     { | ||||
|         return core; | ||||
|     } | ||||
| 
 | ||||
|     inline operator ActionTweenPtr() const | ||||
|     { | ||||
|         return core; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     ActionTweenPtr core; | ||||
| }; | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 动画构造器
 | ||||
| struct Tween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造相对位移动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param vector 移动向量
 | ||||
| 		static inline TweenHelper | ||||
| 		MoveBy(Duration dur, Point const& vector) | ||||
|     static inline TweenHelper MoveBy(Duration dur, Point const& vector) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionMoveBy(dur, vector)); | ||||
|     } | ||||
|  | @ -145,8 +221,7 @@ namespace kiwano | |||
|     /// @brief 构造位移动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param pos 目的坐标
 | ||||
| 		static inline TweenHelper | ||||
| 		MoveTo(Duration dur, Point const& pos) | ||||
|     static inline TweenHelper MoveTo(Duration dur, Point const& pos) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionMoveTo(dur, pos)); | ||||
|     } | ||||
|  | @ -157,8 +232,7 @@ namespace kiwano | |||
|     /// @param vec 跳跃位移向量
 | ||||
|     /// @param height 跳跃高度
 | ||||
|     /// @param jumps 跳跃次数
 | ||||
| 		static inline TweenHelper | ||||
| 		JumpBy(Duration duration, Vec2 const& vec, float height, int jumps = 1) | ||||
|     static inline TweenHelper JumpBy(Duration duration, Vec2 const& vec, float height, int jumps = 1) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionJumpBy(duration, vec, height, jumps)); | ||||
|     } | ||||
|  | @ -169,8 +243,7 @@ namespace kiwano | |||
|     /// @param pos 目的坐标
 | ||||
|     /// @param height 跳跃高度
 | ||||
|     /// @param jumps 跳跃次数
 | ||||
| 		static inline TweenHelper | ||||
| 		JumpTo(Duration duration, Point const& pos, float height, int jumps = 1) | ||||
|     static inline TweenHelper JumpTo(Duration duration, Point const& pos, float height, int jumps = 1) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionJumpTo(duration, pos, height, jumps)); | ||||
|     } | ||||
|  | @ -180,8 +253,7 @@ namespace kiwano | |||
|     /// @param duration 动画时长
 | ||||
|     /// @param scale_x 横向缩放相对变化值
 | ||||
|     /// @param scale_y 纵向缩放相对变化值
 | ||||
| 		static inline TweenHelper | ||||
| 		ScaleBy(Duration dur, float scale_x, float scale_y) | ||||
|     static inline TweenHelper ScaleBy(Duration dur, float scale_x, float scale_y) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionScaleBy(dur, scale_x, scale_y)); | ||||
|     } | ||||
|  | @ -191,8 +263,7 @@ namespace kiwano | |||
|     /// @param duration 动画时长
 | ||||
|     /// @param scale_x 横向缩放目标值
 | ||||
|     /// @param scale_y 纵向缩放目标值
 | ||||
| 		static inline TweenHelper | ||||
| 		ScaleTo(Duration dur, float scale_x, float scale_y) | ||||
|     static inline TweenHelper ScaleTo(Duration dur, float scale_x, float scale_y) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionScaleTo(dur, scale_x, scale_y)); | ||||
|     } | ||||
|  | @ -201,8 +272,7 @@ namespace kiwano | |||
|     /// @brief 构造透明度渐变动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param opacity 目标透明度
 | ||||
| 		static inline TweenHelper | ||||
| 		FadeTo(Duration dur, float opacity) | ||||
|     static inline TweenHelper FadeTo(Duration dur, float opacity) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionFadeTo(dur, opacity)); | ||||
|     } | ||||
|  | @ -210,8 +280,7 @@ namespace kiwano | |||
|     /// \~chinese
 | ||||
|     /// @brief 构造淡入动画
 | ||||
|     /// @param duration 动画时长
 | ||||
| 		static inline TweenHelper | ||||
| 		FadeIn(Duration dur) | ||||
|     static inline TweenHelper FadeIn(Duration dur) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionFadeIn(dur)); | ||||
|     } | ||||
|  | @ -219,8 +288,7 @@ namespace kiwano | |||
|     /// \~chinese
 | ||||
|     /// @brief 构造淡出动画
 | ||||
|     /// @param duration 动画时长
 | ||||
| 		static inline TweenHelper | ||||
| 		FadeOut(Duration dur) | ||||
|     static inline TweenHelper FadeOut(Duration dur) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionFadeOut(dur)); | ||||
|     } | ||||
|  | @ -229,8 +297,7 @@ namespace kiwano | |||
|     /// @brief 构造相对旋转动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param rotation 角度相对变化值
 | ||||
| 		static inline TweenHelper | ||||
| 		RotateBy(Duration dur, float rotation) | ||||
|     static inline TweenHelper RotateBy(Duration dur, float rotation) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionRotateBy(dur, rotation)); | ||||
|     } | ||||
|  | @ -239,8 +306,7 @@ namespace kiwano | |||
|     /// @brief 构造旋转动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param rotation 目标角度
 | ||||
| 		static inline TweenHelper | ||||
| 		RotateTo(Duration dur, float rotation) | ||||
|     static inline TweenHelper RotateTo(Duration dur, float rotation) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); | ||||
|     } | ||||
|  | @ -252,8 +318,8 @@ namespace kiwano | |||
|     /// @param rotating 是否沿路径切线方向旋转
 | ||||
|     /// @param start 路径起点(百分比)
 | ||||
|     /// @param end 路径终点(百分比)
 | ||||
| 		static inline TweenHelper | ||||
| 		Walk(Duration duration, Geometry const& path, bool rotating = false, float start = 0.f, float end = 1.f) | ||||
|     static inline TweenHelper Walk(Duration duration, Geometry const& path, bool rotating = false, float start = 0.f, | ||||
|                                    float end = 1.f) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionWalk(duration, path, rotating, start, end)); | ||||
|     } | ||||
|  | @ -262,8 +328,7 @@ namespace kiwano | |||
|     /// @brief 构建帧动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param[in] frame_seq 序列帧
 | ||||
| 		static inline TweenHelper | ||||
| 		Animation(Duration dur, FrameSequencePtr frames) | ||||
|     static inline TweenHelper Animation(Duration dur, FrameSequencePtr frames) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::Animation(dur, frames)); | ||||
|     } | ||||
|  | @ -272,8 +337,7 @@ namespace kiwano | |||
|     /// @brief 构造自定义动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param tween_func 动画回调函数
 | ||||
| 		static inline TweenHelper | ||||
| 		Custom(Duration dur, ActionCustom::TweenFunc tween_func) | ||||
|     static inline TweenHelper Custom(Duration dur, ActionCustom::TweenFunc tween_func) | ||||
|     { | ||||
|         return TweenHelper(new kiwano::ActionCustom(dur, tween_func)); | ||||
|     } | ||||
|  | @ -281,8 +345,7 @@ namespace kiwano | |||
|     /// \~chinese
 | ||||
|     /// @brief 构建延时动画
 | ||||
|     /// @param delay 延时时长
 | ||||
| 		static inline ActionHelper | ||||
| 		Delay(Duration delay) | ||||
|     static inline ActionHelper Delay(Duration delay) | ||||
|     { | ||||
|         return ActionHelper(new kiwano::ActionDelay(delay)); | ||||
|     } | ||||
|  | @ -291,8 +354,7 @@ namespace kiwano | |||
|     /// @brief 动画组合
 | ||||
|     /// @param actions 动画集合
 | ||||
|     /// @param sequence 动画按顺序依次执行或同时执行
 | ||||
| 		static inline ActionHelper | ||||
| 		Group(Vector<ActionPtr> const& actions, bool sequence = true) | ||||
|     static inline ActionHelper Group(Vector<ActionPtr> const& actions, bool sequence = true) | ||||
|     { | ||||
|         return ActionHelper(new kiwano::ActionGroup(actions, sequence)); | ||||
|     } | ||||
|  | @ -300,12 +362,11 @@ namespace kiwano | |||
|     /// \~chinese
 | ||||
|     /// @brief 同步动画组合
 | ||||
|     /// @param actions 动画集合
 | ||||
| 		static inline ActionHelper | ||||
| 		Multiple(Vector<ActionPtr> const& actions) | ||||
|     static inline ActionHelper Multiple(Vector<ActionPtr> const& actions) | ||||
|     { | ||||
|         return ActionHelper(new kiwano::ActionGroup(actions, false)); | ||||
|     } | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -18,14 +18,14 @@ | |||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/2d/action/ActionManager.h> | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/action/ActionManager.h> | ||||
| #include <kiwano/core/Logger.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	void ActionManager::UpdateActions(Actor* target, Duration dt) | ||||
| 	{ | ||||
| void ActionManager::UpdateActions(Actor* target, Duration dt) | ||||
| { | ||||
|     if (actions_.empty() || !target) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -40,15 +40,15 @@ namespace kiwano | |||
|         if (action->IsRemoveable()) | ||||
|             actions_.remove(action); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Action* ActionManager::AddAction(ActionPtr action) | ||||
| 	{ | ||||
| Action* ActionManager::AddAction(ActionPtr action) | ||||
| { | ||||
|     return AddAction(action.get()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Action* ActionManager::AddAction(Action* action) | ||||
| 	{ | ||||
| Action* ActionManager::AddAction(Action* action) | ||||
| { | ||||
|     KGE_ASSERT(action && "AddAction failed, NULL pointer exception"); | ||||
| 
 | ||||
|     if (action) | ||||
|  | @ -56,55 +56,55 @@ namespace kiwano | |||
|         actions_.push_back(action); | ||||
|     } | ||||
|     return action; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionManager::GetAction(String const & name) | ||||
| 	{ | ||||
| 		if (actions_.empty()) | ||||
| 			return nullptr; | ||||
| 
 | ||||
| 		for (auto& action : actions_) | ||||
| 			if (action->IsName(name)) | ||||
| 				return action; | ||||
| 
 | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 
 | ||||
| 	void ActionManager::ResumeAllActions() | ||||
| 	{ | ||||
| void ActionManager::ResumeAllActions() | ||||
| { | ||||
|     if (actions_.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     for (auto& action : actions_) | ||||
|     { | ||||
| 			action->Resume(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void ActionManager::PauseAllActions() | ||||
| 	{ | ||||
| 		if (actions_.empty()) | ||||
| 			return; | ||||
| 
 | ||||
| 		for (auto& action : actions_) | ||||
| 		{ | ||||
| 			action->Pause(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void ActionManager::StopAllActions() | ||||
| 	{ | ||||
| 		if (actions_.empty()) | ||||
| 			return; | ||||
| 
 | ||||
| 		for (auto& action : actions_) | ||||
| 		{ | ||||
| 			action->Stop(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	const ActionManager::Actions& ActionManager::GetAllActions() const | ||||
| 	{ | ||||
| 		return actions_; | ||||
|         action.Resume(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ActionManager::PauseAllActions() | ||||
| { | ||||
|     if (actions_.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     for (auto& action : actions_) | ||||
|     { | ||||
|         action.Pause(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ActionManager::StopAllActions() | ||||
| { | ||||
|     if (actions_.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     for (auto& action : actions_) | ||||
|     { | ||||
|         action.Stop(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| ActionPtr ActionManager::GetAction(String const& name) | ||||
| { | ||||
|     if (actions_.empty()) | ||||
|         return nullptr; | ||||
| 
 | ||||
|     for (auto& action : actions_) | ||||
|         if (action.IsName(name)) | ||||
|             return &action; | ||||
| 
 | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| const ActionManager::Actions& ActionManager::GetAllActions() const | ||||
| { | ||||
|     return actions_; | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -23,18 +23,18 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actions | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \~chinese | ||||
|  * @brief 动画管理器 | ||||
|  */ | ||||
| 	class KGE_API ActionManager | ||||
| 	{ | ||||
| 	public: | ||||
| class KGE_API ActionManager | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 动画列表
 | ||||
|     using Actions = IntrusiveList<ActionPtr>; | ||||
|  | @ -47,11 +47,6 @@ namespace kiwano | |||
|     /// @brief 添加动画
 | ||||
|     Action* AddAction(Action* action); | ||||
| 
 | ||||
| 		/// \~chinese
 | ||||
| 		/// @brief 获取指定名称的动画
 | ||||
| 		/// @param name 动画名称
 | ||||
| 		ActionPtr GetAction(String const& name); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 继续所有暂停动画
 | ||||
|     void ResumeAllActions(); | ||||
|  | @ -64,18 +59,23 @@ namespace kiwano | |||
|     /// @brief 停止所有动画
 | ||||
|     void StopAllActions(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取指定名称的动画
 | ||||
|     /// @param name 动画名称
 | ||||
|     ActionPtr GetAction(String const& name); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取所有动画
 | ||||
|     Actions const& GetAllActions() const; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 更新动画
 | ||||
|     void UpdateActions(Actor* target, Duration dt); | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Actions actions_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| } | ||||
| /** @} */ | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -19,87 +19,105 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <functional> | ||||
| #include <kiwano/2d/action/ActionTween.h> | ||||
| #include <kiwano/2d/Actor.h> | ||||
| #include <kiwano/2d/action/ActionTween.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Ease Functions
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // Ease Functions
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	inline EaseFunc MakeEaseIn(float rate)				{ return std::bind(math::EaseIn, std::placeholders::_1, rate); } | ||||
| 	inline EaseFunc MakeEaseOut(float rate)				{ return std::bind(math::EaseOut, std::placeholders::_1, rate); } | ||||
| 	inline EaseFunc MakeEaseInOut(float rate)			{ return std::bind(math::EaseInOut, std::placeholders::_1, rate); } | ||||
| 	inline EaseFunc MakeEaseElasticIn(float period)		{ return std::bind(math::EaseElasticIn, std::placeholders::_1, period); } | ||||
| 	inline EaseFunc MakeEaseElasticOut(float period)	{ return std::bind(math::EaseElasticOut, std::placeholders::_1, period); } | ||||
| 	inline EaseFunc MakeEaseElasticInOut(float period)	{ return std::bind(math::EaseElasticInOut, std::placeholders::_1, period); } | ||||
| inline EaseFunc MakeEaseIn(float rate) | ||||
| { | ||||
|     return std::bind(math::EaseIn, std::placeholders::_1, rate); | ||||
| } | ||||
| inline EaseFunc MakeEaseOut(float rate) | ||||
| { | ||||
|     return std::bind(math::EaseOut, std::placeholders::_1, rate); | ||||
| } | ||||
| inline EaseFunc MakeEaseInOut(float rate) | ||||
| { | ||||
|     return std::bind(math::EaseInOut, std::placeholders::_1, rate); | ||||
| } | ||||
| inline EaseFunc MakeEaseElasticIn(float period) | ||||
| { | ||||
|     return std::bind(math::EaseElasticIn, std::placeholders::_1, period); | ||||
| } | ||||
| inline EaseFunc MakeEaseElasticOut(float period) | ||||
| { | ||||
|     return std::bind(math::EaseElasticOut, std::placeholders::_1, period); | ||||
| } | ||||
| inline EaseFunc MakeEaseElasticInOut(float period) | ||||
| { | ||||
|     return std::bind(math::EaseElasticInOut, std::placeholders::_1, period); | ||||
| } | ||||
| 
 | ||||
| 	KGE_API EaseFunc Ease::Linear = math::Linear; | ||||
| 	KGE_API EaseFunc Ease::EaseIn = MakeEaseIn(2.f); | ||||
| 	KGE_API EaseFunc Ease::EaseOut = MakeEaseOut(2.f); | ||||
| 	KGE_API EaseFunc Ease::EaseInOut = MakeEaseInOut(2.f); | ||||
| 	KGE_API EaseFunc Ease::ExpoIn = math::EaseExponentialIn; | ||||
| 	KGE_API EaseFunc Ease::ExpoOut = math::EaseExponentialOut; | ||||
| 	KGE_API EaseFunc Ease::ExpoInOut = math::EaseExponentialInOut; | ||||
| 	KGE_API EaseFunc Ease::BounceIn = math::EaseBounceIn; | ||||
| 	KGE_API EaseFunc Ease::BounceOut = math::EaseBounceOut; | ||||
| 	KGE_API EaseFunc Ease::BounceInOut = math::EaseBounceInOut; | ||||
| 	KGE_API EaseFunc Ease::ElasticIn = MakeEaseElasticIn(0.3f); | ||||
| 	KGE_API EaseFunc Ease::ElasticOut = MakeEaseElasticOut(0.3f); | ||||
| 	KGE_API EaseFunc Ease::ElasticInOut = MakeEaseElasticInOut(0.3f); | ||||
| 	KGE_API EaseFunc Ease::SineIn = math::EaseSineIn; | ||||
| 	KGE_API EaseFunc Ease::SineOut = math::EaseSineOut; | ||||
| 	KGE_API EaseFunc Ease::SineInOut = math::EaseSineInOut; | ||||
| 	KGE_API EaseFunc Ease::BackIn = math::EaseBackIn; | ||||
| 	KGE_API EaseFunc Ease::BackOut = math::EaseBackOut; | ||||
| 	KGE_API EaseFunc Ease::BackInOut = math::EaseBackInOut; | ||||
| 	KGE_API EaseFunc Ease::QuadIn = math::EaseQuadIn; | ||||
| 	KGE_API EaseFunc Ease::QuadOut = math::EaseQuadOut; | ||||
| 	KGE_API EaseFunc Ease::QuadInOut = math::EaseQuadInOut; | ||||
| 	KGE_API EaseFunc Ease::CubicIn = math::EaseCubicIn; | ||||
| 	KGE_API EaseFunc Ease::CubicOut = math::EaseCubicOut; | ||||
| 	KGE_API EaseFunc Ease::CubicInOut = math::EaseCubicInOut; | ||||
| 	KGE_API EaseFunc Ease::QuartIn = math::EaseQuartIn; | ||||
| 	KGE_API EaseFunc Ease::QuartOut = math::EaseQuartOut; | ||||
| 	KGE_API EaseFunc Ease::QuartInOut = math::EaseQuartInOut; | ||||
| 	KGE_API EaseFunc Ease::QuintIn = math::EaseQuintIn; | ||||
| 	KGE_API EaseFunc Ease::QuintOut = math::EaseQuintOut; | ||||
| 	KGE_API EaseFunc Ease::QuintInOut = math::EaseQuintInOut; | ||||
| KGE_API EaseFunc Ease::Linear       = math::Linear; | ||||
| KGE_API EaseFunc Ease::EaseIn       = MakeEaseIn(2.f); | ||||
| KGE_API EaseFunc Ease::EaseOut      = MakeEaseOut(2.f); | ||||
| KGE_API EaseFunc Ease::EaseInOut    = MakeEaseInOut(2.f); | ||||
| KGE_API EaseFunc Ease::ExpoIn       = math::EaseExponentialIn; | ||||
| KGE_API EaseFunc Ease::ExpoOut      = math::EaseExponentialOut; | ||||
| KGE_API EaseFunc Ease::ExpoInOut    = math::EaseExponentialInOut; | ||||
| KGE_API EaseFunc Ease::BounceIn     = math::EaseBounceIn; | ||||
| KGE_API EaseFunc Ease::BounceOut    = math::EaseBounceOut; | ||||
| KGE_API EaseFunc Ease::BounceInOut  = math::EaseBounceInOut; | ||||
| KGE_API EaseFunc Ease::ElasticIn    = MakeEaseElasticIn(0.3f); | ||||
| KGE_API EaseFunc Ease::ElasticOut   = MakeEaseElasticOut(0.3f); | ||||
| KGE_API EaseFunc Ease::ElasticInOut = MakeEaseElasticInOut(0.3f); | ||||
| KGE_API EaseFunc Ease::SineIn       = math::EaseSineIn; | ||||
| KGE_API EaseFunc Ease::SineOut      = math::EaseSineOut; | ||||
| KGE_API EaseFunc Ease::SineInOut    = math::EaseSineInOut; | ||||
| KGE_API EaseFunc Ease::BackIn       = math::EaseBackIn; | ||||
| KGE_API EaseFunc Ease::BackOut      = math::EaseBackOut; | ||||
| KGE_API EaseFunc Ease::BackInOut    = math::EaseBackInOut; | ||||
| KGE_API EaseFunc Ease::QuadIn       = math::EaseQuadIn; | ||||
| KGE_API EaseFunc Ease::QuadOut      = math::EaseQuadOut; | ||||
| KGE_API EaseFunc Ease::QuadInOut    = math::EaseQuadInOut; | ||||
| KGE_API EaseFunc Ease::CubicIn      = math::EaseCubicIn; | ||||
| KGE_API EaseFunc Ease::CubicOut     = math::EaseCubicOut; | ||||
| KGE_API EaseFunc Ease::CubicInOut   = math::EaseCubicInOut; | ||||
| KGE_API EaseFunc Ease::QuartIn      = math::EaseQuartIn; | ||||
| KGE_API EaseFunc Ease::QuartOut     = math::EaseQuartOut; | ||||
| KGE_API EaseFunc Ease::QuartInOut   = math::EaseQuartInOut; | ||||
| KGE_API EaseFunc Ease::QuintIn      = math::EaseQuintIn; | ||||
| KGE_API EaseFunc Ease::QuintOut     = math::EaseQuintOut; | ||||
| KGE_API EaseFunc Ease::QuintInOut   = math::EaseQuintInOut; | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// ActionTween
 | ||||
| 	//-------------------------------------------------------
 | ||||
| //-------------------------------------------------------
 | ||||
| // ActionTween
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionTween::ActionTween() | ||||
| ActionTween::ActionTween() | ||||
|     : dur_() | ||||
|     , ease_func_(nullptr) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ActionTween::ActionTween(Duration duration, EaseFunc func) | ||||
| 	{ | ||||
| ActionTween::ActionTween(Duration duration, EaseFunc func) | ||||
| { | ||||
|     SetDuration(duration); | ||||
|     SetEaseFunc(func); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionTween::SetEaseFunc(EaseFunc const& func) | ||||
| 	{ | ||||
| void ActionTween::SetEaseFunc(EaseFunc const& func) | ||||
| { | ||||
|     ease_func_ = func; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	EaseFunc const & ActionTween::GetEaseFunc() const | ||||
| 	{ | ||||
| EaseFunc const& ActionTween::GetEaseFunc() const | ||||
| { | ||||
|     return ease_func_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	Duration ActionTween::GetDuration() const | ||||
| 	{ | ||||
| Duration ActionTween::GetDuration() const | ||||
| { | ||||
|     return dur_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionTween::Update(Actor* target, Duration dt) | ||||
| 	{ | ||||
| void ActionTween::Update(Actor* target, Duration dt) | ||||
| { | ||||
|     float percent; | ||||
| 
 | ||||
|     if (dur_.IsZero()) | ||||
|  | @ -124,34 +142,33 @@ namespace kiwano | |||
|         percent = ease_func_(percent); | ||||
| 
 | ||||
|     UpdateTween(target, percent); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionTween::SetDuration(Duration duration) | ||||
| 	{ | ||||
| void ActionTween::SetDuration(Duration duration) | ||||
| { | ||||
|     dur_ = duration; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // Move Action
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Move Action
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionMoveBy::ActionMoveBy(Duration duration, Vec2 const& vector, EaseFunc func) | ||||
| ActionMoveBy::ActionMoveBy(Duration duration, Vec2 const& vector, EaseFunc func) | ||||
|     : ActionTween(duration, func) | ||||
| 	{ | ||||
| { | ||||
|     delta_pos_ = vector; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionMoveBy::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionMoveBy::Init(Actor* target) | ||||
| { | ||||
|     if (target) | ||||
|     { | ||||
|         prev_pos_ = start_pos_ = target->GetPosition(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionMoveBy::UpdateTween(Actor* target, float percent) | ||||
| 	{ | ||||
| void ActionMoveBy::UpdateTween(Actor* target, float percent) | ||||
| { | ||||
|     Point diff = target->GetPosition() - prev_pos_; | ||||
|     start_pos_ = start_pos_ + diff; | ||||
| 
 | ||||
|  | @ -159,68 +176,67 @@ namespace kiwano | |||
|     target->SetPosition(new_pos); | ||||
| 
 | ||||
|     prev_pos_ = new_pos; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionMoveBy::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionMoveBy::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionMoveBy(GetDuration(), delta_pos_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionMoveBy::Reverse() const | ||||
| 	{ | ||||
| ActionPtr ActionMoveBy::Reverse() const | ||||
| { | ||||
|     return new (std::nothrow) ActionMoveBy(GetDuration(), -delta_pos_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionMoveTo::ActionMoveTo(Duration duration, Point const& pos, EaseFunc func) | ||||
| ActionMoveTo::ActionMoveTo(Duration duration, Point const& pos, EaseFunc func) | ||||
|     : ActionMoveBy(duration, Point(), func) | ||||
| 	{ | ||||
| { | ||||
|     end_pos_ = pos; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionMoveTo::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionMoveTo::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionMoveTo(GetDuration(), end_pos_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionMoveTo::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionMoveTo::Init(Actor* target) | ||||
| { | ||||
|     ActionMoveBy::Init(target); | ||||
|     delta_pos_ = end_pos_ - start_pos_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // Jump Action
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Jump Action
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionJumpBy::ActionJumpBy(Duration duration, Vec2 const& vec, float height, int jumps, EaseFunc func) | ||||
| ActionJumpBy::ActionJumpBy(Duration duration, Vec2 const& vec, float height, int jumps, EaseFunc func) | ||||
|     : ActionTween(duration, func) | ||||
|     , delta_pos_(vec) | ||||
|     , height_(height) | ||||
|     , jumps_(jumps) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionJumpBy::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionJumpBy::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionJumpBy(GetDuration(), delta_pos_, height_, jumps_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionJumpBy::Reverse() const | ||||
| 	{ | ||||
| ActionPtr ActionJumpBy::Reverse() const | ||||
| { | ||||
|     return new (std::nothrow) ActionJumpBy(GetDuration(), -delta_pos_, height_, jumps_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionJumpBy::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionJumpBy::Init(Actor* target) | ||||
| { | ||||
|     if (target) | ||||
|     { | ||||
|         prev_pos_ = start_pos_ = target->GetPosition(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionJumpBy::UpdateTween(Actor* target, float percent) | ||||
| 	{ | ||||
| void ActionJumpBy::UpdateTween(Actor* target, float percent) | ||||
| { | ||||
|     float frac = fmod(percent * jumps_, 1.f); | ||||
|     float x    = delta_pos_.x * percent; | ||||
|     float y    = height_ * 4 * frac * (1 - frac); | ||||
|  | @ -233,206 +249,202 @@ namespace kiwano | |||
|     target->SetPosition(new_pos); | ||||
| 
 | ||||
|     prev_pos_ = new_pos; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionJumpTo::ActionJumpTo(Duration duration, Point const& pos, float height, int jumps, EaseFunc func) | ||||
| ActionJumpTo::ActionJumpTo(Duration duration, Point const& pos, float height, int jumps, EaseFunc func) | ||||
|     : ActionJumpBy(duration, Point(), height, jumps, func) | ||||
|     , end_pos_(pos) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionJumpTo::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionJumpTo::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionJumpTo(GetDuration(), end_pos_, height_, jumps_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionJumpTo::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionJumpTo::Init(Actor* target) | ||||
| { | ||||
|     ActionJumpBy::Init(target); | ||||
|     delta_pos_ = end_pos_ - start_pos_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // Scale Action
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Scale Action
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionScaleBy::ActionScaleBy(Duration duration, float scale_x, float scale_y, EaseFunc func) | ||||
| ActionScaleBy::ActionScaleBy(Duration duration, float scale_x, float scale_y, EaseFunc func) | ||||
|     : ActionTween(duration, func) | ||||
|     , delta_x_(scale_x) | ||||
|     , delta_y_(scale_y) | ||||
|     , start_scale_x_(0.f) | ||||
|     , start_scale_y_(0.f) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void ActionScaleBy::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionScaleBy::Init(Actor* target) | ||||
| { | ||||
|     if (target) | ||||
|     { | ||||
|         start_scale_x_ = target->GetScaleX(); | ||||
|         start_scale_y_ = target->GetScaleY(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionScaleBy::UpdateTween(Actor* target, float percent) | ||||
| 	{ | ||||
| void ActionScaleBy::UpdateTween(Actor* target, float percent) | ||||
| { | ||||
|     target->SetScale(Vec2{ start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent }); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionScaleBy::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionScaleBy::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionScaleBy(GetDuration(), delta_x_, delta_y_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionScaleBy::Reverse() const | ||||
| 	{ | ||||
| ActionPtr ActionScaleBy::Reverse() const | ||||
| { | ||||
|     return new (std::nothrow) ActionScaleBy(GetDuration(), -delta_x_, -delta_y_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionScaleTo::ActionScaleTo(Duration duration, float scale_x, float scale_y, EaseFunc func) | ||||
| ActionScaleTo::ActionScaleTo(Duration duration, float scale_x, float scale_y, EaseFunc func) | ||||
|     : ActionScaleBy(duration, 0, 0, func) | ||||
| 	{ | ||||
| { | ||||
|     end_scale_x_ = scale_x; | ||||
|     end_scale_y_ = scale_y; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionScaleTo::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionScaleTo::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionScaleTo(GetDuration(), end_scale_x_, end_scale_y_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionScaleTo::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionScaleTo::Init(Actor* target) | ||||
| { | ||||
|     ActionScaleBy::Init(target); | ||||
|     delta_x_ = end_scale_x_ - start_scale_x_; | ||||
|     delta_y_ = end_scale_y_ - start_scale_y_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // Opacity Action
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Opacity Action
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionFadeTo::ActionFadeTo(Duration duration, float opacity, EaseFunc func) | ||||
| ActionFadeTo::ActionFadeTo(Duration duration, float opacity, EaseFunc func) | ||||
|     : ActionTween(duration, func) | ||||
|     , delta_val_(0.f) | ||||
|     , start_val_(0.f) | ||||
|     , end_val_(opacity) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void ActionFadeTo::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionFadeTo::Init(Actor* target) | ||||
| { | ||||
|     if (target) | ||||
|     { | ||||
|         start_val_ = target->GetOpacity(); | ||||
|         delta_val_ = end_val_ - start_val_; | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionFadeTo::UpdateTween(Actor* target, float percent) | ||||
| 	{ | ||||
| void ActionFadeTo::UpdateTween(Actor* target, float percent) | ||||
| { | ||||
|     target->SetOpacity(start_val_ + delta_val_ * percent); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionFadeTo::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionFadeTo::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionFadeTo(GetDuration(), end_val_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionFadeIn::ActionFadeIn(Duration duration, EaseFunc func) | ||||
| ActionFadeIn::ActionFadeIn(Duration duration, EaseFunc func) | ||||
|     : ActionFadeTo(duration, 1, func) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ActionFadeOut::ActionFadeOut(Duration duration, EaseFunc func) | ||||
| ActionFadeOut::ActionFadeOut(Duration duration, EaseFunc func) | ||||
|     : ActionFadeTo(duration, 0, func) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // Rotate Action
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// Rotate Action
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionRotateBy::ActionRotateBy(Duration duration, float rotation, EaseFunc func) | ||||
| ActionRotateBy::ActionRotateBy(Duration duration, float rotation, EaseFunc func) | ||||
|     : ActionTween(duration, func) | ||||
|     , start_val_() | ||||
|     , delta_val_(rotation) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	void ActionRotateBy::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionRotateBy::Init(Actor* target) | ||||
| { | ||||
|     if (target) | ||||
|     { | ||||
|         start_val_ = target->GetRotation(); | ||||
|     } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionRotateBy::UpdateTween(Actor* target, float percent) | ||||
| 	{ | ||||
| void ActionRotateBy::UpdateTween(Actor* target, float percent) | ||||
| { | ||||
|     float rotation = start_val_ + delta_val_ * percent; | ||||
|     if (rotation > 360.f) | ||||
|         rotation -= 360.f; | ||||
| 
 | ||||
|     target->SetRotation(rotation); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionRotateBy::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionRotateBy::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionRotateBy(GetDuration(), delta_val_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionRotateBy::Reverse() const | ||||
| 	{ | ||||
| ActionPtr ActionRotateBy::Reverse() const | ||||
| { | ||||
|     return new (std::nothrow) ActionRotateBy(GetDuration(), -delta_val_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionRotateTo::ActionRotateTo(Duration duration, float rotation, EaseFunc func) | ||||
| ActionRotateTo::ActionRotateTo(Duration duration, float rotation, EaseFunc func) | ||||
|     : ActionRotateBy(duration, 0, func) | ||||
| 	{ | ||||
| { | ||||
|     end_val_ = rotation; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionRotateTo::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionRotateTo::Clone() const | ||||
| { | ||||
|     return new (std::nothrow) ActionRotateTo(GetDuration(), end_val_, GetEaseFunc()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionRotateTo::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionRotateTo::Init(Actor* target) | ||||
| { | ||||
|     ActionRotateBy::Init(target); | ||||
|     delta_val_ = end_val_ - start_val_; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //-------------------------------------------------------
 | ||||
| // ActionCustom
 | ||||
| //-------------------------------------------------------
 | ||||
| 
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 	// ActionCustom
 | ||||
| 	//-------------------------------------------------------
 | ||||
| 
 | ||||
| 	ActionCustom::ActionCustom(Duration duration, TweenFunc tween_func, EaseFunc func) | ||||
| ActionCustom::ActionCustom(Duration duration, TweenFunc tween_func, EaseFunc func) | ||||
|     : ActionTween(duration, func) | ||||
|     , tween_func_(tween_func) | ||||
| 	{ | ||||
| 	} | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 	ActionPtr ActionCustom::Clone() const | ||||
| 	{ | ||||
| ActionPtr ActionCustom::Clone() const | ||||
| { | ||||
|     return new ActionCustom(GetDuration(), tween_func_); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionCustom::Init(Actor* target) | ||||
| 	{ | ||||
| void ActionCustom::Init(Actor* target) | ||||
| { | ||||
|     if (!tween_func_) | ||||
|         this->Done(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 	void ActionCustom::UpdateTween(Actor* target, float percent) | ||||
| 	{ | ||||
| void ActionCustom::UpdateTween(Actor* target, float percent) | ||||
| { | ||||
|     if (tween_func_) | ||||
|         tween_func_(target, percent); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -24,15 +24,15 @@ | |||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 缓动函数
 | ||||
| 	using EaseFunc = Function<float(float)>; | ||||
| /// \~chinese
 | ||||
| /// @brief 缓动函数
 | ||||
| using EaseFunc = Function<float(float)>; | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 缓动函数枚举
 | ||||
| 	/// @details 查看 https://easings.net 获取更多信息
 | ||||
| 	struct Ease | ||||
| 	{ | ||||
| /// \~chinese
 | ||||
| /// @brief 缓动函数枚举
 | ||||
| /// @details 查看 https://easings.net 获取更多信息
 | ||||
| struct Ease | ||||
| { | ||||
|     static KGE_API EaseFunc Linear;        ///< 线性
 | ||||
|     static KGE_API EaseFunc EaseIn;        ///< 由慢变快
 | ||||
|     static KGE_API EaseFunc EaseOut;       ///< 由快变慢
 | ||||
|  | @ -64,35 +64,32 @@ namespace kiwano | |||
|     static KGE_API EaseFunc SineIn; | ||||
|     static KGE_API EaseFunc SineOut; | ||||
|     static KGE_API EaseFunc SineInOut; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| KGE_DECLARE_SMART_PTR(ActionTween); | ||||
| KGE_DECLARE_SMART_PTR(ActionMoveBy); | ||||
| KGE_DECLARE_SMART_PTR(ActionMoveTo); | ||||
| KGE_DECLARE_SMART_PTR(ActionJumpBy); | ||||
| KGE_DECLARE_SMART_PTR(ActionJumpTo); | ||||
| KGE_DECLARE_SMART_PTR(ActionScaleBy); | ||||
| KGE_DECLARE_SMART_PTR(ActionScaleTo); | ||||
| KGE_DECLARE_SMART_PTR(ActionFadeTo); | ||||
| KGE_DECLARE_SMART_PTR(ActionFadeIn); | ||||
| KGE_DECLARE_SMART_PTR(ActionFadeOut); | ||||
| KGE_DECLARE_SMART_PTR(ActionRotateBy); | ||||
| KGE_DECLARE_SMART_PTR(ActionRotateTo); | ||||
| KGE_DECLARE_SMART_PTR(ActionCustom); | ||||
| 
 | ||||
| 	KGE_DECLARE_SMART_PTR(ActionTween); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionMoveBy); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionMoveTo); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionJumpBy); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionJumpTo); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionScaleBy); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionScaleTo); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionFadeTo); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionFadeIn); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionFadeOut); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionRotateBy); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionRotateTo); | ||||
| 	KGE_DECLARE_SMART_PTR(ActionCustom); | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| /**
 | ||||
|  * \addtogroup Actions | ||||
|  * @{ | ||||
|  */ | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 补间动画
 | ||||
| 	class KGE_API ActionTween | ||||
| 		: public Action | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 补间动画
 | ||||
| class KGE_API ActionTween : public Action | ||||
| { | ||||
| public: | ||||
|     ActionTween(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -117,23 +114,21 @@ namespace kiwano | |||
|     /// @brief 设置动画速度缓动函数
 | ||||
|     void SetEaseFunc(EaseFunc const& func); | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Update(Actor* target, Duration dt) override; | ||||
| 
 | ||||
|     virtual void UpdateTween(Actor* target, float percent) = 0; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Duration dur_; | ||||
|     EaseFunc ease_func_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 相对位移动画
 | ||||
| 	class KGE_API ActionMoveBy | ||||
| 		: public ActionTween | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 相对位移动画
 | ||||
| class KGE_API ActionMoveBy : public ActionTween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造相对位移动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -149,24 +144,22 @@ namespace kiwano | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void UpdateTween(Actor* target, float percent) override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     Point start_pos_; | ||||
|     Point prev_pos_; | ||||
|     Vec2  delta_pos_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 位移动画
 | ||||
| 	class KGE_API ActionMoveTo | ||||
| 		: public ActionMoveBy | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 位移动画
 | ||||
| class KGE_API ActionMoveTo : public ActionMoveBy | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造位移动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -186,20 +179,18 @@ namespace kiwano | |||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Point end_pos_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 相对跳跃动画
 | ||||
| 	class KGE_API ActionJumpBy | ||||
| 		: public ActionTween | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 相对跳跃动画
 | ||||
| class KGE_API ActionJumpBy : public ActionTween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造相对跳跃动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -217,26 +208,24 @@ namespace kiwano | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void UpdateTween(Actor* target, float percent) override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     Point start_pos_; | ||||
|     Point delta_pos_; | ||||
|     float height_; | ||||
|     int   jumps_; | ||||
|     Point prev_pos_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 跳跃动画
 | ||||
| 	class KGE_API ActionJumpTo | ||||
| 		: public ActionJumpBy | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 跳跃动画
 | ||||
| class KGE_API ActionJumpTo : public ActionJumpBy | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造跳跃动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -258,20 +247,18 @@ namespace kiwano | |||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     Point end_pos_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 相对缩放动画
 | ||||
| 	class KGE_API ActionScaleBy | ||||
| 		: public ActionTween | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 相对缩放动画
 | ||||
| class KGE_API ActionScaleBy : public ActionTween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造相对缩放动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -288,25 +275,23 @@ namespace kiwano | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void UpdateTween(Actor* target, float percent) override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     float start_scale_x_; | ||||
|     float start_scale_y_; | ||||
|     float delta_x_; | ||||
|     float delta_y_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 缩放动画
 | ||||
| 	class KGE_API ActionScaleTo | ||||
| 		: public ActionScaleBy | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 缩放动画
 | ||||
| class KGE_API ActionScaleTo : public ActionScaleBy | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造缩放动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -327,21 +312,19 @@ namespace kiwano | |||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     float end_scale_x_; | ||||
|     float end_scale_y_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 透明度渐变动画
 | ||||
| 	class KGE_API ActionFadeTo | ||||
| 		: public ActionTween | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 透明度渐变动画
 | ||||
| class KGE_API ActionFadeTo : public ActionTween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造透明度渐变动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -361,52 +344,46 @@ namespace kiwano | |||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void UpdateTween(Actor* target, float percent) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     float start_val_; | ||||
|     float delta_val_; | ||||
|     float end_val_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 淡入动画
 | ||||
| 	class KGE_API ActionFadeIn | ||||
| 		: public ActionFadeTo | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 淡入动画
 | ||||
| class KGE_API ActionFadeIn : public ActionFadeTo | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造淡入动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param func 动画速度缓动函数
 | ||||
|     explicit ActionFadeIn(Duration duration, EaseFunc func = nullptr); | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 淡出动画
 | ||||
| 	class KGE_API ActionFadeOut | ||||
| 		: public ActionFadeTo | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 淡出动画
 | ||||
| class KGE_API ActionFadeOut : public ActionFadeTo | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造淡出动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|     /// @param func 动画速度缓动函数
 | ||||
|     explicit ActionFadeOut(Duration duration, EaseFunc func = nullptr); | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 相对旋转动画
 | ||||
| 	class KGE_API ActionRotateBy | ||||
| 		: public ActionTween | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 相对旋转动画
 | ||||
| class KGE_API ActionRotateBy : public ActionTween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造相对旋转动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -422,23 +399,21 @@ namespace kiwano | |||
|     /// @brief 获取该动画的倒转
 | ||||
|     ActionPtr Reverse() const override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void UpdateTween(Actor* target, float percent) override; | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     float start_val_; | ||||
|     float delta_val_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 旋转动画
 | ||||
| 	class KGE_API ActionRotateTo | ||||
| 		: public ActionRotateBy | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 旋转动画
 | ||||
| class KGE_API ActionRotateTo : public ActionRotateBy | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 构造旋转动画
 | ||||
|     /// @param duration 动画时长
 | ||||
|  | @ -458,20 +433,18 @@ namespace kiwano | |||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     float end_val_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 	/// \~chinese
 | ||||
| 	/// @brief 自定义动画
 | ||||
| 	class KGE_API ActionCustom | ||||
| 		: public ActionTween | ||||
| 	{ | ||||
| 	public: | ||||
| /// \~chinese
 | ||||
| /// @brief 自定义动画
 | ||||
| class KGE_API ActionCustom : public ActionTween | ||||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 动画回调函数
 | ||||
|     /// @details 在动画更新时回调该函数,第一个参数是执行动画的目标,第二个参数是动画进度(0.0 - 1.0)
 | ||||
|  | @ -496,15 +469,15 @@ namespace kiwano | |||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
| 	protected: | ||||
| protected: | ||||
|     void Init(Actor* target) override; | ||||
| 
 | ||||
|     void UpdateTween(Actor* target, float percent) override; | ||||
| 
 | ||||
| 	private: | ||||
| private: | ||||
|     TweenFunc tween_func_; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| 	/** @} */ | ||||
| /** @} */ | ||||
| 
 | ||||
| } | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue