[deploy] Merge pull request #47 from KiwanoEngine/dev

Remove tinyxml2 & add pugixml
This commit is contained in:
Haibo 2020-01-28 16:10:31 +08:00 committed by GitHub
commit 3da3cc6022
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
257 changed files with 44812 additions and 35550 deletions

108
.clang-format Normal file
View File

@ -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

View File

@ -14,7 +14,7 @@ insert_final_newline = true
charset = gb2312 charset = gb2312
# 4 space indentation # 4 space indentation
indent_style = tab indent_style = space
indent_size = 4 indent_size = 4
# Matches the exact files # Matches the exact files

66
README-zh.md Normal file
View File

@ -0,0 +1,66 @@
![Kiwano Logo](https://github.com/Nomango/Kiwano/raw/master/logo/logo_text_h.png)
# Kiwano 游戏引擎
[![Build status](https://ci.appveyor.com/api/projects/status/frqh09om9ldaklr9/branch/master?svg=true)](https://ci.appveyor.com/project/Nomango/kiwano/branch/master)
[![GitHub release](https://img.shields.io/github/release/nomango/kiwano)](https://github.com/Nomango/Kiwano/releases/latest)
[![GitHub license](https://img.shields.io/github/license/nomango/kiwano)](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

View File

@ -6,6 +6,8 @@
[![GitHub release](https://img.shields.io/github/release/nomango/kiwano)](https://github.com/Nomango/Kiwano/releases/latest) [![GitHub release](https://img.shields.io/github/release/nomango/kiwano)](https://github.com/Nomango/Kiwano/releases/latest)
[![GitHub license](https://img.shields.io/github/license/nomango/kiwano)](https://github.com/Nomango/Kiwano/blob/master/LICENSE) [![GitHub license](https://img.shields.io/github/license/nomango/kiwano)](https://github.com/Nomango/Kiwano/blob/master/LICENSE)
English | [简体中文](./README-zh.md)
## Introduction ## Introduction
Kiwano is a open-source 2D C++ game engine, only support win32 platform. 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 ## Features
* Scene management * Scene management
* Transitions between scenes * Transitions between scenes
* Actions behaviours * Action behaviours
* Buttons and menus * Buttons and menus
* Texture atlas support * Texture atlas support
* Audio support * Audio support
* Custom data storage * Custom data storage
* Direct2D based * Physical engine (based on Box2D)
* GUI system (based on ImGui)
## Install ## 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 ! 6. Now you can build your own applications based on Kiwano source code !
## Next plan ## Next plan
* GUI system * Cross-platform
* Physical engine
* Particle system * Particle system
## Contact ## Contact

View File

@ -19,7 +19,6 @@ pull_requests:
environment: environment:
global: global:
time_out_mins: 5 time_out_mins: 5
job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration)
flag_to_deploy: false flag_to_deploy: false
appveyor_api_token: appveyor_api_token:
secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E=
@ -48,11 +47,10 @@ for:
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
VS_PLATFORM_TOOLSET: v142
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
VS_PLATFORM_TOOLSET: v141
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
VS_PLATFORM_TOOLSET: v140 global:
job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration)
- -
branches: branches:
except: except:
@ -62,7 +60,8 @@ for:
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
VS_PLATFORM_TOOLSET: v142 global:
job_to_deploy: 2 # 1(images) * 1(platform) * 2(configuration)
configuration: configuration:
- Debug - Debug
@ -90,9 +89,9 @@ after_build:
artifacts: artifacts:
- path: projects/output/**/*.lib - path: projects/output/**/*.lib
name: $(appveyor_project_name)-v$(appveyor_build_version)-$(VS_PLATFORM_TOOLSET).$(platform).$(configuration) name: PublishedLibraries
- path: projects/output/**/*.pdb - path: projects/output/**/*.pdb
name: $(appveyor_project_name)-v$(appveyor_build_version)-$(VS_PLATFORM_TOOLSET).$(platform).$(configuration) name: PublishedSymbols
before_deploy: before_deploy:
- ps: .\scripts\appveyor\coapp_make.ps1 - ps: .\scripts\appveyor\coapp_make.ps1
@ -100,9 +99,9 @@ before_deploy:
deploy: deploy:
- provider: GitHub - provider: GitHub
repository: KiwanoEngine/Kiwano repository: KiwanoEngine/Kiwano
tag: v$(appveyor_build_version) tag: v$(APPVEYOR_BUILD_VERSION)
release: v$(appveyor_build_version) release: v$(APPVEYOR_BUILD_VERSION)
description: Kiwano-v$(appveyor_build_version) releases. description: Kiwano-v$(APPVEYOR_BUILD_VERSION) releases.
auth_token: auth_token:
secure: pDsK6i03d4qRjtrNXcbhLpAquso/muJWgDSWJHnxP7b6p54kXEvptB67J+1kJOhq secure: pDsK6i03d4qRjtrNXcbhLpAquso/muJWgDSWJHnxP7b6p54kXEvptB67J+1kJOhq
artifact: /.*\.nupkg/ artifact: /.*\.nupkg/

View File

@ -33,7 +33,6 @@
<ClInclude Include="..\..\..\src\3rd-party\curl\typecheck-gcc.h"> <ClInclude Include="..\..\..\src\3rd-party\curl\typecheck-gcc.h">
<Filter>include</Filter> <Filter>include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\3rd-party\curl\tinyxml2.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Library Include="..\..\..\src\3rd-party\curl\libs\libcurl.lib"> <Library Include="..\..\..\src\3rd-party\curl\libs\libcurl.lib">

View File

@ -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>

View File

@ -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>

View File

@ -14,8 +14,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano-physics", "kiwano-ph
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rd-party", "3rd-party", "{2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rd-party", "3rd-party", "{2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}"
EndProject 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}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libimgui", "3rd-party\imgui\libimgui.vcxproj", "{7FA1E56D-62AC-47D1-97D1-40B302724198}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "3rd-party\curl\libcurl.vcxproj", "{A9ABACC7-75A1-46BA-8E48-4105346D9719}" 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}.Debug|Win32.Build.0 = Debug|Win32
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.ActiveCfg = Release|Win32 {DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.ActiveCfg = Release|Win32
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.Build.0 = 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.ActiveCfg = Debug|Win32
{7FA1E56D-62AC-47D1-97D1-40B302724198}.Debug|Win32.Build.0 = Debug|Win32 {7FA1E56D-62AC-47D1-97D1-40B302724198}.Debug|Win32.Build.0 = Debug|Win32
{7FA1E56D-62AC-47D1-97D1-40B302724198}.Release|Win32.ActiveCfg = Release|Win32 {7FA1E56D-62AC-47D1-97D1-40B302724198}.Release|Win32.ActiveCfg = Release|Win32
@ -70,7 +64,6 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{AB47E875-85E5-4105-A71E-88930EAAB910} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
{7FA1E56D-62AC-47D1-97D1-40B302724198} = {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} {A9ABACC7-75A1-46BA-8E48-4105346D9719} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
{0CBA9295-F14D-4966-A7C4-1DD68158176C} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7} {0CBA9295-F14D-4966-A7C4-1DD68158176C} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}

View File

@ -9,15 +9,20 @@
<ClInclude Include="..\..\src\kiwano\2d\action\ActionWalk.h" /> <ClInclude Include="..\..\src\kiwano\2d\action\ActionWalk.h" />
<ClInclude Include="..\..\src\kiwano\2d\action\ActionTween.h" /> <ClInclude Include="..\..\src\kiwano\2d\action\ActionTween.h" />
<ClInclude Include="..\..\src\kiwano\2d\action\Animation.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\Frame.h" />
<ClInclude Include="..\..\src\kiwano\2d\GifSprite.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\Event.h" />
<ClInclude Include="..\..\src\kiwano\core\event\EventType.h" /> <ClInclude Include="..\..\src\kiwano\core\event\EventType.h" />
<ClInclude Include="..\..\src\kiwano\core\event\KeyEvent.h" /> <ClInclude Include="..\..\src\kiwano\core\event\KeyEvent.h" />
<ClInclude Include="..\..\src\kiwano\core\event\MouseEvent.h" /> <ClInclude Include="..\..\src\kiwano\core\event\MouseEvent.h" />
<ClInclude Include="..\..\src\kiwano\core\event\WindowEvent.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\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\kiwano.h" />
<ClInclude Include="..\..\src\kiwano\config.h" /> <ClInclude Include="..\..\src\kiwano\config.h" />
<ClInclude Include="..\..\src\kiwano\macros.h" /> <ClInclude Include="..\..\src\kiwano\macros.h" />
@ -36,7 +41,6 @@
<ClInclude Include="..\..\src\kiwano\core\Component.h" /> <ClInclude Include="..\..\src\kiwano\core\Component.h" />
<ClInclude Include="..\..\src\kiwano\core\EventDispatcher.h" /> <ClInclude Include="..\..\src\kiwano\core\EventDispatcher.h" />
<ClInclude Include="..\..\src\kiwano\core\EventListener.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\Logger.h" />
<ClInclude Include="..\..\src\kiwano\core\ObjectBase.h" /> <ClInclude Include="..\..\src\kiwano\core\ObjectBase.h" />
<ClInclude Include="..\..\src\kiwano\core\RefCounter.h" /> <ClInclude Include="..\..\src\kiwano\core\RefCounter.h" />
@ -44,7 +48,6 @@
<ClInclude Include="..\..\src\kiwano\core\SmartPtr.hpp" /> <ClInclude Include="..\..\src\kiwano\core\SmartPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\core\Timer.h" /> <ClInclude Include="..\..\src\kiwano\core\Timer.h" />
<ClInclude Include="..\..\src\kiwano\core\TimerManager.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\constants.h" />
<ClInclude Include="..\..\src\kiwano\math\ease.h" /> <ClInclude Include="..\..\src\kiwano\math\ease.h" />
<ClInclude Include="..\..\src\kiwano\math\math.h" /> <ClInclude Include="..\..\src\kiwano\math\math.h" />
@ -54,36 +57,33 @@
<ClInclude Include="..\..\src\kiwano\math\scalar.h" /> <ClInclude Include="..\..\src\kiwano\math\scalar.h" />
<ClInclude Include="..\..\src\kiwano\math\Vec2.hpp" /> <ClInclude Include="..\..\src\kiwano\math\Vec2.hpp" />
<ClInclude Include="..\..\src\kiwano\platform\Application.h" /> <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\FileSystem.h" />
<ClInclude Include="..\..\src\kiwano\platform\Input.h" /> <ClInclude Include="..\..\src\kiwano\platform\Input.h" />
<ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" /> <ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\platform\win32\helper.h" /> <ClInclude Include="..\..\src\kiwano\platform\win32\helper.h" />
<ClInclude Include="..\..\src\kiwano\platform\win32\libraries.h" /> <ClInclude Include="..\..\src\kiwano\platform\win32\libraries.h" />
<ClInclude Include="..\..\src\kiwano\platform\Window.h" /> <ClInclude Include="..\..\src\kiwano\platform\Window.h" />
<ClInclude Include="..\..\src\kiwano\renderer\Brush.h" /> <ClInclude Include="..\..\src\kiwano\render\Brush.h" />
<ClInclude Include="..\..\src\kiwano\renderer\Color.h" /> <ClInclude Include="..\..\src\kiwano\render\Color.h" />
<ClInclude Include="..\..\src\kiwano\renderer\Font.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.h" />
<ClInclude Include="..\..\src\kiwano\renderer\Geometry.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.h" />
<ClInclude Include="..\..\src\kiwano\renderer\GeometrySink.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.h" />
<ClInclude Include="..\..\src\kiwano\renderer\GifImage.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\D3DDeviceResourcesBase.h" />
<ClInclude Include="..\..\src\kiwano\renderer\StrokeStyle.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.h" />
<ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\helper.h" />
<ClInclude Include="..\..\src\kiwano\renderer\Texture.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h" />
<ClInclude Include="..\..\src\kiwano\renderer\TextureCache.h" /> <ClInclude Include="..\..\src\kiwano\render\Font.h" />
<ClInclude Include="..\..\src\kiwano\renderer\LayerArea.h" /> <ClInclude Include="..\..\src\kiwano\render\Geometry.h" />
<ClInclude Include="..\..\src\kiwano\renderer\Renderer.h" /> <ClInclude Include="..\..\src\kiwano\render\GeometrySink.h" />
<ClInclude Include="..\..\src\kiwano\renderer\RenderTarget.h" /> <ClInclude Include="..\..\src\kiwano\render\GifImage.h" />
<ClInclude Include="..\..\src\kiwano\renderer\TextLayout.h" /> <ClInclude Include="..\..\src\kiwano\render\LayerArea.h" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.h" /> <ClInclude Include="..\..\src\kiwano\render\RenderContext.h" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.h" /> <ClInclude Include="..\..\src\kiwano\render\Renderer.h" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.h" /> <ClInclude Include="..\..\src\kiwano\render\StrokeStyle.h" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3DDeviceResourcesBase.h" /> <ClInclude Include="..\..\src\kiwano\render\TextLayout.h" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.h" /> <ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\helper.h" /> <ClInclude Include="..\..\src\kiwano\render\Texture.h" />
<ClInclude Include="..\..\src\kiwano\renderer\win32\TextRenderer.h" /> <ClInclude Include="..\..\src\kiwano\render\TextureCache.h" />
<ClInclude Include="..\..\src\kiwano\ui\Button.h" />
<ClInclude Include="..\..\src\kiwano\ui\Menu.h" />
<ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h" /> <ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h" />
<ClInclude Include="..\..\src\kiwano\utils\ResourceCache.h" /> <ClInclude Include="..\..\src\kiwano\utils\ResourceCache.h" />
<ClInclude Include="..\..\src\kiwano\utils\UserData.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\ActionWalk.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\action\ActionTween.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\action\ActionTween.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\action\Animation.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\Canvas.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\DebugActor.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\DebugActor.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Frame.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Frame.cpp" />
@ -111,6 +112,7 @@
<ClCompile Include="..\..\src\kiwano\2d\Transition.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Transition.cpp" />
<ClCompile Include="..\..\src\kiwano\core\AsyncTask.cpp" /> <ClCompile Include="..\..\src\kiwano\core\AsyncTask.cpp" />
<ClCompile Include="..\..\src\kiwano\core\Component.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\EventDispatcher.cpp" />
<ClCompile Include="..\..\src\kiwano\core\EventListener.cpp" /> <ClCompile Include="..\..\src\kiwano\core\EventListener.cpp" />
<ClCompile Include="..\..\src\kiwano\core\event\Event.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\ObjectBase.cpp" />
<ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp" /> <ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp" />
<ClCompile Include="..\..\src\kiwano\core\Resource.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\Timer.cpp" />
<ClCompile Include="..\..\src\kiwano\core\TimerManager.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\Application.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Director.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Input.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\Input.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\win32\StackWalker.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\platform\Window.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Brush.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\Color.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Color.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\Font.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\Geometry.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\GeometrySink.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\GifImage.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\Texture.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\TextRenderer.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\TextureCache.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Font.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\LayerArea.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Geometry.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\Renderer.cpp" /> <ClCompile Include="..\..\src\kiwano\render\GeometrySink.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\RenderTarget.cpp" /> <ClCompile Include="..\..\src\kiwano\render\GifImage.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\TextLayout.cpp" /> <ClCompile Include="..\..\src\kiwano\render\LayerArea.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.cpp" /> <ClCompile Include="..\..\src\kiwano\render\RenderContext.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Renderer.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.cpp" /> <ClCompile Include="..\..\src\kiwano\render\StrokeStyle.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.cpp" /> <ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp" />
<ClCompile Include="..\..\src\kiwano\renderer\win32\TextRenderer.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Texture.cpp" />
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp" /> <ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp" />
<ClCompile Include="..\..\src\kiwano\ui\Menu.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp" /> <ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\ResourceCache.cpp" /> <ClCompile Include="..\..\src\kiwano\utils\ResourceCache.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\UserData.cpp" /> <ClCompile Include="..\..\src\kiwano\utils\UserData.cpp" />
@ -165,11 +166,6 @@
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\3rd-party\tinyxml2\libtinyxml2.vcxproj">
<Project>{ab47e875-85e5-4105-a71e-88930eaab910}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid> <ProjectGuid>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid>
<RootNamespace>kiwano</RootNamespace> <RootNamespace>kiwano</RootNamespace>

View File

@ -7,9 +7,6 @@
<Filter Include="utils"> <Filter Include="utils">
<UniqueIdentifier>{68eac919-ee87-4030-a033-c251731928f5}</UniqueIdentifier> <UniqueIdentifier>{68eac919-ee87-4030-a033-c251731928f5}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="ui">
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
</Filter>
<Filter Include="platform"> <Filter Include="platform">
<UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier> <UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier>
</Filter> </Filter>
@ -19,29 +16,23 @@
<Filter Include="core"> <Filter Include="core">
<UniqueIdentifier>{2e18d99a-e906-499a-9e29-4e0783202644}</UniqueIdentifier> <UniqueIdentifier>{2e18d99a-e906-499a-9e29-4e0783202644}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="renderer">
<UniqueIdentifier>{7897afce-24cb-42b4-9443-56508e4ec89c}</UniqueIdentifier>
</Filter>
<Filter Include="2d\action"> <Filter Include="2d\action">
<UniqueIdentifier>{9314f30d-5742-48b6-94e5-e3b4284106f6}</UniqueIdentifier> <UniqueIdentifier>{9314f30d-5742-48b6-94e5-e3b4284106f6}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="renderer\win32">
<UniqueIdentifier>{30333461-e9bc-4709-84bd-ce6e0e1a3079}</UniqueIdentifier>
</Filter>
<Filter Include="platform\win32"> <Filter Include="platform\win32">
<UniqueIdentifier>{e84dcf9a-e650-473e-8c9c-193804ab9e76}</UniqueIdentifier> <UniqueIdentifier>{e84dcf9a-e650-473e-8c9c-193804ab9e76}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="core\event"> <Filter Include="core\event">
<UniqueIdentifier>{c629aedd-ffb9-4bc1-82c3-f50e77c82e77}</UniqueIdentifier> <UniqueIdentifier>{c629aedd-ffb9-4bc1-82c3-f50e77c82e77}</UniqueIdentifier>
</Filter> </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>
<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"> <ClInclude Include="..\..\src\kiwano\2d\Canvas.h">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </ClInclude>
@ -66,9 +57,6 @@
<ClInclude Include="..\..\src\kiwano\core\Resource.h"> <ClInclude Include="..\..\src\kiwano\core\Resource.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\core\time.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Matrix.hpp"> <ClInclude Include="..\..\src\kiwano\math\Matrix.hpp">
<Filter>math</Filter> <Filter>math</Filter>
</ClInclude> </ClInclude>
@ -156,63 +144,9 @@
<ClInclude Include="..\..\src\kiwano\core\ObjectBase.h"> <ClInclude Include="..\..\src\kiwano\core\ObjectBase.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </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"> <ClInclude Include="..\..\src\kiwano\2d\Transform.h">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </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"> <ClInclude Include="..\..\src\kiwano\math\constants.h">
<Filter>math</Filter> <Filter>math</Filter>
</ClInclude> </ClInclude>
@ -234,36 +168,18 @@
<ClInclude Include="..\..\src\kiwano\platform\FileSystem.h"> <ClInclude Include="..\..\src\kiwano\platform\FileSystem.h">
<Filter>platform</Filter> <Filter>platform</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\core\keys.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Input.h"> <ClInclude Include="..\..\src\kiwano\platform\Input.h">
<Filter>platform</Filter> <Filter>platform</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Window.h"> <ClInclude Include="..\..\src\kiwano\platform\Window.h">
<Filter>platform</Filter> <Filter>platform</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Director.h">
<Filter>platform</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\TextActor.h"> <ClInclude Include="..\..\src\kiwano\2d\TextActor.h">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\core\common.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\RefCounter.h"> <ClInclude Include="..\..\src\kiwano\core\RefCounter.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </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"> <ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp">
<Filter>platform\win32</Filter> <Filter>platform\win32</Filter>
</ClInclude> </ClInclude>
@ -288,14 +204,89 @@
<ClInclude Include="..\..\src\kiwano\core\event\WindowEvent.h"> <ClInclude Include="..\..\src\kiwano\core\event\WindowEvent.h">
<Filter>core\event</Filter> <Filter>core\event</Filter>
</ClInclude> </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>
<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"> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClCompile> </ClCompile>
@ -317,9 +308,6 @@
<ClCompile Include="..\..\src\kiwano\core\Resource.cpp"> <ClCompile Include="..\..\src\kiwano\core\Resource.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\core\time.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\Application.cpp"> <ClCompile Include="..\..\src\kiwano\platform\Application.cpp">
<Filter>platform</Filter> <Filter>platform</Filter>
</ClCompile> </ClCompile>
@ -383,57 +371,9 @@
<ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp"> <ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </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"> <ClCompile Include="..\..\src\kiwano\2d\Transform.cpp">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClCompile> </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"> <ClCompile Include="..\..\src\kiwano\core\Component.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </ClCompile>
@ -455,18 +395,12 @@
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp"> <ClCompile Include="..\..\src\kiwano\platform\Window.cpp">
<Filter>platform</Filter> <Filter>platform</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\Director.cpp">
<Filter>platform</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp"> <ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp">
<Filter>2d</Filter> <Filter>2d</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp"> <ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\GeometrySink.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp"> <ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp">
<Filter>platform\win32</Filter> <Filter>platform\win32</Filter>
</ClCompile> </ClCompile>
@ -485,5 +419,71 @@
<ClCompile Include="..\..\src\kiwano\core\event\WindowEvent.cpp"> <ClCompile Include="..\..\src\kiwano\core\event\WindowEvent.cpp">
<Filter>core\event</Filter> <Filter>core\event</Filter>
</ClCompile> </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> </ItemGroup>
</Project> </Project>

84
scripts/clang-format-all Normal file
View File

@ -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

View File

@ -115,23 +115,23 @@ public:
virtual _Ret invoke(_Args... args) const override 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); return new (::std::nothrow) proxy_mem_callable<_Ty, _Ret, _Args...>(ptr, func);
} }
protected: protected:
proxy_mem_callable(void* ptr, _FuncType func) proxy_mem_callable(_Ty* ptr, _FuncType func)
: ptr_(ptr) : ptr_(ptr)
, func_(func) , func_(func)
{ {
} }
protected: protected:
void* ptr_; _Ty* ptr_;
_FuncType func_; _FuncType func_;
}; };
@ -144,23 +144,23 @@ public:
virtual _Ret invoke(_Args... args) const override 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); return new (::std::nothrow) proxy_const_mem_callable<_Ty, _Ret, _Args...>(ptr, func);
} }
protected: protected:
proxy_const_mem_callable(void* ptr, _FuncType func) proxy_const_mem_callable(_Ty* ptr, _FuncType func)
: ptr_(ptr) : ptr_(ptr)
, func_(func) , func_(func)
{ {
} }
protected: protected:
void* ptr_; _Ty* ptr_;
_FuncType func_; _FuncType func_;
}; };

View File

@ -16,20 +16,19 @@ template <typename _Ty, typename _PTy = typename std::pointer_traits<_Ty>::point
class intrusive_list_item class intrusive_list_item
{ {
public: public:
using pointer_type = _PTy; using pointer = _PTy;
using const_pointer_type = const _PTy;
intrusive_list_item() : prev_(nullptr), next_(nullptr) {} 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_; } const pointer prev_item() const { return prev_; }
pointer_type prev_item() { return prev_; } pointer prev_item() { return prev_; }
const_pointer_type next_item() const { return next_; } const pointer next_item() const { return next_; }
pointer_type next_item() { return next_; } pointer next_item() { return next_; }
private: private:
pointer_type prev_; pointer prev_;
pointer_type next_; pointer next_;
friend class intrusive_list<_Ty, _PTy>; friend class intrusive_list<_Ty, _PTy>;
}; };
@ -39,23 +38,24 @@ template <typename _Ty, typename _PTy>
class intrusive_list class intrusive_list
{ {
public: public:
using pointer_type = _PTy; using value_type = typename std::pointer_traits<_PTy>::element_type;
using const_pointer_type = const _PTy; using pointer = _PTy;
using reference = value_type&;
intrusive_list() : first_(), last_() {} intrusive_list() : first_(), last_() {}
~intrusive_list() { clear(); } ~intrusive_list() { clear(); }
const_pointer_type first_item() const { return first_; } const pointer first_item() const { return first_; }
pointer_type first_item() { return first_; } pointer first_item() { return first_; }
const_pointer_type last_item() const { return last_; } const pointer last_item() const { return last_; }
pointer_type last_item() { return last_; } pointer last_item() { return last_; }
inline bool empty() const inline bool empty() const
{ {
return first_ == nullptr; return first_ == nullptr;
} }
void push_back(pointer_type child) void push_back(pointer child)
{ {
if (child->prev_) if (child->prev_)
child->prev_->next_ = child->next_; child->prev_->next_ = child->next_;
@ -77,7 +77,7 @@ public:
last_ = child; last_ = child;
} }
void push_front(pointer_type child) void push_front(pointer child)
{ {
if (child->prev_) if (child->prev_)
child->prev_->next_ = child->next_; child->prev_->next_ = child->next_;
@ -99,7 +99,7 @@ public:
first_ = child; first_ = child;
} }
void insert_before(pointer_type child, pointer_type before) void insert_before(pointer child, pointer before)
{ {
if (child->prev_) if (child->prev_)
child->prev_->next_ = child->next_; child->prev_->next_ = child->next_;
@ -116,7 +116,7 @@ public:
before->prev_ = child; before->prev_ = child;
} }
void insert_after(pointer_type child, pointer_type after) void insert_after(pointer child, pointer after)
{ {
if (child->prev_) if (child->prev_)
child->prev_->next_ = child->next_; child->prev_->next_ = child->next_;
@ -133,7 +133,7 @@ public:
after->next_ = child; after->next_ = child;
} }
void remove(pointer_type child) void remove(pointer child)
{ {
if (child->next_) if (child->next_)
{ {
@ -159,10 +159,10 @@ public:
void clear() void clear()
{ {
pointer_type p = first_; pointer p = first_;
while (p) while (p)
{ {
pointer_type tmp = p; pointer tmp = p;
p = p->next_; p = p->next_;
if (tmp) if (tmp)
{ {
@ -180,8 +180,8 @@ public:
return; return;
int pos = 0; int pos = 0;
pointer_type p = first_; pointer p = first_;
pointer_type tmp = p; pointer tmp = p;
do do
{ {
tmp = p; tmp = p;
@ -205,15 +205,19 @@ public:
struct iterator_impl struct iterator_impl
{ {
using iterator_category = std::bidirectional_iterator_tag; using iterator_category = std::bidirectional_iterator_tag;
using pointer_type = _PTy; using value_type = typename std::pointer_traits<_PTy>::element_type;
using const_pointer_type = const _PTy; 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 pointer base() const { OC_ASSERT(!is_end_); return const_cast<pointer&>(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 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++(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 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 base_ == other.base_ && is_end_ == other.is_end_; }
inline bool operator!=(iterator_impl const& other) const { return !(*this == other); } inline bool operator!=(iterator_impl const& other) const { return !(*this == other); }
@ -221,11 +225,11 @@ public:
private: private:
bool is_end_; bool is_end_;
pointer_type base_; pointer base_;
}; };
using iterator = iterator_impl<pointer_type>; using iterator = iterator_impl<pointer>;
using const_iterator = iterator_impl<const pointer_type>; using const_iterator = iterator_impl<const pointer>;
using reverse_iterator = std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
@ -241,14 +245,14 @@ public:
inline reverse_iterator rend() { return reverse_iterator(begin()); } inline reverse_iterator rend() { return reverse_iterator(begin()); }
inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
inline const_reverse_iterator crend() const { return rend(); } 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 pointer 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 const pointer 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 pointer 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 const pointer back() const { if (empty()) throw std::out_of_range("back() called on empty intrusive_list"); return last_item(); }
private: private:
pointer_type first_; pointer first_;
pointer_type last_; pointer last_;
}; };
} // namespace oc } // namespace oc

74
src/3rd-party/pugixml/pugiconfig.hpp vendored Normal file
View File

@ -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.
*/

12865
src/3rd-party/pugixml/pugixml.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

1477
src/3rd-party/pugixml/pugixml.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -18,27 +18,25 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/platform/win32/helper.h> // win32::ThrowIfFailed
#include <kiwano/core/Logger.h>
#include <kiwano-audio/libraries.h>
#include <kiwano-audio/AudioEngine.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 kiwano
{ {
namespace audio namespace audio
{ {
AudioEngine::AudioEngine() AudioEngine::AudioEngine()
: x_audio2_(nullptr) : x_audio2_(nullptr)
, mastering_voice_(nullptr) , mastering_voice_(nullptr)
{ {
} }
AudioEngine::~AudioEngine() AudioEngine::~AudioEngine() {}
{
}
void AudioEngine::SetupComponent() void AudioEngine::SetupComponent()
{ {
KGE_SYS_LOG(L"Creating audio resources"); KGE_SYS_LOG(L"Creating audio resources");
HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL); HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
@ -54,10 +52,10 @@ namespace kiwano
} }
win32::ThrowIfFailed(hr); win32::ThrowIfFailed(hr);
} }
void AudioEngine::DestroyComponent() void AudioEngine::DestroyComponent()
{ {
KGE_SYS_LOG(L"Destroying audio resources"); KGE_SYS_LOG(L"Destroying audio resources");
if (mastering_voice_) if (mastering_voice_)
@ -73,10 +71,10 @@ namespace kiwano
} }
dlls::MediaFoundation::Get().MFShutdown(); 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!"); KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -104,22 +102,22 @@ namespace kiwano
win32::WarnIfFailed(hr); win32::WarnIfFailed(hr);
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
void AudioEngine::Open() void AudioEngine::Open()
{ {
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!"); KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
if (x_audio2_) if (x_audio2_)
x_audio2_->StartEngine(); x_audio2_->StartEngine();
} }
void AudioEngine::Close() void AudioEngine::Close()
{ {
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!"); KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
if (x_audio2_) if (x_audio2_)
x_audio2_->StopEngine(); x_audio2_->StopEngine();
}
}
} }
} // namespace audio
} // namespace kiwano

View File

@ -19,37 +19,38 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #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/Sound.h>
#include <kiwano-audio/Transcoder.h>
#include <kiwano/core/Common.h>
#include <kiwano/core/Component.h>
#include <xaudio2.h> #include <xaudio2.h>
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
/**
/**
* \~chinese * \~chinese
* \defgroup Audio * \defgroup Audio
*/ */
/** /**
* \addtogroup Audio * \addtogroup Audio
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API AudioEngine class KGE_API AudioEngine
: public Singleton<AudioEngine> : public Singleton<AudioEngine>
, public ComponentBase , public ComponentBase
{ {
friend Singleton<AudioEngine>; friend Singleton<AudioEngine>;
public: public:
/// \~chinese /// \~chinese
/// @brief 开启音频设备 /// @brief 开启音频设备
void Open(); void Open();
@ -62,21 +63,22 @@ namespace kiwano
/// @brief 从解码器数据缓冲中创建音频对象 /// @brief 从解码器数据缓冲中创建音频对象
bool CreateSound(Sound& sound, const Transcoder::Buffer& buffer); bool CreateSound(Sound& sound, const Transcoder::Buffer& buffer);
public: public:
void SetupComponent() override; void SetupComponent() override;
void DestroyComponent() override; void DestroyComponent() override;
private: private:
AudioEngine(); AudioEngine();
~AudioEngine(); ~AudioEngine();
private: private:
IXAudio2* x_audio2_; IXAudio2* x_audio2_;
IXAudio2MasteringVoice* mastering_voice_; IXAudio2MasteringVoice* mastering_voice_;
}; };
/** @} */ /** @} */
}
} } // namespace audio
} // namespace kiwano

View File

@ -18,31 +18,31 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano-audio/AudioEngine.h>
#include <kiwano-audio/Sound.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/platform/FileSystem.h> #include <kiwano/platform/FileSystem.h>
#include <kiwano-audio/Sound.h>
#include <kiwano-audio/AudioEngine.h>
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
Sound::Sound() Sound::Sound()
: opened_(false) : opened_(false)
, playing_(false) , playing_(false)
, voice_(nullptr) , voice_(nullptr)
{ {
} }
Sound::~Sound() Sound::~Sound()
{ {
Close(); Close();
} }
bool Sound::Load(String const& file_path) bool Sound::Load(String const& file_path)
{ {
if (!FileSystem::instance().IsFileExists(file_path)) if (!FileSystem::Instance().IsFileExists(file_path))
{ {
KGE_WARN(L"Media file '%s' not found", file_path.c_str()); KGE_WARN(L"Media file '%s' not found", file_path.c_str());
return false; return false;
@ -53,7 +53,7 @@ namespace kiwano
Close(); Close();
} }
String full_path = FileSystem::instance().GetFullPathForFile(file_path); String full_path = FileSystem::Instance().GetFullPathForFile(file_path);
HRESULT hr = transcoder_.LoadMediaFile(full_path); HRESULT hr = transcoder_.LoadMediaFile(full_path);
if (FAILED(hr)) if (FAILED(hr))
@ -62,7 +62,7 @@ namespace kiwano
return false; return false;
} }
if (!AudioEngine::instance().CreateSound(*this, transcoder_.GetBuffer())) if (!AudioEngine::Instance().CreateSound(*this, transcoder_.GetBuffer()))
{ {
Close(); Close();
return false; return false;
@ -70,10 +70,10 @@ namespace kiwano
opened_ = true; opened_ = true;
return true; return true;
} }
bool Sound::Load(Resource const& res) bool Sound::Load(Resource const& res)
{ {
if (opened_) if (opened_)
{ {
Close(); Close();
@ -86,7 +86,7 @@ namespace kiwano
return false; return false;
} }
if (!AudioEngine::instance().CreateSound(*this, transcoder_.GetBuffer())) if (!AudioEngine::Instance().CreateSound(*this, transcoder_.GetBuffer()))
{ {
Close(); Close();
return false; return false;
@ -94,15 +94,15 @@ namespace kiwano
opened_ = true; opened_ = true;
return true; return true;
} }
bool Sound::IsValid() const bool Sound::IsValid() const
{ {
return voice_ != nullptr; return voice_ != nullptr;
} }
void Sound::Play(int loop_count) void Sound::Play(int loop_count)
{ {
if (!opened_) if (!opened_)
{ {
KGE_ERROR(L"Sound must be opened first!"); KGE_ERROR(L"Sound must be opened first!");
@ -140,26 +140,26 @@ namespace kiwano
} }
playing_ = SUCCEEDED(hr); playing_ = SUCCEEDED(hr);
} }
void Sound::Pause() void Sound::Pause()
{ {
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
if (SUCCEEDED(voice_->Stop())) if (SUCCEEDED(voice_->Stop()))
playing_ = false; playing_ = false;
} }
void Sound::Resume() void Sound::Resume()
{ {
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
if (SUCCEEDED(voice_->Start())) if (SUCCEEDED(voice_->Start()))
playing_ = true; playing_ = true;
} }
void Sound::Stop() void Sound::Stop()
{ {
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
HRESULT hr = voice_->Stop(); HRESULT hr = voice_->Stop();
@ -172,10 +172,10 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
playing_ = false; playing_ = false;
} }
void Sound::Close() void Sound::Close()
{ {
if (voice_) if (voice_)
{ {
voice_->Stop(); voice_->Stop();
@ -188,10 +188,10 @@ namespace kiwano
opened_ = false; opened_ = false;
playing_ = false; playing_ = false;
} }
bool Sound::IsPlaying() const bool Sound::IsPlaying() const
{ {
if (opened_) if (opened_)
{ {
if (!voice_) if (!voice_)
@ -205,23 +205,23 @@ namespace kiwano
return true; return true;
} }
return false; return false;
} }
float Sound::GetVolume() const float Sound::GetVolume() const
{ {
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
float volume = 0.0f; float volume = 0.0f;
voice_->GetVolume(&volume); voice_->GetVolume(&volume);
return volume; return volume;
} }
void Sound::SetVolume(float volume) void Sound::SetVolume(float volume)
{ {
KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL"); KGE_ASSERT(voice_ != nullptr && "IXAudio2SourceVoice* is NULL");
volume = std::min(std::max(volume, -224.f), 224.f); volume = std::min(std::max(volume, -224.f), 224.f);
voice_->SetVolume(volume); voice_->SetVolume(volume);
}
}
} }
} // namespace audio
} // namespace kiwano

View File

@ -19,35 +19,34 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano-audio/Transcoder.h>
#include <kiwano/core/ObjectBase.h> #include <kiwano/core/ObjectBase.h>
#include <kiwano/core/Resource.h> #include <kiwano/core/Resource.h>
#include <kiwano/platform/win32/ComPtr.hpp> #include <kiwano/platform/win32/ComPtr.hpp>
#include <kiwano-audio/Transcoder.h>
#include <xaudio2.h> #include <xaudio2.h>
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
class AudioEngine; class AudioEngine;
KGE_DECLARE_SMART_PTR(Sound); KGE_DECLARE_SMART_PTR(Sound);
/** /**
* \addtogroup Audio * \addtogroup Audio
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Sound class KGE_API Sound : public virtual ObjectBase
: public ObjectBase {
{
friend class AudioEngine; friend class AudioEngine;
public: public:
Sound(); Sound();
virtual ~Sound(); virtual ~Sound();
@ -100,29 +99,28 @@ namespace kiwano
/// @param volume 音量大小1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量 /// @param volume 音量大小1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量
void SetVolume(float volume); void SetVolume(float volume);
private: private:
IXAudio2SourceVoice* GetXAudio2Voice() const; IXAudio2SourceVoice* GetXAudio2Voice() const;
void SetXAudio2Voice(IXAudio2SourceVoice* voice); void SetXAudio2Voice(IXAudio2SourceVoice* voice);
private: private:
bool opened_; bool opened_;
bool playing_; bool playing_;
Transcoder transcoder_; Transcoder transcoder_;
IXAudio2SourceVoice* voice_; IXAudio2SourceVoice* voice_;
}; };
/** @} */ /** @} */
inline IXAudio2SourceVoice* Sound::GetXAudio2Voice() const
inline IXAudio2SourceVoice* Sound::GetXAudio2Voice() const {
{
return voice_; return voice_;
}
inline void Sound::SetXAudio2Voice(IXAudio2SourceVoice* voice)
{
voice_ = voice;
}
}
} }
inline void Sound::SetXAudio2Voice(IXAudio2SourceVoice* voice)
{
voice_ = voice;
}
} // namespace audio
} // namespace kiwano

View File

@ -22,20 +22,20 @@
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
SoundPlayer::SoundPlayer() SoundPlayer::SoundPlayer()
: volume_(1.f) : volume_(1.f)
{ {
} }
SoundPlayer::~SoundPlayer() SoundPlayer::~SoundPlayer()
{ {
ClearCache(); 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()); int hash_code = static_cast<int>(file_path.hash());
if (sound_cache_.end() != sound_cache_.find(hash_code)) if (sound_cache_.end() != sound_cache_.find(hash_code))
return hash_code; return hash_code;
@ -52,10 +52,10 @@ namespace kiwano
} }
} }
return 0; 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()); size_t hash_code = static_cast<size_t>(res.GetId());
if (sound_cache_.end() != sound_cache_.find(hash_code)) if (sound_cache_.end() != sound_cache_.find(hash_code))
return hash_code; return hash_code;
@ -72,85 +72,85 @@ namespace kiwano
} }
} }
return 0; 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); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Play(loop_count); iter->second->Play(loop_count);
} }
void SoundPlayer::Pause(size_t id) void SoundPlayer::Pause(size_t id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Pause(); iter->second->Pause();
} }
void SoundPlayer::Resume(size_t id) void SoundPlayer::Resume(size_t id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Resume(); iter->second->Resume();
} }
void SoundPlayer::Stop(size_t id) void SoundPlayer::Stop(size_t id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
iter->second->Stop(); iter->second->Stop();
} }
bool SoundPlayer::IsPlaying(size_t id) bool SoundPlayer::IsPlaying(size_t id)
{ {
auto iter = sound_cache_.find(id); auto iter = sound_cache_.find(id);
if (sound_cache_.end() != iter) if (sound_cache_.end() != iter)
return iter->second->IsPlaying(); return iter->second->IsPlaying();
return false; return false;
} }
float SoundPlayer::GetVolume() const float SoundPlayer::GetVolume() const
{ {
return volume_; return volume_;
} }
void SoundPlayer::SetVolume(float volume) void SoundPlayer::SetVolume(float volume)
{ {
volume_ = std::min(std::max(volume, -224.f), 224.f); volume_ = std::min(std::max(volume, -224.f), 224.f);
for (auto& pair : sound_cache_) for (auto& pair : sound_cache_)
{ {
pair.second->SetVolume(volume_); pair.second->SetVolume(volume_);
} }
} }
void SoundPlayer::PauseAll() void SoundPlayer::PauseAll()
{ {
for (auto& pair : sound_cache_) for (auto& pair : sound_cache_)
{ {
pair.second->Pause(); pair.second->Pause();
} }
} }
void SoundPlayer::ResumeAll() void SoundPlayer::ResumeAll()
{ {
for (auto& pair : sound_cache_) for (auto& pair : sound_cache_)
{ {
pair.second->Resume(); pair.second->Resume();
} }
} }
void SoundPlayer::StopAll() void SoundPlayer::StopAll()
{ {
for (auto& pair : sound_cache_) for (auto& pair : sound_cache_)
{ {
pair.second->Stop(); pair.second->Stop();
} }
}
void SoundPlayer::ClearCache()
{
sound_cache_.clear();
}
}
} }
void SoundPlayer::ClearCache()
{
sound_cache_.clear();
}
} // namespace audio
} // namespace kiwano

