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

View File

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

View File

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

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

View File

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

View File

@ -7,9 +7,6 @@
<Filter Include="utils">
<UniqueIdentifier>{68eac919-ee87-4030-a033-c251731928f5}</UniqueIdentifier>
</Filter>
<Filter Include="ui">
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
</Filter>
<Filter Include="platform">
<UniqueIdentifier>{c2654ccc-59f6-4c17-bb6b-99b07fc78702}</UniqueIdentifier>
</Filter>
@ -19,29 +16,23 @@
<Filter Include="core">
<UniqueIdentifier>{2e18d99a-e906-499a-9e29-4e0783202644}</UniqueIdentifier>
</Filter>
<Filter Include="renderer">
<UniqueIdentifier>{7897afce-24cb-42b4-9443-56508e4ec89c}</UniqueIdentifier>
</Filter>
<Filter Include="2d\action">
<UniqueIdentifier>{9314f30d-5742-48b6-94e5-e3b4284106f6}</UniqueIdentifier>
</Filter>
<Filter Include="renderer\win32">
<UniqueIdentifier>{30333461-e9bc-4709-84bd-ce6e0e1a3079}</UniqueIdentifier>
</Filter>
<Filter Include="platform\win32">
<UniqueIdentifier>{e84dcf9a-e650-473e-8c9c-193804ab9e76}</UniqueIdentifier>
</Filter>
<Filter Include="core\event">
<UniqueIdentifier>{c629aedd-ffb9-4bc1-82c3-f50e77c82e77}</UniqueIdentifier>
</Filter>
<Filter Include="render">
<UniqueIdentifier>{adb44ca9-674a-4b77-993f-d65193d8ab06}</UniqueIdentifier>
</Filter>
<Filter Include="render\DirectX">
<UniqueIdentifier>{fd281702-0006-46d2-8fd1-28c502464164}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\kiwano\ui\Button.h">
<Filter>ui</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\ui\Menu.h">
<Filter>ui</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\Canvas.h">
<Filter>2d</Filter>
</ClInclude>
@ -66,9 +57,6 @@
<ClInclude Include="..\..\src\kiwano\core\Resource.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\time.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Matrix.hpp">
<Filter>math</Filter>
</ClInclude>
@ -156,63 +144,9 @@
<ClInclude Include="..\..\src\kiwano\core\ObjectBase.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\Color.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\Font.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\Geometry.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\GifImage.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\LayerArea.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\Renderer.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\TextLayout.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3DDeviceResourcesBase.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\TextRenderer.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\RenderTarget.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\Transform.h">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\Texture.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\TextureCache.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\StrokeStyle.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\Brush.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\constants.h">
<Filter>math</Filter>
</ClInclude>
@ -234,36 +168,18 @@
<ClInclude Include="..\..\src\kiwano\platform\FileSystem.h">
<Filter>platform</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\keys.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Input.h">
<Filter>platform</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Window.h">
<Filter>platform</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Director.h">
<Filter>platform</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\TextActor.h">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\common.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\RefCounter.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\win32\helper.h">
<Filter>renderer\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\renderer\GeometrySink.h">
<Filter>renderer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp">
<Filter>platform\win32</Filter>
</ClInclude>
@ -288,14 +204,89 @@
<ClInclude Include="..\..\src\kiwano\core\event\WindowEvent.h">
<Filter>core\event</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\Button.h">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Director.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Singleton.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Common.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Keys.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Time.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Brush.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Color.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Font.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Geometry.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\GeometrySink.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\GifImage.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\LayerArea.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\RenderContext.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Renderer.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\StrokeStyle.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\TextLayout.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\Texture.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\TextureCache.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\D3DDeviceResourcesBase.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\helper.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h">
<Filter>render\DirectX</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp">
<Filter>ui</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\ui\Menu.cpp">
<Filter>ui</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
<Filter>2d</Filter>
</ClCompile>
@ -317,9 +308,6 @@
<ClCompile Include="..\..\src\kiwano\core\Resource.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\time.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\Application.cpp">
<Filter>platform</Filter>
</ClCompile>
@ -383,57 +371,9 @@
<ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\Color.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\Font.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\Geometry.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\GifImage.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\LayerArea.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\Renderer.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\TextLayout.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\win32\D2DDeviceResources.cpp">
<Filter>renderer\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\win32\D3D10DeviceResources.cpp">
<Filter>renderer\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.cpp">
<Filter>renderer\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.cpp">
<Filter>renderer\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\win32\TextRenderer.cpp">
<Filter>renderer\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\RenderTarget.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\Transform.cpp">
<Filter>2d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\Texture.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\TextureCache.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\Component.cpp">
<Filter>core</Filter>
</ClCompile>
@ -455,18 +395,12 @@
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp">
<Filter>platform</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\Director.cpp">
<Filter>platform</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp">
<Filter>2d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\renderer\GeometrySink.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp">
<Filter>platform\win32</Filter>
</ClCompile>
@ -485,5 +419,71 @@
<ClCompile Include="..\..\src\kiwano\core\event\WindowEvent.cpp">
<Filter>core\event</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\Button.cpp">
<Filter>2d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\Director.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\win32\WindowImpl.cpp">
<Filter>platform\win32</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\Time.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\Brush.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\Color.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\Font.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\Geometry.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\GeometrySink.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\GifImage.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\LayerArea.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\RenderContext.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\Renderer.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\StrokeStyle.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\Texture.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\D2DDeviceResources.cpp">
<Filter>render\DirectX</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\D3D10DeviceResources.cpp">
<Filter>render\DirectX</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\D3D11DeviceResources.cpp">
<Filter>render\DirectX</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.cpp">
<Filter>render\DirectX</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\TextRenderer.cpp">
<Filter>render\DirectX</Filter>
</ClCompile>
</ItemGroup>
</Project>

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,234 +1,189 @@
// Copyright (C) 2019 Nomango
#include <kiwano/core/common.h>
#include <kiwano/platform/Window.h>
#include <kiwano/core/Common.h>
#include <kiwano/core/event/KeyEvent.h>
#include <kiwano/core/event/MouseEvent.h>
#include <kiwano/platform/Input.h>
#include <kiwano/renderer/Renderer.h>
#include <kiwano/platform/Window.h>
#include <kiwano/render/Renderer.h>
#include <kiwano-imgui/ImGuiModule.h>
#include <kiwano-imgui/imgui_impl.h>
#include <XInput.h>
#pragma comment(lib, "xinput")
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
#ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef DBT_DEVNODES_CHANGED
# define DBT_DEVNODES_CHANGED 0x0007
#endif
namespace kiwano
{
namespace imgui
{
ImGuiModule::ImGuiModule()
: has_gamepad_(false)
, want_update_has_gamepad_(false)
, target_window_(nullptr)
{
}
namespace imgui
{
ImGuiModule::ImGuiModule()
: target_window_(nullptr)
{
}
void ImGuiModule::SetupComponent()
{
void ImGuiModule::SetupComponent()
{
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
ImGuiIO& io = ImGui::GetIO();
(void)io;
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
Init(Window::instance().GetHandle());
target_window_ = Renderer::Instance().GetTargetWindow();
target_window_ = Renderer::instance().GetTargetWindow();
}
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |=
ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = target_window_;
void ImGuiModule::DestroyComponent()
{
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during
// the application lifetime.
io.KeyMap[ImGuiKey_Tab] = (int)KeyCode::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = (int)KeyCode::Left;
io.KeyMap[ImGuiKey_RightArrow] = (int)KeyCode::Right;
io.KeyMap[ImGuiKey_UpArrow] = (int)KeyCode::Up;
io.KeyMap[ImGuiKey_DownArrow] = (int)KeyCode::Down;
io.KeyMap[ImGuiKey_Delete] = (int)KeyCode::Delete;
io.KeyMap[ImGuiKey_Backspace] = (int)KeyCode::Back;
io.KeyMap[ImGuiKey_Space] = (int)KeyCode::Space;
io.KeyMap[ImGuiKey_Enter] = (int)KeyCode::Enter;
io.KeyMap[ImGuiKey_Escape] = (int)KeyCode::Esc;
io.KeyMap[ImGuiKey_A] = (int)KeyCode::A;
io.KeyMap[ImGuiKey_C] = (int)KeyCode::C;
io.KeyMap[ImGuiKey_V] = (int)KeyCode::V;
io.KeyMap[ImGuiKey_X] = (int)KeyCode::X;
io.KeyMap[ImGuiKey_Y] = (int)KeyCode::Y;
io.KeyMap[ImGuiKey_Z] = (int)KeyCode::Z;
ImGui_Impl_Init(Renderer::Instance());
}
void ImGuiModule::DestroyComponent()
{
ImGui_Impl_Shutdown();
ImGui::DestroyContext();
}
}
void ImGuiModule::OnUpdate(Duration dt)
{
void ImGuiModule::OnUpdate(Duration dt)
{
ImGuiIO& io = ImGui::GetIO();
// Setup time step
io.DeltaTime = dt.Seconds();
// Read keyboard modifiers inputs
io.KeyCtrl = Input::instance().IsDown(KeyCode::Ctrl);
io.KeyShift = Input::instance().IsDown(KeyCode::Shift);
io.KeyAlt = Input::instance().IsDown(KeyCode::Alt);
io.KeySuper = false;
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
io.KeyCtrl = Input::Instance().IsDown(KeyCode::Ctrl);
io.KeyShift = Input::Instance().IsDown(KeyCode::Shift);
io.KeyAlt = Input::Instance().IsDown(KeyCode::Alt);
io.KeySuper = Input::Instance().IsDown(KeyCode::Super);
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the HandleEvent function below.
// Update OS mouse position
UpdateMousePos();
// Update OS mouse cursor with the cursor requested by imgui
UpdateMouseCursor();
}
// Update game controllers (if enabled and available)
UpdateGamepads();
}
void ImGuiModule::Init(HWND hwnd)
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = hwnd;
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_Tab] = KeyCode::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = KeyCode::Left;
io.KeyMap[ImGuiKey_RightArrow] = KeyCode::Right;
io.KeyMap[ImGuiKey_UpArrow] = KeyCode::Up;
io.KeyMap[ImGuiKey_DownArrow] = KeyCode::Down;
io.KeyMap[ImGuiKey_Delete] = KeyCode::Delete;
io.KeyMap[ImGuiKey_Backspace] = KeyCode::Back;
io.KeyMap[ImGuiKey_Space] = KeyCode::Space;
io.KeyMap[ImGuiKey_Enter] = KeyCode::Enter;
io.KeyMap[ImGuiKey_Escape] = KeyCode::Esc;
io.KeyMap[ImGuiKey_A] = KeyCode::A;
io.KeyMap[ImGuiKey_C] = KeyCode::C;
io.KeyMap[ImGuiKey_V] = KeyCode::V;
io.KeyMap[ImGuiKey_X] = KeyCode::X;
io.KeyMap[ImGuiKey_Y] = KeyCode::Y;
io.KeyMap[ImGuiKey_Z] = KeyCode::Z;
ImGui_Impl_Init(&Renderer::instance());
}
void ImGuiModule::BeforeRender()
{
void ImGuiModule::BeforeRender()
{
NewFrame();
}
}
void ImGuiModule::AfterRender()
{
void ImGuiModule::AfterRender()
{
Render();
}
}
void ImGuiModule::HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
{
void ImGuiModule::HandleEvent(Event* evt)
{
if (ImGui::GetCurrentContext() == NULL)
return;
ImGuiIO& io = ImGui::GetIO();
switch (msg)
if (evt->IsType<MouseEvent>())
{
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
if (evt->IsType<MouseDownEvent>())
{
int button = 0;
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; }
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
::SetCapture(hwnd);
io.MouseDown[button] = true;
break;
MouseButton button = dynamic_cast<MouseDownEvent*>(evt)->button;
int index = 0;
if (button == MouseButton::Left)
index = 0;
else if (button == MouseButton::Right)
index = 1;
else if (button == MouseButton::Middle)
index = 2;
io.MouseDown[index] = true;
}
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
else if (evt->IsType<MouseUpEvent>())
{
int button = 0;
if (msg == WM_LBUTTONUP) { button = 0; }
if (msg == WM_RBUTTONUP) { button = 1; }
if (msg == WM_MBUTTONUP) { button = 2; }
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wparam) == XBUTTON1) ? 3 : 4; }
io.MouseDown[button] = false;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
::ReleaseCapture();
break;
MouseButton button = dynamic_cast<MouseUpEvent*>(evt)->button;
int index = 0;
if (button == MouseButton::Left)
index = 0;
else if (button == MouseButton::Right)
index = 1;
else if (button == MouseButton::Middle)
index = 2;
io.MouseDown[index] = false;
}
case WM_MOUSEWHEEL:
else if (evt->IsType<MouseWheelEvent>())
{
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA;
break;
float wheel = dynamic_cast<MouseWheelEvent*>(evt)->wheel;
io.MouseWheel += wheel;
}
case WM_MOUSEHWHEEL:
}
else if (evt->IsType<KeyEvent>())
{
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA;
break;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (evt->IsType<KeyDownEvent>())
{
if (wparam < 256)
io.KeysDown[wparam] = 1;
break;
KeyCode key = dynamic_cast<KeyDownEvent*>(evt)->code;
io.KeysDown[(int)key] = true;
}
case WM_KEYUP:
case WM_SYSKEYUP:
else if (evt->IsType<KeyUpEvent>())
{
if (wparam < 256)
io.KeysDown[wparam] = 0;
break;
KeyCode key = dynamic_cast<KeyUpEvent*>(evt)->code;
io.KeysDown[(int)key] = false;
}
case WM_CHAR:
else if (evt->IsType<KeyCharEvent>())
{
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
io.AddInputCharacter((uint32_t)wparam);
break;
}
case WM_SETCURSOR:
{
if (LOWORD(lparam) == HTCLIENT)
{
UpdateMouseCursor();
}
break;
}
case WM_DEVICECHANGE:
{
if ((uint32_t)wparam == DBT_DEVNODES_CHANGED)
want_update_has_gamepad_ = true;
break;
}
char ch = dynamic_cast<KeyCharEvent*>(evt)->value;
io.AddInputCharacter(static_cast<ImWchar>(ch));
}
}
}
void ImGuiModule::NewFrame()
{
void ImGuiModule::NewFrame()
{
ImGui_Impl_NewFrame();
ImGuiIO& io = ImGui::GetIO();
KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
// Setup display size (every frame to accommodate for window resizing)
Size display_size = Renderer::instance().GetOutputSize();
Size display_size = Renderer::Instance().GetOutputSize();
io.DisplaySize = ImVec2(display_size.x, display_size.y);
ImGui::NewFrame();
}
}
void ImGuiModule::Render()
{
void ImGuiModule::Render()
{
ImGui::Render();
ImGui_Impl_RenderDrawData(ImGui::GetDrawData());
}
}
void ImGuiModule::UpdateMousePos()
{
void ImGuiModule::UpdateMousePos()
{
ImGuiIO& io = ImGui::GetIO();
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by
// user)
if (io.WantSetMousePos)
{
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
@ -236,74 +191,46 @@ namespace kiwano
::SetCursorPos(pos.x, pos.y);
}
Point pos = Input::instance().GetMousePos();
Point pos = Input::Instance().GetMousePos();
io.MousePos = ImVec2(pos.x, pos.y);
}
}
void ImGuiModule::UpdateMouseCursor()
{
void ImGuiModule::UpdateMouseCursor()
{
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
CursorType cursor = CursorType::Arrow;
switch (ImGui::GetMouseCursor())
{
case ImGuiMouseCursor_Arrow: cursor = CursorType::Arrow; break;
case ImGuiMouseCursor_TextInput: cursor = CursorType::TextInput; break;
case ImGuiMouseCursor_ResizeAll: cursor = CursorType::SizeAll; break;
case ImGuiMouseCursor_ResizeEW: cursor = CursorType::SizeWE; break;
case ImGuiMouseCursor_ResizeNS: cursor = CursorType::SizeNS; break;
case ImGuiMouseCursor_ResizeNESW: cursor = CursorType::SizeNESW; break;
case ImGuiMouseCursor_ResizeNWSE: cursor = CursorType::SizeNWSE; break;
case ImGuiMouseCursor_Hand: cursor = CursorType::Hand; break;
case ImGuiMouseCursor_Arrow:
cursor = CursorType::Arrow;
break;
case ImGuiMouseCursor_TextInput:
cursor = CursorType::TextInput;
break;
case ImGuiMouseCursor_ResizeAll:
cursor = CursorType::SizeAll;
break;
case ImGuiMouseCursor_ResizeEW:
cursor = CursorType::SizeWE;
break;
case ImGuiMouseCursor_ResizeNS:
cursor = CursorType::SizeNS;
break;
case ImGuiMouseCursor_ResizeNESW:
cursor = CursorType::SizeNESW;
break;
case ImGuiMouseCursor_ResizeNWSE:
cursor = CursorType::SizeNWSE;
break;
case ImGuiMouseCursor_Hand:
cursor = CursorType::Hand;
break;
}
Window::instance().SetCursor(cursor);
}
void ImGuiModule::UpdateGamepads()
{
ImGuiIO& io = ImGui::GetIO();
memset(io.NavInputs, 0, sizeof(io.NavInputs));
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return;
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
if (want_update_has_gamepad_)
{
XINPUT_CAPABILITIES caps;
has_gamepad_ = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS);
want_update_has_gamepad_ = false;
}
XINPUT_STATE xinput_state;
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (has_gamepad_ && XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
{
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
#undef MAP_BUTTON
#undef MAP_ANALOG
}
}
}
Window::Instance().SetCursor(cursor);
}
} // namespace imgui
} // namespace kiwano

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,31 +19,30 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/core/common.h>
#include <kiwano/core/Common.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/SmartPtr.hpp>
namespace kiwano
{
namespace network
{
class HttpResponse;
namespace network
{
class HttpResponse;
KGE_DECLARE_SMART_PTR(HttpRequest);
KGE_DECLARE_SMART_PTR(HttpRequest);
/**
/**
* \addtogroup Network
* @{
*/
/**
/**
* \~chinese
* @brief HTTP请求
*/
class KGE_API HttpRequest
: public ObjectBase
{
public:
class KGE_API HttpRequest : public virtual ObjectBase
{
public:
/// \~chinese
/// @brief 响应回调函数
using ResponseCallback = Function<void(HttpRequest* /* request */, HttpResponse* /* response */)>;
@ -115,42 +114,84 @@ namespace kiwano
/// @brief 获取响应回调函数
ResponseCallback const& GetResponseCallback() const;
private:
private:
Type type_;
String url_;
String data_;
Map<String, String> headers_;
ResponseCallback response_cb_;
};
};
/** @} */
/** @} */
inline HttpRequest::HttpRequest() : type_(Type::Unknown) {}
inline HttpRequest::HttpRequest(Type type) : type_(type) {}
inline void HttpRequest::SetUrl(String const& url) { url_ = url; }
inline String const& HttpRequest::GetUrl() const { return url_; }
inline void HttpRequest::SetType(Type type) { type_ = type; }
inline HttpRequest::Type HttpRequest::GetType() const { return type_; }
inline void HttpRequest::SetData(String const& data) { data_ = data; }
inline String const& HttpRequest::GetData() const { return data_; }
inline void HttpRequest::SetHeaders(Map<String, String> const& headers) { headers_ = headers; }
inline void HttpRequest::SetHeader(String const& field, String const& content) { headers_[field] = content; }
inline Map<String, String>& HttpRequest::GetHeaders() { return headers_; }
inline String const& HttpRequest::GetHeader(String const& header) const { return headers_.at(header); }
inline void HttpRequest::SetResponseCallback(ResponseCallback const& callback) { response_cb_ = callback; }
inline HttpRequest::ResponseCallback const& HttpRequest::GetResponseCallback() const { return response_cb_; }
}
inline HttpRequest::HttpRequest()
: type_(Type::Unknown)
{
}
inline HttpRequest::HttpRequest(Type type)
: type_(type)
{
}
inline void HttpRequest::SetUrl(String const& url)
{
url_ = url;
}
inline String const& HttpRequest::GetUrl() const
{
return url_;
}
inline void HttpRequest::SetType(Type type)
{
type_ = type;
}
inline HttpRequest::Type HttpRequest::GetType() const
{
return type_;
}
inline void HttpRequest::SetData(String const& data)
{
data_ = data;
}
inline String const& HttpRequest::GetData() const
{
return data_;
}
inline void HttpRequest::SetHeaders(Map<String, String> const& headers)
{
headers_ = headers;
}
inline void HttpRequest::SetHeader(String const& field, String const& content)
{
headers_[field] = content;
}
inline Map<String, String>& HttpRequest::GetHeaders()
{
return headers_;
}
inline String const& HttpRequest::GetHeader(String const& header) const
{
return headers_.at(header);
}
inline void HttpRequest::SetResponseCallback(ResponseCallback const& callback)
{
response_cb_ = callback;
}
inline HttpRequest::ResponseCallback const& HttpRequest::GetResponseCallback() const
{
return response_cb_;
}
} // namespace network
} // namespace kiwano