View File

@ -19,28 +19,27 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/ObjectBase.h>
#include <kiwano-audio/Sound.h> #include <kiwano-audio/Sound.h>
#include <kiwano/core/ObjectBase.h>
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
KGE_DECLARE_SMART_PTR(SoundPlayer); KGE_DECLARE_SMART_PTR(SoundPlayer);
/** /**
* \addtogroup Audio * \addtogroup Audio
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API SoundPlayer class KGE_API SoundPlayer : public virtual ObjectBase
: public ObjectBase {
{ public:
public:
SoundPlayer(); SoundPlayer();
~SoundPlayer(); ~SoundPlayer();
@ -108,13 +107,13 @@ namespace kiwano
/// @brief 清除缓存 /// @brief 清除缓存
void ClearCache(); void ClearCache();
private: private:
float volume_; float volume_;
using SoundMap = Map<size_t, SoundPtr>; using SoundMap = Map<size_t, SoundPtr>;
SoundMap sound_cache_; SoundMap sound_cache_;
}; };
/** @} */ /** @} */
} } // namespace audio
} } // namespace kiwano

View File

@ -19,42 +19,42 @@
// THE SOFTWARE. // THE SOFTWARE.
#ifndef INITGUID #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 #endif
#include <kiwano/macros.h> #include <kiwano-audio/Transcoder.h>
#include <kiwano/core/common.h> #include <kiwano-audio/libraries.h>
#include <kiwano/core/Resource.h> #include <kiwano/core/Common.h>
#include <kiwano/core/Logger.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/ComPtr.hpp>
#include <kiwano/platform/win32/libraries.h> #include <kiwano/platform/win32/libraries.h>
#include <kiwano-audio/libraries.h>
#include <kiwano-audio/Transcoder.h>
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
Transcoder::Transcoder() Transcoder::Transcoder()
: wave_format_(nullptr) : wave_format_(nullptr)
, wave_data_(nullptr) , wave_data_(nullptr)
, wave_size_(0) , wave_size_(0)
{ {
} }
Transcoder::~Transcoder() Transcoder::~Transcoder()
{ {
ClearBuffer(); ClearBuffer();
} }
Transcoder::Buffer Transcoder::GetBuffer() const Transcoder::Buffer Transcoder::GetBuffer() const
{ {
return Buffer{ wave_data_, wave_size_, wave_format_ }; return Buffer{ wave_data_, wave_size_, wave_format_ };
} }
void Transcoder::ClearBuffer() void Transcoder::ClearBuffer()
{ {
if (wave_format_) if (wave_format_)
{ {
::CoTaskMemFree(wave_format_); ::CoTaskMemFree(wave_format_);
@ -68,19 +68,15 @@ namespace kiwano
} }
wave_size_ = 0; wave_size_ = 0;
} }
HRESULT Transcoder::LoadMediaFile(String const& file_path) HRESULT Transcoder::LoadMediaFile(String const& file_path)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ComPtr<IMFSourceReader> reader; ComPtr<IMFSourceReader> reader;
hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromURL( hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromURL(file_path.c_str(), nullptr, &reader);
file_path.c_str(),
nullptr,
&reader
);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -88,10 +84,10 @@ namespace kiwano
} }
return hr; return hr;
} }
HRESULT Transcoder::LoadMediaResource(Resource const& res) HRESULT Transcoder::LoadMediaResource(Resource const& res)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ComPtr<IStream> stream; ComPtr<IStream> stream;
@ -99,12 +95,13 @@ namespace kiwano
ComPtr<IMFSourceReader> reader; ComPtr<IMFSourceReader> reader;
Resource::Data data = res.GetData(); Resource::Data data = res.GetData();
if (!data) { return E_FAIL; } if (!data)
{
return E_FAIL;
}
stream = win32::dlls::Shlwapi::Get().SHCreateMemStream( stream = win32::dlls::Shlwapi::Get().SHCreateMemStream(static_cast<const BYTE*>(data.buffer),
static_cast<const BYTE*>(data.buffer), static_cast<uint32_t>(data.size));
static_cast<uint32_t>(data.size)
);
if (stream == nullptr) if (stream == nullptr)
{ {
@ -119,11 +116,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromByteStream( hr = dlls::MediaFoundation::Get().MFCreateSourceReaderFromByteStream(byte_stream.get(), nullptr, &reader);
byte_stream.get(),
nullptr,
&reader
);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -132,10 +125,10 @@ namespace kiwano
} }
return hr; return hr;
} }
HRESULT Transcoder::ReadSource(IMFSourceReader* reader) HRESULT Transcoder::ReadSource(IMFSourceReader* reader)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
DWORD max_stream_size = 0; DWORD max_stream_size = 0;
@ -157,29 +150,19 @@ namespace kiwano
// 设置 source reader 的媒体类型,它将使用合适的解码器去解码这个音频 // 设置 source reader 的媒体类型,它将使用合适的解码器去解码这个音频
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = reader->SetCurrentMediaType( hr = reader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, partial_type.get());
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
0,
partial_type.get()
);
} }
// 从 IMFMediaType 中获取 WAVEFORMAT 结构 // 从 IMFMediaType 中获取 WAVEFORMAT 结构
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = reader->GetCurrentMediaType( hr = reader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, &uncompressed_type);
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
&uncompressed_type
);
} }
// 指定音频流 // 指定音频流
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = reader->SetStreamSelection( hr = reader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, true);
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
true
);
} }
// 获取 WAVEFORMAT 数据 // 获取 WAVEFORMAT 数据
@ -187,11 +170,7 @@ namespace kiwano
{ {
uint32_t size = 0; uint32_t size = 0;
hr = dlls::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType( hr = dlls::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType(
uncompressed_type.get(), uncompressed_type.get(), &wave_format_, &size, (DWORD)MFWaveFormatExConvertFlag_Normal);
&wave_format_,
&size,
(DWORD)MFWaveFormatExConvertFlag_Normal
);
} }
// 估算音频流大小 // 估算音频流大小
@ -200,16 +179,10 @@ namespace kiwano
PROPVARIANT prop; PROPVARIANT prop;
PropVariantInit(&prop); PropVariantInit(&prop);
hr = reader->GetPresentationAttribute( hr = reader->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &prop);
(DWORD)MF_SOURCE_READER_MEDIASOURCE,
MF_PD_DURATION,
&prop
);
LONGLONG duration = prop.uhVal.QuadPart; LONGLONG duration = prop.uhVal.QuadPart;
max_stream_size = static_cast<DWORD>( max_stream_size = static_cast<DWORD>((duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1);
(duration * wave_format_->nAvgBytesPerSec) / 10000000 + 1
);
PropVariantClear(&prop); PropVariantClear(&prop);
} }
@ -232,18 +205,18 @@ namespace kiwano
{ {
while (true) while (true)
{ {
hr = reader->ReadSample( hr = reader->ReadSample((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, nullptr, &flags, nullptr,
(DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, &sample);
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)) if (SUCCEEDED(hr))
{ {
@ -254,11 +227,7 @@ namespace kiwano
BYTE* audio_data = nullptr; BYTE* audio_data = nullptr;
DWORD sample_buffer_length = 0; DWORD sample_buffer_length = 0;
hr = buffer->Lock( hr = buffer->Lock(&audio_data, nullptr, &sample_buffer_length);
&audio_data,
nullptr,
&sample_buffer_length
);
if (position + sample_buffer_length >= max_stream_size) if (position + sample_buffer_length >= max_stream_size)
{ {
@ -276,7 +245,10 @@ namespace kiwano
} }
sample = nullptr; sample = nullptr;
if (FAILED(hr)) { break; } if (FAILED(hr))
{
break;
}
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -293,6 +265,6 @@ namespace kiwano
} }
return hr; return hr;
}
}
} }
} // namespace audio
} // namespace kiwano

View File

@ -26,24 +26,24 @@
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
class Sound; class Sound;
/** /**
* \addtogroup Audio * \addtogroup Audio
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Transcoder class KGE_API Transcoder
{ {
friend class Sound; friend class Sound;
public: public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -67,7 +67,7 @@ namespace kiwano
/// @brief 清空数据缓冲 /// @brief 清空数据缓冲
void ClearBuffer(); void ClearBuffer();
private: private:
/// \~chinese /// \~chinese
/// @brief 解码本地音频文件 /// @brief 解码本地音频文件
HRESULT LoadMediaFile(String const& file_path); HRESULT LoadMediaFile(String const& file_path);
@ -80,12 +80,12 @@ namespace kiwano
/// @brief 读取音频源数据 /// @brief 读取音频源数据
HRESULT ReadSource(IMFSourceReader* reader); HRESULT ReadSource(IMFSourceReader* reader);
private: private:
BYTE* wave_data_; BYTE* wave_data_;
uint32_t wave_size_; uint32_t wave_size_;
WAVEFORMATEX* wave_format_; WAVEFORMATEX* wave_format_;
}; };
/** @} */ /** @} */
} } // namespace audio
} } // namespace kiwano

View File

@ -18,21 +18,20 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/core/Logger.h>
#include <kiwano-audio/libraries.h> #include <kiwano-audio/libraries.h>
#include <kiwano/core/Logger.h>
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
namespace dlls namespace dlls
{ {
XAudio2::XAudio2() XAudio2::XAudio2()
: xaudio2() : xaudio2()
, XAudio2Create(nullptr) , XAudio2Create(nullptr)
{ {
const auto xaudio2_dll_names = const auto xaudio2_dll_names = {
{
"xaudio2_9.dll", // for Windows 10 "xaudio2_9.dll", // for Windows 10
"xaudio2_8.dll", // for Windows 8 "xaudio2_8.dll", // for Windows 8
"xaudio2_7.dll" // for DirectX SDK "xaudio2_7.dll" // for DirectX SDK
@ -55,9 +54,9 @@ namespace kiwano
KGE_ERROR(L"Load xaudio2.dll failed"); KGE_ERROR(L"Load xaudio2.dll failed");
throw std::runtime_error("Load xaudio2.dll failed"); throw std::runtime_error("Load xaudio2.dll failed");
} }
} }
MediaFoundation::MediaFoundation() MediaFoundation::MediaFoundation()
: mfplat() : mfplat()
, mfreadwrite() , mfreadwrite()
, MFStartup(nullptr) , MFStartup(nullptr)
@ -67,14 +66,16 @@ namespace kiwano
, MFCreateSourceReaderFromURL(nullptr) , MFCreateSourceReaderFromURL(nullptr)
, MFCreateSourceReaderFromByteStream(nullptr) , MFCreateSourceReaderFromByteStream(nullptr)
, MFCreateMFByteStreamOnStream(nullptr) , MFCreateMFByteStreamOnStream(nullptr)
{ {
if (mfplat.Load("Mfplat.dll")) if (mfplat.Load("Mfplat.dll"))
{ {
MFStartup = mfplat.GetProcess<PFN_MFStartup>("MFStartup"); MFStartup = mfplat.GetProcess<PFN_MFStartup>("MFStartup");
MFShutdown = mfplat.GetProcess<PFN_MFShutdown>("MFShutdown"); MFShutdown = mfplat.GetProcess<PFN_MFShutdown>("MFShutdown");
MFCreateMediaType = mfplat.GetProcess<PFN_MFCreateMediaType>("MFCreateMediaType"); MFCreateMediaType = mfplat.GetProcess<PFN_MFCreateMediaType>("MFCreateMediaType");
MFCreateWaveFormatExFromMFMediaType = mfplat.GetProcess<PFN_MFCreateWaveFormatExFromMFMediaType>("MFCreateWaveFormatExFromMFMediaType"); MFCreateWaveFormatExFromMFMediaType =
MFCreateMFByteStreamOnStream = mfplat.GetProcess<PFN_MFCreateMFByteStreamOnStream>("MFCreateMFByteStreamOnStream"); mfplat.GetProcess<PFN_MFCreateWaveFormatExFromMFMediaType>("MFCreateWaveFormatExFromMFMediaType");
MFCreateMFByteStreamOnStream =
mfplat.GetProcess<PFN_MFCreateMFByteStreamOnStream>("MFCreateMFByteStreamOnStream");
} }
else else
{ {
@ -84,15 +85,17 @@ namespace kiwano
if (mfreadwrite.Load("Mfreadwrite.dll")) if (mfreadwrite.Load("Mfreadwrite.dll"))
{ {
MFCreateSourceReaderFromURL = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromURL>("MFCreateSourceReaderFromURL"); MFCreateSourceReaderFromURL =
MFCreateSourceReaderFromByteStream = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromByteStream>("MFCreateSourceReaderFromByteStream"); mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromURL>("MFCreateSourceReaderFromURL");
MFCreateSourceReaderFromByteStream =
mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromByteStream>("MFCreateSourceReaderFromByteStream");
} }
else else
{ {
KGE_ERROR(L"Load Mfreadwrite.dll failed"); KGE_ERROR(L"Load Mfreadwrite.dll failed");
throw std::runtime_error("Load Mfreadwrite.dll failed"); throw std::runtime_error("Load Mfreadwrite.dll failed");
} }
}
}
}
} }
} // namespace dlls
} // namespace audio
} // namespace kiwano

View File

@ -20,22 +20,22 @@
#pragma once #pragma once
#include <kiwano/core/Library.h> #include <kiwano/core/Library.h>
#include <xaudio2.h>
#include <mfapi.h> #include <mfapi.h>
#include <mfidl.h> #include <mfidl.h>
#include <mfreadwrite.h> #include <mfreadwrite.h>
#include <xaudio2.h>
#ifndef KGE_DOXYGEN_DO_NOT_INCLUDE #ifndef KGE_DOXYGEN_DO_NOT_INCLUDE
namespace kiwano namespace kiwano
{ {
namespace audio namespace audio
{ {
namespace dlls namespace dlls
{ {
class KGE_API XAudio2 class KGE_API XAudio2
{ {
public: public:
static inline XAudio2& Get() static inline XAudio2& Get()
{ {
static XAudio2 instance; static XAudio2 instance;
@ -47,19 +47,18 @@ namespace kiwano
PFN_XAudio2Create XAudio2Create; PFN_XAudio2Create XAudio2Create;
private: private:
XAudio2(); XAudio2();
XAudio2(const XAudio2&) = delete; XAudio2(const XAudio2&) = delete;
XAudio2& operator=(const XAudio2&) = delete; XAudio2& operator=(const XAudio2&) = delete;
Library xaudio2; Library xaudio2;
}; };
class KGE_API MediaFoundation
class KGE_API MediaFoundation {
{ public:
public:
static inline MediaFoundation& Get() static inline MediaFoundation& Get()
{ {
static MediaFoundation instance; static MediaFoundation instance;
@ -83,7 +82,7 @@ namespace kiwano
PFN_MFCreateSourceReaderFromByteStream MFCreateSourceReaderFromByteStream; PFN_MFCreateSourceReaderFromByteStream MFCreateSourceReaderFromByteStream;
PFN_MFCreateMFByteStreamOnStream MFCreateMFByteStreamOnStream; PFN_MFCreateMFByteStreamOnStream MFCreateMFByteStreamOnStream;
private: private:
MediaFoundation(); MediaFoundation();
MediaFoundation(const MediaFoundation&) = delete; MediaFoundation(const MediaFoundation&) = delete;
@ -91,9 +90,9 @@ namespace kiwano
Library mfplat; Library mfplat;
Library mfreadwrite; Library mfreadwrite;
}; };
} } // namespace dlls
} } // namespace audio
} } // namespace kiwano
#endif #endif

View File

@ -22,43 +22,45 @@
namespace kiwano namespace kiwano
{ {
namespace imgui namespace imgui
{ {
ImGuiLayer::ImGuiLayer() ImGuiLayer::ImGuiLayer()
{ {
SetSwallowEvents(true); SetSwallowEvents(true);
} }
ImGuiLayer::~ImGuiLayer() ImGuiLayer::~ImGuiLayer() {}
{
}
void ImGuiLayer::OnRender(RenderTarget* rt) void ImGuiLayer::OnRender(RenderContext& ctx)
{ {
PrepareToRender(rt);
for (const auto& pipeline : pipelines_) for (const auto& pipeline : pipelines_)
{ {
pipeline.second(); 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)); pipelines_.insert(std::make_pair(name, item));
} }
void ImGuiLayer::RemoveItem(String const& name) void ImGuiLayer::RemoveItem(String const& name)
{ {
auto iter = pipelines_.find(name); auto iter = pipelines_.find(name);
if (iter != pipelines_.end()) if (iter != pipelines_.end())
{ {
pipelines_.erase(iter); pipelines_.erase(iter);
} }
}
void ImGuiLayer::RemoveAllItems()
{
pipelines_.clear();
}
}
} }
void ImGuiLayer::RemoveAllItems()
{
pipelines_.clear();
}
} // namespace imgui
} // namespace kiwano

View File

@ -23,31 +23,30 @@
namespace kiwano namespace kiwano
{ {
namespace imgui namespace imgui
{ {
KGE_DECLARE_SMART_PTR(ImGuiLayer); KGE_DECLARE_SMART_PTR(ImGuiLayer);
/// \~chinese /// \~chinese
/// @brief ImGui¹ÜµÀ /// @brief ImGui¹ÜµÀ
using ImGuiPipeline = Function<void()>; using ImGuiPipeline = Function<void()>;
/** /**
* \~chinese * \~chinese
* @brief ImGui图层 * @brief ImGui图层
*/ */
class ImGuiLayer class ImGuiLayer : public Layer
: public Layer {
{ public:
public:
ImGuiLayer(); ImGuiLayer();
virtual ~ImGuiLayer(); virtual ~ImGuiLayer();
/// \~chinese /// \~chinese
/// @brief 添加 ImGui 元素 /// @brief 添加 ImGui 元素
/// @param item ¹ÜµÀ
/// @param name 元素名称 /// @param name 元素名称
void AddItem(ImGuiPipeline const& item, String const& name); /// @param item ¹ÜµÀ
void AddItem(String const& name, ImGuiPipeline const& item);
/// \~chinese /// \~chinese
/// @brief 移除 ImGui 元素 /// @brief 移除 ImGui 元素
@ -59,11 +58,13 @@ namespace kiwano
/// @brief 移除所有元素 /// @brief 移除所有元素
void RemoveAllItems(); void RemoveAllItems();
public: public:
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
private: bool CheckVisibility(RenderContext& ctx) const override;
private:
Map<String, ImGuiPipeline> pipelines_; Map<String, ImGuiPipeline> pipelines_;
}; };
} } // namespace imgui
} } // namespace kiwano

View File

@ -1,234 +1,189 @@
// Copyright (C) 2019 Nomango // 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/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/ImGuiModule.h>
#include <kiwano-imgui/imgui_impl.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 kiwano
{ {
namespace imgui namespace imgui
{ {
ImGuiModule::ImGuiModule() ImGuiModule::ImGuiModule()
: has_gamepad_(false) : target_window_(nullptr)
, want_update_has_gamepad_(false) {
, target_window_(nullptr) }
{
}
void ImGuiModule::SetupComponent() void ImGuiModule::SetupComponent()
{ {
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO();
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls (void)io;
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings // 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_Impl_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
} }
void ImGuiModule::OnUpdate(Duration dt) void ImGuiModule::OnUpdate(Duration dt)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup time step // Setup time step
io.DeltaTime = dt.Seconds(); io.DeltaTime = dt.Seconds();
// Read keyboard modifiers inputs // Read keyboard modifiers inputs
io.KeyCtrl = Input::instance().IsDown(KeyCode::Ctrl); io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl);
io.KeyShift = Input::instance().IsDown(KeyCode::Shift); io.KeyShift = Input::Instance().IsDown(KeyCode::Shift);
io.KeyAlt = Input::instance().IsDown(KeyCode::Alt); io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt);
io.KeySuper = false; io.KeySuper = Input::Instance().IsDown(KeyCode::Super);
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the HandleEvent function below.
// Update OS mouse position // Update OS mouse position
UpdateMousePos(); UpdateMousePos();
// Update OS mouse cursor with the cursor requested by imgui // Update OS mouse cursor with the cursor requested by imgui
UpdateMouseCursor(); UpdateMouseCursor();
}
// Update game controllers (if enabled and available) void ImGuiModule::BeforeRender()
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()
{
NewFrame(); NewFrame();
} }
void ImGuiModule::AfterRender() void ImGuiModule::AfterRender()
{ {
Render(); Render();
} }
void ImGuiModule::HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) void ImGuiModule::HandleEvent(Event* evt)
{ {
if (ImGui::GetCurrentContext() == NULL) if (ImGui::GetCurrentContext() == NULL)
return; return;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
switch (msg) if (evt->IsType<MouseEvent>())
{ {
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: if (evt->IsType<MouseDownEvent>())
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
{ {
int button = 0; MouseButton button = dynamic_cast<MouseDownEvent*>(evt)->button;
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } int index = 0;
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } if (button == MouseButton::Left)
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } index = 0;
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; } else if (button == MouseButton::Right)
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) index = 1;
::SetCapture(hwnd); else if (button == MouseButton::Middle)
index = 2;
io.MouseDown[button] = true; io.MouseDown[index] = true;
break;
} }
case WM_LBUTTONUP: else if (evt->IsType<MouseUpEvent>())
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
{ {
int button = 0; MouseButton button = dynamic_cast<MouseUpEvent*>(evt)->button;
if (msg == WM_LBUTTONUP) { button = 0; } int index = 0;
if (msg == WM_RBUTTONUP) { button = 1; } if (button == MouseButton::Left)
if (msg == WM_MBUTTONUP) { button = 2; } index = 0;
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; } else if (button == MouseButton::Right)
io.MouseDown[button] = false; index = 1;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) else if (button == MouseButton::Middle)
::ReleaseCapture(); index = 2;
break; io.MouseDown[index] = false;
} }
case WM_MOUSEWHEEL: else if (evt->IsType<MouseWheelEvent>())
{ {
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; float wheel = dynamic_cast<MouseWheelEvent*>(evt)->wheel;
break; io.MouseWheel += wheel;
} }
case WM_MOUSEHWHEEL: }
else if (evt->IsType<KeyEvent>())
{ {
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; if (evt->IsType<KeyDownEvent>())
break;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{ {
if (wparam < 256) KeyCode key = dynamic_cast<KeyDownEvent*>(evt)->code;
io.KeysDown[wparam] = 1; io.KeysDown[(int)key] = true;
break;
} }
case WM_KEYUP: else if (evt->IsType<KeyUpEvent>())
case WM_SYSKEYUP:
{ {
if (wparam < 256) KeyCode key = dynamic_cast<KeyUpEvent*>(evt)->code;
io.KeysDown[wparam] = 0; io.KeysDown[(int)key] = false;
break;
} }
case WM_CHAR: else if (evt->IsType<KeyCharEvent>())
{ {
// You can also use ToAscii()+GetKeyboardState() to retrieve characters. // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
io.AddInputCharacter((uint32_t)wparam); char ch = dynamic_cast<KeyCharEvent*>(evt)->value;
break; io.AddInputCharacter(static_cast<ImWchar>(ch));
}
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;
}
} }
} }
}
void ImGuiModule::NewFrame() void ImGuiModule::NewFrame()
{ {
ImGui_Impl_NewFrame(); ImGui_Impl_NewFrame();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
Size display_size = Renderer::instance().GetOutputSize(); Size display_size = Renderer::Instance().GetOutputSize();
io.DisplaySize = ImVec2(display_size.x, display_size.y); io.DisplaySize = ImVec2(display_size.x, display_size.y);
ImGui::NewFrame(); ImGui::NewFrame();
} }
void ImGuiModule::Render() void ImGuiModule::Render()
{ {
ImGui::Render(); ImGui::Render();
ImGui_Impl_RenderDrawData(ImGui::GetDrawData()); ImGui_Impl_RenderDrawData(ImGui::GetDrawData());
} }
void ImGuiModule::UpdateMousePos() void ImGuiModule::UpdateMousePos()
{ {
ImGuiIO& io = ImGui::GetIO(); 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) if (io.WantSetMousePos)
{ {
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
@ -236,74 +191,46 @@ namespace kiwano
::SetCursorPos(pos.x, pos.y); ::SetCursorPos(pos.x, pos.y);
} }
Point pos = Input::instance().GetMousePos(); Point pos = Input::Instance().GetMousePos();
io.MousePos = ImVec2(pos.x, pos.y); io.MousePos = ImVec2(pos.x, pos.y);
} }
void ImGuiModule::UpdateMouseCursor() void ImGuiModule::UpdateMouseCursor()
{ {
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return; return;
CursorType cursor = CursorType::Arrow; CursorType cursor = CursorType::Arrow;
switch (ImGui::GetMouseCursor()) switch (ImGui::GetMouseCursor())
{ {
case ImGuiMouseCursor_Arrow: cursor = CursorType::Arrow; break; case ImGuiMouseCursor_Arrow:
case ImGuiMouseCursor_TextInput: cursor = CursorType::TextInput; break; cursor = CursorType::Arrow;
case ImGuiMouseCursor_ResizeAll: cursor = CursorType::SizeAll; break; break;
case ImGuiMouseCursor_ResizeEW: cursor = CursorType::SizeWE; break; case ImGuiMouseCursor_TextInput:
case ImGuiMouseCursor_ResizeNS: cursor = CursorType::SizeNS; break; cursor = CursorType::TextInput;
case ImGuiMouseCursor_ResizeNESW: cursor = CursorType::SizeNESW; break; break;
case ImGuiMouseCursor_ResizeNWSE: cursor = CursorType::SizeNWSE; break; case ImGuiMouseCursor_ResizeAll:
case ImGuiMouseCursor_Hand: cursor = CursorType::Hand; break; 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); 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
}
}
}
} }
} // namespace imgui
} // namespace kiwano

View File

@ -19,26 +19,26 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/Component.h> #include <kiwano/core/Component.h>
namespace kiwano namespace kiwano
{ {
namespace imgui namespace imgui
{ {
/** /**
* \~chinese * \~chinese
* @brief ImGuiÄ£¿é * @brief ImGuiÄ£¿é
*/ */
class ImGuiModule class ImGuiModule
: public Singleton<ImGuiModule> : public Singleton<ImGuiModule>
, public RenderComponent , public RenderComponent
, public UpdateComponent , public UpdateComponent
, public EventComponent , public EventComponent
{ {
friend Singleton<ImGuiModule>; friend Singleton<ImGuiModule>;
public: public:
ImGuiModule(); ImGuiModule();
void SetupComponent() override; void SetupComponent() override;
@ -49,13 +49,11 @@ namespace kiwano
void AfterRender() override; void AfterRender() override;
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override; void HandleEvent(Event* evt) override;
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;
private: private:
void Init(HWND hwnd);
void NewFrame(); void NewFrame();
void Render(); void Render();
@ -64,12 +62,8 @@ namespace kiwano
void UpdateMouseCursor(); void UpdateMouseCursor();
void UpdateGamepads(); private:
WindowHandle target_window_;
private: };
bool has_gamepad_; } // namespace imgui
bool want_update_has_gamepad_; } // namespace kiwano
HWND target_window_;
};
}
}

View File

@ -8,25 +8,62 @@
#include <kiwano-imgui/imgui_impl_dx11.h> #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 bool ImGui_Impl_Init(::kiwano::Renderer& renderer)
inline void ImGui_Impl_Shutdown() { ImGui_ImplDX11_Shutdown(); } {
inline void ImGui_Impl_NewFrame() { ImGui_ImplDX11_NewFrame(); } return ImGui_ImplDX11_Init(renderer.GetD3DDeviceResources()->GetDevice(),
inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX11_RenderDrawData(draw_data); } 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 void ImGui_Impl_InvalidateDeviceObjects()
inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX11_CreateDeviceObjects(); } {
ImGui_ImplDX11_InvalidateDeviceObjects();
}
inline bool ImGui_Impl_CreateDeviceObjects()
{
return ImGui_ImplDX11_CreateDeviceObjects();
}
#else #else
#include <kiwano-imgui/imgui_impl_dx10.h> #include <kiwano-imgui/imgui_impl_dx10.h>
inline bool ImGui_Impl_Init(::kiwano::Renderer* renderer) { return ImGui_ImplDX10_Init(renderer->GetD3DDeviceResources()->GetDevice()); } inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer)
inline void ImGui_Impl_Shutdown() { ImGui_ImplDX10_Shutdown(); } {
inline void ImGui_Impl_NewFrame() { ImGui_ImplDX10_NewFrame(); } return ImGui_ImplDX10_Init(renderer.GetD3DDeviceResources()->GetDevice());
inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX10_RenderDrawData(draw_data); } }
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 void ImGui_Impl_InvalidateDeviceObjects()
inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX10_CreateDeviceObjects(); } {
ImGui_ImplDX10_InvalidateDeviceObjects();
}
inline bool ImGui_Impl_CreateDeviceObjects()
{
return ImGui_ImplDX10_CreateDeviceObjects();
}
#endif #endif

View File

@ -3,10 +3,10 @@
#include <kiwano-imgui/imgui_impl_dx10.h> #include <kiwano-imgui/imgui_impl_dx10.h>
// DirectX // DirectX
#include <stdio.h>
#include <d3d10_1.h> #include <d3d10_1.h>
#include <d3d10.h> #include <d3d10.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include <stdio.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. #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 ID3D10Blob* g_pPixelShaderBlob = NULL;
static ID3D10PixelShader* g_pPixelShader = NULL; static ID3D10PixelShader* g_pPixelShader = NULL;
static ID3D10SamplerState* g_pFontSampler = NULL; static ID3D10SamplerState* g_pFontSampler = NULL;
static ID3D10ShaderResourceView*g_pFontTextureView = NULL; static ID3D10ShaderResourceView* g_pFontTextureView = NULL;
static ID3D10RasterizerState* g_pRasterizerState = NULL; static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL; static ID3D10BlendState* g_pBlendState = NULL;
static ID3D10DepthStencilState* g_pDepthStencilState = NULL; static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
@ -36,7 +36,8 @@ struct VERTEX_CONSTANT_BUFFER
}; };
// Render Function // Render Function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from
// your main loop)
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
{ {
ID3D10Device* ctx = g_pd3dDevice; ID3D10Device* ctx = g_pd3dDevice;
@ -44,7 +45,11 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 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; g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D10_BUFFER_DESC desc; D3D10_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D10_BUFFER_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_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; g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D10_BUFFER_DESC desc; D3D10_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC)); memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
@ -88,7 +97,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
g_pIB->Unmap(); g_pIB->Unmap();
// Setup orthographic projection matrix into our constant buffer // 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; void* mapped_resource;
if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) 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 R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] = float mvp[4][4] = {
{ { 2.0f / (R - L), 0.0f, 0.0f, 0.0f },
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 0.0f, 2.0f / (T - B), 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 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)); memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
g_pVertexConstantBuffer->Unmap(); 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 struct BACKUP_DX10_STATE
{ {
UINT ScissorRectsCount, ViewportsCount; UINT ScissorRectsCount, ViewportsCount;
@ -126,7 +136,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
ID3D10PixelShader* PS; ID3D10PixelShader* PS;
ID3D10VertexShader* VS; ID3D10VertexShader* VS;
D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology; D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D10Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; ID3D10Buffer * IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat; DXGI_FORMAT IndexBufferFormat;
ID3D10InputLayout* InputLayout; ID3D10InputLayout* InputLayout;
@ -194,7 +204,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
else else
{ {
// Apply scissor/clipping rectangle // 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); ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
@ -210,18 +221,40 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
// Restore modified DX state // Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports); ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); ctx->RSSetState(old.RS);
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); if (old.RS)
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); old.RS->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask);
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); if (old.BlendState)
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release(); old.BlendState->Release();
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release(); ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef);
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); 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->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset);
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); if (old.IndexBuffer)
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); 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() static void ImGui_ImplDX10_CreateFontsTexture()
@ -246,7 +279,7 @@ static void ImGui_ImplDX10_CreateFontsTexture()
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
ID3D10Texture2D *pTexture = NULL; ID3D10Texture2D* pTexture = NULL;
D3D10_SUBRESOURCE_DATA subResource; D3D10_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels; subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
@ -290,16 +323,17 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
if (g_pFontSampler) if (g_pFontSampler)
ImGui_ImplDX10_InvalidateDeviceObjects(); 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) // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of
// If you would like to use this DX10 sample code but remove this dependency you can: // d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) If you would like to use this DX10 sample code but remove this
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] // dependency you can:
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. // 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. // See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader // Create the vertex shader
{ {
static const char* vertexShader = static const char* vertexShader = "cbuffer vertexBuffer : register(b0) \
"cbuffer vertexBuffer : register(b0) \
{\ {\
float4x4 ProjectionMatrix; \ float4x4 ProjectionMatrix; \
};\ };\
@ -326,20 +360,29 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
return output;\ return output;\
}"; }";
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob,
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! 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; 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; return false;
// Create the input layout // Create the input layout
D3D10_INPUT_ELEMENT_DESC local_layout[] = D3D10_INPUT_ELEMENT_DESC local_layout[] = {
{ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA,
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA,
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, 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; return false;
// Create the constant buffer // Create the constant buffer
@ -356,8 +399,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
// Create the pixel shader // Create the pixel shader
{ {
static const char* pixelShader = static const char* pixelShader = "struct PS_INPUT\
"struct PS_INPUT\
{\ {\
float4 pos : SV_POSITION;\ float4 pos : SV_POSITION;\
float4 col : COLOR0;\ float4 col : COLOR0;\
@ -372,10 +414,15 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
return out_col; \ return out_col; \
}"; }";
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob,
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! 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; 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; return false;
} }
@ -414,7 +461,8 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D10_COMPARISON_ALWAYS; desc.DepthFunc = D3D10_COMPARISON_ALWAYS;
desc.StencilEnable = false; 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.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace; desc.BackFace = desc.FrontFace;
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
@ -430,20 +478,73 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
if (!g_pd3dDevice) if (!g_pd3dDevice)
return; return;
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } if (g_pFontSampler)
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; } g_pFontSampler->Release();
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 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_pBlendState)
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } {
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } g_pBlendState->Release();
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } g_pBlendState = NULL;
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } }
if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } if (g_pDepthStencilState)
if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } {
if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } g_pDepthStencilState->Release();
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } 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) bool ImGui_ImplDX10_Init(ID3D10Device* device)
@ -463,8 +564,10 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
g_pd3dDevice = device; g_pd3dDevice = device;
g_pFactory = pFactory; g_pFactory = pFactory;
} }
if (pDXGIDevice) pDXGIDevice->Release(); if (pDXGIDevice)
if (pDXGIAdapter) pDXGIAdapter->Release(); pDXGIDevice->Release();
if (pDXGIAdapter)
pDXGIAdapter->Release();
return true; return true;
} }
@ -472,7 +575,11 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
void ImGui_ImplDX10_Shutdown() void ImGui_ImplDX10_Shutdown()
{ {
ImGui_ImplDX10_InvalidateDeviceObjects(); ImGui_ImplDX10_InvalidateDeviceObjects();
if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } if (g_pFactory)
{
g_pFactory->Release();
g_pFactory = NULL;
}
g_pd3dDevice = NULL; g_pd3dDevice = NULL;
} }

View File