View File

@ -23,23 +23,22 @@
namespace kiwano
{
namespace network
{
KGE_DECLARE_SMART_PTR(HttpResponse);
namespace network
{
KGE_DECLARE_SMART_PTR(HttpResponse);
/**
/**
* \addtogroup Network
* @{
*/
/**
/**
* \~chinese
* @brief HTTP响应
*/
class KGE_API HttpResponse
: public ObjectBase
{
public:
class KGE_API HttpResponse : public virtual ObjectBase
{
public:
HttpResponse(HttpRequestPtr request);
/// \~chinese
@ -86,7 +85,7 @@ namespace kiwano
/// @brief 设置错误信息
void SetError(String const& error_buffer);
private:
private:
bool succeed_;
long response_code_;
HttpRequestPtr request_;
@ -94,32 +93,70 @@ namespace kiwano
String response_header_;
String response_data_;
String error_buffer_;
};
};
/** @} */
/** @} */
inline HttpResponse::HttpResponse(HttpRequestPtr request) : request_(request), succeed_(false), response_code_(0) {}
inline HttpRequestPtr HttpResponse::GetRequest() const { return request_; }
inline void HttpResponse::SetSucceed(bool succeed) { succeed_ = succeed; }
inline bool HttpResponse::IsSucceed() const { return succeed_; }
inline void HttpResponse::SetResponseCode(long response_code) { response_code_ = response_code; }
inline long HttpResponse::GetResponseCode() const { return response_code_; }
inline void HttpResponse::SetHeader(String const& response_header) { response_header_ = response_header; }
inline String HttpResponse::GetHeader() const { return response_header_; }
inline void HttpResponse::SetData(String const& response_data) { response_data_ = response_data; }
inline String const& HttpResponse::GetData() const { return response_data_; }
inline void HttpResponse::SetError(String const& error_buffer) { error_buffer_ = error_buffer; }
inline String const& HttpResponse::GetError() const { return error_buffer_; }
}
inline HttpResponse::HttpResponse(HttpRequestPtr request)
: request_(request)
, succeed_(false)
, response_code_(0)
{
}
inline HttpRequestPtr HttpResponse::GetRequest() const
{
return request_;
}
inline void HttpResponse::SetSucceed(bool succeed)
{
succeed_ = succeed;
}
inline bool HttpResponse::IsSucceed() const
{
return succeed_;
}
inline void HttpResponse::SetResponseCode(long response_code)
{
response_code_ = response_code;
}
inline long HttpResponse::GetResponseCode() const
{
return response_code_;
}
inline void HttpResponse::SetHeader(String const& response_header)
{
response_header_ = response_header;
}
inline String HttpResponse::GetHeader() const
{
return response_header_;
}
inline void HttpResponse::SetData(String const& response_data)
{
response_data_ = response_data;
}
inline String const& HttpResponse::GetData() const
{
return response_data_;
}
inline void HttpResponse::SetError(String const& error_buffer)
{
error_buffer_ = error_buffer;
}
inline String const& HttpResponse::GetError() const
{
return error_buffer_;
}
} // namespace network
} // namespace kiwano

View File

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

View File

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

View File

@ -19,30 +19,29 @@
// THE SOFTWARE.
#pragma once
#include <kiwano-physics/helper.h>
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/ContactEdge.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/helper.h>
namespace kiwano
{
namespace physics
{
class World;
namespace physics
{
class World;
KGE_DECLARE_SMART_PTR(Body);
KGE_DECLARE_SMART_PTR(Body);
/**
/**
* \addtogroup Physics
* @{
*/
/// \~chinese
/// @brief ÎïÌå
class KGE_API Body
: public virtual RefCounter
{
public:
/// \~chinese
/// @brief 物体
class KGE_API Body : public virtual ObjectBase
{
public:
/// \~chinese
/// @brief 物体类型
enum class Type
@ -53,16 +52,20 @@ namespace kiwano
};
Body();
Body(b2Body* body, Actor* actor);
Body(World* world, Actor* actor);
Body(World* world, ActorPtr actor);
virtual ~Body();
/// \~chinese
/// @brief 初始化
/// @param[in] world 物理世界
/// @param[in] actor 绑定的角色
void Init(World* world, Actor* actor);
bool InitBody(World* world, ActorPtr actor);
/// \~chinese
/// @brief 初始化
/// @param[in] world 物理世界
/// @param[in] actor 绑定的角色
bool InitBody(World* world, Actor* actor);
/// \~chinese
/// @brief 添加夹具
@ -298,7 +301,7 @@ namespace kiwano
b2Body* GetB2Body() const;
void SetB2Body(b2Body* body);
private:
private:
/// \~chinese
/// @brief 销毁物体
void UpdateFixtureFilter(b2Fixture* fixture);
@ -307,7 +310,7 @@ namespace kiwano
/// @brief 销毁物体
void Destroy();
private:
private:
Actor* actor_;
World* world_;
b2Body* body_;
@ -315,66 +318,172 @@ namespace kiwano
uint16_t category_bits_;
uint16_t mask_bits_;
int16_t group_index_;
};
};
/** @} */
/** @} */
inline Body::Body(World* world, ActorPtr actor) : Body(world, actor.get()) {}
inline FixtureList Body::GetFixtureList() const { KGE_ASSERT(body_); return FixtureList(Fixture(body_->GetFixtureList())); }
inline ContactEdgeList Body::GetContactList() const { KGE_ASSERT(body_); return ContactEdgeList(ContactEdge(body_->GetContactList())); }
inline uint16_t Body::GetCategoryBits() const { return category_bits_; }
inline uint16_t Body::GetMaskBits() const { return mask_bits_; }
inline int16_t Body::GetGroupIndex() const { return group_index_; }
inline float Body::GetBodyRotation() const { KGE_ASSERT(body_); return math::Radian2Degree(body_->GetAngle()); }
inline void Body::SetBodyRotation(float angle) { SetBodyTransform(GetBodyPosition(), angle); }
inline void Body::SetBodyPosition(Point const& pos) { SetBodyTransform(pos, GetBodyRotation()); }
inline float Body::GetMass() const { KGE_ASSERT(body_); return body_->GetMass(); }
inline float Body::GetInertia() const { KGE_ASSERT(body_); return body_->GetInertia(); }
inline Body::Type Body::GetType() const { KGE_ASSERT(body_); return Type(body_->GetType()); }
inline void Body::SetType(Type type) { KGE_ASSERT(body_); body_->SetType(static_cast<b2BodyType>(type)); }
inline float Body::GetGravityScale() const { KGE_ASSERT(body_); return body_->GetGravityScale(); }
inline void Body::SetGravityScale(float scale) { KGE_ASSERT(body_); body_->SetGravityScale(scale); }
inline bool Body::IsIgnoreRotation() const { KGE_ASSERT(body_); return body_->IsFixedRotation(); }
inline void Body::SetIgnoreRotation(bool flag) { KGE_ASSERT(body_); body_->SetFixedRotation(flag); }
inline bool Body::IsBullet() const { KGE_ASSERT(body_); return body_->IsBullet(); }
inline void Body::SetBullet(bool flag) { KGE_ASSERT(body_); body_->SetBullet(flag); }
inline bool Body::IsAwake() const { KGE_ASSERT(body_); return body_->IsAwake(); }
inline void Body::SetAwake(bool flag) { KGE_ASSERT(body_); body_->SetAwake(flag); }
inline bool Body::IsSleepingAllowed() const { KGE_ASSERT(body_); return body_->IsSleepingAllowed(); }
inline void Body::SetSleepingAllowed(bool flag) { KGE_ASSERT(body_); body_->SetSleepingAllowed(flag); }
inline bool Body::IsActive() const { KGE_ASSERT(body_); return body_->IsActive(); }
inline void Body::SetActive(bool flag) { KGE_ASSERT(body_); body_->SetActive(flag); }
inline Actor* Body::GetActor() const { return actor_; }
inline void Body::SetActor(Actor* actor) { actor_ = actor; }
inline b2Body* Body::GetB2Body() const { return body_; }
inline World* Body::GetWorld() const { return world_; }
}
inline bool Body::InitBody(World* world, ActorPtr actor)
{
return InitBody(world, actor.get());
}
inline FixtureList Body::GetFixtureList() const
{
KGE_ASSERT(body_);
return FixtureList(Fixture(body_->GetFixtureList()));
}
inline ContactEdgeList Body::GetContactList() const
{
KGE_ASSERT(body_);
return ContactEdgeList(ContactEdge(body_->GetContactList()));
}
inline uint16_t Body::GetCategoryBits() const
{
return category_bits_;
}
inline uint16_t Body::GetMaskBits() const
{
return mask_bits_;
}
inline int16_t Body::GetGroupIndex() const
{
return group_index_;
}
inline float Body::GetBodyRotation() const
{
KGE_ASSERT(body_);
return math::Radian2Degree(body_->GetAngle());
}
inline void Body::SetBodyRotation(float angle)
{
SetBodyTransform(GetBodyPosition(), angle);
}
inline void Body::SetBodyPosition(Point const& pos)
{
SetBodyTransform(pos, GetBodyRotation());
}
inline float Body::GetMass() const
{
KGE_ASSERT(body_);
return body_->GetMass();
}
inline float Body::GetInertia() const
{
KGE_ASSERT(body_);
return body_->GetInertia();
}
inline Body::Type Body::GetType() const
{
KGE_ASSERT(body_);
return Type(body_->GetType());
}
inline void Body::SetType(Type type)
{
KGE_ASSERT(body_);
body_->SetType(static_cast<b2BodyType>(type));
}
inline float Body::GetGravityScale() const
{
KGE_ASSERT(body_);
return body_->GetGravityScale();
}
inline void Body::SetGravityScale(float scale)
{
KGE_ASSERT(body_);
body_->SetGravityScale(scale);
}
inline bool Body::IsIgnoreRotation() const
{
KGE_ASSERT(body_);
return body_->IsFixedRotation();
}
inline void Body::SetIgnoreRotation(bool flag)
{
KGE_ASSERT(body_);
body_->SetFixedRotation(flag);
}
inline bool Body::IsBullet() const
{
KGE_ASSERT(body_);
return body_->IsBullet();
}
inline void Body::SetBullet(bool flag)
{
KGE_ASSERT(body_);
body_->SetBullet(flag);
}
inline bool Body::IsAwake() const
{
KGE_ASSERT(body_);
return body_->IsAwake();
}
inline void Body::SetAwake(bool flag)
{
KGE_ASSERT(body_);
body_->SetAwake(flag);
}
inline bool Body::IsSleepingAllowed() const
{
KGE_ASSERT(body_);
return body_->IsSleepingAllowed();
}
inline void Body::SetSleepingAllowed(bool flag)
{
KGE_ASSERT(body_);
body_->SetSleepingAllowed(flag);
}
inline bool Body::IsActive() const
{
KGE_ASSERT(body_);
return body_->IsActive();
}
inline void Body::SetActive(bool flag)
{
KGE_ASSERT(body_);
body_->SetActive(flag);
}
inline Actor* Body::GetActor() const
{
return actor_;
}
inline void Body::SetActor(Actor* actor)
{
actor_ = actor;
}
inline b2Body* Body::GetB2Body() const
{
return body_;
}
inline World* Body::GetWorld() const
{
return world_;
}
} // namespace physics
} // namespace kiwano

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -24,31 +24,30 @@
namespace kiwano
{
namespace physics
{
KGE_DECLARE_SMART_PTR(World);
namespace physics
{
KGE_DECLARE_SMART_PTR(World);
/**
/**
* \~chinese
* \defgroup Physics
*/
/**
/**
* \addtogroup Physics
* @{
*/
/**
/**
* \~chinese
* @brief
*/
class KGE_API World
: public Stage
{
class KGE_API World : public Stage
{
friend class Body;
friend class Joint;
public:
public:
World();
virtual ~World();
@ -107,7 +106,7 @@ namespace kiwano
const b2World* GetB2World() const;
private:
private:
/// \~chinese
/// @brief 移除物体
void RemoveBody(Body* body);
@ -132,10 +131,10 @@ namespace kiwano
/// @brief 关节被移除
void JointRemoved(b2Joint* joint);
protected:
protected:
void Update(Duration dt) override;
private:
private:
b2World world_;
int vel_iter_;
int pos_iter_;
@ -151,49 +150,48 @@ namespace kiwano
bool removing_joint_;
Vector<Joint*> joints_;
};
};
/** @} */
/** @} */
inline float World::GetGlobalScale() const
{
inline float World::GetGlobalScale() const
{
return global_scale_;
}
inline void World::SetGlobalScale(float scale)
{
global_scale_ = scale;
}
inline float World::World2Stage(float value) const
{
return value * GetGlobalScale();
}
inline Vec2 World::World2Stage(const b2Vec2& pos) const
{
return Point(World2Stage(pos.x), World2Stage(pos.y));
}
inline float World::Stage2World(float value) const
{
return value / GetGlobalScale();
}
inline b2Vec2 World::Stage2World(const Vec2& pos) const
{
return b2Vec2(Stage2World(pos.x), Stage2World(pos.y));
}
inline void World::SetVelocityIterations(int vel_iter)
{
vel_iter_ = vel_iter;
}
inline void World::SetPositionIterations(int pos_iter)
{
pos_iter_ = pos_iter;
}
}
}
inline void World::SetGlobalScale(float scale)
{
global_scale_ = scale;
}
inline float World::World2Stage(float value) const
{
return value * GetGlobalScale();
}
inline Vec2 World::World2Stage(const b2Vec2& pos) const
{
return Point(World2Stage(pos.x), World2Stage(pos.y));
}
inline float World::Stage2World(float value) const
{
return value / GetGlobalScale();
}
inline b2Vec2 World::Stage2World(const Vec2& pos) const
{
return b2Vec2(Stage2World(pos.x), Stage2World(pos.y));
}
inline void World::SetVelocityIterations(int vel_iter)
{
vel_iter_ = vel_iter;
}
inline void World::SetPositionIterations(int pos_iter)
{
pos_iter_ = pos_iter;
}
} // namespace physics
} // namespace kiwano