@ -3,9 +3,9 @@
#include <kiwano-imgui/imgui_impl_dx11.h> #include <kiwano-imgui/imgui_impl_dx11.h>
// DirectX // DirectX
#include <stdio.h>
#include <d3d11.h> #include <d3d11.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include <stdio.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. #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 ID3D10Blob* g_pPixelShaderBlob = NULL;
static ID3D11PixelShader* g_pPixelShader = NULL; static ID3D11PixelShader* g_pPixelShader = NULL;
static ID3D11SamplerState* g_pFontSampler = NULL; static ID3D11SamplerState* g_pFontSampler = NULL;
static ID3D11ShaderResourceView*g_pFontTextureView = NULL; static ID3D11ShaderResourceView* g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL; static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL; static ID3D11BlendState* g_pBlendState = NULL;
static ID3D11DepthStencilState* g_pDepthStencilState = NULL; static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
@ -36,7 +36,8 @@ struct VERTEX_CONSTANT_BUFFER
}; };
// Render Function // Render Function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from
// your main loop)
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{ {
ID3D11DeviceContext* ctx = g_pd3dDeviceContext; ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
@ -44,7 +45,11 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 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; g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D11_BUFFER_DESC desc; D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_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_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; g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D11_BUFFER_DESC desc; D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
@ -90,7 +99,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ctx->Unmap(g_pIB, 0); ctx->Unmap(g_pIB, 0);
// Setup orthographic projection matrix into our constant buffer // 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; D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) 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 R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] = float mvp[4][4] = {
{ { 2.0f / (R - L), 0.0f, 0.0f, 0.0f },
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 0.0f, 2.0f / (T - B), 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 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)); memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
ctx->Unmap(g_pVertexConstantBuffer, 0); 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 struct BACKUP_DX11_STATE
{ {
UINT ScissorRectsCount, ViewportsCount; UINT ScissorRectsCount, ViewportsCount;
@ -128,9 +138,9 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ID3D11PixelShader* PS; ID3D11PixelShader* PS;
ID3D11VertexShader* VS; ID3D11VertexShader* VS;
UINT PSInstancesCount, VSInstancesCount; 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; D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; ID3D11Buffer * IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat; DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout; ID3D11InputLayout* InputLayout;
@ -199,7 +209,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
else else
{ {
// Apply scissor/clipping rectangle // 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); ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
@ -215,20 +226,46 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
// Restore modified DX state // Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports); ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); ctx->RSSetState(old.RS);
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); if (old.RS)
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); old.RS->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask);
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); if (old.BlendState)
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); old.BlendState->Release();
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef);
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); if (old.DepthStencilState)
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); old.DepthStencilState->Release();
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->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->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset);
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); if (old.IndexBuffer)
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); 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() static void ImGui_ImplDX11_CreateFontsTexture()
@ -253,7 +290,7 @@ static void ImGui_ImplDX11_CreateFontsTexture()
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
ID3D11Texture2D *pTexture = NULL; ID3D11Texture2D* pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource; D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels; subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
@ -301,16 +338,17 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
if (g_pFontSampler) if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects(); 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) // By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of
// If you would like to use this DX11 sample code but remove this dependency you can: // d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) If you would like to use this DX11 sample code but remove this
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] // dependency you can:
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. // 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. // See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader // Create the vertex shader
{ {
static const char* vertexShader = static const char* vertexShader = "cbuffer vertexBuffer : register(b0) \
"cbuffer vertexBuffer : register(b0) \
{\ {\
float4x4 ProjectionMatrix; \ float4x4 ProjectionMatrix; \
};\ };\
@ -337,20 +375,29 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
return output;\ return output;\
}"; }";
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob,
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! 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; 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; return false;
// Create the input layout // Create the input layout
D3D11_INPUT_ELEMENT_DESC local_layout[] = D3D11_INPUT_ELEMENT_DESC local_layout[] = {
{ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA,
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA,
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 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; return false;
// Create the constant buffer // Create the constant buffer
@ -367,8 +414,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
// Create the pixel shader // Create the pixel shader
{ {
static const char* pixelShader = static const char* pixelShader = "struct PS_INPUT\
"struct PS_INPUT\
{\ {\
float4 pos : SV_POSITION;\ float4 pos : SV_POSITION;\
float4 col : COLOR0;\ float4 col : COLOR0;\
@ -383,10 +429,15 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
return out_col; \ return out_col; \
}"; }";
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob,
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! 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; 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; return false;
} }
@ -425,7 +476,8 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS; desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = false; 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.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace; desc.BackFace = desc.FrontFace;
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
@ -441,20 +493,73 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
if (!g_pd3dDevice) if (!g_pd3dDevice)
return; return;
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } if (g_pFontSampler)
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; } g_pFontSampler->Release();
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 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_pBlendState)
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } {
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } g_pBlendState->Release();
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } g_pBlendState = NULL;
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } }
if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } if (g_pDepthStencilState)
if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } {
if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } g_pDepthStencilState->Release();
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } 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) 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_pd3dDeviceContext = device_context;
g_pFactory = pFactory; g_pFactory = pFactory;
} }
if (pDXGIDevice) pDXGIDevice->Release(); if (pDXGIDevice)
if (pDXGIAdapter) pDXGIAdapter->Release(); pDXGIDevice->Release();
if (pDXGIAdapter)
pDXGIAdapter->Release();
return true; return true;
} }
@ -484,7 +591,11 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
void ImGui_ImplDX11_Shutdown() void ImGui_ImplDX11_Shutdown()
{ {
ImGui_ImplDX11_InvalidateDeviceObjects(); 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_pd3dDevice = NULL;
g_pd3dDeviceContext = NULL; g_pd3dDeviceContext = NULL;
} }

View File

@ -18,24 +18,22 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <thread>
#include <codecvt> #include <codecvt>
#include <thread>
#include <kiwano/core/Logger.h>
#include <kiwano/platform/Application.h>
#include <kiwano-network/HttpRequest.h> #include <kiwano-network/HttpRequest.h>
#include <kiwano-network/HttpResponse.hpp> #include <kiwano-network/HttpResponse.hpp>
#include <kiwano-network/HttpClient.h> #include <kiwano-network/HttpClient.h>
#include <kiwano/core/Logger.h>
#include <kiwano/platform/Application.h>
#include <3rd-party/curl/curl.h> // CURL #include <3rd-party/curl/curl.h> // CURL
namespace namespace
{ {
using namespace kiwano; using namespace kiwano;
using namespace kiwano::network; 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; ByteString* recv_buffer = (ByteString*)userp;
uint32_t total = size * nmemb; uint32_t total = size * nmemb;
@ -44,10 +42,10 @@ namespace
recv_buffer->append((char*)buffer, total); recv_buffer->append((char*)buffer, total);
return 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; std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
ByteString result; ByteString result;
@ -61,10 +59,10 @@ namespace
result = WideToMultiByte(str); result = WideToMultiByte(str);
} }
return result; 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; oc::string_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
String result; String result;
@ -78,11 +76,11 @@ namespace
result = MultiByteToWide(str); result = MultiByteToWide(str);
} }
return result; return result;
} }
class Curl class Curl
{ {
public: public:
Curl() Curl()
: curl_(curl_easy_init()) : curl_(curl_easy_init())
, curl_headers_(nullptr) , 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)) if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer))
return false; return false;
@ -114,13 +113,15 @@ namespace
return false; return false;
const auto ssl_ca_file = wide_to_string(client->GetSSLVerification()); 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)) if (!SetOption(CURLOPT_SSL_VERIFYPEER, 0L))
return false; return false;
if (!SetOption(CURLOPT_SSL_VERIFYHOST, 0L)) if (!SetOption(CURLOPT_SSL_VERIFYHOST, 0L))
return false; return false;
} }
else { else
{
if (!SetOption(CURLOPT_SSL_VERIFYPEER, 1L)) if (!SetOption(CURLOPT_SSL_VERIFYPEER, 1L))
return false; return false;
if (!SetOption(CURLOPT_SSL_VERIFYHOST, 2L)) if (!SetOption(CURLOPT_SSL_VERIFYHOST, 2L))
@ -145,10 +146,8 @@ namespace
return false; return false;
} }
return SetOption(CURLOPT_URL, url.c_str()) return SetOption(CURLOPT_URL, url.c_str()) && SetOption(CURLOPT_WRITEFUNCTION, write_data)
&& SetOption(CURLOPT_WRITEFUNCTION, write_data) && SetOption(CURLOPT_WRITEDATA, response_data) && SetOption(CURLOPT_HEADERFUNCTION, write_data)
&& SetOption(CURLOPT_WRITEDATA, response_data)
&& SetOption(CURLOPT_HEADERFUNCTION, write_data)
&& SetOption(CURLOPT_HEADERDATA, response_header); && SetOption(CURLOPT_HEADERDATA, response_header);
} }
@ -161,111 +160,84 @@ namespace
return code == CURLE_OK && (*response_code >= 200 && *response_code < 300); return code == CURLE_OK && (*response_code >= 200 && *response_code < 300);
} }
template <typename ..._Args> template <typename... _Args>
bool SetOption(CURLoption option, _Args&&... args) bool SetOption(CURLoption option, _Args&&... args)
{ {
return CURLE_OK == curl_easy_setopt(curl_, option, std::forward<_Args>(args)...); return CURLE_OK == curl_easy_setopt(curl_, option, std::forward<_Args>(args)...);
} }
public: public:
static inline bool GetRequest( static inline bool GetRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url,
HttpClient* client, long* response_code, ByteString* response_data, ByteString* response_header,
Vector<ByteString> const& headers,
ByteString const& url,
long* response_code,
ByteString* response_data,
ByteString* response_header,
char* error_buffer) char* error_buffer)
{ {
Curl curl; Curl curl;
return curl.Init(client, headers, url, response_data, response_header, error_buffer) return curl.Init(client, headers, url, response_data, response_header, error_buffer)
&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.SetOption(CURLOPT_FOLLOWLOCATION, true) && curl.Perform(response_code);
&& curl.Perform(response_code);
} }
static inline bool PostRequest( static inline bool PostRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url,
HttpClient* client, ByteString const& request_data, long* response_code, ByteString* response_data,
Vector<ByteString> const& headers, ByteString* response_header, char* error_buffer)
ByteString const& url,
ByteString const& request_data,
long* response_code,
ByteString* response_data,
ByteString* response_header,
char* error_buffer)
{ {
Curl curl; Curl curl;
return curl.Init(client, headers, url, response_data, response_header, error_buffer) return curl.Init(client, headers, url, response_data, response_header, error_buffer)
&& curl.SetOption(CURLOPT_POST, 1) && curl.SetOption(CURLOPT_POST, 1) && curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str())
&& 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 PutRequest( static inline bool PutRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url,
HttpClient* client, ByteString const& request_data, long* response_code, ByteString* response_data,
Vector<ByteString> const& headers, ByteString* response_header, char* error_buffer)
ByteString const& url,
ByteString const& request_data,
long* response_code,
ByteString* response_data,
ByteString* response_header,
char* error_buffer)
{ {
Curl curl; Curl curl;
return curl.Init(client, headers, url, response_data, response_header, error_buffer) return curl.Init(client, headers, url, response_data, response_header, error_buffer)
&& curl.SetOption(CURLOPT_CUSTOMREQUEST, "PUT") && curl.SetOption(CURLOPT_CUSTOMREQUEST, "PUT")
&& curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str()) && curl.SetOption(CURLOPT_POSTFIELDS, request_data.c_str())
&& curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.SetOption(CURLOPT_POSTFIELDSIZE, request_data.size()) && curl.Perform(response_code);
&& curl.Perform(response_code);
} }
static inline bool DeleteRequest( static inline bool DeleteRequest(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url,
HttpClient* client, long* response_code, ByteString* response_data, ByteString* response_header,
Vector<ByteString> const& headers,
ByteString const& url,
long* response_code,
ByteString* response_data,
ByteString* response_header,
char* error_buffer) char* error_buffer)
{ {
Curl curl; Curl curl;
return curl.Init(client, headers, url, response_data, response_header, error_buffer) return curl.Init(client, headers, url, response_data, response_header, error_buffer)
&& curl.SetOption(CURLOPT_CUSTOMREQUEST, "DELETE") && curl.SetOption(CURLOPT_CUSTOMREQUEST, "DELETE") && curl.SetOption(CURLOPT_FOLLOWLOCATION, true)
&& curl.SetOption(CURLOPT_FOLLOWLOCATION, true)
&& curl.Perform(response_code); && curl.Perform(response_code);
} }
private: private:
CURL* curl_; CURL* curl_;
curl_slist* curl_headers_; curl_slist* curl_headers_;
}; };
} } // namespace
namespace kiwano namespace kiwano
{ {
namespace network namespace network
{ {
HttpClient::HttpClient() HttpClient::HttpClient()
: timeout_for_connect_(30000 /* 30 seconds */) : timeout_for_connect_(30000 /* 30 seconds */)
, timeout_for_read_(60000 /* 60 seconds */) , timeout_for_read_(60000 /* 60 seconds */)
{ {
} }
void HttpClient::SetupComponent() void HttpClient::SetupComponent()
{ {
::curl_global_init(CURL_GLOBAL_ALL); ::curl_global_init(CURL_GLOBAL_ALL);
std::thread thread(Closure(this, &HttpClient::NetworkThread)); std::thread thread(Closure(this, &HttpClient::NetworkThread));
thread.detach(); thread.detach();
} }
void HttpClient::DestroyComponent() void HttpClient::DestroyComponent()
{ {
::curl_global_cleanup(); ::curl_global_cleanup();
} }
void HttpClient::Send(HttpRequestPtr request) void HttpClient::Send(HttpRequestPtr request)
{ {
if (!request) if (!request)
return; return;
@ -274,10 +246,10 @@ namespace kiwano
request_mutex_.unlock(); request_mutex_.unlock();
sleep_condition_.notify_one(); sleep_condition_.notify_one();
} }
void HttpClient::NetworkThread() void HttpClient::NetworkThread()
{ {
while (true) while (true)
{ {
HttpRequestPtr request; HttpRequestPtr request;
@ -300,10 +272,10 @@ namespace kiwano
Application::PreformInMainThread(Closure(this, &HttpClient::DispatchResponseCallback)); Application::PreformInMainThread(Closure(this, &HttpClient::DispatchResponseCallback));
} }
} }
void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response) void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response)
{ {
bool ok = false; bool ok = false;
long response_code = 0; long response_code = 0;
char error_message[256] = { 0 }; char error_message[256] = { 0 };
@ -326,10 +298,12 @@ namespace kiwano
ok = Curl::GetRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); ok = Curl::GetRequest(this, headers, url, &response_code, &response_data, &response_header, error_message);
break; break;
case HttpRequest::Type::Post: 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; break;
case HttpRequest::Type::Put: 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; break;
case HttpRequest::Type::Delete: case HttpRequest::Type::Delete:
ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message);
@ -351,10 +325,10 @@ namespace kiwano
{ {
response->SetSucceed(true); response->SetSucceed(true);
} }
} }
void HttpClient::DispatchResponseCallback() void HttpClient::DispatchResponseCallback()
{ {
HttpResponsePtr response; HttpResponsePtr response;
response_mutex_.lock(); response_mutex_.lock();
@ -375,7 +349,7 @@ namespace kiwano
callback(request.get(), response.get()); callback(request.get(), response.get());
} }
} }
}
}
} }
} // namespace network
} // namespace kiwano

View File

@ -19,36 +19,36 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/common.h> #include <condition_variable>
#include <kiwano/core/Common.h>
#include <kiwano/core/Component.h> #include <kiwano/core/Component.h>
#include <mutex> #include <mutex>
#include <condition_variable>
namespace kiwano namespace kiwano
{ {
namespace network namespace network
{ {
/** /**
* \~chinese * \~chinese
* \defgroup Network * \defgroup Network
*/ */
/** /**
* \addtogroup Network * \addtogroup Network
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief HTTP客户端 * @brief HTTP客户端
*/ */
class KGE_API HttpClient class KGE_API HttpClient
: public Singleton<HttpClient> : public Singleton<HttpClient>
, public ComponentBase , public ComponentBase
{ {
friend Singleton<HttpClient>; friend Singleton<HttpClient>;
public: public:
/// \~chinese /// \~chinese
/// @brief 发送HTTP请求 /// @brief 发送HTTP请求
/// @param[in] request HTTP请求 /// @param[in] request HTTP请求
@ -79,12 +79,12 @@ namespace kiwano
/// @brief 获取SSL证书地址 /// @brief 获取SSL证书地址
String const& GetSSLVerification() const; String const& GetSSLVerification() const;
public: public:
virtual void SetupComponent() override; virtual void SetupComponent() override;
virtual void DestroyComponent() override; virtual void DestroyComponent() override;
private: private:
HttpClient(); HttpClient();
void NetworkThread(); void NetworkThread();
@ -93,7 +93,7 @@ namespace kiwano
void DispatchResponseCallback(); void DispatchResponseCallback();
private: private:
Duration timeout_for_connect_; Duration timeout_for_connect_;
Duration timeout_for_read_; Duration timeout_for_read_;
@ -106,40 +106,39 @@ namespace kiwano
Queue<HttpResponsePtr> response_queue_; Queue<HttpResponsePtr> response_queue_;
std::condition_variable_any sleep_condition_; std::condition_variable_any sleep_condition_;
}; };
/** @} */ /** @} */
inline void HttpClient::SetTimeoutForConnect(Duration timeout)
inline void HttpClient::SetTimeoutForConnect(Duration timeout) {
{
timeout_for_connect_ = 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

View File

@ -23,12 +23,12 @@
namespace kiwano namespace kiwano
{ {
namespace network namespace network
{ {
void HttpRequest::SetJsonData(Json const& json) void HttpRequest::SetJsonData(Json const& json)
{ {
SetHeader(L"Content-Type", L"application/json;charset=UTF-8"); SetHeader(L"Content-Type", L"application/json;charset=UTF-8");
data_ = json.dump(); data_ = json.dump();
}
}
} }
} // namespace network
} // namespace kiwano

View File

@ -19,31 +19,30 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/ObjectBase.h> #include <kiwano/core/ObjectBase.h>
#include <kiwano/core/SmartPtr.hpp> #include <kiwano/core/SmartPtr.hpp>
namespace kiwano namespace kiwano
{ {
namespace network namespace network
{ {
class HttpResponse; class HttpResponse;
KGE_DECLARE_SMART_PTR(HttpRequest); KGE_DECLARE_SMART_PTR(HttpRequest);
/** /**
* \addtogroup Network * \addtogroup Network
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief HTTP请求 * @brief HTTP请求
*/ */
class KGE_API HttpRequest class KGE_API HttpRequest : public virtual ObjectBase
: public ObjectBase {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 响应回调函数 /// @brief 响应回调函数
using ResponseCallback = Function<void(HttpRequest* /* request */, HttpResponse* /* response */)>; using ResponseCallback = Function<void(HttpRequest* /* request */, HttpResponse* /* response */)>;
@ -115,42 +114,84 @@ namespace kiwano
/// @brief 获取响应回调函数 /// @brief 获取响应回调函数
ResponseCallback const& GetResponseCallback() const; ResponseCallback const& GetResponseCallback() const;
private: private:
Type type_; Type type_;
String url_; String url_;
String data_; String data_;
Map<String, String> headers_; Map<String, String> headers_;
ResponseCallback response_cb_; ResponseCallback response_cb_;
}; };
/** @} */ /** @} */
inline HttpRequest::HttpRequest() : type_(Type::Unknown) {} 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)
: 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

View File

@ -23,23 +23,22 @@
namespace kiwano namespace kiwano
{ {
namespace network namespace network
{ {
KGE_DECLARE_SMART_PTR(HttpResponse); KGE_DECLARE_SMART_PTR(HttpResponse);
/** /**
* \addtogroup Network * \addtogroup Network
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief HTTP响应 * @brief HTTP响应
*/ */
class KGE_API HttpResponse class KGE_API HttpResponse : public virtual ObjectBase
: public ObjectBase {
{ public:
public:
HttpResponse(HttpRequestPtr request); HttpResponse(HttpRequestPtr request);
/// \~chinese /// \~chinese
@ -86,7 +85,7 @@ namespace kiwano
/// @brief 设置错误信息 /// @brief 设置错误信息
void SetError(String const& error_buffer); void SetError(String const& error_buffer);
private: private:
bool succeed_; bool succeed_;
long response_code_; long response_code_;
HttpRequestPtr request_; HttpRequestPtr request_;
@ -94,32 +93,70 @@ namespace kiwano
String response_header_; String response_header_;
String response_data_; String response_data_;
String error_buffer_; String error_buffer_;
}; };
/** @} */ /** @} */
inline HttpResponse::HttpResponse(HttpRequestPtr request) : request_(request), succeed_(false), response_code_(0) {} inline HttpResponse::HttpResponse(HttpRequestPtr request)
: request_(request)
inline HttpRequestPtr HttpResponse::GetRequest() const { return request_; } , succeed_(false)
, response_code_(0)
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 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

View File

@ -20,6 +20,6 @@
#pragma once #pragma once
#include <kiwano-network/HttpClient.h>
#include <kiwano-network/HttpRequest.h> #include <kiwano-network/HttpRequest.h>
#include <kiwano-network/HttpResponse.hpp> #include <kiwano-network/HttpResponse.hpp>
#include <kiwano-network/HttpClient.h>

View File

@ -23,39 +23,26 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
Body::Body() Body::Body()
: body_(nullptr) : body_(nullptr)
, actor_(nullptr) , actor_(nullptr)
, world_(nullptr) , world_(nullptr)
, category_bits_(0x0001) , category_bits_(0x0001)
, mask_bits_(0xFFFF) , mask_bits_(0xFFFF)
, group_index_(0) , group_index_(0)
{ {
} }
Body::Body(b2Body* body, Actor* actor) Body::~Body()
: Body() {
{
SetB2Body(body);
SetActor(actor);
}
Body::Body(World* world, Actor* actor)
: Body()
{
Init(world, actor);
}
Body::~Body()
{
Destroy(); Destroy();
} }
void Body::Init(World* world, Actor* actor) bool Body::InitBody(World* world, Actor* actor)
{ {
KGE_ASSERT(world); KGE_ASSERT(world);
Destroy(); Destroy();
@ -64,52 +51,57 @@ namespace kiwano
b2BodyDef def; b2BodyDef def;
b2Body* b2body = world->GetB2World()->CreateBody(&def); b2Body* b2body = world->GetB2World()->CreateBody(&def);
if (b2body)
{
SetB2Body(b2body); SetB2Body(b2body);
SetActor(actor); SetActor(actor);
UpdateFromActor(); 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_); KGE_ASSERT(body_ && world_);
return Fixture(this, shape, param); 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)); 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)); 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)); 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)); 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)); return AddFixture(&ChainShape(vertexs, loop), Fixture::Param(density));
} }
void Body::RemoveFixture(Fixture const& fixture) void Body::RemoveFixture(Fixture const& fixture)
{ {
if (fixture.GetB2Fixture()) if (fixture.GetB2Fixture())
{ {
body_->DestroyFixture(fixture.GetB2Fixture()); body_->DestroyFixture(fixture.GetB2Fixture());
} }
} }
void Body::SetCategoryBits(uint16_t category_bits) void Body::SetCategoryBits(uint16_t category_bits)
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
if (category_bits != category_bits_) if (category_bits != category_bits_)
@ -123,10 +115,10 @@ namespace kiwano
fixture = fixture->GetNext(); fixture = fixture->GetNext();
} }
} }
} }
void Body::SetMaskBits(uint16_t mask_bits) void Body::SetMaskBits(uint16_t mask_bits)
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
if (mask_bits != mask_bits_) if (mask_bits != mask_bits_)
@ -140,10 +132,10 @@ namespace kiwano
fixture = fixture->GetNext(); fixture = fixture->GetNext();
} }
} }
} }
void Body::SetGroupIndex(int16_t index) void Body::SetGroupIndex(int16_t index)
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
if (index != group_index_) if (index != group_index_)
@ -157,22 +149,25 @@ namespace kiwano
fixture = fixture->GetNext(); 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_); KGE_ASSERT(body_ && world_);
b2MassData data; b2MassData data;
body_->GetMassData(&data); body_->GetMassData(&data);
if (mass) *mass = data.mass; if (mass)
if (center) *center = world_->World2Stage(data.center); *mass = data.mass;
if (inertia) *inertia = data.I; 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_); KGE_ASSERT(body_ && world_);
b2MassData data; b2MassData data;
@ -180,80 +175,80 @@ namespace kiwano
data.center = world_->Stage2World(center); data.center = world_->Stage2World(center);
data.I = inertia; data.I = inertia;
body_->SetMassData(&data); body_->SetMassData(&data);
} }
void Body::ResetMassData() void Body::ResetMassData()
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
body_->ResetMassData(); body_->ResetMassData();
} }
Point Body::GetBodyPosition() const Point Body::GetBodyPosition() const
{ {
KGE_ASSERT(body_ && world_); KGE_ASSERT(body_ && world_);
return world_->World2Stage(body_->GetPosition()); 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_); KGE_ASSERT(body_ && world_);
body_->SetTransform(world_->Stage2World(pos), math::Degree2Radian(angle)); 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_); KGE_ASSERT(body_ && world_);
return world_->World2Stage(body_->GetLocalPoint(world_->Stage2World(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_); KGE_ASSERT(body_ && world_);
return world_->World2Stage(body_->GetWorldPoint(world_->Stage2World(local))); return world_->World2Stage(body_->GetWorldPoint(world_->Stage2World(local)));
} }
Point Body::GetLocalCenter() const Point Body::GetLocalCenter() const
{ {
KGE_ASSERT(body_ && world_); KGE_ASSERT(body_ && world_);
return world_->World2Stage(body_->GetLocalCenter()); return world_->World2Stage(body_->GetLocalCenter());
} }
Point Body::GetWorldCenter() const Point Body::GetWorldCenter() const
{ {
KGE_ASSERT(body_ && world_); KGE_ASSERT(body_ && world_);
return world_->World2Stage(body_->GetWorldCenter()); 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_); KGE_ASSERT(body_ && world_);
body_->ApplyForce(b2Vec2(force.x, force.y), world_->Stage2World(point), wake); 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_); KGE_ASSERT(body_ && world_);
body_->ApplyForceToCenter(b2Vec2(force.x, force.y), wake); 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_); KGE_ASSERT(body_ && world_);
body_->ApplyTorque(torque, wake); body_->ApplyTorque(torque, wake);
} }
void Body::SetB2Body(b2Body* body) void Body::SetB2Body(b2Body* body)
{ {
body_ = body; body_ = body;
if (body_) if (body_)
{ {
body_->SetUserData(this); body_->SetUserData(this);
} }
} }
void Body::Destroy() void Body::Destroy()
{ {
if (world_ && body_) if (world_)
{ {
world_->RemoveBody(this); world_->RemoveBody(this);
} }
@ -261,10 +256,10 @@ namespace kiwano
body_ = nullptr; body_ = nullptr;
world_ = nullptr; world_ = nullptr;
actor_ = nullptr; actor_ = nullptr;
} }
void Body::UpdateActor() void Body::UpdateActor()
{ {
if (actor_ && body_) if (actor_ && body_)
{ {
if (world_) if (world_)
@ -277,37 +272,31 @@ namespace kiwano
} }
actor_->SetRotation(math::Radian2Degree(body_->GetAngle())); actor_->SetRotation(math::Radian2Degree(body_->GetAngle()));
} }
} }
void Body::UpdateFromActor() void Body::UpdateFromActor()
{ {
if (actor_ && body_) if (actor_ && body_)
{ {
if (world_) if (world_)
{ {
body_->SetTransform( body_->SetTransform(world_->Stage2World(actor_->GetPosition()), math::Degree2Radian(actor_->GetRotation()));
world_->Stage2World(actor_->GetPosition()),
math::Degree2Radian(actor_->GetRotation())
);
} }
else else
{ {
body_->SetTransform( body_->SetTransform(Stage2World(actor_->GetPosition()), math::Degree2Radian(actor_->GetRotation()));
Stage2World(actor_->GetPosition()),
math::Degree2Radian(actor_->GetRotation())
);
}
} }
} }
}
void Body::UpdateFixtureFilter(b2Fixture* fixture) void Body::UpdateFixtureFilter(b2Fixture* fixture)
{ {
b2Filter filter; b2Filter filter;
filter.categoryBits = category_bits_; filter.categoryBits = category_bits_;
filter.maskBits = mask_bits_; filter.maskBits = mask_bits_;
filter.groupIndex = group_index_; filter.groupIndex = group_index_;
fixture->SetFilterData(filter); fixture->SetFilterData(filter);
} }
} } // namespace physics
} } // namespace kiwano

View File

@ -19,30 +19,29 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #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/ContactEdge.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/helper.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
class World; class World;
KGE_DECLARE_SMART_PTR(Body); KGE_DECLARE_SMART_PTR(Body);
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief ÎïÌå /// @brief 物体
class KGE_API Body class KGE_API Body : public virtual ObjectBase
: public virtual RefCounter {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 物体类型 /// @brief 物体类型
enum class Type enum class Type
@ -53,16 +52,20 @@ namespace kiwano
}; };
Body(); Body();
Body(b2Body* body, Actor* actor);
Body(World* world, Actor* actor);
Body(World* world, ActorPtr actor);
virtual ~Body(); virtual ~Body();
/// \~chinese /// \~chinese
/// @brief 初始化 /// @brief 初始化
/// @param[in] world 物理世界 /// @param[in] world 物理世界
/// @param[in] actor 绑定的角色 /// @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 /// \~chinese
/// @brief 添加夹具 /// @brief 添加夹具
@ -298,7 +301,7 @@ namespace kiwano
b2Body* GetB2Body() const; b2Body* GetB2Body() const;
void SetB2Body(b2Body* body); void SetB2Body(b2Body* body);
private: private:
/// \~chinese /// \~chinese
/// @brief 销毁物体 /// @brief 销毁物体
void UpdateFixtureFilter(b2Fixture* fixture); void UpdateFixtureFilter(b2Fixture* fixture);
@ -307,7 +310,7 @@ namespace kiwano
/// @brief 销毁物体 /// @brief 销毁物体
void Destroy(); void Destroy();
private: private:
Actor* actor_; Actor* actor_;
World* world_; World* world_;
b2Body* body_; b2Body* body_;
@ -315,66 +318,172 @@ namespace kiwano
uint16_t category_bits_; uint16_t category_bits_;
uint16_t mask_bits_; uint16_t mask_bits_;
int16_t group_index_; int16_t group_index_;
}; };
/** @} */ /** @} */
inline Body::Body(World* world, ActorPtr actor) : Body(world, actor.get()) {} inline bool Body::InitBody(World* world, ActorPtr actor)
{
inline FixtureList Body::GetFixtureList() const { KGE_ASSERT(body_); return FixtureList(Fixture(body_->GetFixtureList())); } return InitBody(world, actor.get());
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 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

View File

@ -18,50 +18,50 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano-physics/Contact.h>
#include <kiwano-physics/Body.h> #include <kiwano-physics/Body.h>
#include <kiwano-physics/Contact.h>
#include <kiwano-physics/World.h> #include <kiwano-physics/World.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
Contact::Contact() Contact::Contact()
: contact_(nullptr) : contact_(nullptr)
{ {
} }
Contact::Contact(b2Contact* contact) Contact::Contact(b2Contact* contact)
: Contact() : Contact()
{ {
SetB2Contact(contact); SetB2Contact(contact);
} }
Fixture Contact::GetFixtureA() const Fixture Contact::GetFixtureA() const
{ {
KGE_ASSERT(contact_); KGE_ASSERT(contact_);
return Fixture(contact_->GetFixtureA()); return Fixture(contact_->GetFixtureA());
} }
Fixture Contact::GetFixtureB() const Fixture Contact::GetFixtureB() const
{ {
KGE_ASSERT(contact_); KGE_ASSERT(contact_);
return Fixture(contact_->GetFixtureB()); return Fixture(contact_->GetFixtureB());
} }
Body* Contact::GetBodyA() const Body* Contact::GetBodyA() const
{ {
return GetFixtureA().GetBody(); return GetFixtureA().GetBody();
} }
Body* Contact::GetBodyB() const Body* Contact::GetBodyB() const
{ {
return GetFixtureB().GetBody(); return GetFixtureB().GetBody();
} }
void Contact::SetTangentSpeed(float speed) void Contact::SetTangentSpeed(float speed)
{ {
KGE_ASSERT(contact_); KGE_ASSERT(contact_);
Body* body = GetFixtureA().GetBody(); Body* body = GetFixtureA().GetBody();
@ -71,10 +71,10 @@ namespace kiwano
KGE_ASSERT(world); KGE_ASSERT(world);
contact_->SetTangentSpeed(world->Stage2World(speed)); contact_->SetTangentSpeed(world->Stage2World(speed));
} }
float Contact::GetTangentSpeed() const float Contact::GetTangentSpeed() const
{ {
KGE_ASSERT(contact_); KGE_ASSERT(contact_);
const Body* body = GetFixtureA().GetBody(); const Body* body = GetFixtureA().GetBody();
@ -84,7 +84,7 @@ namespace kiwano
KGE_ASSERT(world); KGE_ASSERT(world);
return world->World2Stage(contact_->GetTangentSpeed()); return world->World2Stage(contact_->GetTangentSpeed());
}
}
} }
} // namespace physics
} // namespace kiwano

View File

@ -19,25 +19,25 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano-physics/helper.h>
#include <kiwano-physics/Fixture.h> #include <kiwano-physics/Fixture.h>
#include <kiwano-physics/helper.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
class Body; class Body;
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief ÎïÀí½Ó´¥ /// @brief ÎïÀí½Ó´¥
class KGE_API Contact class KGE_API Contact
{ {
public: public:
Contact(); Contact();
Contact(b2Contact* contact); Contact(b2Contact* contact);
@ -108,22 +108,19 @@ namespace kiwano
b2Contact* GetB2Contact() const; b2Contact* GetB2Contact() const;
void SetB2Contact(b2Contact* contact); 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_; b2Contact* contact_;
}; };
/// \~chinese
/// \~chinese /// @brief ÎïÀí½Ó´¥Áбí
/// @brief ÎïÀí½Ó´¥Áбí class ContactList : public List<Contact>
class ContactList {
: public List<Contact>
{
template <typename _Ty> template <typename _Ty>
class IteratorImpl class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty>
: public std::iterator<std::forward_iterator_tag, _Ty>
{ {
using herit = std::iterator<std::forward_iterator_tag, _Ty>; using herit = std::iterator<std::forward_iterator_tag, _Ty>;
@ -156,12 +153,12 @@ namespace kiwano
return old; return old;
} }
inline bool operator== (const IteratorImpl& rhs) const inline bool operator==(const IteratorImpl& rhs) const
{ {
return elem_ == rhs.elem_; return elem_ == rhs.elem_;
} }
inline bool operator!= (const IteratorImpl& rhs) const inline bool operator!=(const IteratorImpl& rhs) const
{ {
return !operator==(rhs); return !operator==(rhs);
} }
@ -170,14 +167,12 @@ namespace kiwano
_Ty elem_; _Ty elem_;
}; };
public: public:
using value_type = Contact; using value_type = Contact;
using iterator = IteratorImpl<value_type>; using iterator = IteratorImpl<value_type>;
using const_iterator = IteratorImpl<const value_type>; using const_iterator = IteratorImpl<const value_type>;
inline ContactList() inline ContactList() {}
{
}
inline ContactList(const value_type& first) inline ContactList(const value_type& first)
: first_(first) : first_(first)
@ -224,27 +219,77 @@ namespace kiwano
return const_iterator(nullptr); return const_iterator(nullptr);
} }
private: private:
value_type first_; value_type first_;
}; };
/** @} */ /** @} */
inline bool Contact::IsValid() const
inline bool Contact::IsValid() const { return contact_ != nullptr;} {
inline bool Contact::IsTouching() const { KGE_ASSERT(contact_); return contact_->IsTouching(); } return contact_ != nullptr;
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::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

View File

@ -22,19 +22,19 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
ContactEdge::ContactEdge() ContactEdge::ContactEdge()
: edge_(nullptr) : edge_(nullptr)
{ {
}
ContactEdge::ContactEdge(b2ContactEdge* edge)
: ContactEdge()
{
SetB2ContactEdge(edge);
}
}
} }
ContactEdge::ContactEdge(b2ContactEdge* edge)
: ContactEdge()
{
SetB2ContactEdge(edge);
}
} // namespace physics
} // namespace kiwano

View File

@ -23,18 +23,18 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief ½Ó´¥±ß /// @brief ½Ó´¥±ß
class KGE_API ContactEdge class KGE_API ContactEdge
{ {
public: public:
ContactEdge(); ContactEdge();
ContactEdge(b2ContactEdge* edge); ContactEdge(b2ContactEdge* edge);
@ -53,21 +53,19 @@ namespace kiwano
b2ContactEdge* GetB2ContactEdge() const; b2ContactEdge* GetB2ContactEdge() const;
void SetB2ContactEdge(b2ContactEdge* edge); 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_; b2ContactEdge* edge_;
}; };
/// \~chinese
/// \~chinese /// @brief ÎïÀí½Ó´¥±ßÁбí
/// @brief ÎïÀí½Ó´¥±ßÁбí class ContactEdgeList
class ContactEdgeList {
{
template <typename _Ty> template <typename _Ty>
class IteratorImpl class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty>
: public std::iterator<std::forward_iterator_tag, _Ty>
{ {
using herit = std::iterator<std::forward_iterator_tag, _Ty>; using herit = std::iterator<std::forward_iterator_tag, _Ty>;
@ -100,12 +98,12 @@ namespace kiwano
return old; return old;
} }
inline bool operator== (const IteratorImpl& rhs) const inline bool operator==(const IteratorImpl& rhs) const
{ {
return elem_ == rhs.elem_; return elem_ == rhs.elem_;
} }
inline bool operator!= (const IteratorImpl& rhs) const inline bool operator!=(const IteratorImpl& rhs) const
{ {
return !operator==(rhs); return !operator==(rhs);
} }
@ -114,14 +112,12 @@ namespace kiwano
_Ty elem_; _Ty elem_;
}; };
public: public:
using value_type = ContactEdge; using value_type = ContactEdge;
using iterator = IteratorImpl<value_type>; using iterator = IteratorImpl<value_type>;
using const_iterator = IteratorImpl<const value_type>; using const_iterator = IteratorImpl<const value_type>;
inline ContactEdgeList() inline ContactEdgeList() {}
{
}
inline ContactEdgeList(const value_type& first) inline ContactEdgeList(const value_type& first)
: first_(first) : first_(first)
@ -168,19 +164,42 @@ namespace kiwano
return const_iterator(nullptr); return const_iterator(nullptr);
} }
private: private:
value_type first_; value_type first_;
}; };
/** @} */ /** @} */
inline bool ContactEdge::IsValid() const { return edge_ != nullptr; } inline bool ContactEdge::IsValid() const
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); } return edge_ != nullptr;
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 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

View File

@ -22,29 +22,29 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
ContactBeginEvent::ContactBeginEvent() ContactBeginEvent::ContactBeginEvent()
: Event(KGE_EVENT(ContactBeginEvent)) : Event(KGE_EVENT(ContactBeginEvent))
{ {
} }
ContactBeginEvent::ContactBeginEvent(Contact const& contact) ContactBeginEvent::ContactBeginEvent(Contact const& contact)
: ContactBeginEvent() : ContactBeginEvent()
{ {
this->contact = contact; this->contact = contact;
} }
ContactEndEvent::ContactEndEvent() ContactEndEvent::ContactEndEvent()
: Event(KGE_EVENT(ContactEndEvent)) : Event(KGE_EVENT(ContactEndEvent))
{ {
} }
ContactEndEvent::ContactEndEvent(Contact const& contact) ContactEndEvent::ContactEndEvent(Contact const& contact)
: ContactEndEvent() : ContactEndEvent()
{ {
this->contact = contact; this->contact = contact;
} }
} } // namespace physics
} } // namespace kiwano

View File

@ -19,44 +19,45 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano-physics/Contact.h>
#include <kiwano-physics/Body.h> #include <kiwano-physics/Body.h>
#include <kiwano-physics/Contact.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
/** KGE_DECLARE_SMART_PTR(ContactBeginEvent);
KGE_DECLARE_SMART_PTR(ContactEndEvent);
/**
* \addtogroup Events * \addtogroup Events
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief 物理接触开始事件 /// @brief 物理接触开始事件
class KGE_API ContactBeginEvent class KGE_API ContactBeginEvent : public Event
: public Event {
{ public:
public:
Contact contact; ///< 产生的接触 Contact contact; ///< 产生的接触
ContactBeginEvent(); ContactBeginEvent();
ContactBeginEvent(Contact const& contact); ContactBeginEvent(Contact const& contact);
}; };
/// \~chinese /// \~chinese
/// @brief 物理接触结束事件 /// @brief 物理接触结束事件
class KGE_API ContactEndEvent class KGE_API ContactEndEvent : public Event
: public Event {
{ public:
public:
Contact contact; ///< 产生的接触 Contact contact; ///< 产生的接触
ContactEndEvent(); ContactEndEvent();
ContactEndEvent(Contact const& contact); ContactEndEvent(Contact const& contact);
}; };
/** @} */ /** @} */
} } // namespace physics
} } // namespace kiwano

View File

@ -18,29 +18,29 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Body.h> #include <kiwano-physics/Body.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/World.h> #include <kiwano-physics/World.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
Fixture::Fixture() Fixture::Fixture()
: fixture_(nullptr) : fixture_(nullptr)
{ {
} }
Fixture::Fixture(b2Fixture* fixture) Fixture::Fixture(b2Fixture* fixture)
: Fixture() : Fixture()
{ {
SetB2Fixture(fixture); SetB2Fixture(fixture);
} }
Fixture::Fixture(Body* body, Shape* shape, const Param& param) Fixture::Fixture(Body* body, Shape* shape, const Param& param)
: Fixture() : Fixture()
{ {
KGE_ASSERT(body); KGE_ASSERT(body);
if (shape) if (shape)
@ -56,22 +56,22 @@ namespace kiwano
auto fixture = b2body->CreateFixture(&fd); auto fixture = b2body->CreateFixture(&fd);
SetB2Fixture(fixture); SetB2Fixture(fixture);
} }
} }
Body* Fixture::GetBody() const Body* Fixture::GetBody() const
{ {
KGE_ASSERT(fixture_); KGE_ASSERT(fixture_);
return static_cast<Body*>(fixture_->GetBody()->GetUserData()); return static_cast<Body*>(fixture_->GetBody()->GetUserData());
} }
Shape Fixture::GetShape() const Shape Fixture::GetShape() const
{ {
KGE_ASSERT(fixture_); KGE_ASSERT(fixture_);
return Shape(fixture_->GetShape()); 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_); KGE_ASSERT(fixture_);
const Body* body = GetBody(); const Body* body = GetBody();
@ -83,13 +83,16 @@ namespace kiwano
b2MassData data; b2MassData data;
fixture_->GetMassData(&data); fixture_->GetMassData(&data);
if (mass) *mass = data.mass; if (mass)
if (center) *center = world->World2Stage(data.center); *mass = data.mass;
if (inertia) *inertia = data.I; 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_); KGE_ASSERT(fixture_);
const Body* body = GetBody(); const Body* body = GetBody();
@ -99,7 +102,7 @@ namespace kiwano
KGE_ASSERT(world); KGE_ASSERT(world);
return fixture_->TestPoint(world->Stage2World(p)); return fixture_->TestPoint(world->Stage2World(p));
}
}
} }
} // namespace physics
} // namespace kiwano

View File

@ -19,25 +19,25 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano-physics/helper.h>
#include <kiwano-physics/Shape.h> #include <kiwano-physics/Shape.h>
#include <kiwano-physics/helper.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
class Body; class Body;
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief ÎïÀí¼Ð¾ß /// @brief ÎïÀí¼Ð¾ß
class Fixture class Fixture
{ {
public: public:
/// \~chinese /// \~chinese
/// @brief ¼Ð¾ß²ÎÊý /// @brief ¼Ð¾ß²ÎÊý
struct Param struct Param
@ -54,7 +54,8 @@ namespace kiwano
, friction(friction) , friction(friction)
, restitution(restitution) , restitution(restitution)
, is_sensor(is_sensor) , is_sensor(is_sensor)
{} {
}
}; };
Fixture(); Fixture();
@ -117,21 +118,19 @@ namespace kiwano
b2Fixture* GetB2Fixture() const; b2Fixture* GetB2Fixture() const;
void SetB2Fixture(b2Fixture* fixture); 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_; b2Fixture* fixture_;
}; };
/// \~chinese /// \~chinese
/// @brief ÎïÀí¼Ð¾ßÁбí /// @brief ÎïÀí¼Ð¾ßÁбí
class FixtureList class FixtureList : public List<Fixture>
: public List<Fixture> {
{
template <typename _Ty> template <typename _Ty>
class IteratorImpl class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty>
: public std::iterator<std::forward_iterator_tag, _Ty>
{ {
using herit = std::iterator<std::forward_iterator_tag, _Ty>; using herit = std::iterator<std::forward_iterator_tag, _Ty>;
@ -164,12 +163,12 @@ namespace kiwano
return old; return old;
} }
inline bool operator== (const IteratorImpl& rhs) const inline bool operator==(const IteratorImpl& rhs) const
{ {
return elem_ == rhs.elem_; return elem_ == rhs.elem_;
} }
inline bool operator!= (const IteratorImpl& rhs) const inline bool operator!=(const IteratorImpl& rhs) const
{ {
return !operator==(rhs); return !operator==(rhs);
} }
@ -178,14 +177,12 @@ namespace kiwano
_Ty elem_; _Ty elem_;
}; };
public: public:
using value_type = Fixture; using value_type = Fixture;
using iterator = IteratorImpl<value_type>; using iterator = IteratorImpl<value_type>;
using const_iterator = IteratorImpl<const value_type>; using const_iterator = IteratorImpl<const value_type>;
inline FixtureList() inline FixtureList() {}
{
}
inline FixtureList(const value_type& first) inline FixtureList(const value_type& first)
: first_(first) : first_(first)
@ -232,24 +229,71 @@ namespace kiwano
return const_iterator(nullptr); return const_iterator(nullptr);
} }
private: private:
value_type first_; value_type first_;
}; };
/** @} */ /** @} */
inline bool Fixture::IsSensor() const { KGE_ASSERT(fixture_); return fixture_->IsSensor(); } inline bool Fixture::IsSensor() const
inline void Fixture::SetSensor(bool sensor) { KGE_ASSERT(fixture_); fixture_->SetSensor(sensor); } {
inline float Fixture::GetDensity() const { KGE_ASSERT(fixture_); return fixture_->GetDensity(); } KGE_ASSERT(fixture_);
inline void Fixture::SetDensity(float density) { KGE_ASSERT(fixture_); fixture_->SetDensity(density); } return fixture_->IsSensor();
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 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

View File

@ -23,41 +23,30 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
// //
// Joint // Joint
// //
Joint::Joint() Joint::Joint()
: joint_(nullptr) : joint_(nullptr)
, world_(nullptr) , world_(nullptr)
, type_(Type::Unknown) , type_(Type::Unknown)
{ {
} }
Joint::Joint(b2Joint* joint) Joint::~Joint()
: Joint() {
{ Destroy();
SetB2Joint(joint); }
}
Joint::Joint(World* world, b2JointDef* joint_def) bool Joint::InitJoint(World* world, b2JointDef* joint_def)
: Joint() {
{ KGE_ASSERT(world);
Init(world, joint_def);
}
Joint::~Joint() Destroy();
{
if (world_)
{
world_->RemoveJoint(this);
}
}
void Joint::Init(World* world, b2JointDef* joint_def)
{
world_ = world; world_ = world;
if (world_) if (world_)
{ {
@ -65,97 +54,94 @@ namespace kiwano
b2Joint* joint = world_->GetB2World()->CreateJoint(joint_def); b2Joint* joint = world_->GetB2World()->CreateJoint(joint_def);
SetB2Joint(joint); SetB2Joint(joint);
}
}
BodyPtr Joint::GetBodyA() const return joint != nullptr;
{ }
return false;
}
BodyPtr Joint::GetBodyA() const
{
KGE_ASSERT(joint_); KGE_ASSERT(joint_);
b2Body* body = joint_->GetBodyA(); b2Body* body = joint_->GetBodyA();
return BodyPtr(static_cast<Body*>(body->GetUserData())); return BodyPtr(static_cast<Body*>(body->GetUserData()));
} }
BodyPtr Joint::GetBodyB() const BodyPtr Joint::GetBodyB() const
{ {
KGE_ASSERT(joint_); KGE_ASSERT(joint_);
b2Body* body = joint_->GetBodyB(); b2Body* body = joint_->GetBodyB();
return BodyPtr(static_cast<Body*>(body->GetUserData())); return BodyPtr(static_cast<Body*>(body->GetUserData()));
} }
void Joint::SetB2Joint(b2Joint* joint) void Joint::SetB2Joint(b2Joint* joint)
{ {
joint_ = joint; joint_ = joint;
if (joint_) if (joint_)
{ {
type_ = Joint::Type(joint_->GetType()); type_ = Joint::Type(joint_->GetType());
} }
}
void Joint::Destroy()
{
if (world_)
{
world_->RemoveJoint(this);
} }
}
// //
// DistanceJoint // DistanceJoint
// //
DistanceJoint::DistanceJoint() DistanceJoint::DistanceJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
DistanceJoint::DistanceJoint(World* world, b2DistanceJointDef* def) bool DistanceJoint::InitJoint(World* world, DistanceJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
DistanceJoint::DistanceJoint(World* world, DistanceJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2DistanceJointDef def; 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.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio; def.dampingRatio = param.damping_ratio;
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2DistanceJoint*>(GetB2Joint()); 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()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetLength(GetWorld()->Stage2World(length)); raw_joint_->SetLength(GetWorld()->Stage2World(length));
} }
float DistanceJoint::GetLength() const float DistanceJoint::GetLength() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetLength()); return GetWorld()->World2Stage(raw_joint_->GetLength());
} }
// //
// FrictionJoint // FrictionJoint
// //
FrictionJoint::FrictionJoint() FrictionJoint::FrictionJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
FrictionJoint::FrictionJoint(World* world, b2FrictionJointDef* def) bool FrictionJoint::InitJoint(World* world, FrictionJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
FrictionJoint::FrictionJoint(World* world, FrictionJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2FrictionJointDef def; b2FrictionJointDef def;
@ -163,54 +149,47 @@ namespace kiwano
def.maxForce = param.max_force; def.maxForce = param.max_force;
def.maxTorque = world->Stage2World(param.max_torque); def.maxTorque = world->Stage2World(param.max_torque);
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
void FrictionJoint::SetMaxForce(float length) void FrictionJoint::SetMaxForce(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxForce(length); raw_joint_->SetMaxForce(length);
} }
float FrictionJoint::GetMaxForce() const float FrictionJoint::GetMaxForce() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxForce(); return raw_joint_->GetMaxForce();
} }
void FrictionJoint::SetMaxTorque(float length) void FrictionJoint::SetMaxTorque(float length)
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetMaxTorque(GetWorld()->Stage2World(length)); raw_joint_->SetMaxTorque(GetWorld()->Stage2World(length));
} }
float FrictionJoint::GetMaxTorque() const float FrictionJoint::GetMaxTorque() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetMaxTorque()); return GetWorld()->World2Stage(raw_joint_->GetMaxTorque());
} }
// //
// GearJoint // GearJoint
// //
GearJoint::GearJoint() GearJoint::GearJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
GearJoint::GearJoint(World* world, b2GearJointDef* def) bool GearJoint::InitJoint(World* world, GearJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
GearJoint::GearJoint(World* world, GearJoint::Param param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.joint_a && param.joint_b); KGE_ASSERT(param.joint_a && param.joint_b);
b2GearJointDef def; b2GearJointDef def;
@ -218,42 +197,35 @@ namespace kiwano
def.joint2 = param.joint_b->GetB2Joint(); def.joint2 = param.joint_b->GetB2Joint();
def.ratio = param.ratio; def.ratio = param.ratio;
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2GearJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2GearJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
void GearJoint::SetRatio(float ratio) void GearJoint::SetRatio(float ratio)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetRatio(ratio); raw_joint_->SetRatio(ratio);
} }
float GearJoint::GetRatio() const float GearJoint::GetRatio() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return raw_joint_->GetRatio(); return raw_joint_->GetRatio();
} }
// //
// MotorJoint // MotorJoint
// //
MotorJoint::MotorJoint() MotorJoint::MotorJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
MotorJoint::MotorJoint(World* world, b2MotorJointDef* def) bool MotorJoint::InitJoint(World* world, MotorJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
MotorJoint::MotorJoint(World* world, MotorJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2MotorJointDef def; b2MotorJointDef def;
@ -262,58 +234,52 @@ namespace kiwano
def.maxTorque = world->Stage2World(param.max_torque); def.maxTorque = world->Stage2World(param.max_torque);
def.correctionFactor = param.correction_factor; def.correctionFactor = param.correction_factor;
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2MotorJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2MotorJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
void MotorJoint::SetMaxForce(float length) void MotorJoint::SetMaxForce(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxForce(length); raw_joint_->SetMaxForce(length);
} }
float MotorJoint::GetMaxForce() const float MotorJoint::GetMaxForce() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxForce(); return raw_joint_->GetMaxForce();
} }
void MotorJoint::SetMaxTorque(float length) void MotorJoint::SetMaxTorque(float length)
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetMaxTorque(GetWorld()->Stage2World(length)); raw_joint_->SetMaxTorque(GetWorld()->Stage2World(length));
} }
float MotorJoint::GetMaxTorque() const float MotorJoint::GetMaxTorque() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetMaxTorque()); return GetWorld()->World2Stage(raw_joint_->GetMaxTorque());
} }
// //
// PrismaticJoint // PrismaticJoint
// //
PrismaticJoint::PrismaticJoint() PrismaticJoint::PrismaticJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
PrismaticJoint::PrismaticJoint(World* world, b2PrismaticJointDef* def) bool PrismaticJoint::InitJoint(World* world, PrismaticJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
PrismaticJoint::PrismaticJoint(World* world, PrismaticJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2PrismaticJointDef def; 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.enableLimit = param.enable_limit;
def.lowerTranslation = world->Stage2World(param.lower_translation); def.lowerTranslation = world->Stage2World(param.lower_translation);
def.upperTranslation = world->Stage2World(param.upper_translation); def.upperTranslation = world->Stage2World(param.upper_translation);
@ -321,132 +287,119 @@ namespace kiwano
def.maxMotorForce = param.max_motor_force; def.maxMotorForce = param.max_motor_force;
def.motorSpeed = world->Stage2World(param.motor_speed); def.motorSpeed = world->Stage2World(param.motor_speed);
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
float PrismaticJoint::GetJointTranslation() const float PrismaticJoint::GetJointTranslation() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetJointTranslation()); return GetWorld()->World2Stage(raw_joint_->GetJointTranslation());
} }
float PrismaticJoint::GetJointSpeed() const float PrismaticJoint::GetJointSpeed() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetJointSpeed()); return GetWorld()->World2Stage(raw_joint_->GetJointSpeed());
} }
float PrismaticJoint::GetLowerLimit() const float PrismaticJoint::GetLowerLimit() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetLowerLimit()); return GetWorld()->World2Stage(raw_joint_->GetLowerLimit());
} }
float PrismaticJoint::GetUpperLimit() const float PrismaticJoint::GetUpperLimit() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetUpperLimit()); 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()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetLimits(GetWorld()->Stage2World(lower), GetWorld()->Stage2World(upper)); raw_joint_->SetLimits(GetWorld()->Stage2World(lower), GetWorld()->Stage2World(upper));
} }
// //
// PulleyJoint // PulleyJoint
// //
PulleyJoint::PulleyJoint() PulleyJoint::PulleyJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
PulleyJoint::PulleyJoint(World* world, b2PulleyJointDef* def) bool PulleyJoint::InitJoint(World* world, PulleyJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
PulleyJoint::PulleyJoint(World* world, PulleyJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2PulleyJointDef def; b2PulleyJointDef def;
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.ground_anchor_a), world->Stage2World(param.ground_anchor_b), def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.ground_anchor_a),
world->Stage2World(param.anchor_a), world->Stage2World(param.anchor_b), param.ratio); 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()); raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
Point PulleyJoint::GetGroundAnchorA() const Point PulleyJoint::GetGroundAnchorA() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetGroundAnchorA()); return GetWorld()->World2Stage(raw_joint_->GetGroundAnchorA());
} }
Point PulleyJoint::GetGroundAnchorB() const Point PulleyJoint::GetGroundAnchorB() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetGroundAnchorB()); return GetWorld()->World2Stage(raw_joint_->GetGroundAnchorB());
} }
float PulleyJoint::GetRatio() const float PulleyJoint::GetRatio() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return raw_joint_->GetRatio(); return raw_joint_->GetRatio();
} }
float PulleyJoint::GetLengthA() const float PulleyJoint::GetLengthA() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetLengthA()); return GetWorld()->World2Stage(raw_joint_->GetLengthA());
} }
float PulleyJoint::GetLengthB() const float PulleyJoint::GetLengthB() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetLengthB()); return GetWorld()->World2Stage(raw_joint_->GetLengthB());
} }
float PulleyJoint::GetCurrentLengthA() const float PulleyJoint::GetCurrentLengthA() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetCurrentLengthA()); return GetWorld()->World2Stage(raw_joint_->GetCurrentLengthA());
} }
float PulleyJoint::GetCurrentLengthB() const float PulleyJoint::GetCurrentLengthB() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetCurrentLengthB()); return GetWorld()->World2Stage(raw_joint_->GetCurrentLengthB());
} }
// //
// RevoluteJoint // RevoluteJoint
// //
RevoluteJoint::RevoluteJoint() RevoluteJoint::RevoluteJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
RevoluteJoint::RevoluteJoint(World* world, b2RevoluteJointDef* def) bool RevoluteJoint::InitJoint(World* world, RevoluteJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
RevoluteJoint::RevoluteJoint(World* world, RevoluteJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2RevoluteJointDef def; b2RevoluteJointDef def;
@ -458,72 +411,65 @@ namespace kiwano
def.maxMotorTorque = world->Stage2World(param.max_motor_torque); def.maxMotorTorque = world->Stage2World(param.max_motor_torque);
def.motorSpeed = math::Degree2Radian(param.motor_speed); def.motorSpeed = math::Degree2Radian(param.motor_speed);
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2RevoluteJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2RevoluteJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
float RevoluteJoint::GetJointAngle() const float RevoluteJoint::GetJointAngle() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return math::Radian2Degree(raw_joint_->GetJointAngle()); return math::Radian2Degree(raw_joint_->GetJointAngle());
} }
float RevoluteJoint::GetJointSpeed() const float RevoluteJoint::GetJointSpeed() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return math::Radian2Degree(raw_joint_->GetJointSpeed()); return math::Radian2Degree(raw_joint_->GetJointSpeed());
} }
float RevoluteJoint::GetLowerLimit() const float RevoluteJoint::GetLowerLimit() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return math::Radian2Degree(raw_joint_->GetLowerLimit()); return math::Radian2Degree(raw_joint_->GetLowerLimit());
} }
float RevoluteJoint::GetUpperLimit() const float RevoluteJoint::GetUpperLimit() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return math::Radian2Degree(raw_joint_->GetUpperLimit()); 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()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetLimits(math::Degree2Radian(lower), math::Degree2Radian(upper)); raw_joint_->SetLimits(math::Degree2Radian(lower), math::Degree2Radian(upper));
} }
void RevoluteJoint::SetMaxMotorTorque(float torque) void RevoluteJoint::SetMaxMotorTorque(float torque)
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetMaxMotorTorque(GetWorld()->Stage2World(torque)); raw_joint_->SetMaxMotorTorque(GetWorld()->Stage2World(torque));
} }
float RevoluteJoint::GetMaxMotorTorque() const float RevoluteJoint::GetMaxMotorTorque() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetMaxMotorTorque()); return GetWorld()->World2Stage(raw_joint_->GetMaxMotorTorque());
} }
// //
// RopeJoint // RopeJoint
// //
RopeJoint::RopeJoint() RopeJoint::RopeJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
RopeJoint::RopeJoint(World* world, b2RopeJointDef* def) bool RopeJoint::InitJoint(World* world, RopeJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
RopeJoint::RopeJoint(World* world, RopeJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2RopeJointDef def; b2RopeJointDef def;
@ -533,42 +479,35 @@ namespace kiwano
def.localAnchorB = world->Stage2World(param.local_anchor_b); def.localAnchorB = world->Stage2World(param.local_anchor_b);
def.maxLength = world->Stage2World(param.max_length); def.maxLength = world->Stage2World(param.max_length);
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint()); 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()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetMaxLength(GetWorld()->Stage2World(length)); raw_joint_->SetMaxLength(GetWorld()->Stage2World(length));
} }
float RopeJoint::GetMaxLength() const float RopeJoint::GetMaxLength() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetMaxLength()); return GetWorld()->World2Stage(raw_joint_->GetMaxLength());
} }
// //
// WeldJoint // WeldJoint
// //
WeldJoint::WeldJoint() WeldJoint::WeldJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
WeldJoint::WeldJoint(World* world, b2WeldJointDef* def) bool WeldJoint::InitJoint(World* world, WeldJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
WeldJoint::WeldJoint(World* world, WeldJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2WeldJointDef def; b2WeldJointDef def;
@ -576,89 +515,75 @@ namespace kiwano
def.frequencyHz = param.frequency_hz; def.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio; def.dampingRatio = param.damping_ratio;
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2WeldJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2WeldJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
//
// WheelJoint
//
// WheelJoint::WheelJoint()
// WheelJoint
//
WheelJoint::WheelJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
WheelJoint::WheelJoint(World* world, b2WheelJointDef* def) bool WheelJoint::InitJoint(World* world, WheelJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
WheelJoint::WheelJoint(World* world, WheelJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2WheelJointDef def; 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.enableMotor = param.enable_motor;
def.maxMotorTorque = world->Stage2World(param.max_motor_torque); def.maxMotorTorque = world->Stage2World(param.max_motor_torque);
def.motorSpeed = world->Stage2World(param.motor_speed); def.motorSpeed = world->Stage2World(param.motor_speed);
def.frequencyHz = param.frequency_hz; def.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio; def.dampingRatio = param.damping_ratio;
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2WheelJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2WheelJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
float WheelJoint::GetJointTranslation() const float WheelJoint::GetJointTranslation() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetJointTranslation()); return GetWorld()->World2Stage(raw_joint_->GetJointTranslation());
} }
float WheelJoint::GetJointLinearSpeed() const float WheelJoint::GetJointLinearSpeed() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetJointLinearSpeed()); return GetWorld()->World2Stage(raw_joint_->GetJointLinearSpeed());
} }
void WheelJoint::SetMaxMotorTorque(float torque) void WheelJoint::SetMaxMotorTorque(float torque)
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
raw_joint_->SetMaxMotorTorque(GetWorld()->Stage2World(torque)); raw_joint_->SetMaxMotorTorque(GetWorld()->Stage2World(torque));
} }
float WheelJoint::GetMaxMotorTorque() const float WheelJoint::GetMaxMotorTorque() const
{ {
KGE_ASSERT(raw_joint_ && GetWorld()); KGE_ASSERT(raw_joint_ && GetWorld());
return GetWorld()->World2Stage(raw_joint_->GetMaxMotorTorque()); return GetWorld()->World2Stage(raw_joint_->GetMaxMotorTorque());
} }
// //
// MouseJoint // MouseJoint
// //
MouseJoint::MouseJoint() MouseJoint::MouseJoint()
: Joint() : Joint()
, raw_joint_(nullptr) , raw_joint_(nullptr)
{ {
} }
MouseJoint::MouseJoint(World* world, b2MouseJointDef* def) bool MouseJoint::InitJoint(World* world, MouseJoint::Param const& param)
: Joint(world, def) {
, raw_joint_(nullptr)
{
}
MouseJoint::MouseJoint(World* world, MouseJoint::Param const& param)
: Joint()
, raw_joint_(nullptr)
{
KGE_ASSERT(param.body_a && param.body_b); KGE_ASSERT(param.body_a && param.body_b);
b2MouseJointDef def; b2MouseJointDef def;
@ -669,21 +594,22 @@ namespace kiwano
def.frequencyHz = param.frequency_hz; def.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio; def.dampingRatio = param.damping_ratio;
Init(world, &def); Joint::InitJoint(world, &def);
raw_joint_ = static_cast<b2MouseJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2MouseJoint*>(GetB2Joint());
} return raw_joint_ != nullptr;
}
void MouseJoint::SetMaxForce(float length) void MouseJoint::SetMaxForce(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxForce(length); raw_joint_->SetMaxForce(length);
} }
float MouseJoint::GetMaxForce() const float MouseJoint::GetMaxForce() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxForce(); return raw_joint_->GetMaxForce();
} }
} } // namespace physics
} } // namespace kiwano

File diff suppressed because it is too large Load Diff

View File

@ -23,114 +23,114 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
Shape::Shape() Shape::Shape()
: shape_(nullptr) : shape_(nullptr)
{ {
} }
Shape::Shape(b2Shape* shape) Shape::Shape(b2Shape* shape)
: shape_(shape) : shape_(shape)
{ {
} }
b2Shape* Shape::GetB2Shape() const b2Shape* Shape::GetB2Shape() const
{ {
return shape_; return shape_;
} }
void Shape::SetB2Shape(b2Shape* shape) void Shape::SetB2Shape(b2Shape* shape)
{ {
shape_ = shape; shape_ = shape;
} }
// //
// CircleShape // CircleShape
// //
CircleShape::CircleShape() CircleShape::CircleShape()
: Shape(&circle_) : Shape(&circle_)
, circle_() , circle_()
, radius_(0.f) , radius_(0.f)
{ {
} }
CircleShape::CircleShape(float radius, Point const& offset) CircleShape::CircleShape(float radius, Point const& offset)
: CircleShape() : CircleShape()
{ {
Set(radius, offset); Set(radius, offset);
} }
void CircleShape::Set(float radius, Point const& offset) void CircleShape::Set(float radius, Point const& offset)
{ {
radius_ = radius; radius_ = radius;
offset_ = offset; offset_ = offset;
} }
void CircleShape::FitWorld(World* world) void CircleShape::FitWorld(World* world)
{ {
KGE_ASSERT(world); KGE_ASSERT(world);
circle_.m_radius = world->Stage2World(radius_); circle_.m_radius = world->Stage2World(radius_);
circle_.m_p = world->Stage2World(offset_); circle_.m_p = world->Stage2World(offset_);
} }
// //
// BoxShape // BoxShape
// //
BoxShape::BoxShape() BoxShape::BoxShape()
: Shape(&polygon_) : Shape(&polygon_)
, polygon_() , polygon_()
, rotation_(0.f) , rotation_(0.f)
{ {
} }
BoxShape::BoxShape(Vec2 const& size, Point const& offset, float rotation) BoxShape::BoxShape(Vec2 const& size, Point const& offset, float rotation)
: BoxShape() : BoxShape()
{ {
Set(size, offset, rotation); 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; box_size_ = size;
offset_ = offset; offset_ = offset;
rotation_ = rotation; rotation_ = rotation;
} }
void BoxShape::FitWorld(World* world) void BoxShape::FitWorld(World* world)
{ {
KGE_ASSERT(world); KGE_ASSERT(world);
b2Vec2 box = world->Stage2World(box_size_); b2Vec2 box = world->Stage2World(box_size_);
b2Vec2 offset = world->Stage2World(offset_); b2Vec2 offset = world->Stage2World(offset_);
polygon_.SetAsBox(box.x / 2, box.y / 2, offset, rotation_); polygon_.SetAsBox(box.x / 2, box.y / 2, offset, rotation_);
} }
// //
// PolygonShape // PolygonShape
// //
PolygonShape::PolygonShape() PolygonShape::PolygonShape()
: Shape(&polygon_) : Shape(&polygon_)
, polygon_() , polygon_()
{ {
} }
PolygonShape::PolygonShape(Vector<Point> const& vertexs) PolygonShape::PolygonShape(Vector<Point> const& vertexs)
: PolygonShape() : PolygonShape()
{ {
Set(vertexs); Set(vertexs);
} }
void PolygonShape::Set(Vector<Point> const& vertexs) void PolygonShape::Set(Vector<Point> const& vertexs)
{ {
vertexs_ = vertexs; vertexs_ = vertexs;
} }
void PolygonShape::FitWorld(World* world) void PolygonShape::FitWorld(World* world)
{ {
KGE_ASSERT(world); KGE_ASSERT(world);
Vector<b2Vec2> b2vertexs; Vector<b2Vec2> b2vertexs;
@ -141,64 +141,64 @@ namespace kiwano
} }
polygon_.Set(&b2vertexs[0], static_cast<int32>(b2vertexs.size())); polygon_.Set(&b2vertexs[0], static_cast<int32>(b2vertexs.size()));
} }
// //
// EdgeShape // EdgeShape
// //
EdgeShape::EdgeShape() EdgeShape::EdgeShape()
: Shape(&edge_) : Shape(&edge_)
, edge_() , edge_()
{ {
} }
EdgeShape::EdgeShape(Point const& p1, Point const& p2) EdgeShape::EdgeShape(Point const& p1, Point const& p2)
: EdgeShape() : EdgeShape()
{ {
Set(p1, p2); 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_[0] = p1;
p_[1] = p2; p_[1] = p2;
} }
void EdgeShape::FitWorld(World* world) void EdgeShape::FitWorld(World* world)
{ {
KGE_ASSERT(world); KGE_ASSERT(world);
b2Vec2 p1 = world->Stage2World(p_[0]); b2Vec2 p1 = world->Stage2World(p_[0]);
b2Vec2 p2 = world->Stage2World(p_[1]); b2Vec2 p2 = world->Stage2World(p_[1]);
edge_.Set(p1, p2); edge_.Set(p1, p2);
} }
// //
// ChainShape // ChainShape
// //
ChainShape::ChainShape() ChainShape::ChainShape()
: Shape(&chain_) : Shape(&chain_)
, chain_() , chain_()
, loop_(false) , loop_(false)
{ {
} }
ChainShape::ChainShape(Vector<Point> const& vertexs, bool loop) ChainShape::ChainShape(Vector<Point> const& vertexs, bool loop)
: ChainShape() : ChainShape()
{ {
Set(vertexs, loop); Set(vertexs, loop);
} }
void ChainShape::Set(Vector<Point> const& vertexs, bool loop) void ChainShape::Set(Vector<Point> const& vertexs, bool loop)
{ {
vertexs_ = vertexs; vertexs_ = vertexs;
loop_ = loop; loop_ = loop;
} }
void ChainShape::FitWorld(World* world) void ChainShape::FitWorld(World* world)
{ {
KGE_ASSERT(world); KGE_ASSERT(world);
Vector<b2Vec2> b2vertexs; Vector<b2Vec2> b2vertexs;
@ -216,7 +216,7 @@ namespace kiwano
{ {
chain_.CreateChain(&b2vertexs[0], static_cast<int32>(b2vertexs.size())); chain_.CreateChain(&b2vertexs[0], static_cast<int32>(b2vertexs.size()));
} }
} }
} } // namespace physics
} } // namespace kiwano

View File

@ -23,140 +23,135 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
class World; class World;
class Fixture; class Fixture;
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief 形状基类 /// @brief 形状基类
class KGE_API Shape class KGE_API Shape
{ {
friend class Fixture; friend class Fixture;
public: public:
Shape(); Shape();
Shape(b2Shape* shape); Shape(b2Shape* shape);
b2Shape* GetB2Shape() const; b2Shape* GetB2Shape() const;
void SetB2Shape(b2Shape* shape); void SetB2Shape(b2Shape* shape);
private: private:
virtual void FitWorld(World* world) {} virtual void FitWorld(World* world) {}
private: private:
b2Shape* shape_; b2Shape* shape_;
}; };
/// \~chinese /// \~chinese
/// @brief 圆形形状 /// @brief 圆形形状
class KGE_API CircleShape class KGE_API CircleShape : public Shape
: public Shape {
{ public:
public:
CircleShape(); CircleShape();
CircleShape(float radius, Point const& offset = Point()); CircleShape(float radius, Point const& offset = Point());
void Set(float radius, Point const& offset = Point()); void Set(float radius, Point const& offset = Point());
private: private:
void FitWorld(World* world) override; void FitWorld(World* world) override;
private: private:
float radius_; float radius_;
Point offset_; Point offset_;
b2CircleShape circle_; b2CircleShape circle_;
}; };
/// \~chinese /// \~chinese
/// @brief 盒子形状 /// @brief 盒子形状
class KGE_API BoxShape class KGE_API BoxShape : public Shape
: public Shape {
{ public:
public:
BoxShape(); BoxShape();
BoxShape(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f); 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); void Set(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f);
private: private:
void FitWorld(World* world) override; void FitWorld(World* world) override;
private: private:
float rotation_; float rotation_;
Vec2 box_size_; Vec2 box_size_;
Point offset_; Point offset_;
b2PolygonShape polygon_; b2PolygonShape polygon_;
}; };
/// \~chinese /// \~chinese
/// @brief 多边形形状 /// @brief 多边形形状
class KGE_API PolygonShape class KGE_API PolygonShape : public Shape
: public Shape {
{ public:
public:
PolygonShape(); PolygonShape();
PolygonShape(Vector<Point> const& vertexs); PolygonShape(Vector<Point> const& vertexs);
void Set(Vector<Point> const& vertexs); void Set(Vector<Point> const& vertexs);
private: private:
void FitWorld(World* world) override; void FitWorld(World* world) override;
private: private:
Vector<Point> vertexs_; Vector<Point> vertexs_;
b2PolygonShape polygon_; b2PolygonShape polygon_;
}; };
/// \~chinese /// \~chinese
/// @brief 线段形状, 用于表示一条边 /// @brief 线段形状, 用于表示一条边
class KGE_API EdgeShape class KGE_API EdgeShape : public Shape
: public Shape {
{ public:
public:
EdgeShape(); EdgeShape();
EdgeShape(Point const& p1, Point const& p2); EdgeShape(Point const& p1, Point const& p2);
void Set(Point const& p1, Point const& p2); void Set(Point const& p1, Point const& p2);
private: private:
void FitWorld(World* world) override; void FitWorld(World* world) override;
private: private:
Point p_[2]; Point p_[2];
b2EdgeShape edge_; b2EdgeShape edge_;
}; };
/// \~chinese /// \~chinese
/// @brief 链式形状 /// @brief 链式形状
class KGE_API ChainShape class KGE_API ChainShape : public Shape
: public Shape {
{ public:
public:
ChainShape(); ChainShape();
ChainShape(Vector<Point> const& vertexs, bool loop = false); ChainShape(Vector<Point> const& vertexs, bool loop = false);
void Set(Vector<Point> const& vertexs, bool loop = false); void Set(Vector<Point> const& vertexs, bool loop = false);
private: private:
void FitWorld(World* world) override; void FitWorld(World* world) override;
private: private:
bool loop_; bool loop_;
Vector<Point> vertexs_; Vector<Point> vertexs_;
b2ChainShape chain_; b2ChainShape chain_;
}; };
/** @} */ /** @} */
} } // namespace physics
} } // namespace kiwano

View File