View File

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

View File

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

View File

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

View File

@ -19,50 +19,50 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/core/common.h>
#include <kiwano/core/time.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/math/math.h>
#include <kiwano/2d/Transform.h>
#include <kiwano/2d/action/ActionManager.h>
#include <kiwano/core/TimerManager.h>
#include <kiwano/core/EventDispatcher.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/Time.h>
#include <kiwano/core/TimerManager.h>
#include <kiwano/math/math.h>
namespace kiwano
{
class Stage;
class Director;
class RenderTarget;
class Stage;
class Director;
class RenderContext;
KGE_DECLARE_SMART_PTR(Actor);
KGE_DECLARE_SMART_PTR(Actor);
/**
/**
* \~chinese
* \defgroup Actors
*/
/**
/**
* \addtogroup Actors
* @{
*/
/**
/**
* \~chinese
* @brief
* @details
* @details
*
*/
class KGE_API Actor
: public ObjectBase
class KGE_API Actor
: public virtual ObjectBase
, public TimerManager
, public ActionManager
, public EventDispatcher
, public IntrusiveListItem<ActorPtr>
{
, protected IntrusiveListItem<ActorPtr>
{
friend class Director;
friend class Transition;
friend IntrusiveList<ActorPtr>;
public:
public:
/// \~chinese
/// @brief 子成员列表
using Children = IntrusiveList<ActorPtr>;
@ -73,6 +73,8 @@ namespace kiwano
Actor();
virtual ~Actor();
/// \~chinese
/// @brief 更新角色
/// @details 每帧画面刷新前调用该函数,重载该函数以实现角色的更新处理
@ -81,9 +83,10 @@ namespace kiwano
/// \~chinese
/// @brief 渲染角色
/// @details 每帧画面刷新时调用该函数,默认不进行渲染,重载该函数以实现具体渲染过程
/// @param rt 渲染目标
virtual void OnRender(RenderTarget* rt);
/// @details
/// 每帧画面刷新时调用该函数,默认不进行渲染,重载该函数以实现具体渲染过程
/// @param ctx 渲染上下文
virtual void OnRender(RenderContext& ctx);
/// \~chinese
/// @brief 获取显示状态
@ -117,34 +120,6 @@ namespace kiwano
/// @brief 获取 y 坐标
float GetPositionY() const;
/// \~chinese
/// @brief 获取缩放比例
Point const& GetScale() const;
/// \~chinese
/// @brief 获取横向缩放比例
float GetScaleX() const;
/// \~chinese
/// @brief 获取纵向缩放比例
float GetScaleY() const;
/// \~chinese
/// @brief 获取错切角度
Point const& GetSkew() const;
/// \~chinese
/// @brief 获取横向错切角度
float GetSkewX() const;
/// \~chinese
/// @brief 获取纵向错切角度
float GetSkewY() const;
/// \~chinese
/// @brief 获取旋转角度
float GetRotation() const;
/// \~chinese
/// @brief 获取宽度
float GetWidth() const;
@ -189,6 +164,34 @@ namespace kiwano
/// @brief 获取显示透明度
float GetDisplayedOpacity() const;
/// \~chinese
/// @brief 获取旋转角度
float GetRotation() const;
/// \~chinese
/// @brief 获取缩放比例
Point const& GetScale() const;
/// \~chinese
/// @brief 获取横向缩放比例
float GetScaleX() const;
/// \~chinese
/// @brief 获取纵向缩放比例
float GetScaleY() const;
/// \~chinese
/// @brief 获取错切角度
Point const& GetSkew() const;
/// \~chinese
/// @brief 获取横向错切角度
float GetSkewX() const;
/// \~chinese
/// @brief 获取纵向错切角度
float GetSkewY() const;
/// \~chinese
/// @brief 获取变换
Transform GetTransform() const;
@ -362,10 +365,6 @@ namespace kiwano
/// @brief 从父角色移除
void RemoveFromParent();
/// \~chinese
/// @brief 判断点是否在角色内
virtual bool ContainsPoint(const Point& point) const;
/// \~chinese
/// @brief 暂停角色更新
void PauseUpdating();
@ -386,38 +385,44 @@ namespace kiwano
/// @brief 获取更新时的回调函数
UpdateCallback GetCallbackOnUpdate() const;
/// \~chinese
/// @brief 判断点是否在角色内
virtual bool ContainsPoint(const Point& point) const;
/// \~chinese
/// @brief 渲染角色边界
void ShowBorder(bool show);
/// \~chinese
/// @brief 分发事件
void Dispatch(Event& evt) override;
/// @param evt 事件
/// @return 是否继续分发该事件
virtual bool DispatchEvent(Event* evt);
/// \~chinese
/// @brief 设置默认锚点
static void SetDefaultAnchor(float anchor_x, float anchor_y);
protected:
protected:
/// \~chinese
/// @brief 更新自身和所有子角色
virtual void Update(Duration dt);
/// \~chinese
/// @brief 渲染自身和所有子角色
virtual void Render(RenderTarget* rt);
virtual void Render(RenderContext& ctx);
/// \~chinese
/// @brief 绘制自身和所有子角色的边界
virtual void RenderBorder(RenderTarget* rt);
virtual void RenderBorder(RenderContext& ctx);
/// \~chinese
/// @brief 检查是否在渲染目标的视区内
virtual bool CheckVisibilty(RenderTarget* rt) const;
/// @brief 检查是否在渲染上下文的视区内
virtual bool CheckVisibility(RenderContext& ctx) const;
/// \~chinese
/// @brief 渲染前初始化渲染目标状态,仅当 CheckVisibilty 返回真时调用该函数
virtual void PrepareToRender(RenderTarget* rt);
/// @brief 渲染前初始化渲染上下文状态,仅当 CheckVisibility 返回真时调用该函数
virtual void PrepareToRender(RenderContext& ctx);
/// \~chinese
/// @brief 更新自己的二维变换,并通知所有子角色
@ -435,7 +440,11 @@ namespace kiwano
/// @brief 设置节点所在舞台
void SetStage(Stage* stage);
private:
/// \~chinese
/// @brief 处理事件
void HandleEvent(Event* evt);
private:
bool visible_;
bool update_pausing_;
bool cascade_opacity_;
@ -462,224 +471,222 @@ namespace kiwano
mutable bool dirty_transform_inverse_;
mutable Matrix3x2 transform_matrix_;
mutable Matrix3x2 transform_matrix_inverse_;
};
};
/** @} */
/** @} */
inline void Actor::OnUpdate(Duration dt)
{
inline void Actor::OnUpdate(Duration dt)
{
KGE_NOT_USED(dt);
}
inline void Actor::OnRender(RenderTarget* rt)
{
KGE_NOT_USED(rt);
}
inline bool Actor::IsVisible() const
{
return visible_;
}
inline bool Actor::IsResponsible() const
{
return responsible_;
}
inline bool Actor::IsCascadeOpacityEnabled() const
{
return cascade_opacity_;
}
inline size_t Actor::GetHashName() const
{
return hash_name_;
}
inline int Actor::GetZOrder() const
{
return z_order_;
}
inline Point const& Actor::GetPosition() const
{
return transform_.position;
}
inline float Actor::GetPositionX() const
{
return GetPosition().x;
}
inline float Actor::GetPositionY() const
{
return GetPosition().y;
}
inline Point const& Actor::GetScale() const
{
return transform_.scale;
}
inline float Actor::GetScaleX() const
{
return GetScale().x;
}
inline float Actor::GetScaleY() const
{
return GetScale().y;
}
inline Point const& Actor::GetSkew() const
{
return transform_.skew;
}
inline float Actor::GetSkewX() const
{
return GetSkew().x;
}
inline float Actor::GetSkewY() const
{
return GetSkew().y;
}
inline float Actor::GetRotation() const
{
return transform_.rotation;
}
inline float Actor::GetWidth() const
{
return GetSize().x;
}
inline float Actor::GetHeight() const
{
return GetSize().y;
}
inline Size const& Actor::GetSize() const
{
return size_;
}
inline float Actor::GetScaledWidth() const
{
return GetWidth() * GetScaleX();
}
inline float Actor::GetScaledHeight() const
{
return GetHeight() * GetScaleY();
}
inline Size Actor::GetScaledSize() const
{
return Size{ GetScaledWidth(), GetScaledHeight() };
}
inline Point const& Actor::GetAnchor() const
{
return anchor_;
}
inline float Actor::GetAnchorX() const
{
return GetAnchor().x;
}
inline float Actor::GetAnchorY() const
{
return GetAnchor().y;
}
inline float Actor::GetOpacity() const
{
return opacity_;
}
inline float Actor::GetDisplayedOpacity() const
{
return displayed_opacity_;
}
inline Transform Actor::GetTransform() const
{
return transform_;
}
inline Actor* Actor::GetParent() const
{
return parent_;
}
inline Stage* Actor::GetStage() const
{
return stage_;
}
inline void Actor::PauseUpdating()
{
update_pausing_ = true;
}
inline void Actor::ResumeUpdating()
{
update_pausing_ = false;
}
inline bool Actor::IsUpdatePausing() const
{
return update_pausing_;
}
inline void Actor::SetCallbackOnUpdate(UpdateCallback const& cb)
{
cb_update_ = cb;
}
inline Actor::UpdateCallback Actor::GetCallbackOnUpdate() const
{
return cb_update_;
}
inline void Actor::ShowBorder(bool show)
{
show_border_ = show;
}
inline void Actor::SetPosition(float x, float y)
{
SetPosition(Point{ x, y });
}
inline void Actor::Move(float vx, float vy)
{
Move(Vec2{ vx, vy });
}
inline void Actor::SetScale(float scalex, float scaley)
{
SetScale(Vec2{ scalex, scaley });
}
inline void Actor::SetAnchor(float anchorx, float anchory)
{
SetAnchor(Vec2{ anchorx, anchory });
}
inline void Actor::SetSize(float width, float height)
{
SetSize(Size{ width, height });
}
inline void Actor::SetSkew(float skewx, float skewy)
{
SetSkew(Vec2{ skewx, skewy });
}
}
inline void Actor::OnRender(RenderContext& ctx)
{
KGE_NOT_USED(ctx);
}
inline bool Actor::IsVisible() const
{
return visible_;
}
inline bool Actor::IsResponsible() const
{
return responsible_;
}
inline bool Actor::IsCascadeOpacityEnabled() const
{
return cascade_opacity_;
}
inline size_t Actor::GetHashName() const
{
return hash_name_;
}
inline int Actor::GetZOrder() const
{
return z_order_;
}
inline Point const& Actor::GetPosition() const
{
return transform_.position;
}
inline float Actor::GetPositionX() const
{
return GetPosition().x;
}
inline float Actor::GetPositionY() const
{
return GetPosition().y;
}
inline Point const& Actor::GetScale() const
{
return transform_.scale;
}
inline float Actor::GetScaleX() const
{
return GetScale().x;
}
inline float Actor::GetScaleY() const
{
return GetScale().y;
}
inline Point const& Actor::GetSkew() const
{
return transform_.skew;
}
inline float Actor::GetSkewX() const
{
return GetSkew().x;
}
inline float Actor::GetSkewY() const
{
return GetSkew().y;
}
inline float Actor::GetRotation() const
{
return transform_.rotation;
}
inline float Actor::GetWidth() const
{
return GetSize().x;
}
inline float Actor::GetHeight() const
{
return GetSize().y;
}
inline Size const& Actor::GetSize() const
{
return size_;
}
inline float Actor::GetScaledWidth() const
{
return GetWidth() * GetScaleX();
}
inline float Actor::GetScaledHeight() const
{
return GetHeight() * GetScaleY();
}
inline Size Actor::GetScaledSize() const
{
return Size{ GetScaledWidth(), GetScaledHeight() };
}
inline Point const& Actor::GetAnchor() const
{
return anchor_;
}
inline float Actor::GetAnchorX() const
{
return GetAnchor().x;
}
inline float Actor::GetAnchorY() const
{
return GetAnchor().y;
}
inline float Actor::GetOpacity() const
{
return opacity_;
}
inline float Actor::GetDisplayedOpacity() const
{
return displayed_opacity_;
}
inline Transform Actor::GetTransform() const
{
return transform_;
}
inline Actor* Actor::GetParent() const
{
return parent_;
}
inline Stage* Actor::GetStage() const
{
return stage_;
}
inline void Actor::PauseUpdating()
{
update_pausing_ = true;
}
inline void Actor::ResumeUpdating()
{
update_pausing_ = false;
}
inline bool Actor::IsUpdatePausing() const
{
return update_pausing_;
}
inline void Actor::SetCallbackOnUpdate(UpdateCallback const& cb)
{
cb_update_ = cb;
}
inline Actor::UpdateCallback Actor::GetCallbackOnUpdate() const
{
return cb_update_;
}
inline void Actor::ShowBorder(bool show)
{
show_border_ = show;
}
inline void Actor::SetPosition(float x, float y)
{
SetPosition(Point{ x, y });
}
inline void Actor::Move(float vx, float vy)
{
Move(Vec2{ vx, vy });
}
inline void Actor::SetScale(float scalex, float scaley)
{
SetScale(Vec2{ scalex, scaley });
}
inline void Actor::SetAnchor(float anchorx, float anchory)
{
SetAnchor(Vec2{ anchorx, anchory });
}
inline void Actor::SetSize(float width, float height)
{
SetSize(Size{ width, height });
}
inline void Actor::SetSkew(float skewx, float skewy)
{
SetSkew(Vec2{ skewx, skewy });
}
} // namespace kiwano

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,20 +19,16 @@
// THE SOFTWARE.
#include <kiwano/2d/Sprite.h>
#include <kiwano/renderer/Renderer.h>
#include <kiwano/render/Renderer.h>
namespace kiwano
{
Sprite::Sprite()
{
}
Sprite::Sprite() {}
Sprite::~Sprite()
{
}
Sprite::~Sprite() {}
bool Sprite::Load(String const& file_path)
{
bool Sprite::Load(String const& file_path)
{
FramePtr frame = new (std::nothrow) Frame;
if (frame->Load(file_path))
{
@ -40,10 +36,10 @@ namespace kiwano
return true;
}
return false;
}
}
bool Sprite::Load(Resource const& res)
{
bool Sprite::Load(Resource const& res)
{
FramePtr frame = new (std::nothrow) Frame;
if (frame->Load(res))
{
@ -51,19 +47,19 @@ namespace kiwano
return true;
}
return false;
}
}
void Sprite::SetCropRect(const Rect& crop_rect)
{
void Sprite::SetCropRect(const Rect& crop_rect)
{
if (frame_)
{
frame_->SetCropRect(crop_rect);
SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
}
}
}
void Sprite::SetFrame(FramePtr frame)
{
void Sprite::SetFrame(FramePtr frame)
{
if (frame_ != frame)
{
frame_ = frame;
@ -72,15 +68,15 @@ namespace kiwano
SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
}
}
}
void Sprite::OnRender(RenderTarget* rt)
{
rt->DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
}
bool Sprite::CheckVisibilty(RenderTarget* rt) const
{
return frame_ && frame_->IsValid() && Actor::CheckVisibilty(rt);
}
}
void Sprite::OnRender(RenderContext& ctx)
{
ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
}
bool Sprite::CheckVisibility(RenderContext& ctx) const
{
return frame_ && frame_->IsValid() && Actor::CheckVisibility(ctx);
}
} // namespace kiwano

View File

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

View File

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

View File

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

View File

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

View File

@ -20,26 +20,25 @@
#pragma once
#include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Color.h>
#include <kiwano/renderer/TextLayout.h>
#include <kiwano/render/Color.h>
#include <kiwano/render/TextLayout.h>
namespace kiwano
{
KGE_DECLARE_SMART_PTR(TextActor);
KGE_DECLARE_SMART_PTR(TextActor);
/**
/**
* \addtogroup Actors
* @{
*/
/**
/**
* \~chinese
* @brief
*/
class KGE_API TextActor
: public Actor
{
public:
class KGE_API TextActor : public Actor
{
public:
/// \~chinese
/// @brief 构建空的文本角色
TextActor();
@ -69,6 +68,10 @@ namespace kiwano
/// @brief 获取文本布局
const TextLayout& GetLayout() const;
/// \~chinese
/// @brief »ñÈ¡Îı¾²¼¾Ö´óС
Size GetLayoutSize() const;
/// \~chinese
/// @brief 获取填充画刷
BrushPtr GetFillBrush() const;
@ -143,7 +146,7 @@ namespace kiwano
/// \~chinese
/// @brief 设置文字描边线相交样式
void SetOutlineStroke(StrokeStyle outline_stroke);
void SetOutlineStroke(const StrokeStyle& outline_stroke);
/// \~chinese
/// @brief 设置是否显示下划线(默认值为 false
@ -166,129 +169,133 @@ namespace kiwano
/// @brief 获取默认文字样式
static const TextStyle& GetDefaultStyle();
void OnRender(RenderTarget* rt) override;
void OnRender(RenderContext& ctx) override;
void OnUpdate(Duration dt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
protected:
bool CheckVisibility(RenderContext& ctx) const override;
private:
private:
bool show_underline_;
bool show_strikethrough_;
TextLayout text_layout_;
};
};
/** @} */
/** @} */
inline const String& TextActor::GetText() const
{
inline const String& TextActor::GetText() const
{
return text_layout_.GetText();
}
inline FontPtr TextActor::GetFont() const
{
return text_layout_.GetStyle().font;
}
inline const TextStyle& TextActor::GetStyle() const
{
return text_layout_.GetStyle();
}
inline const TextLayout& TextActor::GetLayout() const
{
return text_layout_;
}
inline BrushPtr TextActor::GetFillBrush() const
{
return text_layout_.GetFillBrush();
}
inline BrushPtr TextActor::GetOutlineBrush() const
{
return text_layout_.GetOutlineBrush();
}
inline void TextActor::SetText(String const& text)
{
text_layout_.SetText(text);
}
inline void TextActor::SetStyle(const TextStyle& style)
{
text_layout_.SetStyle(style);
}
inline void TextActor::SetFont(FontPtr font)
{
text_layout_.SetFont(font);
}
inline void TextActor::SetFontFamily(String const& family)
{
text_layout_.SetFontFamily(family);
}
inline void TextActor::SetFontSize(float size)
{
text_layout_.SetFontSize(size);
}
inline void TextActor::SetFontWeight(uint32_t weight)
{
text_layout_.SetFontWeight(weight);
}
inline void TextActor::SetItalic(bool italic)
{
text_layout_.SetItalic(italic);
}
inline void TextActor::SetWrapWidth(float wrap_width)
{
text_layout_.SetWrapWidth(wrap_width);
}
inline void TextActor::SetLineSpacing(float line_spacing)
{
text_layout_.SetLineSpacing(line_spacing);
}
inline void TextActor::SetAlignment(TextAlign align)
{
text_layout_.SetAlignment(align);
}
inline void TextActor::SetUnderline(bool enable)
{
show_underline_ = enable;
}
inline void TextActor::SetStrikethrough(bool enable)
{
show_strikethrough_ = enable;
}
inline void TextActor::SetFillBrush(BrushPtr brush)
{
text_layout_.SetFillBrush(brush);
}
inline void TextActor::SetOutlineBrush(BrushPtr brush)
{
text_layout_.SetOutlineBrush(brush);
}
inline void TextActor::SetOutlineWidth(float outline_width)
{
text_layout_.SetOutlineWidth(outline_width);
}
inline void TextActor::SetOutlineStroke(StrokeStyle outline_stroke)
{
text_layout_.SetOutlineStroke(outline_stroke);
}
}
inline FontPtr TextActor::GetFont() const
{
return text_layout_.GetStyle().font;
}
inline const TextStyle& TextActor::GetStyle() const
{
return text_layout_.GetStyle();
}
inline const TextLayout& TextActor::GetLayout() const
{
return text_layout_;
}
inline Size TextActor::GetLayoutSize() const
{
return text_layout_.GetLayoutSize();
}
inline BrushPtr TextActor::GetFillBrush() const
{
return text_layout_.GetFillBrush();
}
inline BrushPtr TextActor::GetOutlineBrush() const
{
return text_layout_.GetOutlineBrush();
}
inline void TextActor::SetText(String const& text)
{
text_layout_.SetText(text);
}
inline void TextActor::SetStyle(const TextStyle& style)
{
text_layout_.SetStyle(style);
}
inline void TextActor::SetFont(FontPtr font)
{
text_layout_.SetFont(font);
}
inline void TextActor::SetFontFamily(String const& family)
{
text_layout_.SetFontFamily(family);
}
inline void TextActor::SetFontSize(float size)
{
text_layout_.SetFontSize(size);
}
inline void TextActor::SetFontWeight(uint32_t weight)
{
text_layout_.SetFontWeight(weight);
}
inline void TextActor::SetItalic(bool italic)
{
text_layout_.SetItalic(italic);
}
inline void TextActor::SetWrapWidth(float wrap_width)
{
text_layout_.SetWrapWidth(wrap_width);
}
inline void TextActor::SetLineSpacing(float line_spacing)
{
text_layout_.SetLineSpacing(line_spacing);
}
inline void TextActor::SetAlignment(TextAlign align)
{
text_layout_.SetAlignment(align);
}
inline void TextActor::SetUnderline(bool enable)
{
show_underline_ = enable;
}
inline void TextActor::SetStrikethrough(bool enable)
{
show_strikethrough_ = enable;
}
inline void TextActor::SetFillBrush(BrushPtr brush)
{
text_layout_.SetFillBrush(brush);
}
inline void TextActor::SetOutlineBrush(BrushPtr brush)
{
text_layout_.SetOutlineBrush(brush);
}
inline void TextActor::SetOutlineWidth(float outline_width)
{
text_layout_.SetOutlineWidth(outline_width);
}
inline void TextActor::SetOutlineStroke(const StrokeStyle& outline_stroke)
{
text_layout_.SetOutlineStroke(outline_stroke);
}
} // namespace kiwano

View File

@ -22,28 +22,25 @@
namespace kiwano
{
Transform::Transform()
Transform::Transform()
: position()
, rotation(0.f)
, scale(1.f, 1.f)
, skew(0.f, 0.f)
{
}
{
}
Matrix3x2 Transform::ToMatrix() const
{
Matrix3x2 Transform::ToMatrix() const
{
if (!skew.IsOrigin())
{
return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation);
}
return Matrix3x2::SRT(position, scale, rotation);
}
bool Transform::operator== (Transform const& rhs) const
{
return position == rhs.position &&
rotation == rhs.rotation &&
scale == rhs.scale &&
skew == rhs.skew;
}
}
bool Transform::operator==(Transform const& rhs) const
{
return position == rhs.position && rotation == rhs.rotation && scale == rhs.scale && skew == rhs.skew;
}
} // namespace kiwano