@ -19,22 +19,23 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "World.h" #include "World.h"
#include <kiwano-physics/ContactEvent.h> #include <kiwano-physics/ContactEvent.h>
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
namespace namespace
{ {
const float default_global_scale = 100.f; // 100 pixels per meters const float default_global_scale = 100.f; // 100 pixels per meters
} }
class World::DestructionListener : public b2DestructionListener class World::DestructionListener : public b2DestructionListener
{ {
World* world_; World* world_;
public: public:
DestructionListener(World* world) DestructionListener(World* world)
: 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_; World* world_;
public: public:
ContactListener(World* world) ContactListener(World* world)
: world_(world) : world_(world)
{ {
@ -67,21 +64,29 @@ namespace kiwano
void BeginContact(b2Contact* contact) override void BeginContact(b2Contact* contact) override
{ {
ContactBeginEvent evt(contact); ContactBeginEventPtr evt = new ContactBeginEvent(contact);
world_->Dispatch(evt); world_->DispatchEvent(evt.get());
} }
void EndContact(b2Contact* contact) override void EndContact(b2Contact* contact) override
{ {
ContactEndEvent evt(contact); ContactEndEventPtr evt = new ContactEndEvent(contact);
world_->Dispatch(evt); world_->DispatchEvent(evt.get());
} }
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override { KGE_NOT_USED(contact); KGE_NOT_USED(oldManifold); } void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override { KGE_NOT_USED(contact); KGE_NOT_USED(impulse); } {
}; 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)) : world_(b2Vec2(0, 10.0f))
, vel_iter_(6) , vel_iter_(6)
, pos_iter_(2) , pos_iter_(2)
@ -89,16 +94,16 @@ namespace kiwano
, destruction_listener_(nullptr) , destruction_listener_(nullptr)
, contact_listener_(nullptr) , contact_listener_(nullptr)
, removing_joint_(false) , removing_joint_(false)
{ {
destruction_listener_ = new DestructionListener(this); destruction_listener_ = new DestructionListener(this);
world_.SetDestructionListener(destruction_listener_); world_.SetDestructionListener(destruction_listener_);
contact_listener_ = new ContactListener(this); contact_listener_ = new ContactListener(this);
world_.SetContactListener(contact_listener_); world_.SetContactListener(contact_listener_);
} }
World::~World() World::~World()
{ {
world_.SetDestructionListener(nullptr); world_.SetDestructionListener(nullptr);
if (destruction_listener_) if (destruction_listener_)
{ {
@ -117,18 +122,18 @@ namespace kiwano
RemoveAllChildren(); RemoveAllChildren();
RemoveAllBodies(); RemoveAllBodies();
RemoveAllJoints(); RemoveAllJoints();
} }
void World::RemoveBody(Body* body) void World::RemoveBody(Body* body)
{ {
if (body && body->GetB2Body()) if (body && body->GetB2Body())
{ {
world_.DestroyBody(body->GetB2Body()); world_.DestroyBody(body->GetB2Body());
} }
} }
void World::RemoveAllBodies() void World::RemoveAllBodies()
{ {
if (world_.GetBodyCount()) if (world_.GetBodyCount())
{ {
b2Body* body = world_.GetBodyList(); b2Body* body = world_.GetBodyList();
@ -139,18 +144,18 @@ namespace kiwano
body = next; body = next;
} }
} }
} }
void World::AddJoint(Joint* joint) void World::AddJoint(Joint* joint)
{ {
if (joint) if (joint)
{ {
joints_.push_back(joint); joints_.push_back(joint);
} }
} }
void World::RemoveJoint(Joint* joint) void World::RemoveJoint(Joint* joint)
{ {
if (joint) if (joint)
{ {
auto iter = std::find(joints_.begin(), joints_.end(), 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()) if (world_.GetJointCount())
{ {
removing_joint_ = true; removing_joint_ = true;
@ -185,53 +190,50 @@ namespace kiwano
removing_joint_ = false; removing_joint_ = false;
} }
joints_.clear(); joints_.clear();
} }
void World::JointRemoved(b2Joint* joint) void World::JointRemoved(b2Joint* joint)
{ {
if (!removing_joint_ && joint) if (!removing_joint_ && joint)
{ {
auto iter = std::find_if( auto iter = std::find_if(joints_.begin(), joints_.end(),
joints_.begin(), [joint](Joint* j) -> bool { return j->GetB2Joint() == joint; });
joints_.end(),
[joint](Joint* j) -> bool { return j->GetB2Joint() == joint; }
);
if (iter != joints_.end()) if (iter != joints_.end())
{ {
joints_.erase(iter); joints_.erase(iter);
} }
} }
} }
b2World* World::GetB2World() b2World* World::GetB2World()
{ {
return &world_; return &world_;
} }
const b2World* World::GetB2World() const const b2World* World::GetB2World() const
{ {
return &world_; return &world_;
} }
Vec2 World::GetGravity() const Vec2 World::GetGravity() const
{ {
b2Vec2 g = world_.GetGravity(); b2Vec2 g = world_.GetGravity();
return Vec2(g.x, g.y); return Vec2(g.x, g.y);
} }
void World::SetGravity(Vec2 gravity) void World::SetGravity(Vec2 gravity)
{ {
world_.SetGravity(b2Vec2(gravity.x, gravity.y)); world_.SetGravity(b2Vec2(gravity.x, gravity.y));
} }
ContactList World::GetContactList() ContactList World::GetContactList()
{ {
return ContactList(Contact(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_); world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
b2Body* b2body = world_.GetBodyList(); b2Body* b2body = world_.GetBodyList();
@ -247,7 +249,7 @@ namespace kiwano
} }
Stage::Update(dt); Stage::Update(dt);
}
}
} }
} // namespace physics
} // namespace kiwano

View File

@ -24,31 +24,30 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
KGE_DECLARE_SMART_PTR(World); KGE_DECLARE_SMART_PTR(World);
/** /**
* \~chinese * \~chinese
* \defgroup Physics * \defgroup Physics
*/ */
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API World class KGE_API World : public Stage
: public Stage {
{
friend class Body; friend class Body;
friend class Joint; friend class Joint;
public: public:
World(); World();
virtual ~World(); virtual ~World();
@ -107,7 +106,7 @@ namespace kiwano
const b2World* GetB2World() const; const b2World* GetB2World() const;
private: private:
/// \~chinese /// \~chinese
/// @brief 移除物体 /// @brief 移除物体
void RemoveBody(Body* body); void RemoveBody(Body* body);
@ -132,10 +131,10 @@ namespace kiwano
/// @brief 关节被移除 /// @brief 关节被移除
void JointRemoved(b2Joint* joint); void JointRemoved(b2Joint* joint);
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
private: private:
b2World world_; b2World world_;
int vel_iter_; int vel_iter_;
int pos_iter_; int pos_iter_;
@ -151,49 +150,48 @@ namespace kiwano
bool removing_joint_; bool removing_joint_;
Vector<Joint*> joints_; Vector<Joint*> joints_;
}; };
/** @} */
/** @} */ inline float World::GetGlobalScale() const
{
inline float World::GetGlobalScale() const
{
return global_scale_; 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

View File

@ -26,9 +26,15 @@
namespace kiwano namespace kiwano
{ {
namespace physics namespace physics
{ {
inline b2Vec2 Stage2World(const Vec2& pos) { return b2Vec2(pos.x, pos.y); } inline b2Vec2 Stage2World(const Vec2& pos)
inline Vec2 World2Stage(const b2Vec2& pos) { return Vec2(pos.x, pos.y); } {
} return b2Vec2(pos.x, pos.y);
} }
inline Vec2 World2Stage(const b2Vec2& pos)
{
return Vec2(pos.x, pos.y);
}
} // namespace physics
} // namespace kiwano

View File

@ -20,10 +20,10 @@
#pragma once #pragma once
#include <kiwano-physics/Shape.h> #include <kiwano-physics/Body.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Contact.h> #include <kiwano-physics/Contact.h>
#include <kiwano-physics/ContactEvent.h> #include <kiwano-physics/ContactEvent.h>
#include <kiwano-physics/Body.h> #include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Joint.h> #include <kiwano-physics/Joint.h>
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/World.h> #include <kiwano-physics/World.h>

View File

@ -21,23 +21,23 @@
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/Stage.h> #include <kiwano/2d/Stage.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
namespace namespace
{ {
float default_anchor_x = 0.f; float default_anchor_x = 0.f;
float default_anchor_y = 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_x = anchor_x;
default_anchor_y = anchor_y; default_anchor_y = anchor_y;
} }
Actor::Actor() Actor::Actor()
: visible_(true) : visible_(true)
, visible_in_rt_(true) , visible_in_rt_(true)
, update_pausing_(false) , update_pausing_(false)
@ -57,11 +57,13 @@ namespace kiwano
, opacity_(1.f) , opacity_(1.f)
, displayed_opacity_(1.f) , displayed_opacity_(1.f)
, anchor_(default_anchor_x, default_anchor_y) , anchor_(default_anchor_x, default_anchor_y)
{ {
} }
void Actor::Update(Duration dt) Actor::~Actor() {}
{
void Actor::Update(Duration dt)
{
UpdateActions(this, dt); UpdateActions(this, dt);
UpdateTimers(dt); UpdateTimers(dt);
@ -82,10 +84,10 @@ namespace kiwano
child->Update(dt); child->Update(dt);
} }
} }
} }
void Actor::Render(RenderTarget* rt) void Actor::Render(RenderContext& ctx)
{ {
if (!visible_) if (!visible_)
return; return;
@ -93,10 +95,10 @@ namespace kiwano
if (children_.empty()) if (children_.empty())
{ {
if (CheckVisibilty(rt)) if (CheckVisibility(ctx))
{ {
PrepareToRender(rt); PrepareToRender(ctx);
OnRender(rt); OnRender(ctx);
} }
} }
else else
@ -108,53 +110,53 @@ namespace kiwano
if (child->GetZOrder() >= 0) if (child->GetZOrder() >= 0)
break; break;
child->Render(rt); child->Render(ctx);
child = child->next_item().get(); child = child->next_item().get();
} }
if (CheckVisibilty(rt)) if (CheckVisibility(ctx))
{ {
PrepareToRender(rt); PrepareToRender(ctx);
OnRender(rt); OnRender(ctx);
} }
while (child) while (child)
{ {
child->Render(rt); child->Render(ctx);
child = child->next_item().get(); child = child->next_item().get();
} }
} }
} }
void Actor::PrepareToRender(RenderTarget* rt) void Actor::PrepareToRender(RenderContext& ctx)
{ {
rt->SetTransform(transform_matrix_); ctx.SetTransform(transform_matrix_);
rt->SetBrushOpacity(GetDisplayedOpacity()); ctx.SetBrushOpacity(GetDisplayedOpacity());
} }
void Actor::RenderBorder(RenderTarget* rt) void Actor::RenderBorder(RenderContext& ctx)
{ {
if (show_border_ && !size_.IsOrigin()) if (show_border_ && !size_.IsOrigin())
{ {
Rect bounds = GetBounds(); Rect bounds = GetBounds();
rt->SetTransform(transform_matrix_); ctx.SetTransform(transform_matrix_);
rt->SetCurrentBrush(GetStage()->GetBorderFillBrush()); ctx.SetCurrentBrush(GetStage()->GetBorderFillBrush());
rt->FillRectangle(bounds); ctx.FillRectangle(bounds);
rt->SetCurrentBrush(GetStage()->GetBorderStrokeBrush()); ctx.SetCurrentBrush(GetStage()->GetBorderStrokeBrush());
rt->DrawRectangle(bounds, 2.f); ctx.DrawRectangle(bounds, 2.f);
} }
for (auto child = children_.first_item(); child; child = child->next_item()) 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_) if (dirty_visibility_)
{ {
dirty_visibility_ = false; dirty_visibility_ = false;
@ -165,93 +167,99 @@ namespace kiwano
} }
else else
{ {
visible_in_rt_ = rt->CheckVisibility(GetBounds(), GetTransformMatrix()); visible_in_rt_ = ctx.CheckVisibility(GetBounds(), GetTransformMatrix());
} }
} }
return visible_in_rt_; return visible_in_rt_;
} }
void Actor::Dispatch(Event& evt) bool Actor::DispatchEvent(Event* evt)
{ {
if (!visible_) if (!visible_)
return; return true;
ActorPtr prev; // Dispatch to children those are greater than 0 in Z-Order
for (auto child = children_.last_item(); child; child = prev) Actor* child = children_.last_item().get();
while (child)
{ {
prev = child->prev_item(); if (child->GetZOrder() < 0)
child->Dispatch(evt); 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 (responsible_)
{ {
if (evt.IsType<MouseMoveEvent>()) if (evt->IsType<MouseMoveEvent>())
{ {
auto& mouse_evt = evt.SafeCast<MouseMoveEvent>(); auto mouse_evt = dynamic_cast<MouseMoveEvent*>(evt);
if (!mouse_evt.target && ContainsPoint(mouse_evt.pos)) bool contains = ContainsPoint(mouse_evt->pos);
{ if (!hover_ && contains)
mouse_evt.target = this;
if (!hover_)
{ {
hover_ = true; hover_ = true;
MouseHoverEvent hover; MouseHoverEventPtr hover = new MouseHoverEvent;
hover.pos = mouse_evt.pos; hover->pos = mouse_evt->pos;
hover.left_btn_down = mouse_evt.left_btn_down; EventDispatcher::DispatchEvent(hover.get());
hover.right_btn_down = mouse_evt.right_btn_down;
hover.target = this;
EventDispatcher::Dispatch(hover);
} }
} else if (hover_ && !contains)
else if (hover_)
{ {
hover_ = false; hover_ = false;
pressed_ = false; pressed_ = false;
MouseOutEvent out; MouseOutEventPtr out = new MouseOutEvent;
out.pos = mouse_evt.pos; out->pos = mouse_evt->pos;
out.left_btn_down = mouse_evt.left_btn_down; EventDispatcher::DispatchEvent(out.get());
out.right_btn_down = mouse_evt.right_btn_down;
out.target = this;
EventDispatcher::Dispatch(out);
} }
} }
if (evt.IsType<MouseDownEvent>() && hover_) if (evt->IsType<MouseDownEvent>() && hover_)
{ {
pressed_ = true; pressed_ = true;
evt.SafeCast<MouseDownEvent>().target = this;
} }
if (evt.IsType<MouseUpEvent>() && pressed_) if (evt->IsType<MouseUpEvent>() && pressed_)
{ {
pressed_ = false; pressed_ = false;
auto mouse_up_evt = evt.SafeCast<MouseUpEvent>(); auto mouse_up_evt = dynamic_cast<MouseUpEvent*>(evt);
mouse_up_evt.target = this;
MouseClickEvent click; MouseClickEventPtr click = new MouseClickEvent;
click.pos = mouse_up_evt.pos; click->pos = mouse_up_evt->pos;
click.left_btn_down = mouse_up_evt.left_btn_down; click->button = mouse_up_evt->button;
click.right_btn_down = mouse_up_evt.right_btn_down; EventDispatcher::DispatchEvent(click.get());
click.target = this;
click.button = mouse_up_evt.button;
EventDispatcher::Dispatch(click);
} }
} }
}
EventDispatcher::Dispatch(evt); Matrix3x2 const& Actor::GetTransformMatrix() const
} {
Matrix3x2 const & Actor::GetTransformMatrix() const
{
UpdateTransform(); UpdateTransform();
return transform_matrix_; return transform_matrix_;
} }
Matrix3x2 const & Actor::GetTransformInverseMatrix() const Matrix3x2 const& Actor::GetTransformInverseMatrix() const
{ {
UpdateTransform(); UpdateTransform();
if (dirty_transform_inverse_) if (dirty_transform_inverse_)
{ {
@ -259,10 +267,10 @@ namespace kiwano
dirty_transform_inverse_ = false; dirty_transform_inverse_ = false;
} }
return transform_matrix_inverse_; return transform_matrix_inverse_;
} }
void Actor::UpdateTransform() const void Actor::UpdateTransform() const
{ {
if (!dirty_transform_) if (!dirty_transform_)
return; return;
@ -290,10 +298,10 @@ namespace kiwano
// update children's transform // update children's transform
for (auto child = children_.first_item().get(); child; child = child->next_item().get()) for (auto child = children_.first_item().get(); child; child = child->next_item().get())
child->dirty_transform_ = true; child->dirty_transform_ = true;
} }
void Actor::UpdateOpacity() void Actor::UpdateOpacity()
{ {
if (parent_ && parent_->IsCascadeOpacityEnabled()) if (parent_ && parent_->IsCascadeOpacityEnabled())
{ {
displayed_opacity_ = opacity_ * parent_->displayed_opacity_; displayed_opacity_ = opacity_ * parent_->displayed_opacity_;
@ -307,10 +315,10 @@ namespace kiwano
{ {
child->UpdateOpacity(); child->UpdateOpacity();
} }
} }
void Actor::SetStage(Stage* stage) void Actor::SetStage(Stage* stage)
{ {
if (stage_ != stage) if (stage_ != stage)
{ {
stage_ = stage; stage_ = stage;
@ -319,10 +327,10 @@ namespace kiwano
child->stage_ = stage; child->stage_ = stage;
} }
} }
} }
void Actor::Reorder() void Actor::Reorder()
{ {
if (parent_) if (parent_)
{ {
ActorPtr me = this; ActorPtr me = this;
@ -351,140 +359,140 @@ namespace kiwano
parent_->children_.push_front(me); parent_->children_.push_front(me);
} }
} }
} }
void Actor::SetZOrder(int zorder) void Actor::SetZOrder(int zorder)
{ {
if (z_order_ != zorder) if (z_order_ != zorder)
{ {
z_order_ = zorder; z_order_ = zorder;
Reorder(); Reorder();
} }
} }
void Actor::SetOpacity(float opacity) void Actor::SetOpacity(float opacity)
{ {
if (opacity_ == opacity) if (opacity_ == opacity)
return; return;
displayed_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f); displayed_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f);
UpdateOpacity(); UpdateOpacity();
} }
void Actor::SetCascadeOpacityEnabled(bool enabled) void Actor::SetCascadeOpacityEnabled(bool enabled)
{ {
if (cascade_opacity_ == enabled) if (cascade_opacity_ == enabled)
return; return;
cascade_opacity_ = enabled; cascade_opacity_ = enabled;
UpdateOpacity(); UpdateOpacity();
} }
void Actor::SetAnchor(Vec2 const& anchor) void Actor::SetAnchor(Vec2 const& anchor)
{ {
if (anchor_ == anchor) if (anchor_ == anchor)
return; return;
anchor_ = anchor; anchor_ = anchor;
dirty_transform_ = true; dirty_transform_ = true;
} }
void Actor::SetWidth(float width) void Actor::SetWidth(float width)
{ {
SetSize(Size{ width, size_.y }); SetSize(Size{ width, size_.y });
} }
void Actor::SetHeight(float height) void Actor::SetHeight(float height)
{ {
SetSize(Size{ size_.x, height }); SetSize(Size{ size_.x, height });
} }
void Actor::SetSize(Size const& size) void Actor::SetSize(Size const& size)
{ {
if (size_ == size) if (size_ == size)
return; return;
size_ = size; size_ = size;
dirty_transform_ = true; dirty_transform_ = true;
} }
void Actor::SetTransform(Transform const& transform) void Actor::SetTransform(Transform const& transform)
{ {
transform_ = transform; transform_ = transform;
dirty_transform_ = true; dirty_transform_ = true;
is_fast_transform_ = false; is_fast_transform_ = false;
} }
void Actor::SetVisible(bool val) void Actor::SetVisible(bool val)
{ {
visible_ = val; visible_ = val;
} }
void Actor::SetName(String const& name) void Actor::SetName(String const& name)
{ {
if (!IsName(name)) if (!IsName(name))
{ {
ObjectBase::SetName(name); ObjectBase::SetName(name);
hash_name_ = std::hash<String>{}(name); hash_name_ = std::hash<String>{}(name);
} }
} }
void Actor::SetPosition(const Point & pos) void Actor::SetPosition(const Point& pos)
{ {
if (transform_.position == pos) if (transform_.position == pos)
return; return;
transform_.position = pos; transform_.position = pos;
dirty_transform_ = true; dirty_transform_ = true;
} }
void Actor::SetPositionX(float x) void Actor::SetPositionX(float x)
{ {
SetPosition(Point{ x, transform_.position.y }); SetPosition(Point{ x, transform_.position.y });
} }
void Actor::SetPositionY(float y) void Actor::SetPositionY(float y)
{ {
SetPosition(Point{ transform_.position.x, 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 }); 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) if (transform_.scale == scale)
return; return;
transform_.scale = scale; transform_.scale = scale;
dirty_transform_ = true; dirty_transform_ = true;
is_fast_transform_ = false; is_fast_transform_ = false;
} }
void Actor::SetSkew(Vec2 const& skew) void Actor::SetSkew(Vec2 const& skew)
{ {
if (transform_.skew == skew) if (transform_.skew == skew)
return; return;
transform_.skew = skew; transform_.skew = skew;
dirty_transform_ = true; dirty_transform_ = true;
is_fast_transform_ = false; is_fast_transform_ = false;
} }
void Actor::SetRotation(float angle) void Actor::SetRotation(float angle)
{ {
if (transform_.rotation == angle) if (transform_.rotation == angle)
return; return;
transform_.rotation = angle; transform_.rotation = angle;
dirty_transform_ = true; dirty_transform_ = true;
is_fast_transform_ = false; 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"); KGE_ASSERT(child && "Actor::AddChild failed, NULL pointer exception");
if (child) if (child)
@ -513,33 +521,33 @@ namespace kiwano
child->Reorder(); child->Reorder();
child->UpdateOpacity(); child->UpdateOpacity();
} }
} }
void Actor::AddChild(ActorPtr child, int zorder) void Actor::AddChild(ActorPtr child, int zorder)
{ {
AddChild(child.get()); AddChild(child.get());
} }
void Actor::AddChildren(Vector<ActorPtr> const& children) void Actor::AddChildren(Vector<ActorPtr> const& children)
{ {
for (const auto& actor : children) for (const auto& actor : children)
{ {
this->AddChild(actor); this->AddChild(actor);
} }
} }
Rect Actor::GetBounds() const Rect Actor::GetBounds() const
{ {
return Rect{ Point{}, size_ }; return Rect{ Point{}, size_ };
} }
Rect Actor::GetBoundingBox() const Rect Actor::GetBoundingBox() const
{ {
return GetTransformMatrix().Transform(GetBounds()); return GetTransformMatrix().Transform(GetBounds());
} }
Vector<ActorPtr> Actor::GetChildren(String const& name) const Vector<ActorPtr> Actor::GetChildren(String const& name) const
{ {
Vector<ActorPtr> children; Vector<ActorPtr> children;
size_t hash_code = std::hash<String>{}(name); size_t hash_code = std::hash<String>{}(name);
@ -551,10 +559,10 @@ namespace kiwano
} }
} }
return children; return children;
} }
Actor* Actor::GetChild(String const& name) const Actor* Actor::GetChild(String const& name) const
{ {
size_t hash_code = std::hash<String>{}(name); size_t hash_code = std::hash<String>{}(name);
for (auto child = children_.first_item().get(); child; child = child->next_item().get()) for (auto child = children_.first_item().get(); child; child = child->next_item().get())
@ -565,33 +573,33 @@ namespace kiwano
} }
} }
return nullptr; return nullptr;
} }
Actor::Children& Actor::GetAllChildren() Actor::Children& Actor::GetAllChildren()
{ {
return children_; return children_;
} }
Actor::Children const & Actor::GetAllChildren() const Actor::Children const& Actor::GetAllChildren() const
{ {
return children_; return children_;
} }
void Actor::RemoveFromParent() void Actor::RemoveFromParent()
{ {
if (parent_) if (parent_)
{ {
parent_->RemoveChild(this); parent_->RemoveChild(this);
} }
} }
void Actor::RemoveChild(ActorPtr child) void Actor::RemoveChild(ActorPtr child)
{ {
RemoveChild(child.get()); RemoveChild(child.get());
} }
void Actor::RemoveChild(Actor * child) void Actor::RemoveChild(Actor* child)
{ {
KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception"); KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception");
if (children_.empty()) if (children_.empty())
@ -600,13 +608,14 @@ namespace kiwano
if (child) if (child)
{ {
child->parent_ = nullptr; child->parent_ = nullptr;
if (child->stage_) child->SetStage(nullptr); if (child->stage_)
child->SetStage(nullptr);
children_.remove(ActorPtr(child)); children_.remove(ActorPtr(child));
} }
} }
void Actor::RemoveChildren(String const& child_name) void Actor::RemoveChildren(String const& child_name)
{ {
if (children_.empty()) if (children_.empty())
{ {
return; return;
@ -624,25 +633,25 @@ namespace kiwano
RemoveChild(child); RemoveChild(child);
} }
} }
} }
void Actor::RemoveAllChildren() void Actor::RemoveAllChildren()
{ {
children_.clear(); children_.clear();
} }
void Actor::SetResponsible(bool enable) void Actor::SetResponsible(bool enable)
{ {
responsible_ = 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) if (size_.x == 0.f || size_.y == 0.f)
return false; return false;
Point local = GetTransformInverseMatrix().Transform(point); Point local = GetTransformInverseMatrix().Transform(point);
return GetBounds().ContainsPoint(local); return GetBounds().ContainsPoint(local);
}
} }
} // namespace kiwano

View File

@ -19,50 +19,50 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #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/Transform.h>
#include <kiwano/2d/action/ActionManager.h> #include <kiwano/2d/action/ActionManager.h>
#include <kiwano/core/TimerManager.h>
#include <kiwano/core/EventDispatcher.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 namespace kiwano
{ {
class Stage; class Stage;
class Director; class Director;
class RenderTarget; class RenderContext;
KGE_DECLARE_SMART_PTR(Actor); KGE_DECLARE_SMART_PTR(Actor);
/** /**
* \~chinese * \~chinese
* \defgroup Actors * \defgroup Actors
*/ */
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
*
*/ */
class KGE_API Actor class KGE_API Actor
: public ObjectBase : public virtual ObjectBase
, public TimerManager , public TimerManager
, public ActionManager , public ActionManager
, public EventDispatcher , public EventDispatcher
, public IntrusiveListItem<ActorPtr> , protected IntrusiveListItem<ActorPtr>
{ {
friend class Director; friend class Director;
friend class Transition; friend class Transition;
friend IntrusiveList<ActorPtr>; friend IntrusiveList<ActorPtr>;
public: public:
/// \~chinese /// \~chinese
/// @brief 子成员列表 /// @brief 子成员列表
using Children = IntrusiveList<ActorPtr>; using Children = IntrusiveList<ActorPtr>;
@ -73,6 +73,8 @@ namespace kiwano
Actor(); Actor();
virtual ~Actor();
/// \~chinese /// \~chinese
/// @brief 更新角色 /// @brief 更新角色
/// @details 每帧画面刷新前调用该函数,重载该函数以实现角色的更新处理 /// @details 每帧画面刷新前调用该函数,重载该函数以实现角色的更新处理
@ -81,9 +83,10 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 渲染角色 /// @brief 渲染角色
/// @details 每帧画面刷新时调用该函数,默认不进行渲染,重载该函数以实现具体渲染过程 /// @details
/// @param rt 渲染目标 /// 每帧画面刷新时调用该函数,默认不进行渲染,重载该函数以实现具体渲染过程
virtual void OnRender(RenderTarget* rt); /// @param ctx 渲染上下文
virtual void OnRender(RenderContext& ctx);
/// \~chinese /// \~chinese
/// @brief 获取显示状态 /// @brief 获取显示状态
@ -117,34 +120,6 @@ namespace kiwano
/// @brief 获取 y 坐标 /// @brief 获取 y 坐标
float GetPositionY() const; 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 /// \~chinese
/// @brief 获取宽度 /// @brief 获取宽度
float GetWidth() const; float GetWidth() const;
@ -189,6 +164,34 @@ namespace kiwano
/// @brief 获取显示透明度 /// @brief 获取显示透明度
float GetDisplayedOpacity() const; 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 /// \~chinese
/// @brief 获取变换 /// @brief 获取变换
Transform GetTransform() const; Transform GetTransform() const;
@ -362,10 +365,6 @@ namespace kiwano
/// @brief 从父角色移除 /// @brief 从父角色移除
void RemoveFromParent(); void RemoveFromParent();
/// \~chinese
/// @brief 判断点是否在角色内
virtual bool ContainsPoint(const Point& point) const;
/// \~chinese /// \~chinese
/// @brief 暂停角色更新 /// @brief 暂停角色更新
void PauseUpdating(); void PauseUpdating();
@ -386,38 +385,44 @@ namespace kiwano
/// @brief 获取更新时的回调函数 /// @brief 获取更新时的回调函数
UpdateCallback GetCallbackOnUpdate() const; UpdateCallback GetCallbackOnUpdate() const;
/// \~chinese
/// @brief 判断点是否在角色内
virtual bool ContainsPoint(const Point& point) const;
/// \~chinese /// \~chinese
/// @brief 渲染角色边界 /// @brief 渲染角色边界
void ShowBorder(bool show); void ShowBorder(bool show);
/// \~chinese /// \~chinese
/// @brief 分发事件 /// @brief 分发事件
void Dispatch(Event& evt) override; /// @param evt 事件
/// @return 是否继续分发该事件
virtual bool DispatchEvent(Event* evt);
/// \~chinese /// \~chinese
/// @brief 设置默认锚点 /// @brief 设置默认锚点
static void SetDefaultAnchor(float anchor_x, float anchor_y); static void SetDefaultAnchor(float anchor_x, float anchor_y);
protected: protected:
/// \~chinese /// \~chinese
/// @brief 更新自身和所有子角色 /// @brief 更新自身和所有子角色
virtual void Update(Duration dt); virtual void Update(Duration dt);
/// \~chinese /// \~chinese
/// @brief 渲染自身和所有子角色 /// @brief 渲染自身和所有子角色
virtual void Render(RenderTarget* rt); virtual void Render(RenderContext& ctx);
/// \~chinese /// \~chinese
/// @brief 绘制自身和所有子角色的边界 /// @brief 绘制自身和所有子角色的边界
virtual void RenderBorder(RenderTarget* rt); virtual void RenderBorder(RenderContext& ctx);
/// \~chinese /// \~chinese
/// @brief 检查是否在渲染目标的视区内 /// @brief 检查是否在渲染上下文的视区内
virtual bool CheckVisibilty(RenderTarget* rt) const; virtual bool CheckVisibility(RenderContext& ctx) const;
/// \~chinese /// \~chinese
/// @brief 渲染前初始化渲染目标状态,仅当 CheckVisibilty 返回真时调用该函数 /// @brief 渲染前初始化渲染上下文状态,仅当 CheckVisibility 返回真时调用该函数
virtual void PrepareToRender(RenderTarget* rt); virtual void PrepareToRender(RenderContext& ctx);
/// \~chinese /// \~chinese
/// @brief 更新自己的二维变换,并通知所有子角色 /// @brief 更新自己的二维变换,并通知所有子角色
@ -435,7 +440,11 @@ namespace kiwano
/// @brief 设置节点所在舞台 /// @brief 设置节点所在舞台
void SetStage(Stage* stage); void SetStage(Stage* stage);
private: /// \~chinese
/// @brief 处理事件
void HandleEvent(Event* evt);
private:
bool visible_; bool visible_;
bool update_pausing_; bool update_pausing_;
bool cascade_opacity_; bool cascade_opacity_;
@ -462,224 +471,222 @@ namespace kiwano
mutable bool dirty_transform_inverse_; mutable bool dirty_transform_inverse_;
mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_;
mutable Matrix3x2 transform_matrix_inverse_; mutable Matrix3x2 transform_matrix_inverse_;
}; };
/** @} */ /** @} */
inline void Actor::OnUpdate(Duration dt)
inline void Actor::OnUpdate(Duration dt) {
{
KGE_NOT_USED(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

207
src/kiwano/2d/Button.cpp Normal file
View File

@ -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

164
src/kiwano/2d/Button.h Normal file
View File

@ -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

View File

@ -20,213 +20,176 @@
#include <kiwano/2d/Canvas.h> #include <kiwano/2d/Canvas.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
Canvas::Canvas() Canvas::Canvas()
: cache_expired_(false) : cache_expired_(false)
, stroke_width_(1.0f) , stroke_width_(1.0f)
, stroke_style_(StrokeStyle::Miter) , stroke_style_()
{ {
} }
Canvas::~Canvas() Canvas::~Canvas() {}
{
}
void Canvas::BeginDraw() void Canvas::BeginDraw()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->BeginDraw(); ctx_->BeginDraw();
} }
void Canvas::EndDraw() void Canvas::EndDraw()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->EndDraw(); ctx_->EndDraw();
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::OnRender(RenderTarget* rt) void Canvas::OnRender(RenderContext& ctx)
{ {
UpdateCache(); UpdateCache();
if (texture_cached_ && texture_cached_->IsValid()) if (texture_cached_ && texture_cached_->IsValid())
{ {
PrepareToRender(rt); PrepareToRender(ctx);
Rect bitmap_rect(0.f, 0.f, texture_cached_->GetWidth(), texture_cached_->GetHeight()); 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(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(brush); ctx_->SetCurrentBrush(brush);
} }
float Canvas::GetStrokeWidth() const float Canvas::GetStrokeWidth() const
{ {
return stroke_width_; return stroke_width_;
} }
void Canvas::SetBrushTransform(Transform const& transform) void Canvas::SetBrushTransform(Transform const& transform)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetTransform(transform.ToMatrix()); ctx_->SetTransform(transform.ToMatrix());
} }
void Canvas::SetBrushTransform(Matrix3x2 const & transform) void Canvas::SetBrushTransform(Matrix3x2 const& transform)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetTransform(transform); ctx_->SetTransform(transform);
} }
void Canvas::PushLayerArea(LayerArea& area) void Canvas::PushLayerArea(LayerArea& area)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->PushLayer(area); ctx_->PushLayer(area);
} }
void Canvas::PopLayerArea() void Canvas::PopLayerArea()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->PopLayer(); ctx_->PopLayer();
} }
void Canvas::PushClipRect(Rect const& clip_rect) void Canvas::PushClipRect(Rect const& clip_rect)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->PushClipRect(clip_rect); ctx_->PushClipRect(clip_rect);
} }
void Canvas::PopClipRect() void Canvas::PopClipRect()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->PopClipRect(); ctx_->PopClipRect();
} }
void Canvas::DrawLine(Point const& begin, Point const& end) void Canvas::DrawLine(Point const& begin, Point const& end)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_); ctx_->SetCurrentBrush(stroke_brush_);
rt_->DrawLine( ctx_->DrawLine(begin, end, stroke_width_, stroke_style_);
begin,
end,
stroke_width_,
stroke_style_
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::DrawCircle(Point const& center, float radius) void Canvas::DrawCircle(Point const& center, float radius)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_); ctx_->SetCurrentBrush(stroke_brush_);
rt_->DrawEllipse( ctx_->DrawEllipse(center, Vec2(radius, radius), stroke_width_, stroke_style_);
center,
Vec2(radius, radius),
stroke_width_,
stroke_style_
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::DrawEllipse(Point const& center, Vec2 const& radius) void Canvas::DrawEllipse(Point const& center, Vec2 const& radius)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_); ctx_->SetCurrentBrush(stroke_brush_);
rt_->DrawEllipse( ctx_->DrawEllipse(center, radius, stroke_width_, stroke_style_);
center,
radius,
stroke_width_,
stroke_style_
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::DrawRect(Rect const& rect) void Canvas::DrawRect(Rect const& rect)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_); ctx_->SetCurrentBrush(stroke_brush_);
rt_->DrawRectangle( ctx_->DrawRectangle(rect, stroke_width_, stroke_style_);
rect,
stroke_width_,
stroke_style_
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius) void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_); ctx_->SetCurrentBrush(stroke_brush_);
rt_->DrawRoundedRectangle( ctx_->DrawRoundedRectangle(rect, radius, stroke_width_, stroke_style_);
rect,
radius,
stroke_width_,
stroke_style_
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::FillCircle(Point const& center, float radius) void Canvas::FillCircle(Point const& center, float radius)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_); ctx_->SetCurrentBrush(fill_brush_);
rt_->FillEllipse( ctx_->FillEllipse(center, Vec2(radius, radius));
center,
Vec2(radius, radius)
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::FillEllipse(Point const& center, Vec2 const& radius) void Canvas::FillEllipse(Point const& center, Vec2 const& radius)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_); ctx_->SetCurrentBrush(fill_brush_);
rt_->FillEllipse( ctx_->FillEllipse(center, radius);
center,
radius
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::FillRect(Rect const& rect) void Canvas::FillRect(Rect const& rect)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_); ctx_->SetCurrentBrush(fill_brush_);
rt_->FillRectangle( ctx_->FillRectangle(rect);
rect
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius) void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_); ctx_->SetCurrentBrush(fill_brush_);
rt_->FillRoundedRectangle( ctx_->FillRoundedRectangle(rect, radius);
rect,
radius
);
cache_expired_ = true; 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) if (texture)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->DrawTexture(*texture, src_rect, dest_rect); ctx_->DrawTexture(*texture, src_rect, dest_rect);
cache_expired_ = true; cache_expired_ = true;
} }
} }
void Canvas::DrawTextLayout(String const& text, Point const& point) void Canvas::DrawTextLayout(String const& text, Point const& point)
{ {
if (text.empty()) if (text.empty())
return; return;
@ -234,91 +197,85 @@ namespace kiwano
layout.SetStyle(text_style_); layout.SetStyle(text_style_);
layout.SetText(text); layout.SetText(text);
DrawTextLayout(layout, point); DrawTextLayout(layout, point);
} }
void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point) void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point)
{ {
InitRenderTargetAndBrushs(); 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); geo_sink_.BeginPath(begin_pos);
} }
void Canvas::EndPath(bool closed) void Canvas::EndPath(bool closed)
{ {
geo_sink_.EndPath(closed); geo_sink_.EndPath(closed);
} }
void Canvas::AddLine(Point const & point) void Canvas::AddLine(Point const& point)
{ {
geo_sink_.AddLine(point); geo_sink_.AddLine(point);
} }
void Canvas::AddLines(Vector<Point> const& points) void Canvas::AddLines(Vector<Point> const& points)
{ {
geo_sink_.AddLines(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); 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); geo_sink_.AddArc(point, radius, rotation, clockwise, is_small);
} }
void Canvas::StrokePath() void Canvas::StrokePath()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_); ctx_->SetCurrentBrush(stroke_brush_);
rt_->DrawGeometry( ctx_->DrawGeometry(geo_sink_.GetGeometry(), stroke_width_, stroke_style_);
geo_sink_.GetGeometry(),
stroke_width_,
stroke_style_
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::FillPath() void Canvas::FillPath()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_); ctx_->SetCurrentBrush(fill_brush_);
rt_->FillGeometry( ctx_->FillGeometry(geo_sink_.GetGeometry());
geo_sink_.GetGeometry()
);
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::Clear() void Canvas::Clear()
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->Clear(); ctx_->Clear();
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::Clear(Color const& clear_color) void Canvas::Clear(Color const& clear_color)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
rt_->Clear(clear_color); ctx_->Clear(clear_color);
cache_expired_ = true; cache_expired_ = true;
} }
TexturePtr Canvas::ExportToTexture() const TexturePtr Canvas::ExportToTexture() const
{ {
UpdateCache(); UpdateCache();
return texture_cached_; return texture_cached_;
} }
void Canvas::InitRenderTargetAndBrushs() void Canvas::InitRenderTargetAndBrushs()
{
if (!ctx_)
{ {
if (!rt_) Renderer::Instance().CreateTextureRenderTarget(ctx_);
{
Renderer::instance().CreateTextureRenderTarget(rt_);
} }
if (!stroke_brush_) if (!stroke_brush_)
@ -332,22 +289,22 @@ namespace kiwano
fill_brush_ = new Brush; fill_brush_ = new Brush;
fill_brush_->SetColor(Color::White); fill_brush_->SetColor(Color::White);
} }
} }
void Canvas::UpdateCache() const void Canvas::UpdateCache() const
{ {
if (cache_expired_ && rt_) if (cache_expired_ && ctx_)
{ {
if (!texture_cached_) if (!texture_cached_)
{ {
texture_cached_ = new Texture; texture_cached_ = new Texture;
} }
if (rt_->GetOutput(*texture_cached_)) if (ctx_->GetOutput(*texture_cached_))
{ {
cache_expired_ = false; cache_expired_ = false;
} }
} }
}
} }
} // namespace kiwano

View File

@ -20,26 +20,25 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/RenderTarget.h> #include <kiwano/render/GeometrySink.h>
#include <kiwano/renderer/GeometrySink.h> #include <kiwano/render/RenderContext.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Canvas); KGE_DECLARE_SMART_PTR(Canvas);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Canvas class KGE_API Canvas : public Actor
: public Actor {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 构建空画布 /// @brief 构建空画布
Canvas(); Canvas();
@ -206,7 +205,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 设置轮廓样式 /// @brief 设置轮廓样式
/// @param stroke_style 轮廓样式 /// @param stroke_style 轮廓样式
void SetStrokeStyle(StrokeStyle stroke_style); void SetStrokeStyle(const StrokeStyle& stroke_style);
/// \~chinese /// \~chinese
/// @brief 设置文字画刷样式 /// @brief 设置文字画刷样式
@ -262,14 +261,14 @@ namespace kiwano
/// @brief 导出纹理 /// @brief 导出纹理
TexturePtr ExportToTexture() const; TexturePtr ExportToTexture() const;
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
private: private:
void InitRenderTargetAndBrushs(); void InitRenderTargetAndBrushs();
void UpdateCache() const; void UpdateCache() const;
private: private:
float stroke_width_; float stroke_width_;
TextStyle text_style_; TextStyle text_style_;
StrokeStyle stroke_style_; StrokeStyle stroke_style_;
@ -279,56 +278,55 @@ namespace kiwano
mutable bool cache_expired_; mutable bool cache_expired_;
mutable TexturePtr texture_cached_; 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); 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; stroke_style_ = stroke_style;
} }
inline void Canvas::SetTextStyle(TextStyle const& text_style) inline void Canvas::SetTextStyle(TextStyle const& text_style)
{ {
text_style_ = text_style; text_style_ = text_style;
} }
inline void Canvas::SetStrokeColor(Color const& color) inline void Canvas::SetStrokeColor(Color const& color)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
stroke_brush_->SetColor(color); stroke_brush_->SetColor(color);
} }
inline void Canvas::SetFillColor(Color const& color) inline void Canvas::SetFillColor(Color const& color)
{ {
InitRenderTargetAndBrushs(); InitRenderTargetAndBrushs();
fill_brush_->SetColor(color); 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

View File

@ -19,19 +19,19 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/DebugActor.h> #include <kiwano/2d/DebugActor.h>
#include <kiwano/renderer/Renderer.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/render/Renderer.h>
#include <psapi.h> #include <psapi.h>
#pragma comment(lib, "psapi.lib") #pragma comment(lib, "psapi.lib")
namespace kiwano namespace kiwano
{ {
namespace namespace
{ {
class comma_numpunct : public std::numpunct<wchar_t> class comma_numpunct : public std::numpunct<wchar_t>
{ {
private: private:
virtual wchar_t do_thousands_sep() const override virtual wchar_t do_thousands_sep() const override
{ {
return L','; return L',';
@ -41,49 +41,47 @@ namespace kiwano
{ {
return "\03"; return "\03";
} }
}; };
} // namespace
std::locale comma_locale(std::locale(), new comma_numpunct); DebugActor::DebugActor()
} {
DebugActor::DebugActor()
{
SetName(L"kiwano-debug-actor"); SetName(L"kiwano-debug-actor");
SetPosition(Point{ 10, 10 }); SetPosition(Point{ 10, 10 });
SetResponsible(true); SetResponsible(true);
SetCascadeOpacityEnabled(true); SetCascadeOpacityEnabled(true);
comma_locale_ = std::locale(std::locale(), new comma_numpunct);
background_brush_ = new Brush; background_brush_ = new Brush;
background_brush_->SetColor(Color(0.0f, 0.0f, 0.0f, 0.7f)); background_brush_->SetColor(Color(0.0f, 0.0f, 0.0f, 0.7f));
debug_text_ = new TextActor; BrushPtr fill_brush = new Brush;
debug_text_->SetPosition(Point{ 10, 10 }); fill_brush->SetColor(Color::White);
this->AddChild(debug_text_);
TextStyle style; TextStyle style;
style.font_family = L"Arial"; style.font_family = L"Arial";
style.font_size = 16.f; style.font_size = 16.f;
style.font_weight = FontWeight::Normal; style.font_weight = FontWeight::Normal;
style.line_spacing = 20.f; style.line_spacing = 20.f;
debug_text_->SetStyle(style); style.fill_brush = fill_brush;
debug_text_->SetFillColor(Color::White); debug_text_.SetStyle(style);
AddListener<MouseHoverEvent>([=](Event&) { SetOpacity(0.4f); }); AddListener<MouseHoverEvent>([=](Event*) { SetOpacity(0.4f); });
AddListener<MouseOutEvent>([=](Event&) { SetOpacity(1.f); }); AddListener<MouseOutEvent>([=](Event*) { SetOpacity(1.f); });
} }
DebugActor::~DebugActor() DebugActor::~DebugActor() {}
{
}
void DebugActor::OnRender(RenderTarget* rt) void DebugActor::OnRender(RenderContext& ctx)
{ {
rt->SetCurrentBrush(background_brush_); ctx.SetCurrentBrush(background_brush_);
rt->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }); 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); KGE_NOT_USED(dt);
frame_time_.push_back(Time::Now()); frame_time_.push_back(Time::Now());
@ -95,7 +93,7 @@ namespace kiwano
StringStream ss; StringStream ss;
// For formatting integers with commas // For formatting integers with commas
(void)ss.imbue(comma_locale); (void)ss.imbue(comma_locale_);
ss << "Fps: " << frame_time_.size() << std::endl; ss << "Fps: " << frame_time_.size() << std::endl;
@ -106,9 +104,10 @@ namespace kiwano
} }
#endif #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: "; ss << "Memory: ";
{ {
@ -124,22 +123,24 @@ namespace kiwano
ss << pmc.PrivateUsage / 1024 << "Kb"; 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

View File

@ -20,42 +20,39 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/TextActor.h> #include <kiwano/render/TextLayout.h>
#include <kiwano/renderer/Color.h>
#include <kiwano/renderer/Brush.h>
namespace kiwano namespace kiwano
{ {
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API DebugActor class KGE_API DebugActor : public Actor
: public Actor {
{ public:
public:
DebugActor(); DebugActor();
virtual ~DebugActor(); virtual ~DebugActor();
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;
protected: protected:
bool CheckVisibilty(RenderTarget* rt) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
std::locale comma_locale_;
BrushPtr background_brush_; BrushPtr background_brush_;
TextActorPtr debug_text_; TextLayout debug_text_;
Vector<Time> frame_time_; Vector<Time> frame_time_;
}; };
/** @} */ /** @} */
} // namespace kiwano
}

View File

@ -19,38 +19,36 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/Frame.h> #include <kiwano/2d/Frame.h>
#include <kiwano/renderer/TextureCache.h> #include <kiwano/render/TextureCache.h>
namespace kiwano namespace kiwano
{ {
Frame::Frame() Frame::Frame() {}
{
}
bool Frame::Load(String const& file_path) bool Frame::Load(String const& file_path)
{ {
TexturePtr texture = TextureCache::instance().AddOrGetTexture(file_path); TexturePtr texture = TextureCache::Instance().AddOrGetTexture(file_path);
if (texture->IsValid()) if (texture->IsValid())
{ {
SetTexture(texture); SetTexture(texture);
return true; return true;
} }
return false; return false;
} }
bool Frame::Load(Resource const& res) bool Frame::Load(Resource const& res)
{ {
TexturePtr texture = TextureCache::instance().AddOrGetTexture(res); TexturePtr texture = TextureCache::Instance().AddOrGetTexture(res);
if (texture->IsValid()) if (texture->IsValid())
{ {
SetTexture(texture); SetTexture(texture);
return true; return true;
} }
return false; return false;
} }
void Frame::SetCropRect(Rect const& crop_rect) void Frame::SetCropRect(Rect const& crop_rect)
{ {
if (texture_->IsValid()) if (texture_->IsValid())
{ {
auto bitmap_size = texture_->GetSize(); 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.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); 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; texture_ = texture;
if (texture_->IsValid()) if (texture_->IsValid())
{ {
@ -70,5 +68,5 @@ namespace kiwano
crop_rect_.right_bottom.x = texture_->GetWidth(); crop_rect_.right_bottom.x = texture_->GetWidth();
crop_rect_.right_bottom.y = texture_->GetHeight(); crop_rect_.right_bottom.y = texture_->GetHeight();
} }
}
} }
} // namespace kiwano

View File

@ -20,20 +20,19 @@
#pragma once #pragma once
#include <kiwano/core/ObjectBase.h> #include <kiwano/core/ObjectBase.h>
#include <kiwano/renderer/Texture.h> #include <kiwano/render/Texture.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Frame); KGE_DECLARE_SMART_PTR(Frame);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Frame class KGE_API Frame : public virtual ObjectBase
: public ObjectBase {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 构建空图像帧 /// @brief 构建空图像帧
Frame(); Frame();
@ -86,16 +85,37 @@ namespace kiwano
/// @brief 获取纹理 /// @brief 获取纹理
TexturePtr GetTexture() const; TexturePtr GetTexture() const;
private: private:
TexturePtr texture_; TexturePtr texture_;
Rect crop_rect_; Rect crop_rect_;
}; };
inline bool Frame::IsValid() const { return texture_ && texture_->IsValid(); } inline bool Frame::IsValid() const
inline float Frame::GetWidth() const { return crop_rect_.GetWidth(); } {
inline float Frame::GetHeight() const { return crop_rect_.GetHeight(); } return texture_ && texture_->IsValid();
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 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

View File

@ -23,31 +23,27 @@
namespace kiwano namespace kiwano
{ {
FrameSequence::FrameSequence() FrameSequence::FrameSequence() {}
{
}
FrameSequence::FrameSequence(Vector<FramePtr> const& frames) FrameSequence::FrameSequence(Vector<FramePtr> const& frames)
{ {
this->AddFrames(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"); KGE_ASSERT(frame && "FrameSequence::Add failed, NULL pointer exception");
if (frame) if (frame)
{ {
frames_.push_back(frame); frames_.push_back(frame);
} }
} }
void FrameSequence::AddFrames(Vector<FramePtr> const& frames) void FrameSequence::AddFrames(Vector<FramePtr> const& frames)
{ {
if (frames_.empty()) if (frames_.empty())
frames_ = frames; frames_ = frames;
else else
@ -56,36 +52,36 @@ namespace kiwano
for (const auto& texture : frames) for (const auto& texture : frames)
AddFrame(texture); AddFrame(texture);
} }
} }
FramePtr FrameSequence::GetFrame(size_t index) const FramePtr FrameSequence::GetFrame(size_t index) const
{ {
KGE_ASSERT(index < frames_.size()); KGE_ASSERT(index < frames_.size());
return frames_[index]; return frames_[index];
} }
Vector<FramePtr> const& FrameSequence::GetFrames() const Vector<FramePtr> const& FrameSequence::GetFrames() const
{ {
return frames_; return frames_;
} }
size_t FrameSequence::GetFramesCount() const size_t FrameSequence::GetFramesCount() const
{ {
return frames_.size(); return frames_.size();
} }
FrameSequencePtr FrameSequence::Clone() const FrameSequencePtr FrameSequence::Clone() const
{ {
auto frame_seq = new (std::nothrow) FrameSequence; auto frame_seq = new (std::nothrow) FrameSequence;
if (frame_seq) if (frame_seq)
{ {
frame_seq->AddFrames(frames_); frame_seq->AddFrames(frames_);
} }
return frame_seq; return frame_seq;
} }
FrameSequencePtr FrameSequence::Reverse() const FrameSequencePtr FrameSequence::Reverse() const
{ {
auto frame_seq = new (std::nothrow) FrameSequence; auto frame_seq = new (std::nothrow) FrameSequence;
if (!frames_.empty()) if (!frames_.empty())
{ {
@ -96,6 +92,6 @@ namespace kiwano
} }
} }
return frame_seq; return frame_seq;
}
} }
} // namespace kiwano

View File

@ -19,22 +19,21 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/common.h>
#include <kiwano/core/time.h>
#include <kiwano/2d/Frame.h> #include <kiwano/2d/Frame.h>
#include <kiwano/core/Common.h>
#include <kiwano/core/Time.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(FrameSequence); KGE_DECLARE_SMART_PTR(FrameSequence);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API FrameSequence class KGE_API FrameSequence : public virtual ObjectBase
: public ObjectBase {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 构建空序列帧 /// @brief 构建空序列帧
FrameSequence(); FrameSequence();
@ -77,7 +76,7 @@ namespace kiwano
/// @brief 获取序列帧的倒转 /// @brief 获取序列帧的倒转
FrameSequencePtr Reverse() const; FrameSequencePtr Reverse() const;
private: private:
Vector<FramePtr> frames_; Vector<FramePtr> frames_;
}; };
} } // namespace kiwano

View File

@ -19,33 +19,33 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/GifSprite.h> #include <kiwano/2d/GifSprite.h>
#include <kiwano/renderer/TextureCache.h> #include <kiwano/render/Renderer.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/TextureCache.h>
namespace kiwano namespace kiwano
{ {
GifSprite::GifSprite() GifSprite::GifSprite()
: animating_(false) : animating_(false)
, next_index_(0) , next_index_(0)
, total_loop_count_(1) , total_loop_count_(1)
, loop_count_(0) , loop_count_(0)
{ {
} }
bool GifSprite::Load(String const& file_path) bool GifSprite::Load(String const& file_path)
{ {
GifImagePtr image = TextureCache::instance().AddOrGetGifImage(file_path); GifImagePtr image = TextureCache::Instance().AddOrGetGifImage(file_path);
return Load(image); return Load(image);
} }
bool GifSprite::Load(Resource const& res) bool GifSprite::Load(Resource const& res)
{ {
GifImagePtr image = TextureCache::instance().AddOrGetGifImage(res); GifImagePtr image = TextureCache::Instance().AddOrGetGifImage(res);
return Load(image); return Load(image);
} }
bool GifSprite::Load(GifImagePtr gif) bool GifSprite::Load(GifImagePtr gif)
{ {
if (gif && gif->IsValid()) if (gif && gif->IsValid())
{ {
gif_ = gif; gif_ = gif;
@ -58,7 +58,7 @@ namespace kiwano
if (!frame_rt_) if (!frame_rt_)
{ {
Renderer::instance().CreateTextureRenderTarget(frame_rt_); Renderer::Instance().CreateTextureRenderTarget(frame_rt_);
} }
if (gif_->GetFramesCount() > 0) if (gif_->GetFramesCount() > 0)
@ -68,20 +68,20 @@ namespace kiwano
return true; return true;
} }
return false; 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(ctx);
{
PrepareToRender(rt);
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); Actor::Update(dt);
if (gif_ && gif_->IsValid() && animating_) if (gif_ && gif_->IsValid() && animating_)
@ -94,24 +94,24 @@ namespace kiwano
ComposeNextFrame(); ComposeNextFrame();
} }
} }
} }
void GifSprite::SetGifImage(GifImagePtr gif) void GifSprite::SetGifImage(GifImagePtr gif)
{ {
gif_ = gif; gif_ = gif;
RestartAnimation(); RestartAnimation();
} }
void GifSprite::RestartAnimation() void GifSprite::RestartAnimation()
{ {
animating_ = true; animating_ = true;
next_index_ = 0; next_index_ = 0;
loop_count_ = 0; loop_count_ = 0;
frame_.disposal_type = GifImage::DisposalType::None; frame_.disposal_type = GifImage::DisposalType::None;
} }
void GifSprite::ComposeNextFrame() void GifSprite::ComposeNextFrame()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
KGE_ASSERT(gif_); KGE_ASSERT(gif_);
@ -125,10 +125,10 @@ namespace kiwano
animating_ = (!EndOfAnimation() && gif_->GetFramesCount() > 1); animating_ = (!EndOfAnimation() && gif_->GetFramesCount() > 1);
} }
} }
void GifSprite::DisposeCurrentFrame() void GifSprite::DisposeCurrentFrame()
{ {
switch (frame_.disposal_type) switch (frame_.disposal_type)
{ {
case GifImage::DisposalType::Unknown: case GifImage::DisposalType::Unknown:
@ -143,10 +143,10 @@ namespace kiwano
RestoreSavedFrame(); RestoreSavedFrame();
break; break;
} }
} }
void GifSprite::OverlayNextFrame() void GifSprite::OverlayNextFrame()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
KGE_ASSERT(gif_ && gif_->IsValid()); KGE_ASSERT(gif_ && gif_->IsValid());
@ -193,10 +193,10 @@ namespace kiwano
{ {
done_cb_(); done_cb_();
} }
} }
void GifSprite::SaveComposedFrame() void GifSprite::SaveComposedFrame()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
TexturePtr frame_to_be_saved = new Texture; TexturePtr frame_to_be_saved = new Texture;
@ -206,15 +206,16 @@ namespace kiwano
if (!saved_frame_) if (!saved_frame_)
{ {
saved_frame_ = new Texture; 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); saved_frame_->CopyFrom(frame_to_be_saved);
} }
} }
void GifSprite::RestoreSavedFrame() void GifSprite::RestoreSavedFrame()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
if (saved_frame_) if (saved_frame_)
@ -226,10 +227,10 @@ namespace kiwano
frame_to_copy_to->CopyFrom(saved_frame_); frame_to_copy_to->CopyFrom(saved_frame_);
} }
} }
} }
void GifSprite::ClearCurrentFrameArea() void GifSprite::ClearCurrentFrameArea()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
frame_rt_->BeginDraw(); frame_rt_->BeginDraw();
@ -238,6 +239,6 @@ namespace kiwano
frame_rt_->PopClipRect(); frame_rt_->PopClipRect();
return frame_rt_->EndDraw(); return frame_rt_->EndDraw();
}
} }
} // namespace kiwano

View File

@ -21,26 +21,25 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/core/Resource.h> #include <kiwano/core/Resource.h>
#include <kiwano/renderer/RenderTarget.h> #include <kiwano/render/GifImage.h>
#include <kiwano/renderer/GifImage.h> #include <kiwano/render/RenderContext.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(GifSprite); KGE_DECLARE_SMART_PTR(GifSprite);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief GIF * @brief GIF
*/ */
class KGE_API GifSprite class KGE_API GifSprite : public Actor
: public Actor {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief GIF播放循环结束回调 /// @brief GIF播放循环结束回调
using LoopDoneCallback = Function<void(int /* times */)>; using LoopDoneCallback = Function<void(int /* times */)>;
@ -98,9 +97,9 @@ namespace kiwano
/// @brief 获取 GIF 图片 /// @brief 获取 GIF 图片
GifImagePtr GetGifImage() const; GifImagePtr GetGifImage() const;
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
private: private:
void Update(Duration dt) override; void Update(Duration dt) override;
/// \~chinese /// \~chinese
@ -135,7 +134,7 @@ namespace kiwano
/// @brief 清空当前图像区域 /// @brief 清空当前图像区域
void ClearCurrentFrameArea(); void ClearCurrentFrameArea();
private: private:
bool animating_; bool animating_;
int total_loop_count_; int total_loop_count_;
int loop_count_; int loop_count_;
@ -147,24 +146,48 @@ namespace kiwano
GifImage::Frame frame_; GifImage::Frame frame_;
TexturePtr saved_frame_; TexturePtr saved_frame_;
TexturePtr frame_to_render_; TexturePtr frame_to_render_;
TextureRenderTargetPtr frame_rt_; TextureRenderContextPtr frame_rt_;
}; };
/** @} */ /** @} */
inline void GifSprite::SetLoopCount(int loops) { total_loop_count_ = loops; } inline void GifSprite::SetLoopCount(int loops)
{
inline void GifSprite::SetLoopDoneCallback(LoopDoneCallback const& cb) { loop_cb_ = cb; } total_loop_count_ = loops;
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::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

View File

@ -20,71 +20,63 @@
#pragma once #pragma once
#include <kiwano/2d/Layer.h> #include <kiwano/2d/Layer.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
Layer::Layer() Layer::Layer()
: swallow_(false) : swallow_(false)
{ {
} }
Layer::~Layer() Layer::~Layer() {}
{
}
void Layer::SetClipRect(Rect const& clip_rect) void Layer::SetClipRect(Rect const& clip_rect)
{ {
area_.SetAreaRect(clip_rect); area_.SetAreaRect(clip_rect);
} }
void Layer::SetOpacity(float opacity) void Layer::SetOpacity(float opacity)
{ {
// Actor::SetOpacity(opacity); // Actor::SetOpacity(opacity);
area_.SetOpacity(opacity); area_.SetOpacity(opacity);
} }
void Layer::SetMaskGeometry(Geometry const& mask) void Layer::SetMaskGeometry(Geometry const& mask)
{ {
area_.SetMaskGeometry(mask); area_.SetMaskGeometry(mask);
} }
void Layer::SetMaskTransform(Matrix3x2 const& transform) void Layer::SetMaskTransform(Matrix3x2 const& transform)
{ {
area_.SetMaskTransform(transform); area_.SetMaskTransform(transform);
} }
void Layer::Dispatch(Event& evt) bool Layer::DispatchEvent(Event* evt)
{ {
if (!IsVisible()) if (!IsVisible())
return; return true;
if (!swallow_) if (swallow_)
{ {
ActorPtr prev; return EventDispatcher::DispatchEvent(evt);
for (auto child = GetAllChildren().last_item(); child; child = prev)
{
prev = child->prev_item();
child->Dispatch(evt);
}
} }
return Actor::DispatchEvent(evt);
}
EventDispatcher::Dispatch(evt); void Layer::Render(RenderContext& ctx)
} {
ctx.PushLayer(area_);
void Layer::Render(RenderTarget* rt) Actor::Render(ctx);
{
rt->PushLayer(area_);
Actor::Render(rt); ctx.PopLayer();
}
rt->PopLayer(); bool Layer::CheckVisibility(RenderContext& ctx) const
} {
bool Layer::CheckVisibilty(RenderTarget* rt) const
{
// Do not need to render Layer // Do not need to render Layer
return false; return false;
}
} }
} // namespace kiwano

View File