View File

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

View File

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

View File

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

View File

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

View File

@ -19,40 +19,40 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/core/common.h>
#include <kiwano/core/time.h>
#include <kiwano/core/SmartPtr.hpp>
#include <kiwano/core/Common.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/SmartPtr.hpp>
#include <kiwano/core/Time.h>
#include <kiwano/math/math.h>
namespace kiwano
{
class Actor;
class ActionManager;
class Actor;
class ActionManager;
KGE_DECLARE_SMART_PTR(Action);
KGE_DECLARE_SMART_PTR(Action);
/**
/**
* \~chinese
* \defgroup Actions
*/
/**
/**
* \addtogroup Actions
* @{
*/
/// \~chinese
/// @brief ¶¯»­
class KGE_API Action
: public ObjectBase
/// \~chinese
/// @brief ¶¯»­
class KGE_API Action
: public virtual ObjectBase
, protected IntrusiveListItem<ActionPtr>
{
{
friend class ActionManager;
friend class ActionGroup;
friend IntrusiveList<ActionPtr>;
public:
public:
/// \~chinese
/// @brief 动画结束时的回调函数
using DoneCallback = Function<void(Actor* /* target */)>;
@ -122,7 +122,7 @@ namespace kiwano
/// @brief 获取动画循环结束时的回调函数
DoneCallback GetLoopDoneCallback() const;
protected:
protected:
/// \~chinese
/// @brief 初始化动画
virtual void Init(Actor* target);
@ -178,7 +178,7 @@ namespace kiwano
/// @brief 是否可移除
bool IsRemoveable() const;
private:
private:
Status status_;
bool running_;
bool detach_target_;
@ -188,103 +188,102 @@ namespace kiwano
Duration elapsed_;
DoneCallback cb_done_;
DoneCallback cb_loop_done_;
};
};
/** @} */
/** @} */
inline void Action::Resume()
{
inline void Action::Resume()
{
running_ = true;
}
inline void Action::Pause()
{
running_ = false;
}
inline void Action::Stop()
{
Done();
}
inline void Action::SetDelay(Duration delay)
{
delay_ = delay;
}
inline void Action::SetLoops(int loops)
{
loops_ = loops;
}
inline void Action::RemoveTargetWhenDone()
{
detach_target_ = true;
}
inline void Action::SetDoneCallback(DoneCallback const& cb)
{
cb_done_ = cb;
}
inline void Action::SetLoopDoneCallback(DoneCallback const& cb)
{
cb_loop_done_ = cb;
}
inline void Action::Done()
{
status_ = Status::Done;
}
inline Action::Status Action::GetStatus() const
{
return status_;
}
inline bool Action::IsRunning() const
{
return running_;
}
inline bool Action::IsDone() const
{
return status_ == Status::Done || status_ == Status::Removeable;
}
inline bool Action::IsRemoveable() const
{
return status_ == Status::Removeable;
}
inline int Action::GetLoops() const
{
return loops_;
}
inline Duration Action::GetDelay() const
{
return delay_;
}
inline Duration Action::GetElapsed() const
{
return elapsed_;
}
inline int Action::GetLoopsDone() const
{
return loops_done_;
}
inline Action::DoneCallback Action::GetDoneCallback() const
{
return cb_done_;
}
inline Action::DoneCallback Action::GetLoopDoneCallback() const
{
return cb_loop_done_;
}
}
inline void Action::Pause()
{
running_ = false;
}
inline void Action::Stop()
{
Done();
}
inline void Action::SetDelay(Duration delay)
{
delay_ = delay;
}
inline void Action::SetLoops(int loops)
{
loops_ = loops;
}
inline void Action::RemoveTargetWhenDone()
{
detach_target_ = true;
}
inline void Action::SetDoneCallback(DoneCallback const& cb)
{
cb_done_ = cb;
}
inline void Action::SetLoopDoneCallback(DoneCallback const& cb)
{
cb_loop_done_ = cb;
}
inline void Action::Done()
{
status_ = Status::Done;
}
inline Action::Status Action::GetStatus() const
{
return status_;
}
inline bool Action::IsRunning() const
{
return running_;
}
inline bool Action::IsDone() const
{
return status_ == Status::Done || status_ == Status::Removeable;
}
inline bool Action::IsRemoveable() const
{
return status_ == Status::Removeable;
}
inline int Action::GetLoops() const
{
return loops_;
}
inline Duration Action::GetDelay() const
{
return delay_;
}
inline Duration Action::GetElapsed() const
{
return elapsed_;
}
inline int Action::GetLoopsDone() const
{
return loops_done_;
}
inline Action::DoneCallback Action::GetDoneCallback() const
{
return cb_done_;
}
inline Action::DoneCallback Action::GetLoopDoneCallback() const
{
return cb_loop_done_;
}
} // namespace kiwano

View File

@ -22,19 +22,19 @@
namespace kiwano
{
ActionDelay::ActionDelay(Duration delay)
{
ActionDelay::ActionDelay(Duration delay)
{
SetDelay(delay);
}
ActionPtr ActionDelay::Clone() const
{
return new ActionDelay(GetDelay());
}
ActionPtr ActionDelay::Reverse() const
{
return new ActionDelay(GetDelay());
}
}
ActionPtr ActionDelay::Clone() const
{
return new ActionDelay(GetDelay());
}
ActionPtr ActionDelay::Reverse() const
{
return new ActionDelay(GetDelay());
}
} // namespace kiwano

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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