@ -20,26 +20,25 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/LayerArea.h> #include <kiwano/render/LayerArea.h>
#include <kiwano/renderer/RenderTarget.h> #include <kiwano/render/RenderContext.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Layer); KGE_DECLARE_SMART_PTR(Layer);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Layer class KGE_API Layer : public Actor
: public Actor {
{ public:
public:
Layer(); Layer();
virtual ~Layer(); virtual ~Layer();
@ -82,26 +81,37 @@ namespace kiwano
/// @brief 获取图层区域 /// @brief 获取图层区域
LayerArea const& GetArea() const; LayerArea const& GetArea() const;
void Dispatch(Event& evt) override; bool DispatchEvent(Event* evt) override;
protected: protected:
void Render(RenderTarget* rt) override; void Render(RenderContext& ctx) override;
bool CheckVisibilty(RenderTarget* rt) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
bool swallow_; bool swallow_;
LayerArea area_; 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

View File

@ -20,50 +20,48 @@
#include <kiwano/2d/ShapeActor.h> #include <kiwano/2d/ShapeActor.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
ShapeActor::ShapeActor() ShapeActor::ShapeActor()
: stroke_width_(1.f) : stroke_width_(1.f)
, stroke_style_(StrokeStyle::Miter) , stroke_style_()
{ {
} }
ShapeActor::~ShapeActor() ShapeActor::~ShapeActor() {}
{
}
Rect ShapeActor::GetBounds() const Rect ShapeActor::GetBounds() const
{ {
return bounds_; return bounds_;
} }
Rect ShapeActor::GetBoundingBox() const Rect ShapeActor::GetBoundingBox() const
{ {
if (!geo_.IsValid()) if (!geo_.IsValid())
return Rect{}; return Rect{};
return geo_.GetBoundingBox(GetTransformMatrix()); return geo_.GetBoundingBox(GetTransformMatrix());
} }
bool ShapeActor::ContainsPoint(const Point& point) const bool ShapeActor::ContainsPoint(const Point& point) const
{ {
return geo_.ContainsPoint(point, &GetTransformMatrix()); return geo_.ContainsPoint(point, &GetTransformMatrix());
} }
void ShapeActor::SetStrokeWidth(float width) void ShapeActor::SetStrokeWidth(float width)
{ {
stroke_width_ = std::max(width, 0.f); stroke_width_ = std::max(width, 0.f);
} }
void ShapeActor::SetStrokeStyle(StrokeStyle stroke_style) void ShapeActor::SetStrokeStyle(const StrokeStyle& stroke_style)
{ {
stroke_style_ = stroke_style; stroke_style_ = stroke_style;
} }
void ShapeActor::SetGeometry(Geometry const& geometry) void ShapeActor::SetGeometry(Geometry const& geometry)
{ {
geo_ = geometry; geo_ = geometry;
if (geo_.IsValid()) if (geo_.IsValid())
{ {
@ -75,10 +73,10 @@ namespace kiwano
bounds_ = Rect{}; bounds_ = Rect{};
SetSize(0.f, 0.f); SetSize(0.f, 0.f);
} }
} }
void ShapeActor::OnRender(RenderTarget* rt) void ShapeActor::OnRender(RenderContext& ctx)
{ {
// Create default brush // Create default brush
if (!fill_brush_) if (!fill_brush_)
{ {
@ -92,187 +90,150 @@ namespace kiwano
stroke_brush_->SetColor(Color::Transparent); stroke_brush_->SetColor(Color::Transparent);
} }
rt->SetCurrentBrush(stroke_brush_); ctx.SetCurrentBrush(stroke_brush_);
rt->DrawGeometry(geo_, stroke_width_ * 2 /* twice width for widening */, stroke_style_); ctx.DrawGeometry(geo_, stroke_width_ * 2 /* twice width for widening */, stroke_style_);
rt->SetCurrentBrush(fill_brush_); ctx.SetCurrentBrush(fill_brush_);
rt->FillGeometry(geo_); ctx.FillGeometry(geo_);
} }
bool ShapeActor::CheckVisibilty(RenderTarget* rt) const bool ShapeActor::CheckVisibility(RenderContext& ctx) const
{ {
return geo_.IsValid() && Actor::CheckVisibilty(rt); 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) if (begin_ != begin || end_ != end)
{ {
begin_ = begin; begin_ = begin;
end_ = end; end_ = end;
SetGeometry(Geometry::CreateLine(begin, 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_) if (size != rect_size_)
{ {
rect_size_ = size; rect_size_ = size;
SetGeometry(Geometry::CreateRect(Rect{ Point{}, 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); SetRoundedRect(GetSize(), radius);
} }
void RoundRectActor::SetRectSize(Size const& size) void RoundRectActor::SetRectSize(Size const& size)
{ {
SetRoundedRect(size, radius_); 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) if (rect_size_ != size || radius_ != radius)
{ {
rect_size_ = size; rect_size_ = size;
radius_ = radius; radius_ = radius;
SetGeometry(Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius)); SetGeometry(Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius));
} }
} }
//-------------------------------------------------------
// CircleActor
//-------------------------------------------------------
//------------------------------------------------------- CircleActor::CircleActor()
// CircleActor
//-------------------------------------------------------
CircleActor::CircleActor()
: radius_(0.f) : radius_(0.f)
{ {
} }
CircleActor::~CircleActor() CircleActor::~CircleActor() {}
{
}
void CircleActor::SetRadius(float radius) void CircleActor::SetRadius(float radius)
{ {
if (radius_ != radius) if (radius_ != radius)
{ {
radius_ = radius; radius_ = radius;
SetGeometry(Geometry::CreateCircle(Point{ 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) if (radius_ != radius)
{ {
radius_ = radius; radius_ = radius;
SetGeometry(Geometry::CreateEllipse(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) if (points.size() > 1)
{ {
SetGeometry( SetGeometry(
GeometrySink() GeometrySink().BeginPath(points[0]).AddLines(&points[1], points.size() - 1).EndPath(true).GetGeometry());
.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); sink_.BeginPath(begin_pos);
} }
void PathShapeActor::EndPath(bool closed) void PathShapeActor::EndPath(bool closed)
{ {
sink_.EndPath(closed); sink_.EndPath(closed);
Geometry geo = sink_.GetGeometry(); Geometry geo = sink_.GetGeometry();
@ -280,31 +241,31 @@ namespace kiwano
{ {
SetGeometry(geo); 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

View File

@ -20,35 +20,34 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Brush.h> #include <kiwano/render/Brush.h>
#include <kiwano/renderer/Geometry.h> #include <kiwano/render/Geometry.h>
#include <kiwano/renderer/GeometrySink.h> #include <kiwano/render/GeometrySink.h>
#include <kiwano/renderer/StrokeStyle.h> #include <kiwano/render/StrokeStyle.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(ShapeActor); KGE_DECLARE_SMART_PTR(ShapeActor);
KGE_DECLARE_SMART_PTR(LineActor); KGE_DECLARE_SMART_PTR(LineActor);
KGE_DECLARE_SMART_PTR(RectActor); KGE_DECLARE_SMART_PTR(RectActor);
KGE_DECLARE_SMART_PTR(RoundRectActor); KGE_DECLARE_SMART_PTR(RoundRectActor);
KGE_DECLARE_SMART_PTR(CircleActor); KGE_DECLARE_SMART_PTR(CircleActor);
KGE_DECLARE_SMART_PTR(EllipseActor); KGE_DECLARE_SMART_PTR(EllipseActor);
KGE_DECLARE_SMART_PTR(PolygonActor); KGE_DECLARE_SMART_PTR(PolygonActor);
KGE_DECLARE_SMART_PTR(PathShapeActor); KGE_DECLARE_SMART_PTR(PathShapeActor);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API ShapeActor class KGE_API ShapeActor : public Actor
: public Actor {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 构造二维形状角色 /// @brief 构造二维形状角色
ShapeActor(); ShapeActor();
@ -69,7 +68,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 获取线条样式 /// @brief 获取线条样式
StrokeStyle SetStrokeStyle() const; const StrokeStyle& GetStrokeStyle() const;
/// \~chinese /// \~chinese
/// @brief 获取形状 /// @brief 获取形状
@ -113,33 +112,31 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 设置线条样式 /// @brief 设置线条样式
void SetStrokeStyle(StrokeStyle stroke_style); void SetStrokeStyle(const StrokeStyle& stroke_style);
/// \~chinese /// \~chinese
/// @brief 设置几何形状 /// @brief 设置几何形状
void SetGeometry(Geometry const& geometry); void SetGeometry(Geometry const& geometry);
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
protected: protected:
bool CheckVisibilty(RenderTarget* rt) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
BrushPtr fill_brush_; BrushPtr fill_brush_;
BrushPtr stroke_brush_; BrushPtr stroke_brush_;
float stroke_width_; float stroke_width_;
StrokeStyle stroke_style_; StrokeStyle stroke_style_;
Rect bounds_; Rect bounds_;
Geometry geo_; Geometry geo_;
}; };
/// \~chinese
/// \~chinese /// @brief 线段图形角色
/// @brief 线段图形角色 class KGE_API LineActor : public ShapeActor
class KGE_API LineActor {
: public ShapeActor public:
{
public:
LineActor(); LineActor();
virtual ~LineActor(); virtual ~LineActor();
@ -168,18 +165,16 @@ namespace kiwano
/// @param end 线段终点 /// @param end 线段终点
void SetLine(Point const& begin, Point const& end); void SetLine(Point const& begin, Point const& end);
private: private:
Point begin_; Point begin_;
Point end_; Point end_;
}; };
/// \~chinese
/// \~chinese /// @brief 矩形角色
/// @brief 矩形角色 class KGE_API RectActor : public ShapeActor
class KGE_API RectActor {
: public ShapeActor public:
{
public:
RectActor(); RectActor();
virtual ~RectActor(); virtual ~RectActor();
@ -193,18 +188,15 @@ namespace kiwano
/// @param size 矩形大小 /// @param size 矩形大小
void SetRectSize(Size const& size); void SetRectSize(Size const& size);
private: private:
Size rect_size_; Size rect_size_;
}; };
/// \~chinese
/// @brief 圆角矩形角色
/// \~chinese class KGE_API RoundRectActor : public ShapeActor
/// @brief 圆角矩形角色 {
class KGE_API RoundRectActor public:
: public ShapeActor
{
public:
RoundRectActor(); RoundRectActor();
virtual ~RoundRectActor(); virtual ~RoundRectActor();
@ -233,18 +225,16 @@ namespace kiwano
/// @param radius 圆角半径 /// @param radius 圆角半径
void SetRoundedRect(Size const& size, Vec2 const& radius); void SetRoundedRect(Size const& size, Vec2 const& radius);
private: private:
Size rect_size_; Size rect_size_;
Vec2 radius_; Vec2 radius_;
}; };
/// \~chinese
/// \~chinese /// @brief 圆形角色
/// @brief 圆形角色 class KGE_API CircleActor : public ShapeActor
class KGE_API CircleActor {
: public ShapeActor public:
{
public:
CircleActor(); CircleActor();
virtual ~CircleActor(); virtual ~CircleActor();
@ -258,17 +248,15 @@ namespace kiwano
/// @param radius 圆形半径 /// @param radius 圆形半径
void SetRadius(float radius); void SetRadius(float radius);
private: private:
float radius_; float radius_;
}; };
/// \~chinese
/// \~chinese /// @brief 椭圆角色
/// @brief 椭圆角色 class KGE_API EllipseActor : public ShapeActor
class KGE_API EllipseActor {
: public ShapeActor public:
{
public:
EllipseActor(); EllipseActor();
virtual ~EllipseActor(); virtual ~EllipseActor();
@ -282,17 +270,15 @@ namespace kiwano
/// @param radius 椭圆半径 /// @param radius 椭圆半径
void SetRadius(Vec2 const& radius); void SetRadius(Vec2 const& radius);
private: private:
Vec2 radius_; Vec2 radius_;
}; };
/// \~chinese
/// \~chinese /// @brief 多边形角色
/// @brief 多边形角色 class KGE_API PolygonActor : public ShapeActor
class KGE_API PolygonActor {
: public ShapeActor public:
{
public:
PolygonActor(); PolygonActor();
virtual ~PolygonActor(); virtual ~PolygonActor();
@ -301,15 +287,13 @@ namespace kiwano
/// @brief 设置多边形端点 /// @brief 设置多边形端点
/// @param points 多边形端点集合 /// @param points 多边形端点集合
void SetVertices(Vector<Point> const& points); void SetVertices(Vector<Point> const& points);
}; };
/// \~chinese
/// \~chinese /// @brief 路径图形角色
/// @brief 路径图形角色 class KGE_API PathShapeActor : public ShapeActor
class KGE_API PathShapeActor {
: public ShapeActor public:
{
public:
PathShapeActor(); PathShapeActor();
virtual ~PathShapeActor(); virtual ~PathShapeActor();
@ -354,49 +338,97 @@ namespace kiwano
/// @brief 清除路径 /// @brief 清除路径
void ClearPath(); void ClearPath();
private: private:
GeometrySink sink_; GeometrySink sink_;
}; };
/** @} */ /** @} */
inline void ShapeActor::SetStrokeColor(Color const& color) inline void ShapeActor::SetStrokeColor(Color const& color)
{ {
if (!stroke_brush_) if (!stroke_brush_)
{ {
stroke_brush_ = new Brush; stroke_brush_ = new Brush;
} }
stroke_brush_->SetColor(color); stroke_brush_->SetColor(color);
} }
inline void ShapeActor::SetFillColor(Color const& color) inline void ShapeActor::SetFillColor(Color const& color)
{ {
if (!fill_brush_) if (!fill_brush_)
{ {
fill_brush_ = new Brush; fill_brush_ = new Brush;
} }
fill_brush_->SetColor(color); 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

View File

@ -19,20 +19,16 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/Sprite.h> #include <kiwano/2d/Sprite.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano 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; FramePtr frame = new (std::nothrow) Frame;
if (frame->Load(file_path)) if (frame->Load(file_path))
{ {
@ -40,10 +36,10 @@ namespace kiwano
return true; return true;
} }
return false; return false;
} }
bool Sprite::Load(Resource const& res) bool Sprite::Load(Resource const& res)
{ {
FramePtr frame = new (std::nothrow) Frame; FramePtr frame = new (std::nothrow) Frame;
if (frame->Load(res)) if (frame->Load(res))
{ {
@ -51,19 +47,19 @@ namespace kiwano
return true; return true;
} }
return false; return false;
} }
void Sprite::SetCropRect(const Rect& crop_rect) void Sprite::SetCropRect(const Rect& crop_rect)
{ {
if (frame_) if (frame_)
{ {
frame_->SetCropRect(crop_rect); frame_->SetCropRect(crop_rect);
SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() }); SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
} }
} }
void Sprite::SetFrame(FramePtr frame) void Sprite::SetFrame(FramePtr frame)
{ {
if (frame_ != frame) if (frame_ != frame)
{ {
frame_ = frame; frame_ = frame;
@ -72,15 +68,15 @@ namespace kiwano
SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() }); 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

View File

@ -24,21 +24,20 @@
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Sprite); KGE_DECLARE_SMART_PTR(Sprite);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief ¾«Áé * @brief ¾«Áé
*/ */
class KGE_API Sprite class KGE_API Sprite : public Actor
: public Actor {
{ public:
public:
Sprite(); Sprite();
virtual ~Sprite(); virtual ~Sprite();
@ -67,17 +66,19 @@ namespace kiwano
/// @param[in] frame ͼÏñÖ¡ /// @param[in] frame ͼÏñÖ¡
void SetFrame(FramePtr frame); void SetFrame(FramePtr frame);
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
protected: protected:
bool CheckVisibilty(RenderTarget* rt) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
FramePtr frame_; FramePtr frame_;
}; };
/** @} */ /** @} */
inline FramePtr Sprite::GetFrame() const { return frame_; }
inline FramePtr Sprite::GetFrame() const
{
return frame_;
} }
} // namespace kiwano

View File

@ -20,35 +20,33 @@
#include <kiwano/2d/Stage.h> #include <kiwano/2d/Stage.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
Stage::Stage() Stage::Stage()
{ {
SetStage(this); SetStage(this);
SetAnchor(Vec2{ 0, 0 }); 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"); KGE_SYS_LOG(L"Stage entered");
} }
void Stage::OnExit() void Stage::OnExit()
{ {
KGE_SYS_LOG(L"Stage exited"); KGE_SYS_LOG(L"Stage exited");
} }
void Stage::RenderBorder(RenderTarget* rt) void Stage::RenderBorder(RenderContext& ctx)
{ {
rt->SetBrushOpacity(1.0f); ctx.SetBrushOpacity(GetDisplayedOpacity());
if (!border_fill_brush_) if (!border_fill_brush_)
{ {
@ -62,7 +60,7 @@ namespace kiwano
border_stroke_brush_->SetColor(Color(Color::Red, .8f)); border_stroke_brush_->SetColor(Color(Color::Red, .8f));
} }
Actor::RenderBorder(rt); Actor::RenderBorder(ctx);
}
} }
} // namespace kiwano

View File

@ -20,30 +20,29 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Brush.h> #include <kiwano/render/Brush.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Stage); KGE_DECLARE_SMART_PTR(Stage);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
* @see kiwano::Actor kiwano::Director * @see kiwano::Actor kiwano::Director
*/ */
class KGE_API Stage class KGE_API Stage : public Actor
: public Actor {
{
friend class Transition; friend class Transition;
friend class Director; friend class Director;
public: public:
Stage(); Stage();
virtual ~Stage(); virtual ~Stage();
@ -74,36 +73,35 @@ namespace kiwano
/// @brief 设置角色边界轮廓画刷 /// @brief 设置角色边界轮廓画刷
void SetBorderStrokeBrush(BrushPtr brush); void SetBorderStrokeBrush(BrushPtr brush);
protected: protected:
/// \~chinese /// \~chinese
/// @brief 绘制所有子角色的边界 /// @brief 绘制所有子角色的边界
void RenderBorder(RenderTarget* rt) override; void RenderBorder(RenderContext& ctx) override;
private: private:
BrushPtr border_fill_brush_; BrushPtr border_fill_brush_;
BrushPtr border_stroke_brush_; BrushPtr border_stroke_brush_;
}; };
/** @} */ /** @} */
inline BrushPtr Stage::GetBorderFillBrush() const inline BrushPtr Stage::GetBorderFillBrush() const
{ {
return border_fill_brush_; 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

View File

@ -20,16 +20,16 @@
#include <kiwano/2d/TextActor.h> #include <kiwano/2d/TextActor.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
namespace namespace
{ {
TextStyle text_default_style; TextStyle text_default_style;
void InitDefaultTextStyle() void InitDefaultTextStyle()
{ {
static bool inited = false; static bool inited = false;
if (!inited) if (!inited)
{ {
@ -39,58 +39,60 @@ namespace kiwano
text_default_style.fill_brush = new Brush; text_default_style.fill_brush = new Brush;
text_default_style.fill_brush->SetColor(Color::White); 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; text_default_style = style;
} }
const TextStyle& TextActor::GetDefaultStyle() const TextStyle& TextActor::GetDefaultStyle()
{ {
InitDefaultTextStyle();
return text_default_style; return text_default_style;
} }
TextActor::TextActor() TextActor::TextActor()
: TextActor(String()) : TextActor(String())
{ {
} }
TextActor::TextActor(String const& text) TextActor::TextActor(String const& text)
: TextActor(text, text_default_style) : TextActor(text, GetDefaultStyle())
{ {
} }
TextActor::TextActor(String const& text, const TextStyle& style) TextActor::TextActor(String const& text, const TextStyle& style)
: show_underline_(false) : show_underline_(false)
, show_strikethrough_(false) , show_strikethrough_(false)
{ {
InitDefaultTextStyle();
SetText(text); SetText(text);
SetStyle(style); SetStyle(style);
} }
TextActor::~TextActor() TextActor::~TextActor() {}
{
}
void TextActor::OnRender(RenderTarget* rt) void TextActor::OnRender(RenderContext& ctx)
{ {
rt->DrawTextLayout(text_layout_); ctx.DrawTextLayout(text_layout_);
} }
void TextActor::OnUpdate(Duration dt) void TextActor::OnUpdate(Duration dt)
{ {
UpdateLayout(); UpdateLayout();
} }
void TextActor::UpdateLayout() void TextActor::UpdateLayout()
{ {
if (text_layout_.IsDirty()) if (text_layout_.IsDirty())
{ {
text_layout_.Update(); text_layout_.Update();
}
if (text_layout_.GetDirtyFlag() & TextLayout::DirtyFlag::Updated)
{
text_layout_.SetDirtyFlag(TextLayout::DirtyFlag::Clean);
if (show_underline_) if (show_underline_)
text_layout_.SetUnderline(true, 0, text_layout_.GetText().length()); text_layout_.SetUnderline(true, 0, text_layout_.GetText().length());
@ -100,30 +102,31 @@ namespace kiwano
SetSize(text_layout_.GetLayoutSize()); SetSize(text_layout_.GetLayoutSize());
} }
} }
bool TextActor::CheckVisibilty(RenderTarget* rt) const bool TextActor::CheckVisibility(RenderContext& ctx) const
{ {
return text_layout_.IsValid() && Actor::CheckVisibilty(rt); return text_layout_.IsValid() && Actor::CheckVisibility(ctx);
} }
void TextActor::SetFillColor(Color const& color) void TextActor::SetFillColor(Color const& color)
{ {
if (!text_layout_.GetFillBrush()) if (!text_layout_.GetFillBrush() || text_layout_.GetFillBrush() == GetDefaultStyle().fill_brush)
{ {
BrushPtr brush = new Brush; BrushPtr brush = new Brush;
text_layout_.SetFillBrush(brush); text_layout_.SetFillBrush(brush);
} }
text_layout_.GetFillBrush()->SetColor(color); text_layout_.GetFillBrush()->SetColor(color);
} }
void TextActor::SetOutlineColor(Color const& outline_color) void TextActor::SetOutlineColor(Color const& outline_color)
{ {
if (!text_layout_.GetOutlineBrush()) if (!text_layout_.GetOutlineBrush() || text_layout_.GetOutlineBrush() == GetDefaultStyle().outline_brush)
{ {
BrushPtr brush = new Brush; BrushPtr brush = new Brush;
text_layout_.SetOutlineBrush(brush); text_layout_.SetOutlineBrush(brush);
} }
text_layout_.GetOutlineBrush()->SetColor(outline_color); text_layout_.GetOutlineBrush()->SetColor(outline_color);
}
} }
} // namespace kiwano

View File

@ -20,26 +20,25 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Color.h> #include <kiwano/render/Color.h>
#include <kiwano/renderer/TextLayout.h> #include <kiwano/render/TextLayout.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(TextActor); KGE_DECLARE_SMART_PTR(TextActor);
/** /**
* \addtogroup Actors * \addtogroup Actors
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API TextActor class KGE_API TextActor : public Actor
: public Actor {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 构建空的文本角色 /// @brief 构建空的文本角色
TextActor(); TextActor();
@ -69,6 +68,10 @@ namespace kiwano
/// @brief 获取文本布局 /// @brief 获取文本布局
const TextLayout& GetLayout() const; const TextLayout& GetLayout() const;
/// \~chinese
/// @brief »ñÈ¡Îı¾²¼¾Ö´óС
Size GetLayoutSize() const;
/// \~chinese /// \~chinese
/// @brief 获取填充画刷 /// @brief 获取填充画刷
BrushPtr GetFillBrush() const; BrushPtr GetFillBrush() const;
@ -143,7 +146,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 设置文字描边线相交样式 /// @brief 设置文字描边线相交样式
void SetOutlineStroke(StrokeStyle outline_stroke); void SetOutlineStroke(const StrokeStyle& outline_stroke);
/// \~chinese /// \~chinese
/// @brief 设置是否显示下划线(默认值为 false /// @brief 设置是否显示下划线(默认值为 false
@ -166,129 +169,133 @@ namespace kiwano
/// @brief 获取默认文字样式 /// @brief 获取默认文字样式
static const TextStyle& GetDefaultStyle(); static const TextStyle& GetDefaultStyle();
void OnRender(RenderTarget* rt) override; void OnRender(RenderContext& ctx) override;
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;
protected: protected:
bool CheckVisibilty(RenderTarget* rt) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
bool show_underline_; bool show_underline_;
bool show_strikethrough_; bool show_strikethrough_;
TextLayout text_layout_; TextLayout text_layout_;
}; };
/** @} */ /** @} */
inline const String& TextActor::GetText() const inline const String& TextActor::GetText() const
{ {
return text_layout_.GetText(); 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

View File

@ -22,28 +22,25 @@
namespace kiwano namespace kiwano
{ {
Transform::Transform() Transform::Transform()
: position() : position()
, rotation(0.f) , rotation(0.f)
, scale(1.f, 1.f) , scale(1.f, 1.f)
, skew(0.f, 0.f) , skew(0.f, 0.f)
{ {
} }
Matrix3x2 Transform::ToMatrix() const Matrix3x2 Transform::ToMatrix() const
{ {
if (!skew.IsOrigin()) if (!skew.IsOrigin())
{ {
return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation); return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation);
} }
return 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

View File

@ -23,25 +23,25 @@
namespace kiwano namespace kiwano
{ {
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class Transform class Transform
{ {
public: public:
float rotation; ///< 旋转 float rotation; ///< 旋转
Point position; ///< 坐标 Point position; ///< 坐标
Point scale; ///< 缩放 Point scale; ///< 缩放
Point skew; ///< 错切角度 Point skew; ///< 错切角度
public: public:
Transform(); Transform();
/// \~chinese /// \~chinese
/// @brief 将二维放射变换转换为矩阵 /// @brief 将二维放射变换转换为矩阵
Matrix3x2 ToMatrix() const; Matrix3x2 ToMatrix() const;
bool operator== (const Transform& rhs) const; bool operator==(const Transform& rhs) const;
}; };
} } // namespace kiwano

View File

@ -18,20 +18,20 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/Transition.h>
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/Stage.h> #include <kiwano/2d/Stage.h>
#include <kiwano/platform/Window.h> #include <kiwano/2d/Transition.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/renderer/Renderer.h> #include <kiwano/platform/Window.h>
#include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
//------------------------------------------------------- //-------------------------------------------------------
// Transition // Transition
//------------------------------------------------------- //-------------------------------------------------------
Transition::Transition(Duration duration) Transition::Transition(Duration duration)
: done_(false) : done_(false)
, duration_(duration) , duration_(duration)
, delta_() , delta_()
@ -41,26 +41,24 @@ namespace kiwano
, in_stage_(nullptr) , in_stage_(nullptr)
, out_layer_() , out_layer_()
, in_layer_() , in_layer_()
{ {
} }
Transition::~Transition() Transition::~Transition() {}
{
}
bool Transition::IsDone() bool Transition::IsDone()
{ {
return done_; return done_;
} }
void Transition::Init(StagePtr prev, StagePtr next) void Transition::Init(StagePtr prev, StagePtr next)
{ {
process_ = 0; process_ = 0;
delta_ = Duration{}; delta_ = Duration{};
out_stage_ = prev; out_stage_ = prev;
in_stage_ = next; in_stage_ = next;
window_size_ = Renderer::instance().GetOutputSize(); window_size_ = Renderer::Instance().GetOutputSize();
if (in_stage_) if (in_stage_)
{ {
@ -71,10 +69,10 @@ namespace kiwano
{ {
out_layer_.SetAreaRect(Rect{ Point(), window_size_ }); out_layer_.SetAreaRect(Rect{ Point(), window_size_ });
} }
} }
void Transition::Update(Duration dt) void Transition::Update(Duration dt)
{ {
if (duration_.IsZero()) if (duration_.IsZero())
{ {
process_ = 1; process_ = 1;
@ -89,131 +87,119 @@ namespace kiwano
{ {
this->Stop(); this->Stop();
} }
} }
void Transition::Render(RenderTarget* rt) void Transition::Render(RenderContext& ctx)
{ {
if (out_stage_) if (out_stage_)
{ {
out_stage_->PrepareToRender(rt); out_stage_->PrepareToRender(ctx);
rt->PushClipRect(Rect{ Point{}, window_size_ }); ctx.PushClipRect(Rect{ Point{}, window_size_ });
rt->PushLayer(out_layer_); ctx.PushLayer(out_layer_);
out_stage_->Render(rt); out_stage_->Render(ctx);
rt->PopLayer(); ctx.PopLayer();
rt->PopClipRect(); ctx.PopClipRect();
} }
if (in_stage_) if (in_stage_)
{ {
in_stage_->PrepareToRender(rt); in_stage_->PrepareToRender(ctx);
rt->PushClipRect(Rect{ Point{}, window_size_ }); ctx.PushClipRect(Rect{ Point{}, window_size_ });
rt->PushLayer(in_layer_); ctx.PushLayer(in_layer_);
in_stage_->Render(rt); in_stage_->Render(ctx);
rt->PopLayer(); ctx.PopLayer();
rt->PopClipRect(); ctx.PopClipRect();
}
} }
}
void Transition::Stop() void Transition::Stop()
{ {
done_ = true; done_ = true;
Reset(); Reset();
} }
//------------------------------------------------------- //-------------------------------------------------------
// BoxTransition // BoxTransition
//------------------------------------------------------- //-------------------------------------------------------
BoxTransition::BoxTransition(Duration duration) BoxTransition::BoxTransition(Duration duration)
: Transition(duration) : Transition(duration)
{ {
} }
void BoxTransition::Init(StagePtr prev, StagePtr next) void BoxTransition::Init(StagePtr prev, StagePtr next)
{ {
Transition::Init(prev, next); Transition::Init(prev, next);
in_layer_.SetOpacity(0.f); in_layer_.SetOpacity(0.f);
} }
void BoxTransition::Update(Duration dt) void BoxTransition::Update(Duration dt)
{ {
Transition::Update(dt); Transition::Update(dt);
if (process_ < .5f) if (process_ < .5f)
{ {
out_layer_.SetAreaRect( out_layer_.SetAreaRect(Rect(window_size_.x * process_, window_size_.y * process_,
Rect( window_size_.x * (1 - process_), window_size_.y * (1 - process_)));
window_size_.x * process_,
window_size_.y * process_,
window_size_.x * (1 - process_),
window_size_.y * (1 - process_)
)
);
} }
else else
{ {
out_layer_.SetOpacity(0.f); out_layer_.SetOpacity(0.f);
in_layer_.SetOpacity(1.f); in_layer_.SetOpacity(1.f);
in_layer_.SetAreaRect( in_layer_.SetAreaRect(Rect(window_size_.x * (1 - process_), window_size_.y * (1 - process_),
Rect( window_size_.x * process_, window_size_.y * process_));
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) : Transition(duration)
{ {
} }
void EmergeTransition::Init(StagePtr prev, StagePtr next) void EmergeTransition::Init(StagePtr prev, StagePtr next)
{ {
Transition::Init(prev, next); Transition::Init(prev, next);
out_layer_.SetOpacity(1.f); out_layer_.SetOpacity(1.f);
in_layer_.SetOpacity(0.f); in_layer_.SetOpacity(0.f);
} }
void EmergeTransition::Update(Duration dt) void EmergeTransition::Update(Duration dt)
{ {
Transition::Update(dt); Transition::Update(dt);
out_layer_.SetOpacity(1 - process_); out_layer_.SetOpacity(1 - process_);
in_layer_.SetOpacity(process_); in_layer_.SetOpacity(process_);
} }
//------------------------------------------------------- //-------------------------------------------------------
// FadeTransition // FadeTransition
//------------------------------------------------------- //-------------------------------------------------------
FadeTransition::FadeTransition(Duration duration) FadeTransition::FadeTransition(Duration duration)
: Transition(duration) : Transition(duration)
{ {
} }
void FadeTransition::Init(StagePtr prev, StagePtr next) void FadeTransition::Init(StagePtr prev, StagePtr next)
{ {
Transition::Init(prev, next); Transition::Init(prev, next);
out_layer_.SetOpacity(1.f); out_layer_.SetOpacity(1.f);
in_layer_.SetOpacity(0.f); in_layer_.SetOpacity(0.f);
} }
void FadeTransition::Update(Duration dt) void FadeTransition::Update(Duration dt)
{ {
Transition::Update(dt); Transition::Update(dt);
if (process_ < 0.5) if (process_ < 0.5)
@ -226,20 +212,20 @@ namespace kiwano
out_layer_.SetOpacity(0.f); out_layer_.SetOpacity(0.f);
in_layer_.SetOpacity((process_ - 0.5f) * 2); in_layer_.SetOpacity((process_ - 0.5f) * 2);
} }
} }
//------------------------------------------------------- //-------------------------------------------------------
// MoveTransition // MoveTransition
//------------------------------------------------------- //-------------------------------------------------------
MoveTransition::MoveTransition(Duration duration, Type type) MoveTransition::MoveTransition(Duration duration, Type type)
: Transition(duration) : Transition(duration)
, type_(type) , type_(type)
{ {
} }
void MoveTransition::Init(StagePtr prev, StagePtr next) void MoveTransition::Init(StagePtr prev, StagePtr next)
{ {
Transition::Init(prev, next); Transition::Init(prev, next);
switch (type_) switch (type_)
@ -273,10 +259,10 @@ namespace kiwano
transform.position = start_pos_; transform.position = start_pos_;
in_stage_->SetTransform(transform); in_stage_->SetTransform(transform);
} }
} }
void MoveTransition::Update(Duration dt) void MoveTransition::Update(Duration dt)
{ {
Transition::Update(dt); Transition::Update(dt);
if (out_stage_) if (out_stage_)
@ -292,10 +278,10 @@ namespace kiwano
transform.position = start_pos_ + pos_delta_ * process_; transform.position = start_pos_ + pos_delta_ * process_;
in_stage_->SetTransform(transform); in_stage_->SetTransform(transform);
} }
} }
void MoveTransition::Reset() void MoveTransition::Reset()
{ {
if (out_stage_) if (out_stage_)
{ {
out_stage_->SetTransform(Transform{}); out_stage_->SetTransform(Transform{});
@ -305,20 +291,20 @@ namespace kiwano
{ {
in_stage_->SetTransform(Transform{}); in_stage_->SetTransform(Transform{});
} }
} }
//------------------------------------------------------- //-------------------------------------------------------
// RotationTransition // RotationTransition
//------------------------------------------------------- //-------------------------------------------------------
RotationTransition::RotationTransition(Duration duration, float rotation) RotationTransition::RotationTransition(Duration duration, float rotation)
: Transition(duration) : Transition(duration)
, rotation_(rotation) , rotation_(rotation)
{ {
} }
void RotationTransition::Init(StagePtr prev, StagePtr next) void RotationTransition::Init(StagePtr prev, StagePtr next)
{ {
Transition::Init(prev, next); Transition::Init(prev, next);
auto transform = Transform{}; auto transform = Transform{};
@ -337,10 +323,10 @@ namespace kiwano
} }
in_layer_.SetOpacity(0.f); in_layer_.SetOpacity(0.f);
} }
void RotationTransition::Update(Duration dt) void RotationTransition::Update(Duration dt)
{ {
Transition::Update(dt); Transition::Update(dt);
if (process_ < .5f) if (process_ < .5f)
@ -367,10 +353,10 @@ namespace kiwano
in_stage_->SetTransform(transform); in_stage_->SetTransform(transform);
} }
} }
} }
void RotationTransition::Reset() void RotationTransition::Reset()
{ {
if (out_stage_) if (out_stage_)
{ {
out_stage_->SetTransform(Transform{}); out_stage_->SetTransform(Transform{});
@ -382,5 +368,5 @@ namespace kiwano
in_stage_->SetTransform(Transform{}); in_stage_->SetTransform(Transform{});
in_stage_->SetAnchor(Vec2{ 0.f, 0.f }); in_stage_->SetAnchor(Vec2{ 0.f, 0.f });
} }
}
} }
} // namespace kiwano

View File

@ -20,38 +20,35 @@
#pragma once #pragma once
#include <kiwano/2d/Stage.h> #include <kiwano/2d/Stage.h>
#include <kiwano/renderer/LayerArea.h> #include <kiwano/render/LayerArea.h>
namespace kiwano namespace kiwano
{ {
class Director; class Director;
class RenderTarget; class RenderContext;
KGE_DECLARE_SMART_PTR(Transition); KGE_DECLARE_SMART_PTR(Transition);
KGE_DECLARE_SMART_PTR(FadeTransition); KGE_DECLARE_SMART_PTR(FadeTransition);
KGE_DECLARE_SMART_PTR(EmergeTransition); KGE_DECLARE_SMART_PTR(EmergeTransition);
KGE_DECLARE_SMART_PTR(BoxTransition); KGE_DECLARE_SMART_PTR(BoxTransition);
KGE_DECLARE_SMART_PTR(MoveTransition); KGE_DECLARE_SMART_PTR(MoveTransition);
KGE_DECLARE_SMART_PTR(RotationTransition); KGE_DECLARE_SMART_PTR(RotationTransition);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Transition class KGE_API Transition : public virtual ObjectBase
: public ObjectBase {
{
friend class Director; friend class Director;
public: public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param duration * @param duration
*/ */
explicit Transition( explicit Transition(Duration duration);
Duration duration
);
virtual ~Transition(); virtual ~Transition();
@ -61,17 +58,14 @@ namespace kiwano
*/ */
bool IsDone(); bool IsDone();
protected: protected:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param[in] prev * @param[in] prev
* @param[in] next * @param[in] next
*/ */
virtual void Init( virtual void Init(StagePtr prev, StagePtr next);
StagePtr prev,
StagePtr next
);
/** /**
* \~chinese * \~chinese
@ -83,9 +77,9 @@ namespace kiwano
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param[in] rt äÖȾĿ±ê * @param[in] ctx äÖȾÉÏÏÂÎÄ
*/ */
virtual void Render(RenderTarget* rt); virtual void Render(RenderContext& ctx);
/** /**
* \~chinese * \~chinese
@ -99,7 +93,7 @@ namespace kiwano
*/ */
virtual void Reset() {} virtual void Reset() {}
protected: protected:
bool done_; bool done_;
float process_; float process_;
Duration duration_; Duration duration_;
@ -109,102 +103,79 @@ namespace kiwano
StagePtr in_stage_; StagePtr in_stage_;
LayerArea out_layer_; LayerArea out_layer_;
LayerArea in_layer_; LayerArea in_layer_;
}; };
/**
/**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
*/ */
class FadeTransition class FadeTransition : public Transition
: public Transition {
{ public:
public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param duration * @param duration
*/ */
explicit FadeTransition( explicit FadeTransition(Duration duration);
Duration duration
);
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
virtual void Init( virtual void Init(StagePtr prev, StagePtr next) override;
StagePtr prev, };
StagePtr next
) override;
};
/**
/**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
*/ */
class EmergeTransition class EmergeTransition : public Transition
: public Transition {
{ public:
public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param duration * @param duration
*/ */
explicit EmergeTransition( explicit EmergeTransition(Duration duration);
Duration duration
);
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
virtual void Init( virtual void Init(StagePtr prev, StagePtr next) override;
StagePtr prev, };
StagePtr next
) override;
};
/**
/**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
*/ */
class BoxTransition class BoxTransition : public Transition
: public Transition {
{ public:
public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param duration * @param duration
*/ */
explicit BoxTransition( explicit BoxTransition(Duration duration);
Duration duration
);
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
virtual void Init( virtual void Init(StagePtr prev, StagePtr next) override;
StagePtr prev, };
StagePtr next
) override;
};
/**
/**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
*/ */
class MoveTransition class MoveTransition : public Transition
: public Transition {
{ public:
public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -223,59 +194,45 @@ namespace kiwano
* @param duration * @param duration
* @param type * @param type
*/ */
explicit MoveTransition( explicit MoveTransition(Duration duration, Type type);
Duration duration,
Type type
);
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
virtual void Init( virtual void Init(StagePtr prev, StagePtr next) override;
StagePtr prev,
StagePtr next
) override;
void Reset() override; void Reset() override;
private: private:
Type type_; Type type_;
Point pos_delta_; Point pos_delta_;
Point start_pos_; Point start_pos_;
}; };
/**
/**
* \~chinese * \~chinese
* @brief * @brief
* @details * @details
*/ */
class RotationTransition class RotationTransition : public Transition
: public Transition {
{ public:
public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param duration * @param duration
* @param rotation * @param rotation
*/ */
explicit RotationTransition( explicit RotationTransition(Duration duration, float rotation = 360);
Duration duration,
float rotation = 360
);
protected: protected:
void Update(Duration dt) override; void Update(Duration dt) override;
virtual void Init( virtual void Init(StagePtr prev, StagePtr next) override;
StagePtr prev,
StagePtr next
) override;
void Reset() override; void Reset() override;
private: private:
float rotation_; float rotation_;
}; };
} } // namespace kiwano

View File

@ -18,35 +18,31 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/action/Action.h>
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/action/Action.h>
namespace kiwano namespace kiwano
{ {
Action::Action() Action::Action()
: running_(true) : running_(true)
, detach_target_(false) , detach_target_(false)
, loops_done_(0) , loops_done_(0)
, loops_(0) , loops_(0)
, status_(Status::NotStarted) , 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); 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!"); KGE_ASSERT(target != nullptr && "Action target should NOT be nullptr!");
elapsed_ += dt; elapsed_ += dt;
@ -81,15 +77,14 @@ namespace kiwano
status_ = Status::Removeable; status_ = Status::Removeable;
} }
} }
void Action::Complete(Actor* target) void Action::Complete(Actor* target)
{ {
if (cb_loop_done_) if (cb_loop_done_)
cb_loop_done_(target); cb_loop_done_(target);
if (loops_ >= 0 if (loops_ >= 0 && loops_done_ >= loops_)
&& loops_done_ >= loops_)
{ {
Done(); Done();
} }
@ -99,15 +94,15 @@ namespace kiwano
} }
++loops_done_; ++loops_done_;
} }
void Action::Restart(Actor* target) void Action::Restart(Actor* target)
{ {
status_ = Status::NotStarted; status_ = Status::NotStarted;
elapsed_ = 0; elapsed_ = 0;
loops_done_ = 0; loops_done_ = 0;
Init(target); Init(target);
}
} }
} // namespace kiwano

View File

@ -19,40 +19,40 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/time.h>
#include <kiwano/core/SmartPtr.hpp>
#include <kiwano/core/ObjectBase.h> #include <kiwano/core/ObjectBase.h>
#include <kiwano/core/SmartPtr.hpp>
#include <kiwano/core/Time.h>
#include <kiwano/math/math.h> #include <kiwano/math/math.h>
namespace kiwano namespace kiwano
{ {
class Actor; class Actor;
class ActionManager; class ActionManager;
KGE_DECLARE_SMART_PTR(Action); KGE_DECLARE_SMART_PTR(Action);
/** /**
* \~chinese * \~chinese
* \defgroup Actions * \defgroup Actions
*/ */
/** /**
* \addtogroup Actions * \addtogroup Actions
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief ¶¯»­ /// @brief ¶¯»­
class KGE_API Action class KGE_API Action
: public ObjectBase : public virtual ObjectBase
, protected IntrusiveListItem<ActionPtr> , protected IntrusiveListItem<ActionPtr>
{ {
friend class ActionManager; friend class ActionManager;
friend class ActionGroup; friend class ActionGroup;
friend IntrusiveList<ActionPtr>; friend IntrusiveList<ActionPtr>;
public: public:
/// \~chinese /// \~chinese
/// @brief 动画结束时的回调函数 /// @brief 动画结束时的回调函数
using DoneCallback = Function<void(Actor* /* target */)>; using DoneCallback = Function<void(Actor* /* target */)>;
@ -122,7 +122,7 @@ namespace kiwano
/// @brief 获取动画循环结束时的回调函数 /// @brief 获取动画循环结束时的回调函数
DoneCallback GetLoopDoneCallback() const; DoneCallback GetLoopDoneCallback() const;
protected: protected:
/// \~chinese /// \~chinese
/// @brief 初始化动画 /// @brief 初始化动画
virtual void Init(Actor* target); virtual void Init(Actor* target);
@ -178,7 +178,7 @@ namespace kiwano
/// @brief 是否可移除 /// @brief 是否可移除
bool IsRemoveable() const; bool IsRemoveable() const;
private: private:
Status status_; Status status_;
bool running_; bool running_;
bool detach_target_; bool detach_target_;
@ -188,103 +188,102 @@ namespace kiwano
Duration elapsed_; Duration elapsed_;
DoneCallback cb_done_; DoneCallback cb_done_;
DoneCallback cb_loop_done_; DoneCallback cb_loop_done_;
}; };
/** @} */ /** @} */
inline void Action::Resume()
inline void Action::Resume() {
{
running_ = true; 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

View File

@ -22,19 +22,19 @@
namespace kiwano namespace kiwano
{ {
ActionDelay::ActionDelay(Duration delay) ActionDelay::ActionDelay(Duration delay)
{ {
SetDelay(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

View File

@ -23,23 +23,20 @@
namespace kiwano namespace kiwano
{ {
/** /**
* \addtogroup Actions * \addtogroup Actions
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief 延时动画 /// @brief 延时动画
class KGE_API ActionDelay class KGE_API ActionDelay : public Action
: public Action {
{ public:
public:
/// \~chinese /// \~chinese
/// @brief 构建延时动画 /// @brief 构建延时动画
/// @param delay 延时时长 /// @param delay 延时时长
ActionDelay( ActionDelay(Duration delay);
Duration delay
);
/// \~chinese /// \~chinese
/// @brief 获取该动画的拷贝对象 /// @brief 获取该动画的拷贝对象
@ -48,7 +45,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override; ActionPtr Reverse() const override;
}; };
/** @} */ /** @} */
} } // namespace kiwano

View File

@ -18,33 +18,31 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/action/ActionGroup.h>
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/action/ActionGroup.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
namespace kiwano namespace kiwano
{ {
//------------------------------------------------------- //-------------------------------------------------------
// ActionGroup // ActionGroup
//------------------------------------------------------- //-------------------------------------------------------
ActionGroup::ActionGroup() ActionGroup::ActionGroup()
: sequence_(true) : sequence_(true)
{ {
} }
ActionGroup::ActionGroup(Vector<ActionPtr> const& actions, bool sequence) ActionGroup::ActionGroup(Vector<ActionPtr> const& actions, bool sequence)
: sequence_(sequence) : sequence_(sequence)
{ {
this->Add(actions); this->Add(actions);
} }
ActionGroup::~ActionGroup() ActionGroup::~ActionGroup() {}
{
}
void ActionGroup::Init(Actor* target) void ActionGroup::Init(Actor* target)
{ {
if (actions_.empty()) if (actions_.empty())
{ {
Done(); Done();
@ -62,10 +60,10 @@ namespace kiwano
current_->Restart(target); current_->Restart(target);
} }
} }
} }
void ActionGroup::Update(Actor* target, Duration dt) void ActionGroup::Update(Actor* target, Duration dt)
{ {
if (sequence_) if (sequence_)
{ {
if (current_) if (current_)
@ -100,24 +98,24 @@ namespace kiwano
Complete(target); Complete(target);
} }
} }
} }
void ActionGroup::Add(ActionPtr action) void ActionGroup::Add(ActionPtr action)
{ {
if (action) if (action)
{ {
actions_.push_back(action); actions_.push_back(action);
} }
} }
void ActionGroup::Add(Vector<ActionPtr> const& actions) void ActionGroup::Add(Vector<ActionPtr> const& actions)
{ {
for (const auto& action : actions) for (const auto& action : actions)
Add(action); Add(action);
} }
ActionPtr ActionGroup::Clone() const ActionPtr ActionGroup::Clone() const
{ {
auto group = new (std::nothrow) ActionGroup(); auto group = new (std::nothrow) ActionGroup();
if (group) if (group)
{ {
@ -130,10 +128,10 @@ namespace kiwano
} }
} }
return group; return group;
} }
ActionPtr ActionGroup::Reverse() const ActionPtr ActionGroup::Reverse() const
{ {
auto group = new (std::nothrow) ActionGroup(); auto group = new (std::nothrow) ActionGroup();
if (group && !actions_.empty()) if (group && !actions_.empty())
{ {
@ -143,6 +141,6 @@ namespace kiwano
} }
} }
return group; return group;
}
} }
} // namespace kiwano

View File

@ -23,19 +23,18 @@
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(ActionGroup); KGE_DECLARE_SMART_PTR(ActionGroup);
/** /**
* \addtogroup Actions * \addtogroup Actions
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief 动画组合 /// @brief 动画组合
class KGE_API ActionGroup class KGE_API ActionGroup : public Action
: public Action {
{ public:
public:
using ActionList = IntrusiveList<ActionPtr>; using ActionList = IntrusiveList<ActionPtr>;
ActionGroup(); ActionGroup();
@ -70,19 +69,22 @@ namespace kiwano
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override; ActionPtr Reverse() const override;
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void Update(Actor* target, Duration dt) override; void Update(Actor* target, Duration dt) override;
private: private:
bool sequence_; bool sequence_;
ActionPtr current_; ActionPtr current_;
ActionList actions_; ActionList actions_;
}; };
/** @} */ /** @} */
inline ActionGroup::ActionList const& ActionGroup::GetActions() const { return actions_; }
inline ActionGroup::ActionList const& ActionGroup::GetActions() const
{
return actions_;
} }
} // namespace kiwano

View File

@ -19,124 +19,200 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/2d/action/ActionTween.h>
#include <kiwano/2d/action/ActionWalk.h>
#include <kiwano/2d/action/ActionDelay.h> #include <kiwano/2d/action/ActionDelay.h>
#include <kiwano/2d/action/ActionGroup.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> #include <kiwano/2d/action/Animation.h>
namespace kiwano namespace kiwano
{ {
/** /**
* \addtogroup Actions * \addtogroup Actions
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief 动画辅助类 /// @brief 动画辅助类
struct ActionHelper struct ActionHelper
{ {
using DoneCallback = Action::DoneCallback; using DoneCallback = Action::DoneCallback;
/// \~chinese /// \~chinese
/// @brief 设置循环次数 /// @brief 设置循环次数
inline ActionHelper& SetLoops(int loops) { core->SetLoops(loops); return (*this); } inline ActionHelper& SetLoops(int loops)
{
core->SetLoops(loops);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置动画延迟 /// @brief 设置动画延迟
inline ActionHelper& SetDelay(Duration delay) { core->SetDelay(delay); return (*this); } inline ActionHelper& SetDelay(Duration delay)
{
core->SetDelay(delay);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置动画结束回调函数 /// @brief 设置动画结束回调函数
inline ActionHelper& SetDoneCallback(DoneCallback const& cb) { core->SetDoneCallback(cb); return (*this); } inline ActionHelper& SetDoneCallback(DoneCallback const& cb)
{
core->SetDoneCallback(cb);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置动画循环结束时的回调函数 /// @brief 设置动画循环结束时的回调函数
inline ActionHelper& SetLoopDoneCallback(DoneCallback const& cb) { core->SetLoopDoneCallback(cb); return (*this); } inline ActionHelper& SetLoopDoneCallback(DoneCallback const& cb)
{
core->SetLoopDoneCallback(cb);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 动画结束时移除目标角色 /// @brief 动画结束时移除目标角色
inline ActionHelper& RemoveTargetWhenDone() { core->RemoveTargetWhenDone(); return (*this); } inline ActionHelper& RemoveTargetWhenDone()
{
core->RemoveTargetWhenDone();
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置名称 /// @brief 设置名称
inline ActionHelper& SetName(String const& name) { core->SetName(name); return (*this); } inline ActionHelper& SetName(String const& name)
{
core->SetName(name);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 获取指针 /// @brief 获取指针
inline ActionPtr Get() const { return core; } inline ActionPtr Get() const
inline ActionHelper(ActionPtr core) : core(core) {}
inline operator ActionPtr() const { return core; }
private:
ActionPtr core;
};
/// \~chinese
/// @brief 补间动画辅助类
struct TweenHelper
{ {
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; using DoneCallback = Action::DoneCallback;
/// \~chinese /// \~chinese
/// @brief 设置动画持续时长 /// @brief 设置动画持续时长
inline TweenHelper& SetDuration(Duration dur) { core->SetDuration(dur); return (*this); } inline TweenHelper& SetDuration(Duration dur)
{
core->SetDuration(dur);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置循环次数 /// @brief 设置循环次数
inline TweenHelper& SetLoops(int loops) { core->SetLoops(loops); return (*this); } inline TweenHelper& SetLoops(int loops)
{
core->SetLoops(loops);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置缓动函数 /// @brief 设置缓动函数
inline TweenHelper& SetEaseFunc(EaseFunc ease) { core->SetEaseFunc(ease); return (*this); } inline TweenHelper& SetEaseFunc(EaseFunc ease)
{
core->SetEaseFunc(ease);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置动画延迟 /// @brief 设置动画延迟
inline TweenHelper& SetDelay(Duration delay) { core->SetDelay(delay); return (*this); } inline TweenHelper& SetDelay(Duration delay)
{
core->SetDelay(delay);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置动画结束回调函数 /// @brief 设置动画结束回调函数
inline TweenHelper& SetDoneCallback(DoneCallback const& cb) { core->SetDoneCallback(cb); return (*this); } inline TweenHelper& SetDoneCallback(DoneCallback const& cb)
{
core->SetDoneCallback(cb);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置动画循环结束时的回调函数 /// @brief 设置动画循环结束时的回调函数
inline TweenHelper& SetLoopDoneCallback(DoneCallback const& cb) { core->SetLoopDoneCallback(cb); return (*this); } inline TweenHelper& SetLoopDoneCallback(DoneCallback const& cb)
{
core->SetLoopDoneCallback(cb);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 动画结束时移除目标角色 /// @brief 动画结束时移除目标角色
inline TweenHelper& RemoveTargetWhenDone() { core->RemoveTargetWhenDone(); return (*this); } inline TweenHelper& RemoveTargetWhenDone()
{
core->RemoveTargetWhenDone();
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 设置名称 /// @brief 设置名称
inline TweenHelper& SetName(String const& name) { core->SetName(name); return (*this); } inline TweenHelper& SetName(String const& name)
{
core->SetName(name);
return (*this);
}
/// \~chinese /// \~chinese
/// @brief 获取指针 /// @brief 获取指针
inline ActionTweenPtr Get() const { return core; } inline ActionTweenPtr Get() const
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: 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 /// \~chinese
/// @brief 构造相对位移动画 /// @brief 构造相对位移动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param vector 移动向量 /// @param vector 移动向量
static inline TweenHelper static inline TweenHelper MoveBy(Duration dur, Point const& vector)
MoveBy(Duration dur, Point const& vector)
{ {
return TweenHelper(new kiwano::ActionMoveBy(dur, vector)); return TweenHelper(new kiwano::ActionMoveBy(dur, vector));
} }
@ -145,8 +221,7 @@ namespace kiwano
/// @brief 构造位移动画 /// @brief 构造位移动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param pos 目的坐标 /// @param pos 目的坐标
static inline TweenHelper static inline TweenHelper MoveTo(Duration dur, Point const& pos)
MoveTo(Duration dur, Point const& pos)
{ {
return TweenHelper(new kiwano::ActionMoveTo(dur, pos)); return TweenHelper(new kiwano::ActionMoveTo(dur, pos));
} }
@ -157,8 +232,7 @@ namespace kiwano
/// @param vec 跳跃位移向量 /// @param vec 跳跃位移向量
/// @param height 跳跃高度 /// @param height 跳跃高度
/// @param jumps 跳跃次数 /// @param jumps 跳跃次数
static inline TweenHelper static inline TweenHelper JumpBy(Duration duration, Vec2 const& vec, float height, int jumps = 1)
JumpBy(Duration duration, Vec2 const& vec, float height, int jumps = 1)
{ {
return TweenHelper(new kiwano::ActionJumpBy(duration, vec, height, jumps)); return TweenHelper(new kiwano::ActionJumpBy(duration, vec, height, jumps));
} }
@ -169,8 +243,7 @@ namespace kiwano
/// @param pos 目的坐标 /// @param pos 目的坐标
/// @param height 跳跃高度 /// @param height 跳跃高度
/// @param jumps 跳跃次数 /// @param jumps 跳跃次数
static inline TweenHelper static inline TweenHelper JumpTo(Duration duration, Point const& pos, float height, int jumps = 1)
JumpTo(Duration duration, Point const& pos, float height, int jumps = 1)
{ {
return TweenHelper(new kiwano::ActionJumpTo(duration, pos, height, jumps)); return TweenHelper(new kiwano::ActionJumpTo(duration, pos, height, jumps));
} }
@ -180,8 +253,7 @@ namespace kiwano
/// @param duration 动画时长 /// @param duration 动画时长
/// @param scale_x 横向缩放相对变化值 /// @param scale_x 横向缩放相对变化值
/// @param scale_y 纵向缩放相对变化值 /// @param scale_y 纵向缩放相对变化值
static inline TweenHelper static inline TweenHelper ScaleBy(Duration dur, float scale_x, float scale_y)
ScaleBy(Duration dur, float scale_x, float scale_y)
{ {
return TweenHelper(new kiwano::ActionScaleBy(dur, scale_x, scale_y)); return TweenHelper(new kiwano::ActionScaleBy(dur, scale_x, scale_y));
} }
@ -191,8 +263,7 @@ namespace kiwano
/// @param duration 动画时长 /// @param duration 动画时长
/// @param scale_x 横向缩放目标值 /// @param scale_x 横向缩放目标值
/// @param scale_y 纵向缩放目标值 /// @param scale_y 纵向缩放目标值
static inline TweenHelper static inline TweenHelper ScaleTo(Duration dur, float scale_x, float scale_y)
ScaleTo(Duration dur, float scale_x, float scale_y)
{ {
return TweenHelper(new kiwano::ActionScaleTo(dur, scale_x, scale_y)); return TweenHelper(new kiwano::ActionScaleTo(dur, scale_x, scale_y));
} }
@ -201,8 +272,7 @@ namespace kiwano
/// @brief 构造透明度渐变动画 /// @brief 构造透明度渐变动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param opacity 目标透明度 /// @param opacity 目标透明度
static inline TweenHelper static inline TweenHelper FadeTo(Duration dur, float opacity)
FadeTo(Duration dur, float opacity)
{ {
return TweenHelper(new kiwano::ActionFadeTo(dur, opacity)); return TweenHelper(new kiwano::ActionFadeTo(dur, opacity));
} }
@ -210,8 +280,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 构造淡入动画 /// @brief 构造淡入动画
/// @param duration 动画时长 /// @param duration 动画时长
static inline TweenHelper static inline TweenHelper FadeIn(Duration dur)
FadeIn(Duration dur)
{ {
return TweenHelper(new kiwano::ActionFadeIn(dur)); return TweenHelper(new kiwano::ActionFadeIn(dur));
} }
@ -219,8 +288,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 构造淡出动画 /// @brief 构造淡出动画
/// @param duration 动画时长 /// @param duration 动画时长
static inline TweenHelper static inline TweenHelper FadeOut(Duration dur)
FadeOut(Duration dur)
{ {
return TweenHelper(new kiwano::ActionFadeOut(dur)); return TweenHelper(new kiwano::ActionFadeOut(dur));
} }
@ -229,8 +297,7 @@ namespace kiwano
/// @brief 构造相对旋转动画 /// @brief 构造相对旋转动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param rotation 角度相对变化值 /// @param rotation 角度相对变化值
static inline TweenHelper static inline TweenHelper RotateBy(Duration dur, float rotation)
RotateBy(Duration dur, float rotation)
{ {
return TweenHelper(new kiwano::ActionRotateBy(dur, rotation)); return TweenHelper(new kiwano::ActionRotateBy(dur, rotation));
} }
@ -239,8 +306,7 @@ namespace kiwano
/// @brief 构造旋转动画 /// @brief 构造旋转动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param rotation 目标角度 /// @param rotation 目标角度
static inline TweenHelper static inline TweenHelper RotateTo(Duration dur, float rotation)
RotateTo(Duration dur, float rotation)
{ {
return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); return TweenHelper(new kiwano::ActionRotateTo(dur, rotation));
} }
@ -252,8 +318,8 @@ namespace kiwano
/// @param rotating 是否沿路径切线方向旋转 /// @param rotating 是否沿路径切线方向旋转
/// @param start 路径起点(百分比) /// @param start 路径起点(百分比)
/// @param end 路径终点(百分比) /// @param end 路径终点(百分比)
static inline TweenHelper static inline TweenHelper Walk(Duration duration, Geometry const& path, bool rotating = false, float start = 0.f,
Walk(Duration duration, Geometry const& path, bool rotating = false, float start = 0.f, float end = 1.f) float end = 1.f)
{ {
return TweenHelper(new kiwano::ActionWalk(duration, path, rotating, start, end)); return TweenHelper(new kiwano::ActionWalk(duration, path, rotating, start, end));
} }
@ -262,8 +328,7 @@ namespace kiwano
/// @brief 构建帧动画 /// @brief 构建帧动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param[in] frame_seq 序列帧 /// @param[in] frame_seq 序列帧
static inline TweenHelper static inline TweenHelper Animation(Duration dur, FrameSequencePtr frames)
Animation(Duration dur, FrameSequencePtr frames)
{ {
return TweenHelper(new kiwano::Animation(dur, frames)); return TweenHelper(new kiwano::Animation(dur, frames));
} }
@ -272,8 +337,7 @@ namespace kiwano
/// @brief 构造自定义动画 /// @brief 构造自定义动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param tween_func 动画回调函数 /// @param tween_func 动画回调函数
static inline TweenHelper static inline TweenHelper Custom(Duration dur, ActionCustom::TweenFunc tween_func)
Custom(Duration dur, ActionCustom::TweenFunc tween_func)
{ {
return TweenHelper(new kiwano::ActionCustom(dur, tween_func)); return TweenHelper(new kiwano::ActionCustom(dur, tween_func));
} }
@ -281,8 +345,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 构建延时动画 /// @brief 构建延时动画
/// @param delay 延时时长 /// @param delay 延时时长
static inline ActionHelper static inline ActionHelper Delay(Duration delay)
Delay(Duration delay)
{ {
return ActionHelper(new kiwano::ActionDelay(delay)); return ActionHelper(new kiwano::ActionDelay(delay));
} }
@ -291,8 +354,7 @@ namespace kiwano
/// @brief 动画组合 /// @brief 动画组合
/// @param actions 动画集合 /// @param actions 动画集合
/// @param sequence 动画按顺序依次执行或同时执行 /// @param sequence 动画按顺序依次执行或同时执行
static inline ActionHelper static inline ActionHelper Group(Vector<ActionPtr> const& actions, bool sequence = true)
Group(Vector<ActionPtr> const& actions, bool sequence = true)
{ {
return ActionHelper(new kiwano::ActionGroup(actions, sequence)); return ActionHelper(new kiwano::ActionGroup(actions, sequence));
} }
@ -300,12 +362,11 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 同步动画组合 /// @brief 同步动画组合
/// @param actions 动画集合 /// @param actions 动画集合
static inline ActionHelper static inline ActionHelper Multiple(Vector<ActionPtr> const& actions)
Multiple(Vector<ActionPtr> const& actions)
{ {
return ActionHelper(new kiwano::ActionGroup(actions, false)); return ActionHelper(new kiwano::ActionGroup(actions, false));
} }
}; };
/** @} */ /** @} */
} } // namespace kiwano

View File

@ -18,14 +18,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/2d/action/ActionManager.h>
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/action/ActionManager.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
namespace kiwano namespace kiwano
{ {
void ActionManager::UpdateActions(Actor* target, Duration dt) void ActionManager::UpdateActions(Actor* target, Duration dt)
{ {
if (actions_.empty() || !target) if (actions_.empty() || !target)
return; return;
@ -40,15 +40,15 @@ namespace kiwano
if (action->IsRemoveable()) if (action->IsRemoveable())
actions_.remove(action); actions_.remove(action);
} }
} }
Action* ActionManager::AddAction(ActionPtr action) Action* ActionManager::AddAction(ActionPtr action)
{ {
return AddAction(action.get()); return AddAction(action.get());
} }
Action* ActionManager::AddAction(Action* action) Action* ActionManager::AddAction(Action* action)
{ {
KGE_ASSERT(action && "AddAction failed, NULL pointer exception"); KGE_ASSERT(action && "AddAction failed, NULL pointer exception");
if (action) if (action)
@ -56,55 +56,55 @@ namespace kiwano
actions_.push_back(action); actions_.push_back(action);
} }
return action; return action;
} }
ActionPtr ActionManager::GetAction(String const & name) void ActionManager::ResumeAllActions()
{ {
if (actions_.empty())
return nullptr;
for (auto& action : actions_)
if (action->IsName(name))
return action;
return nullptr;
}
void ActionManager::ResumeAllActions()
{
if (actions_.empty()) if (actions_.empty())
return; return;
for (auto& action : actions_) for (auto& action : actions_)
{ {
action->Resume(); 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_;
} }
} }
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

View File

@ -23,18 +23,18 @@
namespace kiwano namespace kiwano
{ {
/** /**
* \addtogroup Actions * \addtogroup Actions
* @{ * @{
*/ */
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API ActionManager class KGE_API ActionManager
{ {
public: public:
/// \~chinese /// \~chinese
/// @brief 动画列表 /// @brief 动画列表
using Actions = IntrusiveList<ActionPtr>; using Actions = IntrusiveList<ActionPtr>;
@ -47,11 +47,6 @@ namespace kiwano
/// @brief 添加动画 /// @brief 添加动画
Action* AddAction(Action* action); Action* AddAction(Action* action);
/// \~chinese
/// @brief 获取指定名称的动画
/// @param name 动画名称
ActionPtr GetAction(String const& name);
/// \~chinese /// \~chinese
/// @brief 继续所有暂停动画 /// @brief 继续所有暂停动画
void ResumeAllActions(); void ResumeAllActions();
@ -64,18 +59,23 @@ namespace kiwano
/// @brief 停止所有动画 /// @brief 停止所有动画
void StopAllActions(); void StopAllActions();
/// \~chinese
/// @brief 获取指定名称的动画
/// @param name 动画名称
ActionPtr GetAction(String const& name);
/// \~chinese /// \~chinese
/// @brief 获取所有动画 /// @brief 获取所有动画
Actions const& GetAllActions() const; Actions const& GetAllActions() const;
protected: protected:
/// \~chinese /// \~chinese
/// @brief 更新动画 /// @brief 更新动画
void UpdateActions(Actor* target, Duration dt); void UpdateActions(Actor* target, Duration dt);
private: private:
Actions actions_; Actions actions_;
}; };
/** @} */ /** @} */
} } // namespace kiwano

View File

@ -19,87 +19,105 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <functional> #include <functional>
#include <kiwano/2d/action/ActionTween.h>
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/action/ActionTween.h>
namespace kiwano namespace kiwano
{ {
//------------------------------------------------------- //-------------------------------------------------------
// Ease Functions // Ease Functions
//------------------------------------------------------- //-------------------------------------------------------
inline EaseFunc MakeEaseIn(float rate) { return std::bind(math::EaseIn, std::placeholders::_1, rate); } inline EaseFunc MakeEaseIn(float 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); } return std::bind(math::EaseIn, 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 MakeEaseOut(float rate)
inline EaseFunc MakeEaseElasticInOut(float period) { return std::bind(math::EaseElasticInOut, std::placeholders::_1, period); } {
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::Linear = math::Linear;
KGE_API EaseFunc Ease::EaseIn = MakeEaseIn(2.f); KGE_API EaseFunc Ease::EaseIn = MakeEaseIn(2.f);
KGE_API EaseFunc Ease::EaseOut = MakeEaseOut(2.f); KGE_API EaseFunc Ease::EaseOut = MakeEaseOut(2.f);
KGE_API EaseFunc Ease::EaseInOut = MakeEaseInOut(2.f); KGE_API EaseFunc Ease::EaseInOut = MakeEaseInOut(2.f);
KGE_API EaseFunc Ease::ExpoIn = math::EaseExponentialIn; KGE_API EaseFunc Ease::ExpoIn = math::EaseExponentialIn;
KGE_API EaseFunc Ease::ExpoOut = math::EaseExponentialOut; KGE_API EaseFunc Ease::ExpoOut = math::EaseExponentialOut;
KGE_API EaseFunc Ease::ExpoInOut = math::EaseExponentialInOut; KGE_API EaseFunc Ease::ExpoInOut = math::EaseExponentialInOut;
KGE_API EaseFunc Ease::BounceIn = math::EaseBounceIn; KGE_API EaseFunc Ease::BounceIn = math::EaseBounceIn;
KGE_API EaseFunc Ease::BounceOut = math::EaseBounceOut; KGE_API EaseFunc Ease::BounceOut = math::EaseBounceOut;
KGE_API EaseFunc Ease::BounceInOut = math::EaseBounceInOut; KGE_API EaseFunc Ease::BounceInOut = math::EaseBounceInOut;
KGE_API EaseFunc Ease::ElasticIn = MakeEaseElasticIn(0.3f); KGE_API EaseFunc Ease::ElasticIn = MakeEaseElasticIn(0.3f);
KGE_API EaseFunc Ease::ElasticOut = MakeEaseElasticOut(0.3f); KGE_API EaseFunc Ease::ElasticOut = MakeEaseElasticOut(0.3f);
KGE_API EaseFunc Ease::ElasticInOut = MakeEaseElasticInOut(0.3f); KGE_API EaseFunc Ease::ElasticInOut = MakeEaseElasticInOut(0.3f);
KGE_API EaseFunc Ease::SineIn = math::EaseSineIn; KGE_API EaseFunc Ease::SineIn = math::EaseSineIn;
KGE_API EaseFunc Ease::SineOut = math::EaseSineOut; KGE_API EaseFunc Ease::SineOut = math::EaseSineOut;
KGE_API EaseFunc Ease::SineInOut = math::EaseSineInOut; KGE_API EaseFunc Ease::SineInOut = math::EaseSineInOut;
KGE_API EaseFunc Ease::BackIn = math::EaseBackIn; KGE_API EaseFunc Ease::BackIn = math::EaseBackIn;
KGE_API EaseFunc Ease::BackOut = math::EaseBackOut; KGE_API EaseFunc Ease::BackOut = math::EaseBackOut;
KGE_API EaseFunc Ease::BackInOut = math::EaseBackInOut; KGE_API EaseFunc Ease::BackInOut = math::EaseBackInOut;
KGE_API EaseFunc Ease::QuadIn = math::EaseQuadIn; KGE_API EaseFunc Ease::QuadIn = math::EaseQuadIn;
KGE_API EaseFunc Ease::QuadOut = math::EaseQuadOut; KGE_API EaseFunc Ease::QuadOut = math::EaseQuadOut;
KGE_API EaseFunc Ease::QuadInOut = math::EaseQuadInOut; KGE_API EaseFunc Ease::QuadInOut = math::EaseQuadInOut;
KGE_API EaseFunc Ease::CubicIn = math::EaseCubicIn; KGE_API EaseFunc Ease::CubicIn = math::EaseCubicIn;
KGE_API EaseFunc Ease::CubicOut = math::EaseCubicOut; KGE_API EaseFunc Ease::CubicOut = math::EaseCubicOut;
KGE_API EaseFunc Ease::CubicInOut = math::EaseCubicInOut; KGE_API EaseFunc Ease::CubicInOut = math::EaseCubicInOut;
KGE_API EaseFunc Ease::QuartIn = math::EaseQuartIn; KGE_API EaseFunc Ease::QuartIn = math::EaseQuartIn;
KGE_API EaseFunc Ease::QuartOut = math::EaseQuartOut; KGE_API EaseFunc Ease::QuartOut = math::EaseQuartOut;
KGE_API EaseFunc Ease::QuartInOut = math::EaseQuartInOut; KGE_API EaseFunc Ease::QuartInOut = math::EaseQuartInOut;
KGE_API EaseFunc Ease::QuintIn = math::EaseQuintIn; KGE_API EaseFunc Ease::QuintIn = math::EaseQuintIn;
KGE_API EaseFunc Ease::QuintOut = math::EaseQuintOut; KGE_API EaseFunc Ease::QuintOut = math::EaseQuintOut;
KGE_API EaseFunc Ease::QuintInOut = math::EaseQuintInOut; KGE_API EaseFunc Ease::QuintInOut = math::EaseQuintInOut;
//------------------------------------------------------- //-------------------------------------------------------
// ActionTween // ActionTween
//------------------------------------------------------- //-------------------------------------------------------
ActionTween::ActionTween() ActionTween::ActionTween()
: dur_() : dur_()
, ease_func_(nullptr) , ease_func_(nullptr)
{ {
} }
ActionTween::ActionTween(Duration duration, EaseFunc func) ActionTween::ActionTween(Duration duration, EaseFunc func)
{ {
SetDuration(duration); SetDuration(duration);
SetEaseFunc(func); SetEaseFunc(func);
} }
void ActionTween::SetEaseFunc(EaseFunc const& func) void ActionTween::SetEaseFunc(EaseFunc const& func)
{ {
ease_func_ = func; ease_func_ = func;
} }
EaseFunc const & ActionTween::GetEaseFunc() const EaseFunc const& ActionTween::GetEaseFunc() const
{ {
return ease_func_; return ease_func_;
} }
Duration ActionTween::GetDuration() const Duration ActionTween::GetDuration() const
{ {
return dur_; return dur_;
} }
void ActionTween::Update(Actor* target, Duration dt) void ActionTween::Update(Actor* target, Duration dt)
{ {
float percent; float percent;
if (dur_.IsZero()) if (dur_.IsZero())
@ -124,34 +142,33 @@ namespace kiwano
percent = ease_func_(percent); percent = ease_func_(percent);
UpdateTween(target, percent); UpdateTween(target, percent);
} }
void ActionTween::SetDuration(Duration duration) void ActionTween::SetDuration(Duration duration)
{ {
dur_ = duration; dur_ = duration;
} }
//-------------------------------------------------------
// Move Action
//-------------------------------------------------------
//------------------------------------------------------- ActionMoveBy::ActionMoveBy(Duration duration, Vec2 const& vector, EaseFunc func)
// Move Action
//-------------------------------------------------------
ActionMoveBy::ActionMoveBy(Duration duration, Vec2 const& vector, EaseFunc func)
: ActionTween(duration, func) : ActionTween(duration, func)
{ {
delta_pos_ = vector; delta_pos_ = vector;
} }
void ActionMoveBy::Init(Actor* target) void ActionMoveBy::Init(Actor* target)
{ {
if (target) if (target)
{ {
prev_pos_ = start_pos_ = target->GetPosition(); 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_; Point diff = target->GetPosition() - prev_pos_;
start_pos_ = start_pos_ + diff; start_pos_ = start_pos_ + diff;
@ -159,68 +176,67 @@ namespace kiwano
target->SetPosition(new_pos); target->SetPosition(new_pos);
prev_pos_ = new_pos; prev_pos_ = new_pos;
} }
ActionPtr ActionMoveBy::Clone() const ActionPtr ActionMoveBy::Clone() const
{ {
return new (std::nothrow) ActionMoveBy(GetDuration(), delta_pos_, GetEaseFunc()); 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()); 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) : ActionMoveBy(duration, Point(), func)
{ {
end_pos_ = pos; end_pos_ = pos;
} }
ActionPtr ActionMoveTo::Clone() const ActionPtr ActionMoveTo::Clone() const
{ {
return new (std::nothrow) ActionMoveTo(GetDuration(), end_pos_, GetEaseFunc()); return new (std::nothrow) ActionMoveTo(GetDuration(), end_pos_, GetEaseFunc());
} }
void ActionMoveTo::Init(Actor* target) void ActionMoveTo::Init(Actor* target)
{ {
ActionMoveBy::Init(target); ActionMoveBy::Init(target);
delta_pos_ = end_pos_ - start_pos_; delta_pos_ = end_pos_ - start_pos_;
} }
//-------------------------------------------------------
// Jump Action
//-------------------------------------------------------
//------------------------------------------------------- ActionJumpBy::ActionJumpBy(Duration duration, Vec2 const& vec, float height, int jumps, EaseFunc func)
// Jump Action
//-------------------------------------------------------
ActionJumpBy::ActionJumpBy(Duration duration, Vec2 const& vec, float height, int jumps, EaseFunc func)
: ActionTween(duration, func) : ActionTween(duration, func)
, delta_pos_(vec) , delta_pos_(vec)
, height_(height) , height_(height)
, jumps_(jumps) , jumps_(jumps)
{ {
} }
ActionPtr ActionJumpBy::Clone() const ActionPtr ActionJumpBy::Clone() const
{ {
return new (std::nothrow) ActionJumpBy(GetDuration(), delta_pos_, height_, jumps_, GetEaseFunc()); 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()); return new (std::nothrow) ActionJumpBy(GetDuration(), -delta_pos_, height_, jumps_, GetEaseFunc());
} }
void ActionJumpBy::Init(Actor* target) void ActionJumpBy::Init(Actor* target)
{ {
if (target) if (target)
{ {
prev_pos_ = start_pos_ = target->GetPosition(); 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 frac = fmod(percent * jumps_, 1.f);
float x = delta_pos_.x * percent; float x = delta_pos_.x * percent;
float y = height_ * 4 * frac * (1 - frac); float y = height_ * 4 * frac * (1 - frac);
@ -233,206 +249,202 @@ namespace kiwano
target->SetPosition(new_pos); target->SetPosition(new_pos);
prev_pos_ = 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) : ActionJumpBy(duration, Point(), height, jumps, func)
, end_pos_(pos) , end_pos_(pos)
{ {
} }
ActionPtr ActionJumpTo::Clone() const ActionPtr ActionJumpTo::Clone() const
{ {
return new (std::nothrow) ActionJumpTo(GetDuration(), end_pos_, height_, jumps_, GetEaseFunc()); return new (std::nothrow) ActionJumpTo(GetDuration(), end_pos_, height_, jumps_, GetEaseFunc());
} }
void ActionJumpTo::Init(Actor* target) void ActionJumpTo::Init(Actor* target)
{ {
ActionJumpBy::Init(target); ActionJumpBy::Init(target);
delta_pos_ = end_pos_ - start_pos_; delta_pos_ = end_pos_ - start_pos_;
} }
//-------------------------------------------------------
// Scale Action
//-------------------------------------------------------
//------------------------------------------------------- ActionScaleBy::ActionScaleBy(Duration duration, float scale_x, float scale_y, EaseFunc func)
// Scale Action
//-------------------------------------------------------
ActionScaleBy::ActionScaleBy(Duration duration, float scale_x, float scale_y, EaseFunc func)
: ActionTween(duration, func) : ActionTween(duration, func)
, delta_x_(scale_x) , delta_x_(scale_x)
, delta_y_(scale_y) , delta_y_(scale_y)
, start_scale_x_(0.f) , start_scale_x_(0.f)
, start_scale_y_(0.f) , start_scale_y_(0.f)
{ {
} }
void ActionScaleBy::Init(Actor* target) void ActionScaleBy::Init(Actor* target)
{ {
if (target) if (target)
{ {
start_scale_x_ = target->GetScaleX(); start_scale_x_ = target->GetScaleX();
start_scale_y_ = target->GetScaleY(); 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 }); 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()); 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()); 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) : ActionScaleBy(duration, 0, 0, func)
{ {
end_scale_x_ = scale_x; end_scale_x_ = scale_x;
end_scale_y_ = scale_y; 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()); 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); ActionScaleBy::Init(target);
delta_x_ = end_scale_x_ - start_scale_x_; delta_x_ = end_scale_x_ - start_scale_x_;
delta_y_ = end_scale_y_ - start_scale_y_; delta_y_ = end_scale_y_ - start_scale_y_;
} }
//-------------------------------------------------------
// Opacity Action
//-------------------------------------------------------
//------------------------------------------------------- ActionFadeTo::ActionFadeTo(Duration duration, float opacity, EaseFunc func)
// Opacity Action
//-------------------------------------------------------
ActionFadeTo::ActionFadeTo(Duration duration, float opacity, EaseFunc func)
: ActionTween(duration, func) : ActionTween(duration, func)
, delta_val_(0.f) , delta_val_(0.f)
, start_val_(0.f) , start_val_(0.f)
, end_val_(opacity) , end_val_(opacity)
{ {
} }
void ActionFadeTo::Init(Actor* target) void ActionFadeTo::Init(Actor* target)
{ {
if (target) if (target)
{ {
start_val_ = target->GetOpacity(); start_val_ = target->GetOpacity();
delta_val_ = end_val_ - start_val_; 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); target->SetOpacity(start_val_ + delta_val_ * percent);
} }
ActionPtr ActionFadeTo::Clone() const ActionPtr ActionFadeTo::Clone() const
{ {
return new (std::nothrow) ActionFadeTo(GetDuration(), end_val_, GetEaseFunc()); 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) : ActionFadeTo(duration, 1, func)
{ {
} }
ActionFadeOut::ActionFadeOut(Duration duration, EaseFunc func) ActionFadeOut::ActionFadeOut(Duration duration, EaseFunc func)
: ActionFadeTo(duration, 0, func) : ActionFadeTo(duration, 0, func)
{ {
} }
//-------------------------------------------------------
// Rotate Action
//-------------------------------------------------------
//------------------------------------------------------- ActionRotateBy::ActionRotateBy(Duration duration, float rotation, EaseFunc func)
// Rotate Action
//-------------------------------------------------------
ActionRotateBy::ActionRotateBy(Duration duration, float rotation, EaseFunc func)
: ActionTween(duration, func) : ActionTween(duration, func)
, start_val_() , start_val_()
, delta_val_(rotation) , delta_val_(rotation)
{ {
} }
void ActionRotateBy::Init(Actor* target) void ActionRotateBy::Init(Actor* target)
{ {
if (target) if (target)
{ {
start_val_ = target->GetRotation(); 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; float rotation = start_val_ + delta_val_ * percent;
if (rotation > 360.f) if (rotation > 360.f)
rotation -= 360.f; rotation -= 360.f;
target->SetRotation(rotation); target->SetRotation(rotation);
} }
ActionPtr ActionRotateBy::Clone() const ActionPtr ActionRotateBy::Clone() const
{ {
return new (std::nothrow) ActionRotateBy(GetDuration(), delta_val_, GetEaseFunc()); 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()); 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) : ActionRotateBy(duration, 0, func)
{ {
end_val_ = rotation; end_val_ = rotation;
} }
ActionPtr ActionRotateTo::Clone() const ActionPtr ActionRotateTo::Clone() const
{ {
return new (std::nothrow) ActionRotateTo(GetDuration(), end_val_, GetEaseFunc()); return new (std::nothrow) ActionRotateTo(GetDuration(), end_val_, GetEaseFunc());
} }
void ActionRotateTo::Init(Actor* target) void ActionRotateTo::Init(Actor* target)
{ {
ActionRotateBy::Init(target); ActionRotateBy::Init(target);
delta_val_ = end_val_ - start_val_; delta_val_ = end_val_ - start_val_;
} }
//-------------------------------------------------------
// ActionCustom
//-------------------------------------------------------
//------------------------------------------------------- ActionCustom::ActionCustom(Duration duration, TweenFunc tween_func, EaseFunc func)
// ActionCustom
//-------------------------------------------------------
ActionCustom::ActionCustom(Duration duration, TweenFunc tween_func, EaseFunc func)
: ActionTween(duration, func) : ActionTween(duration, func)
, tween_func_(tween_func) , tween_func_(tween_func)
{ {
} }
ActionPtr ActionCustom::Clone() const ActionPtr ActionCustom::Clone() const
{ {
return new ActionCustom(GetDuration(), tween_func_); return new ActionCustom(GetDuration(), tween_func_);
} }
void ActionCustom::Init(Actor* target) void ActionCustom::Init(Actor* target)
{ {
if (!tween_func_) if (!tween_func_)
this->Done(); this->Done();
} }
void ActionCustom::UpdateTween(Actor* target, float percent) void ActionCustom::UpdateTween(Actor* target, float percent)
{ {
if (tween_func_) if (tween_func_)
tween_func_(target, percent); tween_func_(target, percent);
}
} }
} // namespace kiwano

View File

@ -24,15 +24,15 @@
namespace kiwano namespace kiwano
{ {
/// \~chinese /// \~chinese
/// @brief 缓动函数 /// @brief 缓动函数
using EaseFunc = Function<float(float)>; using EaseFunc = Function<float(float)>;
/// \~chinese /// \~chinese
/// @brief 缓动函数枚举 /// @brief 缓动函数枚举
/// @details 查看 https://easings.net 获取更多信息 /// @details 查看 https://easings.net 获取更多信息
struct Ease struct Ease
{ {
static KGE_API EaseFunc Linear; ///< 线性 static KGE_API EaseFunc Linear; ///< 线性
static KGE_API EaseFunc EaseIn; ///< 由慢变快 static KGE_API EaseFunc EaseIn; ///< 由慢变快
static KGE_API EaseFunc EaseOut; ///< 由快变慢 static KGE_API EaseFunc EaseOut; ///< 由快变慢
@ -64,35 +64,32 @@ namespace kiwano
static KGE_API EaseFunc SineIn; static KGE_API EaseFunc SineIn;
static KGE_API EaseFunc SineOut; static KGE_API EaseFunc SineOut;
static KGE_API EaseFunc SineInOut; 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 * \addtogroup Actions
* @{ * @{
*/ */
/// \~chinese /// \~chinese
/// @brief 补间动画 /// @brief 补间动画
class KGE_API ActionTween class KGE_API ActionTween : public Action
: public Action {
{ public:
public:
ActionTween(); ActionTween();
/// \~chinese /// \~chinese
@ -117,23 +114,21 @@ namespace kiwano
/// @brief 设置动画速度缓动函数 /// @brief 设置动画速度缓动函数
void SetEaseFunc(EaseFunc const& func); void SetEaseFunc(EaseFunc const& func);
protected: protected:
void Update(Actor* target, Duration dt) override; void Update(Actor* target, Duration dt) override;
virtual void UpdateTween(Actor* target, float percent) = 0; virtual void UpdateTween(Actor* target, float percent) = 0;
private: private:
Duration dur_; Duration dur_;
EaseFunc ease_func_; EaseFunc ease_func_;
}; };
/// \~chinese
/// \~chinese /// @brief 相对位移动画
/// @brief 相对位移动画 class KGE_API ActionMoveBy : public ActionTween
class KGE_API ActionMoveBy {
: public ActionTween public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造相对位移动画 /// @brief 构造相对位移动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -149,24 +144,22 @@ namespace kiwano
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override; ActionPtr Reverse() const override;
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override; void UpdateTween(Actor* target, float percent) override;
protected: protected:
Point start_pos_; Point start_pos_;
Point prev_pos_; Point prev_pos_;
Vec2 delta_pos_; Vec2 delta_pos_;
}; };
/// \~chinese
/// \~chinese /// @brief 位移动画
/// @brief 位移动画 class KGE_API ActionMoveTo : public ActionMoveBy
class KGE_API ActionMoveTo {
: public ActionMoveBy public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造位移动画 /// @brief 构造位移动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -186,20 +179,18 @@ namespace kiwano
return nullptr; return nullptr;
} }
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
private: private:
Point end_pos_; Point end_pos_;
}; };
/// \~chinese
/// \~chinese /// @brief 相对跳跃动画
/// @brief 相对跳跃动画 class KGE_API ActionJumpBy : public ActionTween
class KGE_API ActionJumpBy {
: public ActionTween public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造相对跳跃动画 /// @brief 构造相对跳跃动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -217,26 +208,24 @@ namespace kiwano
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override; ActionPtr Reverse() const override;
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override; void UpdateTween(Actor* target, float percent) override;
protected: protected:
Point start_pos_; Point start_pos_;
Point delta_pos_; Point delta_pos_;
float height_; float height_;
int jumps_; int jumps_;
Point prev_pos_; Point prev_pos_;
}; };
/// \~chinese
/// \~chinese /// @brief 跳跃动画
/// @brief 跳跃动画 class KGE_API ActionJumpTo : public ActionJumpBy
class KGE_API ActionJumpTo {
: public ActionJumpBy public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造跳跃动画 /// @brief 构造跳跃动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -258,20 +247,18 @@ namespace kiwano
return nullptr; return nullptr;
} }
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
private: private:
Point end_pos_; Point end_pos_;
}; };
/// \~chinese
/// \~chinese /// @brief 相对缩放动画
/// @brief 相对缩放动画 class KGE_API ActionScaleBy : public ActionTween
class KGE_API ActionScaleBy {
: public ActionTween public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造相对缩放动画 /// @brief 构造相对缩放动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -288,25 +275,23 @@ namespace kiwano
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override; ActionPtr Reverse() const override;
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override; void UpdateTween(Actor* target, float percent) override;
protected: protected:
float start_scale_x_; float start_scale_x_;
float start_scale_y_; float start_scale_y_;
float delta_x_; float delta_x_;
float delta_y_; float delta_y_;
}; };
/// \~chinese
/// \~chinese /// @brief 缩放动画
/// @brief 缩放动画 class KGE_API ActionScaleTo : public ActionScaleBy
class KGE_API ActionScaleTo {
: public ActionScaleBy public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造缩放动画 /// @brief 构造缩放动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -327,21 +312,19 @@ namespace kiwano
return nullptr; return nullptr;
} }
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
private: private:
float end_scale_x_; float end_scale_x_;
float end_scale_y_; float end_scale_y_;
}; };
/// \~chinese
/// \~chinese /// @brief 透明度渐变动画
/// @brief 透明度渐变动画 class KGE_API ActionFadeTo : public ActionTween
class KGE_API ActionFadeTo {
: public ActionTween public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造透明度渐变动画 /// @brief 构造透明度渐变动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -361,52 +344,46 @@ namespace kiwano
return nullptr; return nullptr;
} }
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override; void UpdateTween(Actor* target, float percent) override;
private: private:
float start_val_; float start_val_;
float delta_val_; float delta_val_;
float end_val_; float end_val_;
}; };
/// \~chinese
/// \~chinese /// @brief 淡入动画
/// @brief 淡入动画 class KGE_API ActionFadeIn : public ActionFadeTo
class KGE_API ActionFadeIn {
: public ActionFadeTo public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造淡入动画 /// @brief 构造淡入动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param func 动画速度缓动函数 /// @param func 动画速度缓动函数
explicit ActionFadeIn(Duration duration, EaseFunc func = nullptr); explicit ActionFadeIn(Duration duration, EaseFunc func = nullptr);
}; };
/// \~chinese
/// \~chinese /// @brief 淡出动画
/// @brief 淡出动画 class KGE_API ActionFadeOut : public ActionFadeTo
class KGE_API ActionFadeOut {
: public ActionFadeTo public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造淡出动画 /// @brief 构造淡出动画
/// @param duration 动画时长 /// @param duration 动画时长
/// @param func 动画速度缓动函数 /// @param func 动画速度缓动函数
explicit ActionFadeOut(Duration duration, EaseFunc func = nullptr); explicit ActionFadeOut(Duration duration, EaseFunc func = nullptr);
}; };
/// \~chinese
/// \~chinese /// @brief 相对旋转动画
/// @brief 相对旋转动画 class KGE_API ActionRotateBy : public ActionTween
class KGE_API ActionRotateBy {
: public ActionTween public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造相对旋转动画 /// @brief 构造相对旋转动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -422,23 +399,21 @@ namespace kiwano
/// @brief 获取该动画的倒转 /// @brief 获取该动画的倒转
ActionPtr Reverse() const override; ActionPtr Reverse() const override;
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override; void UpdateTween(Actor* target, float percent) override;
protected: protected:
float start_val_; float start_val_;
float delta_val_; float delta_val_;
}; };
/// \~chinese
/// \~chinese /// @brief 旋转动画
/// @brief 旋转动画 class KGE_API ActionRotateTo : public ActionRotateBy
class KGE_API ActionRotateTo {
: public ActionRotateBy public:
{
public:
/// \~chinese /// \~chinese
/// @brief 构造旋转动画 /// @brief 构造旋转动画
/// @param duration 动画时长 /// @param duration 动画时长
@ -458,20 +433,18 @@ namespace kiwano
return nullptr; return nullptr;
} }
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
private: private:
float end_val_; float end_val_;
}; };
/// \~chinese
/// \~chinese /// @brief 自定义动画
/// @brief 自定义动画 class KGE_API ActionCustom : public ActionTween
class KGE_API ActionCustom {
: public ActionTween public:
{
public:
/// \~chinese /// \~chinese
/// @brief 动画回调函数 /// @brief 动画回调函数
/// @details 在动画更新时回调该函数第一个参数是执行动画的目标第二个参数是动画进度0.0 - 1.0 /// @details 在动画更新时回调该函数第一个参数是执行动画的目标第二个参数是动画进度0.0 - 1.0
@ -496,15 +469,15 @@ namespace kiwano
return nullptr; return nullptr;
} }
protected: protected:
void Init(Actor* target) override; void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override; void UpdateTween(Actor* target, float percent) override;
private: private:
TweenFunc tween_func_; TweenFunc tween_func_;
}; };
/** @} */ /** @} */
} } // namespace kiwano

Some files were not shown because too many files have changed in this diff Show More