Update Audio & Network & Imgui
This commit is contained in:
parent
f8db6f3550
commit
56dea4c055
3
Doxyfile
3
Doxyfile
|
|
@ -55,7 +55,8 @@ EXCLUDE = src/3rd-party \
|
||||||
|
|
||||||
ENABLE_PREPROCESSING = YES
|
ENABLE_PREPROCESSING = YES
|
||||||
MACRO_EXPANSION = YES
|
MACRO_EXPANSION = YES
|
||||||
PREDEFINED = KGE_API=
|
PREDEFINED = KGE_API= \
|
||||||
|
KGE_DISABLE_DOXYGEN=
|
||||||
|
|
||||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||||
# contain include files that are not input files but should be processed by the
|
# contain include files that are not input files but should be processed by the
|
||||||
|
|
|
||||||
|
|
@ -185,4 +185,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -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\StackWalker\StackWalker.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\src\3rd-party\StackWalker\StackWalker.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>{3A3948DC-9865-46B3-B7B9-7E5572704ED2}</ProjectGuid>
|
|
||||||
<RootNamespace>libStackWalker</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<OutDir>$(SolutionDir)\output\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
|
|
||||||
<IntDir>$(SolutionDir)\build\$(PlatformToolset)\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<OutDir>$(SolutionDir)\output\$(PlatformToolset)\$(Platform)\$(Configuration)\</OutDir>
|
|
||||||
<IntDir>$(SolutionDir)\build\$(PlatformToolset)\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
|
||||||
<AdditionalIncludeDirectories>../../../src/3rd-party;</AdditionalIncludeDirectories>
|
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
|
||||||
<AdditionalIncludeDirectories>../../../src/3rd-party;</AdditionalIncludeDirectories>
|
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\src\3rd-party\StackWalker\StackWalker.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\..\src\3rd-party\StackWalker\StackWalker.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -102,4 +102,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -102,4 +102,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -94,4 +94,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kiwano-physics", "kiwano-ph
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rd-party", "3rd-party", "{2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rd-party", "3rd-party", "{2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libStackWalker", "3rd-party\StackWalker\libStackWalker.vcxproj", "{3A3948DC-9865-46B3-B7B9-7E5572704ED2}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtinyxml2", "3rd-party\tinyxml2\libtinyxml2.vcxproj", "{AB47E875-85E5-4105-A71E-88930EAAB910}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtinyxml2", "3rd-party\tinyxml2\libtinyxml2.vcxproj", "{AB47E875-85E5-4105-A71E-88930EAAB910}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libimgui", "3rd-party\imgui\libimgui.vcxproj", "{7FA1E56D-62AC-47D1-97D1-40B302724198}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libimgui", "3rd-party\imgui\libimgui.vcxproj", "{7FA1E56D-62AC-47D1-97D1-40B302724198}"
|
||||||
|
|
@ -47,10 +45,10 @@ Global
|
||||||
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Debug|Win32.Build.0 = Debug|Win32
|
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|Win32.ActiveCfg = Release|Win32
|
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|Win32.Build.0 = Release|Win32
|
{A7062ED8-8910-48A5-A3BC-C1612672571F}.Release|Win32.Build.0 = Release|Win32
|
||||||
{3A3948DC-9865-46B3-B7B9-7E5572704ED2}.Debug|Win32.ActiveCfg = Debug|Win32
|
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{3A3948DC-9865-46B3-B7B9-7E5572704ED2}.Debug|Win32.Build.0 = Debug|Win32
|
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{3A3948DC-9865-46B3-B7B9-7E5572704ED2}.Release|Win32.ActiveCfg = Release|Win32
|
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{3A3948DC-9865-46B3-B7B9-7E5572704ED2}.Release|Win32.Build.0 = Release|Win32
|
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.Build.0 = Release|Win32
|
||||||
{AB47E875-85E5-4105-A71E-88930EAAB910}.Debug|Win32.ActiveCfg = Debug|Win32
|
{AB47E875-85E5-4105-A71E-88930EAAB910}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{AB47E875-85E5-4105-A71E-88930EAAB910}.Debug|Win32.Build.0 = 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.ActiveCfg = Release|Win32
|
||||||
|
|
@ -67,16 +65,11 @@ Global
|
||||||
{0CBA9295-F14D-4966-A7C4-1DD68158176C}.Debug|Win32.Build.0 = Debug|Win32
|
{0CBA9295-F14D-4966-A7C4-1DD68158176C}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{0CBA9295-F14D-4966-A7C4-1DD68158176C}.Release|Win32.ActiveCfg = Release|Win32
|
{0CBA9295-F14D-4966-A7C4-1DD68158176C}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{0CBA9295-F14D-4966-A7C4-1DD68158176C}.Release|Win32.Build.0 = Release|Win32
|
{0CBA9295-F14D-4966-A7C4-1DD68158176C}.Release|Win32.Build.0 = Release|Win32
|
||||||
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{DF599AFB-744F-41E5-AF0C-2146F90575C8}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{3A3948DC-9865-46B3-B7B9-7E5572704ED2} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
|
||||||
{AB47E875-85E5-4105-A71E-88930EAAB910} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
{AB47E875-85E5-4105-A71E-88930EAAB910} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
||||||
{7FA1E56D-62AC-47D1-97D1-40B302724198} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
{7FA1E56D-62AC-47D1-97D1-40B302724198} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
||||||
{A9ABACC7-75A1-46BA-8E48-4105346D9719} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
{A9ABACC7-75A1-46BA-8E48-4105346D9719} = {2D8919F2-8922-4B3F-8F68-D4127C6BCBB7}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -108,4 +108,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -110,4 +110,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -106,4 +106,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -116,4 +116,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@
|
||||||
<ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" />
|
<ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\platform\Input.cpp" />
|
<ClCompile Include="..\..\src\kiwano\platform\Input.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" />
|
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\kiwano\platform\win32\StackWalker.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp" />
|
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp" />
|
<ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\renderer\Color.cpp" />
|
<ClCompile Include="..\..\src\kiwano\renderer\Color.cpp" />
|
||||||
|
|
@ -158,9 +159,6 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\3rd-party\StackWalker\libStackWalker.vcxproj">
|
|
||||||
<Project>{3a3948dc-9865-46b3-b7b9-7e5572704ed2}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\3rd-party\tinyxml2\libtinyxml2.vcxproj">
|
<ProjectReference Include="..\3rd-party\tinyxml2\libtinyxml2.vcxproj">
|
||||||
<Project>{ab47e875-85e5-4105-a71e-88930eaab910}</Project>
|
<Project>{ab47e875-85e5-4105-a71e-88930eaab910}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
@ -179,7 +177,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -241,4 +239,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -458,5 +458,8 @@
|
||||||
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp">
|
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp">
|
||||||
<Filter>platform\win32</Filter>
|
<Filter>platform\win32</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\kiwano\platform\win32\StackWalker.cpp">
|
||||||
|
<Filter>platform\win32</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -3,14 +3,19 @@ function Set-FileConfiguration {
|
||||||
[string]$filePath
|
[string]$filePath
|
||||||
)
|
)
|
||||||
|
|
||||||
$replace = "<DebugInformationFormat>(EditAndContinue|ProgramDatabase)</DebugInformationFormat>"
|
$debugInfoReplace = "<DebugInformationFormat>(EditAndContinue|ProgramDatabase)</DebugInformationFormat>"
|
||||||
$replaceTo = "<DebugInformationFormat>None</DebugInformationFormat>"
|
$debugInfoReplaceTo = "<DebugInformationFormat>None</DebugInformationFormat>"
|
||||||
|
|
||||||
|
$optimizationReplace = "<WholeProgramOptimization>true</WholeProgramOptimization>"
|
||||||
|
$optimizationReplaceTo = "<WholeProgramOptimization>false</WholeProgramOptimization>"
|
||||||
|
|
||||||
# Create a copy of .vcxproj file
|
# Create a copy of .vcxproj file
|
||||||
Copy-Item -Path $filePath -Destination ($filePath + '.template')
|
Copy-Item -Path $filePath -Destination ($filePath + '.template')
|
||||||
|
|
||||||
# Overlay some configurations
|
# Overlay some configurations
|
||||||
Get-Content ($filePath + '.template') -Encoding UTF8 | ForEach-Object { $_ -replace $replace, $replaceTo } | Out-File $filePath -Encoding UTF8
|
Get-Content ($filePath + '.template') -Encoding UTF8 | ForEach-Object {
|
||||||
|
( $_ -replace $debugInfoReplace, $debugInfoReplaceTo ) -replace $optimizationReplace, $optimizationReplaceTo
|
||||||
|
} | Out-File $filePath -Encoding UTF8
|
||||||
|
|
||||||
# Delete the copy file
|
# Delete the copy file
|
||||||
Remove-Item -Path ($filePath + '.template')
|
Remove-Item -Path ($filePath + '.template')
|
||||||
|
|
@ -24,3 +29,12 @@ Get-ChildItem -Path 'projects\' -Directory | ForEach-Object {
|
||||||
Set-FileConfiguration ($dirPath + '\' + $_)
|
Set-FileConfiguration ($dirPath + '\' + $_)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Get-ChildItem -Path 'projects\3rd-party' -Directory | ForEach-Object {
|
||||||
|
$dirPath = "projects\3rd-party\$($_)"
|
||||||
|
|
||||||
|
# Search all vcxproj files
|
||||||
|
Get-ChildItem -Path $dirPath *.vcxproj -File | ForEach-Object {
|
||||||
|
Set-FileConfiguration ($dirPath + '\' + $_)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,187 +0,0 @@
|
||||||
/**********************************************************************
|
|
||||||
*
|
|
||||||
* StackWalker.h
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* History:
|
|
||||||
* 2005-07-27 v1 - First public release on http://www.codeproject.com/
|
|
||||||
* (for additional changes see History in 'StackWalker.cpp'!
|
|
||||||
*
|
|
||||||
**********************************************************************/
|
|
||||||
// #pragma once is supported starting with _MCS_VER 1000,
|
|
||||||
// so we need not to check the version (because we only support _MSC_VER >= 1100)!
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// special defines for VC5/6 (if no actual PSDK is installed):
|
|
||||||
#if _MSC_VER < 1300
|
|
||||||
typedef unsigned __int64 DWORD64, *PDWORD64;
|
|
||||||
#if defined(_WIN64)
|
|
||||||
typedef unsigned __int64 SIZE_T, *PSIZE_T;
|
|
||||||
#else
|
|
||||||
typedef unsigned long SIZE_T, *PSIZE_T;
|
|
||||||
#endif
|
|
||||||
#endif // _MSC_VER < 1300
|
|
||||||
|
|
||||||
class StackWalkerInternal; // forward
|
|
||||||
class StackWalker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef enum StackWalkOptions
|
|
||||||
{
|
|
||||||
// No addition info will be retrived
|
|
||||||
// (only the address is available)
|
|
||||||
RetrieveNone = 0,
|
|
||||||
|
|
||||||
// Try to get the symbol-name
|
|
||||||
RetrieveSymbol = 1,
|
|
||||||
|
|
||||||
// Try to get the line for this symbol
|
|
||||||
RetrieveLine = 2,
|
|
||||||
|
|
||||||
// Try to retrieve the module-infos
|
|
||||||
RetrieveModuleInfo = 4,
|
|
||||||
|
|
||||||
// Also retrieve the version for the DLL/EXE
|
|
||||||
RetrieveFileVersion = 8,
|
|
||||||
|
|
||||||
// Contains all the abouve
|
|
||||||
RetrieveVerbose = 0xF,
|
|
||||||
|
|
||||||
// Generate a "good" symbol-search-path
|
|
||||||
SymBuildPath = 0x10,
|
|
||||||
|
|
||||||
// Also use the public Microsoft-Symbol-Server
|
|
||||||
SymUseSymSrv = 0x20,
|
|
||||||
|
|
||||||
// Contains all the abouve "Sym"-options
|
|
||||||
SymAll = 0x30,
|
|
||||||
|
|
||||||
// Contains all options (default)
|
|
||||||
OptionsAll = 0x3F
|
|
||||||
} StackWalkOptions;
|
|
||||||
|
|
||||||
StackWalker(
|
|
||||||
int options = OptionsAll, // 'int' is by design, to combine the enum-flags
|
|
||||||
LPCSTR szSymPath = NULL,
|
|
||||||
DWORD dwProcessId = GetCurrentProcessId(),
|
|
||||||
HANDLE hProcess = GetCurrentProcess()
|
|
||||||
);
|
|
||||||
StackWalker(DWORD dwProcessId, HANDLE hProcess);
|
|
||||||
virtual ~StackWalker();
|
|
||||||
|
|
||||||
typedef BOOL (__stdcall *PReadProcessMemoryRoutine)(
|
|
||||||
HANDLE hProcess,
|
|
||||||
DWORD64 qwBaseAddress,
|
|
||||||
PVOID lpBuffer,
|
|
||||||
DWORD nSize,
|
|
||||||
LPDWORD lpNumberOfBytesRead,
|
|
||||||
LPVOID pUserData // optional data, which was passed in "ShowCallstack"
|
|
||||||
);
|
|
||||||
|
|
||||||
BOOL LoadModules();
|
|
||||||
|
|
||||||
BOOL ShowCallstack(
|
|
||||||
HANDLE hThread = GetCurrentThread(),
|
|
||||||
const CONTEXT *context = NULL,
|
|
||||||
PReadProcessMemoryRoutine readMemoryFunction = NULL,
|
|
||||||
LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback
|
|
||||||
);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1300
|
|
||||||
// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public"
|
|
||||||
// in older compilers in order to use it... starting with VC7 we can declare it as "protected"
|
|
||||||
protected:
|
|
||||||
#endif
|
|
||||||
enum { STACKWALK_MAX_NAMELEN = 1024 }; // max name length for found symbols
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Entry for each Callstack-Entry
|
|
||||||
typedef struct CallstackEntry
|
|
||||||
{
|
|
||||||
DWORD64 offset; // if 0, we have no valid entry
|
|
||||||
CHAR name[STACKWALK_MAX_NAMELEN];
|
|
||||||
CHAR undName[STACKWALK_MAX_NAMELEN];
|
|
||||||
CHAR undFullName[STACKWALK_MAX_NAMELEN];
|
|
||||||
DWORD64 offsetFromSmybol;
|
|
||||||
DWORD offsetFromLine;
|
|
||||||
DWORD lineNumber;
|
|
||||||
CHAR lineFileName[STACKWALK_MAX_NAMELEN];
|
|
||||||
DWORD symType;
|
|
||||||
LPCSTR symTypeString;
|
|
||||||
CHAR moduleName[STACKWALK_MAX_NAMELEN];
|
|
||||||
DWORD64 baseOfImage;
|
|
||||||
CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
|
|
||||||
} CallstackEntry;
|
|
||||||
|
|
||||||
enum CallstackEntryType {firstEntry, nextEntry, lastEntry};
|
|
||||||
|
|
||||||
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
|
|
||||||
virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion);
|
|
||||||
virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry);
|
|
||||||
virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
|
|
||||||
virtual void OnOutput(LPCSTR szText);
|
|
||||||
|
|
||||||
StackWalkerInternal *m_sw;
|
|
||||||
HANDLE m_hProcess;
|
|
||||||
DWORD m_dwProcessId;
|
|
||||||
BOOL m_modulesLoaded;
|
|
||||||
LPSTR m_szSymPath;
|
|
||||||
|
|
||||||
int m_options;
|
|
||||||
|
|
||||||
static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead);
|
|
||||||
|
|
||||||
friend StackWalkerInternal;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// The "ugly" assembler-implementation is needed for systems before XP
|
|
||||||
// If you have a new PSDK and you only compile for XP and later, then you can use
|
|
||||||
// the "RtlCaptureContext"
|
|
||||||
// Currently there is no define which determines the PSDK-Version...
|
|
||||||
// So we just use the compiler-version (and assumes that the PSDK is
|
|
||||||
// the one which was installed by the VS-IDE)
|
|
||||||
|
|
||||||
// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later...
|
|
||||||
// But I currently use it in x64/IA64 environments...
|
|
||||||
//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400)
|
|
||||||
|
|
||||||
#if defined(_M_IX86)
|
|
||||||
#ifdef CURRENT_THREAD_VIA_EXCEPTION
|
|
||||||
// TODO: The following is not a "good" implementation,
|
|
||||||
// because the callstack is only valid in the "__except" block...
|
|
||||||
#define GET_CURRENT_CONTEXT(c, contextFlags) \
|
|
||||||
do { \
|
|
||||||
memset(&c, 0, sizeof(CONTEXT)); \
|
|
||||||
EXCEPTION_POINTERS *pExp = NULL; \
|
|
||||||
__try { \
|
|
||||||
throw 0; \
|
|
||||||
} __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \
|
|
||||||
if (pExp != NULL) \
|
|
||||||
memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \
|
|
||||||
c.ContextFlags = contextFlags; \
|
|
||||||
} while(0);
|
|
||||||
#else
|
|
||||||
// The following should be enough for walking the callstack...
|
|
||||||
#define GET_CURRENT_CONTEXT(c, contextFlags) \
|
|
||||||
do { \
|
|
||||||
memset(&c, 0, sizeof(CONTEXT)); \
|
|
||||||
c.ContextFlags = contextFlags; \
|
|
||||||
__asm call x \
|
|
||||||
__asm x: pop eax \
|
|
||||||
__asm mov c.Eip, eax \
|
|
||||||
__asm mov c.Ebp, ebp \
|
|
||||||
__asm mov c.Esp, esp \
|
|
||||||
} while(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// The following is defined for x86 (XP and higher), x64 and IA64:
|
|
||||||
#define GET_CURRENT_CONTEXT(c, contextFlags) \
|
|
||||||
do { \
|
|
||||||
memset(&c, 0, sizeof(CONTEXT)); \
|
|
||||||
c.ContextFlags = contextFlags; \
|
|
||||||
RtlCaptureContext(&c); \
|
|
||||||
} while(0);
|
|
||||||
#endif
|
|
||||||
|
|
@ -75,36 +75,51 @@ namespace kiwano
|
||||||
dlls::MediaFoundation::Get().MFShutdown();
|
dlls::MediaFoundation::Get().MFShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT AudioEngine::CreateVoice(IXAudio2SourceVoice** voice, const Transcoder::Buffer& buffer)
|
bool AudioEngine::CreateSound(Sound& sound, const Transcoder::Buffer& buffer)
|
||||||
{
|
{
|
||||||
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
|
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
|
||||||
|
|
||||||
if (voice == nullptr)
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if (buffer.format == nullptr)
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
return E_INVALIDARG;
|
IXAudio2SourceVoice* voice = nullptr;
|
||||||
|
hr = x_audio2_->CreateSourceVoice(&voice, buffer.format, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
IXAudio2SourceVoice* old = sound.GetXAudio2Voice();
|
||||||
|
if (old)
|
||||||
|
{
|
||||||
|
old->DestroyVoice();
|
||||||
|
old = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
sound.SetXAudio2Voice(voice);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*voice)
|
win32::WarnIfFailed(hr);
|
||||||
{
|
return SUCCEEDED(hr);
|
||||||
(*voice)->DestroyVoice();
|
|
||||||
(*voice) = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x_audio2_->CreateSourceVoice(voice, buffer.format, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::Open()
|
void AudioEngine::Open()
|
||||||
{
|
{
|
||||||
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
|
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
|
||||||
|
|
||||||
x_audio2_->StartEngine();
|
if (x_audio2_)
|
||||||
|
x_audio2_->StartEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::Close()
|
void AudioEngine::Close()
|
||||||
{
|
{
|
||||||
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
|
KGE_ASSERT(x_audio2_ && "AudioEngine hasn't been initialized!");
|
||||||
|
|
||||||
x_audio2_->StopEngine();
|
if (x_audio2_)
|
||||||
|
x_audio2_->StopEngine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,27 @@
|
||||||
#include <kiwano/core/common.h>
|
#include <kiwano/core/common.h>
|
||||||
#include <kiwano/core/Component.h>
|
#include <kiwano/core/Component.h>
|
||||||
#include <kiwano-audio/Transcoder.h>
|
#include <kiwano-audio/Transcoder.h>
|
||||||
|
#include <kiwano-audio/Sound.h>
|
||||||
#include <xaudio2.h>
|
#include <xaudio2.h>
|
||||||
|
|
||||||
namespace kiwano
|
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 Singleton<AudioEngine>
|
||||||
, public ComponentBase
|
, public ComponentBase
|
||||||
|
|
@ -35,16 +50,17 @@ namespace kiwano
|
||||||
friend Singleton<AudioEngine>;
|
friend Singleton<AudioEngine>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 开启设备
|
/// \~chinese
|
||||||
|
/// @brief 开启音频设备
|
||||||
void Open();
|
void Open();
|
||||||
|
|
||||||
// 关闭设备
|
/// \~chinese
|
||||||
|
/// @brief 关闭音频设备
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
HRESULT CreateVoice(
|
/// \~chinese
|
||||||
IXAudio2SourceVoice** voice,
|
/// @brief 从解码器数据缓冲中创建音频对象
|
||||||
const Transcoder::Buffer& buffer
|
bool CreateSound(Sound& sound, const Transcoder::Buffer& buffer);
|
||||||
);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SetupComponent() override;
|
void SetupComponent() override;
|
||||||
|
|
@ -60,5 +76,7 @@ namespace kiwano
|
||||||
IXAudio2* x_audio2_;
|
IXAudio2* x_audio2_;
|
||||||
IXAudio2MasteringVoice* mastering_voice_;
|
IXAudio2MasteringVoice* mastering_voice_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,6 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound::Sound(String const& file_path)
|
|
||||||
: Sound()
|
|
||||||
{
|
|
||||||
Load(file_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sound::Sound(Resource const& res)
|
|
||||||
: Sound()
|
|
||||||
{
|
|
||||||
Load(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sound::~Sound()
|
Sound::~Sound()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
|
@ -68,19 +56,15 @@ namespace kiwano
|
||||||
String full_path = FileSystem::instance().GetFullPathForFile(file_path);
|
String full_path = FileSystem::instance().GetFullPathForFile(file_path);
|
||||||
|
|
||||||
HRESULT hr = transcoder_.LoadMediaFile(full_path);
|
HRESULT hr = transcoder_.LoadMediaFile(full_path);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_ERROR(L"Load media file failed with HRESULT of %08X", hr);
|
KGE_ERROR(L"Load media file failed with HRESULT of %08X", hr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = AudioEngine::instance().CreateVoice(&voice_, transcoder_.GetBuffer());
|
if (!AudioEngine::instance().CreateSound(*this, transcoder_.GetBuffer()))
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
KGE_ERROR(L"Create source voice failed with HRESULT of %08X", hr);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,19 +80,15 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = transcoder_.LoadMediaResource(res);
|
HRESULT hr = transcoder_.LoadMediaResource(res);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_ERROR(L"Load media resource failed with HRESULT of %08X", hr);
|
KGE_ERROR(L"Load media resource failed with HRESULT of %08X", hr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = AudioEngine::instance().CreateVoice(&voice_, transcoder_.GetBuffer());
|
if (!AudioEngine::instance().CreateSound(*this, transcoder_.GetBuffer()))
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
KGE_ERROR(L"Create source voice failed with HRESULT of %08X", hr);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,6 +96,11 @@ namespace kiwano
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sound::IsValid() const
|
||||||
|
{
|
||||||
|
return voice_ != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Sound::Play(int loop_count)
|
void Sound::Play(int loop_count)
|
||||||
{
|
{
|
||||||
if (!opened_)
|
if (!opened_)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <kiwano/core/ObjectBase.h>
|
#include <kiwano/core/ObjectBase.h>
|
||||||
#include <kiwano/core/Resource.h>
|
#include <kiwano/core/Resource.h>
|
||||||
|
#include <kiwano/platform/win32/ComPtr.hpp>
|
||||||
#include <kiwano-audio/Transcoder.h>
|
#include <kiwano-audio/Transcoder.h>
|
||||||
#include <xaudio2.h>
|
#include <xaudio2.h>
|
||||||
|
|
||||||
|
|
@ -28,68 +29,100 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
namespace audio
|
namespace audio
|
||||||
{
|
{
|
||||||
|
class AudioEngine;
|
||||||
|
|
||||||
KGE_DECLARE_SMART_PTR(Sound);
|
KGE_DECLARE_SMART_PTR(Sound);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup Audio
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 音频
|
||||||
|
*/
|
||||||
class KGE_API Sound
|
class KGE_API Sound
|
||||||
: public ObjectBase
|
: public ObjectBase
|
||||||
{
|
{
|
||||||
|
friend class AudioEngine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sound();
|
Sound();
|
||||||
|
|
||||||
Sound(
|
|
||||||
String const& file_path /* 本地音频文件 */
|
|
||||||
);
|
|
||||||
|
|
||||||
Sound(
|
|
||||||
Resource const& res /* 音乐资源 */
|
|
||||||
);
|
|
||||||
|
|
||||||
virtual ~Sound();
|
virtual ~Sound();
|
||||||
|
|
||||||
// 打开本地音频文件
|
/// \~chinese
|
||||||
bool Load(
|
/// @brief 打开本地音频文件
|
||||||
String const& file_path
|
/// @param res 本地音频文件路径
|
||||||
);
|
bool Load(String const& file_path);
|
||||||
|
|
||||||
// 打开音乐资源
|
/// \~chinese
|
||||||
bool Load(
|
/// @brief 打开音频资源
|
||||||
Resource const& res /* 音乐资源 */
|
/// @param res 音频资源
|
||||||
);
|
bool Load(Resource const& res);
|
||||||
|
|
||||||
// 播放
|
/// \~chinese
|
||||||
void Play(
|
/// @brief 是否有效
|
||||||
int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
|
bool IsValid() const;
|
||||||
);
|
|
||||||
|
|
||||||
// 暂停
|
/// \~chinese
|
||||||
|
/// @brief 播放
|
||||||
|
/// @param loop_count 播放循环次数,设置 -1 为循环播放
|
||||||
|
void Play(int loop_count = 0);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 暂停
|
||||||
void Pause();
|
void Pause();
|
||||||
|
|
||||||
// 继续
|
/// \~chinese
|
||||||
|
/// @brief 继续
|
||||||
void Resume();
|
void Resume();
|
||||||
|
|
||||||
// 停止
|
/// \~chinese
|
||||||
|
/// @brief 停止
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
// 关闭并回收资源
|
/// \~chinese
|
||||||
|
/// @brief 关闭并销毁资源
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
// 是否正在播放
|
/// \~chinese
|
||||||
|
/// @brief 是否正在播放
|
||||||
bool IsPlaying() const;
|
bool IsPlaying() const;
|
||||||
|
|
||||||
// 获取音量
|
/// \~chinese
|
||||||
|
/// @brief 获取音量
|
||||||
float GetVolume() const;
|
float GetVolume() const;
|
||||||
|
|
||||||
// 设置音量
|
/// \~chinese
|
||||||
void SetVolume(
|
/// @brief 设置音量
|
||||||
float volume /* 1 为原始音量, 大于 1 为放大音量, 0 为最小音量 */
|
/// @param volume 音量大小,1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量
|
||||||
);
|
void SetVolume(float volume);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool opened_;
|
IXAudio2SourceVoice* GetXAudio2Voice() const;
|
||||||
bool playing_;
|
|
||||||
Transcoder transcoder_;
|
|
||||||
|
|
||||||
|
void SetXAudio2Voice(IXAudio2SourceVoice* voice);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool opened_;
|
||||||
|
bool playing_;
|
||||||
|
Transcoder transcoder_;
|
||||||
IXAudio2SourceVoice* voice_;
|
IXAudio2SourceVoice* voice_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
inline IXAudio2SourceVoice* Sound::GetXAudio2Voice() const
|
||||||
|
{
|
||||||
|
return voice_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Sound::SetXAudio2Voice(IXAudio2SourceVoice* voice)
|
||||||
|
{
|
||||||
|
voice_ = voice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,69 +28,84 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
KGE_DECLARE_SMART_PTR(SoundPlayer);
|
KGE_DECLARE_SMART_PTR(SoundPlayer);
|
||||||
|
|
||||||
// 音乐播放器
|
/**
|
||||||
|
* \addtogroup Audio
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 音频播放器
|
||||||
|
*/
|
||||||
class KGE_API SoundPlayer
|
class KGE_API SoundPlayer
|
||||||
: protected ObjectBase
|
: public ObjectBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SoundPlayer();
|
SoundPlayer();
|
||||||
|
|
||||||
~SoundPlayer();
|
~SoundPlayer();
|
||||||
|
|
||||||
// 加载本地音频文件, 返回该资源的标识符
|
/// \~chinese
|
||||||
size_t Load(
|
/// @brief 加载本地音频文件
|
||||||
String const& file_path
|
/// @param file_path 本地音频文件路径
|
||||||
);
|
/// @return 音频标识符
|
||||||
|
size_t Load(String const& file_path);
|
||||||
|
|
||||||
// 加载音乐资源, 返回该资源的标识符
|
/// \~chinese
|
||||||
size_t Load(
|
/// @brief 加载音频资源
|
||||||
Resource const& res /* 音乐资源 */
|
/// @param res 音频资源
|
||||||
);
|
/// @return 音频标识符
|
||||||
|
size_t Load(Resource const& res);
|
||||||
|
|
||||||
// 播放音乐
|
/// \~chinese
|
||||||
void Play(
|
/// @brief 播放音频
|
||||||
size_t id, /* 标识符 */
|
/// @param id 音频标识符
|
||||||
int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
|
/// @param loop_count 播放循环次数,设置 -1 为循环播放
|
||||||
);
|
void Play(size_t id, int loop_count = 0);
|
||||||
|
|
||||||
// 暂停音乐
|
/// \~chinese
|
||||||
void Pause(
|
/// @brief 暂停音频
|
||||||
size_t id /* 标识符 */
|
/// @param id 音频标识符
|
||||||
);
|
void Pause(size_t id);
|
||||||
|
|
||||||
// 继续播放音乐
|
/// \~chinese
|
||||||
void Resume(
|
/// @brief 继续播放音频
|
||||||
size_t id /* 标识符 */
|
/// @param id 音频标识符
|
||||||
);
|
void Resume(size_t id);
|
||||||
|
|
||||||
// 停止音乐
|
/// \~chinese
|
||||||
void Stop(
|
/// @brief 停止音频
|
||||||
size_t id /* 标识符 */
|
/// @param id 音频标识符
|
||||||
);
|
void Stop(size_t id);
|
||||||
|
|
||||||
// 获取音乐播放状态
|
/// \~chinese
|
||||||
bool IsPlaying(
|
/// @brief 获取音频播放状态
|
||||||
size_t id /* 标识符 */
|
/// @param id 音频标识符
|
||||||
);
|
bool IsPlaying(size_t id);
|
||||||
|
|
||||||
// 获取音量
|
/// \~chinese
|
||||||
|
/// @brief 获取音量
|
||||||
float GetVolume() const;
|
float GetVolume() const;
|
||||||
|
|
||||||
// 设置音量
|
/// \~chinese
|
||||||
void SetVolume(
|
/// @brief 设置音量
|
||||||
float volume /* 1.0 为原始音量 */
|
/// @param volume 音量大小,1.0 为原始音量, 大于 1 为放大音量, 0 为最小音量
|
||||||
);
|
void SetVolume(float volume);
|
||||||
|
|
||||||
// 暂停所有音乐
|
/// \~chinese
|
||||||
|
/// @brief 暂停所有音频
|
||||||
void PauseAll();
|
void PauseAll();
|
||||||
|
|
||||||
// 继续播放所有音乐
|
/// \~chinese
|
||||||
|
/// @brief 继续播放所有音频
|
||||||
void ResumeAll();
|
void ResumeAll();
|
||||||
|
|
||||||
// 停止所有音乐
|
/// \~chinese
|
||||||
|
/// @brief 停止所有音频
|
||||||
void StopAll();
|
void StopAll();
|
||||||
|
|
||||||
// 清除缓存
|
/// \~chinese
|
||||||
|
/// @brief 清除缓存
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -99,5 +114,7 @@ namespace kiwano
|
||||||
using SoundMap = Map<size_t, SoundPtr>;
|
using SoundMap = Map<size_t, SoundPtr>;
|
||||||
SoundMap sound_cache_;
|
SoundMap sound_cache_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,41 +28,64 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
namespace audio
|
namespace audio
|
||||||
{
|
{
|
||||||
|
class Sound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup Audio
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 音频解码器
|
||||||
|
*/
|
||||||
class KGE_API Transcoder
|
class KGE_API Transcoder
|
||||||
{
|
{
|
||||||
|
friend class Sound;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 音频数据缓冲
|
||||||
|
*/
|
||||||
struct Buffer
|
struct Buffer
|
||||||
{
|
{
|
||||||
BYTE* data;
|
BYTE* data; ///< 音频数据
|
||||||
uint32_t size;
|
uint32_t size; ///< 音频数据大小
|
||||||
const WAVEFORMATEX* format;
|
const WAVEFORMATEX* format; ///< 音频数据格式
|
||||||
};
|
};
|
||||||
|
|
||||||
Transcoder();
|
Transcoder();
|
||||||
|
|
||||||
~Transcoder();
|
~Transcoder();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取数据缓冲
|
||||||
Buffer GetBuffer() const;
|
Buffer GetBuffer() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 清空数据缓冲
|
||||||
void ClearBuffer();
|
void ClearBuffer();
|
||||||
|
|
||||||
HRESULT LoadMediaFile(
|
private:
|
||||||
String const& file_path
|
/// \~chinese
|
||||||
);
|
/// @brief 解码本地音频文件
|
||||||
|
HRESULT LoadMediaFile(String const& file_path);
|
||||||
|
|
||||||
HRESULT LoadMediaResource(
|
/// \~chinese
|
||||||
Resource const& res
|
/// @brief 解码音频资源
|
||||||
);
|
HRESULT LoadMediaResource(Resource const& res);
|
||||||
|
|
||||||
HRESULT ReadSource(
|
/// \~chinese
|
||||||
IMFSourceReader* reader
|
/// @brief 读取音频源数据
|
||||||
);
|
HRESULT ReadSource(IMFSourceReader* reader);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BYTE* wave_data_;
|
BYTE* wave_data_;
|
||||||
uint32_t wave_size_;
|
uint32_t wave_size_;
|
||||||
WAVEFORMATEX* wave_format_;
|
WAVEFORMATEX* wave_format_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
const auto xaudio2_dll_names =
|
const auto xaudio2_dll_names =
|
||||||
{
|
{
|
||||||
L"xaudio2_9.dll", // for Windows 10
|
"xaudio2_9.dll", // for Windows 10
|
||||||
L"xaudio2_8.dll", // for Windows 8
|
"xaudio2_8.dll", // for Windows 8
|
||||||
L"xaudio2_7.dll" // for DirectX SDK
|
"xaudio2_7.dll" // for DirectX SDK
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& name : xaudio2_dll_names)
|
for (const auto& name : xaudio2_dll_names)
|
||||||
|
|
@ -48,7 +48,7 @@ namespace kiwano
|
||||||
|
|
||||||
if (xaudio2.IsValid())
|
if (xaudio2.IsValid())
|
||||||
{
|
{
|
||||||
XAudio2Create = xaudio2.GetProcess<PFN_XAudio2Create>(L"XAudio2Create");
|
XAudio2Create = xaudio2.GetProcess<PFN_XAudio2Create>("XAudio2Create");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -68,28 +68,28 @@ namespace kiwano
|
||||||
, MFCreateSourceReaderFromByteStream(nullptr)
|
, MFCreateSourceReaderFromByteStream(nullptr)
|
||||||
, MFCreateMFByteStreamOnStream(nullptr)
|
, MFCreateMFByteStreamOnStream(nullptr)
|
||||||
{
|
{
|
||||||
if (mfplat.Load(L"Mfplat.dll"))
|
if (mfplat.Load("Mfplat.dll"))
|
||||||
{
|
{
|
||||||
MFStartup = mfplat.GetProcess<PFN_MFStartup>(L"MFStartup");
|
MFStartup = mfplat.GetProcess<PFN_MFStartup>("MFStartup");
|
||||||
MFShutdown = mfplat.GetProcess<PFN_MFShutdown>(L"MFShutdown");
|
MFShutdown = mfplat.GetProcess<PFN_MFShutdown>("MFShutdown");
|
||||||
MFCreateMediaType = mfplat.GetProcess<PFN_MFCreateMediaType>(L"MFCreateMediaType");
|
MFCreateMediaType = mfplat.GetProcess<PFN_MFCreateMediaType>("MFCreateMediaType");
|
||||||
MFCreateWaveFormatExFromMFMediaType = mfplat.GetProcess<PFN_MFCreateWaveFormatExFromMFMediaType>(L"MFCreateWaveFormatExFromMFMediaType");
|
MFCreateWaveFormatExFromMFMediaType = mfplat.GetProcess<PFN_MFCreateWaveFormatExFromMFMediaType>("MFCreateWaveFormatExFromMFMediaType");
|
||||||
MFCreateMFByteStreamOnStream = mfplat.GetProcess<PFN_MFCreateMFByteStreamOnStream>(L"MFCreateMFByteStreamOnStream");
|
MFCreateMFByteStreamOnStream = mfplat.GetProcess<PFN_MFCreateMFByteStreamOnStream>("MFCreateMFByteStreamOnStream");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG(L"Load Mfplat.dll failed");
|
KGE_ERROR(L"Load Mfplat.dll failed");
|
||||||
throw std::runtime_error("Load Mfplat.dll failed");
|
throw std::runtime_error("Load Mfplat.dll failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mfreadwrite.Load(L"Mfreadwrite.dll"))
|
if (mfreadwrite.Load("Mfreadwrite.dll"))
|
||||||
{
|
{
|
||||||
MFCreateSourceReaderFromURL = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromURL>(L"MFCreateSourceReaderFromURL");
|
MFCreateSourceReaderFromURL = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromURL>("MFCreateSourceReaderFromURL");
|
||||||
MFCreateSourceReaderFromByteStream = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromByteStream>(L"MFCreateSourceReaderFromByteStream");
|
MFCreateSourceReaderFromByteStream = mfreadwrite.GetProcess<PFN_MFCreateSourceReaderFromByteStream>("MFCreateSourceReaderFromByteStream");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG(L"Load Mfreadwrite.dll failed");
|
KGE_ERROR(L"Load Mfreadwrite.dll failed");
|
||||||
throw std::runtime_error("Load Mfreadwrite.dll failed");
|
throw std::runtime_error("Load Mfreadwrite.dll failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
#include <mfidl.h>
|
#include <mfidl.h>
|
||||||
#include <mfreadwrite.h>
|
#include <mfreadwrite.h>
|
||||||
|
|
||||||
|
#ifndef KGE_DOXYGEN_DO_NOT_INCLUDE
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
namespace audio
|
namespace audio
|
||||||
|
|
@ -93,3 +95,5 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,14 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
KGE_DECLARE_SMART_PTR(ImGuiLayer);
|
KGE_DECLARE_SMART_PTR(ImGuiLayer);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief ImGui管道
|
||||||
using ImGuiPipeline = Function<void()>;
|
using ImGuiPipeline = Function<void()>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief ImGui图层
|
||||||
|
*/
|
||||||
class ImGuiLayer
|
class ImGuiLayer
|
||||||
: public Layer
|
: public Layer
|
||||||
{
|
{
|
||||||
|
|
@ -37,18 +43,20 @@ namespace kiwano
|
||||||
|
|
||||||
virtual ~ImGuiLayer();
|
virtual ~ImGuiLayer();
|
||||||
|
|
||||||
// Ìí¼Ó ImGui ÔªËØ
|
/// \~chinese
|
||||||
void AddItem(
|
/// @brief 添加 ImGui 元素
|
||||||
ImGuiPipeline const& item,
|
/// @param item 管道
|
||||||
String const& name
|
/// @param name 元素名称
|
||||||
);
|
void AddItem(ImGuiPipeline const& item, String const& name);
|
||||||
|
|
||||||
// ÒÆ³ý ImGui ÔªËØ
|
/// \~chinese
|
||||||
void RemoveItem(
|
/// @brief 移除 ImGui 元素
|
||||||
String const& name
|
/// @param name 元素名称
|
||||||
);
|
void RemoveItem(String const& name);
|
||||||
|
|
||||||
// 移除所有元素
|
// 移除所有元素
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 移除所有元素
|
||||||
void RemoveAllItems();
|
void RemoveAllItems();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
namespace imgui
|
namespace imgui
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief ImGuiÄ£¿é
|
||||||
|
*/
|
||||||
class ImGuiModule
|
class ImGuiModule
|
||||||
: public Singleton<ImGuiModule>
|
: public Singleton<ImGuiModule>
|
||||||
, public RenderComponent
|
, public RenderComponent
|
||||||
|
|
@ -34,13 +38,6 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
friend Singleton<ImGuiModule>;
|
friend Singleton<ImGuiModule>;
|
||||||
|
|
||||||
private:
|
|
||||||
void Init(HWND hwnd);
|
|
||||||
|
|
||||||
void NewFrame();
|
|
||||||
|
|
||||||
void Render();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ImGuiModule();
|
ImGuiModule();
|
||||||
|
|
||||||
|
|
@ -48,14 +45,21 @@ namespace kiwano
|
||||||
|
|
||||||
void DestroyComponent() override;
|
void DestroyComponent() override;
|
||||||
|
|
||||||
void OnUpdate(Duration dt) override;
|
|
||||||
|
|
||||||
void BeforeRender() override;
|
void BeforeRender() override;
|
||||||
|
|
||||||
void AfterRender() override;
|
void AfterRender() override;
|
||||||
|
|
||||||
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override;
|
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override;
|
||||||
|
|
||||||
|
void OnUpdate(Duration dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init(HWND hwnd);
|
||||||
|
|
||||||
|
void NewFrame();
|
||||||
|
|
||||||
|
void Render();
|
||||||
|
|
||||||
void UpdateMousePos();
|
void UpdateMousePos();
|
||||||
|
|
||||||
void UpdateMouseCursor();
|
void UpdateMouseCursor();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef KGE_DOXYGEN_DO_NOT_INCLUDE
|
||||||
|
|
||||||
#if !defined(KGE_USE_DIRECTX10)
|
#if !defined(KGE_USE_DIRECTX10)
|
||||||
|
|
||||||
#include <kiwano-imgui/imgui_impl_dx11.h>
|
#include <kiwano-imgui/imgui_impl_dx11.h>
|
||||||
|
|
@ -27,3 +29,5 @@ inline void ImGui_Impl_InvalidateDeviceObjects() { ImGui_ImplDX10_Invalid
|
||||||
inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX10_CreateDeviceObjects(); }
|
inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX10_CreateDeviceObjects(); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <3rd-party/imgui/imgui.h>
|
#include <3rd-party/imgui/imgui.h>
|
||||||
|
|
||||||
|
#ifndef KGE_DOXYGEN_DO_NOT_INCLUDE
|
||||||
|
|
||||||
struct ID3D10Device;
|
struct ID3D10Device;
|
||||||
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
|
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
|
||||||
|
|
@ -13,3 +15,5 @@ IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
|
||||||
// Use if you want to reset your rendering device without losing ImGui state.
|
// Use if you want to reset your rendering device without losing ImGui state.
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <3rd-party/imgui/imgui.h>
|
#include <3rd-party/imgui/imgui.h>
|
||||||
|
|
||||||
|
#ifndef KGE_DOXYGEN_DO_NOT_INCLUDE
|
||||||
|
|
||||||
struct ID3D11Device;
|
struct ID3D11Device;
|
||||||
struct ID3D11DeviceContext;
|
struct ID3D11DeviceContext;
|
||||||
|
|
||||||
|
|
@ -14,3 +16,5 @@ IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||||
// Use if you want to reset your rendering device without losing ImGui state.
|
// Use if you want to reset your rendering device without losing ImGui state.
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ namespace
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
oc::string* recv_buffer = (oc::string*)userp;
|
ByteString* recv_buffer = (ByteString*)userp;
|
||||||
uint32_t total = size * nmemb;
|
uint32_t total = size * nmemb;
|
||||||
|
|
||||||
// add data to the end of recv_buffer
|
// add data to the end of recv_buffer
|
||||||
|
|
@ -46,10 +46,10 @@ namespace
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
oc::string convert_to_utf8(oc::wstring const& str)
|
ByteString convert_to_utf8(String const& str)
|
||||||
{
|
{
|
||||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||||
oc::string result;
|
ByteString result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -58,15 +58,15 @@ namespace
|
||||||
catch (std::range_error&)
|
catch (std::range_error&)
|
||||||
{
|
{
|
||||||
// bad conversion
|
// bad conversion
|
||||||
result = wide_to_string(str);
|
result = WideToMultiByte(str);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
oc::wstring convert_from_utf8(oc::string const& str)
|
String convert_from_utf8(ByteString const& str)
|
||||||
{
|
{
|
||||||
oc::string_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
oc::string_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||||
oc::wstring result;
|
String result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -75,7 +75,7 @@ namespace
|
||||||
catch (std::range_error&)
|
catch (std::range_error&)
|
||||||
{
|
{
|
||||||
// bad conversion
|
// bad conversion
|
||||||
result = string_to_wide(str);
|
result = MultiByteToWide(str);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +104,7 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Init(HttpClient* client, Vector<oc::string> const& headers, oc::string const& url, oc::string* response_data, oc::string* response_header, char* error_buffer)
|
bool Init(HttpClient* client, Vector<ByteString> const& headers, ByteString const& url, ByteString* response_data, ByteString* response_header, char* error_buffer)
|
||||||
{
|
{
|
||||||
if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer))
|
if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -170,11 +170,11 @@ namespace
|
||||||
public:
|
public:
|
||||||
static inline bool GetRequest(
|
static inline bool GetRequest(
|
||||||
HttpClient* client,
|
HttpClient* client,
|
||||||
Vector<oc::string> const& headers,
|
Vector<ByteString> const& headers,
|
||||||
oc::string const& url,
|
ByteString const& url,
|
||||||
long* response_code,
|
long* response_code,
|
||||||
oc::string* response_data,
|
ByteString* response_data,
|
||||||
oc::string* response_header,
|
ByteString* response_header,
|
||||||
char* error_buffer)
|
char* error_buffer)
|
||||||
{
|
{
|
||||||
Curl curl;
|
Curl curl;
|
||||||
|
|
@ -185,12 +185,12 @@ namespace
|
||||||
|
|
||||||
static inline bool PostRequest(
|
static inline bool PostRequest(
|
||||||
HttpClient* client,
|
HttpClient* client,
|
||||||
Vector<oc::string> const& headers,
|
Vector<ByteString> const& headers,
|
||||||
oc::string const& url,
|
ByteString const& url,
|
||||||
oc::string const& request_data,
|
ByteString const& request_data,
|
||||||
long* response_code,
|
long* response_code,
|
||||||
oc::string* response_data,
|
ByteString* response_data,
|
||||||
oc::string* response_header,
|
ByteString* response_header,
|
||||||
char* error_buffer)
|
char* error_buffer)
|
||||||
{
|
{
|
||||||
Curl curl;
|
Curl curl;
|
||||||
|
|
@ -203,12 +203,12 @@ namespace
|
||||||
|
|
||||||
static inline bool PutRequest(
|
static inline bool PutRequest(
|
||||||
HttpClient* client,
|
HttpClient* client,
|
||||||
Vector<oc::string> const& headers,
|
Vector<ByteString> const& headers,
|
||||||
oc::string const& url,
|
ByteString const& url,
|
||||||
oc::string const& request_data,
|
ByteString const& request_data,
|
||||||
long* response_code,
|
long* response_code,
|
||||||
oc::string* response_data,
|
ByteString* response_data,
|
||||||
oc::string* response_header,
|
ByteString* response_header,
|
||||||
char* error_buffer)
|
char* error_buffer)
|
||||||
{
|
{
|
||||||
Curl curl;
|
Curl curl;
|
||||||
|
|
@ -221,11 +221,11 @@ namespace
|
||||||
|
|
||||||
static inline bool DeleteRequest(
|
static inline bool DeleteRequest(
|
||||||
HttpClient* client,
|
HttpClient* client,
|
||||||
Vector<oc::string> const& headers,
|
Vector<ByteString> const& headers,
|
||||||
oc::string const& url,
|
ByteString const& url,
|
||||||
long* response_code,
|
long* response_code,
|
||||||
oc::string* response_data,
|
ByteString* response_data,
|
||||||
oc::string* response_header,
|
ByteString* response_header,
|
||||||
char* error_buffer)
|
char* error_buffer)
|
||||||
{
|
{
|
||||||
Curl curl;
|
Curl curl;
|
||||||
|
|
@ -307,13 +307,13 @@ namespace kiwano
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
long response_code = 0;
|
long response_code = 0;
|
||||||
char error_message[256] = { 0 };
|
char error_message[256] = { 0 };
|
||||||
oc::string response_header;
|
ByteString response_header;
|
||||||
oc::string response_data;
|
ByteString response_data;
|
||||||
|
|
||||||
oc::string url = convert_to_utf8(request->GetUrl());
|
ByteString url = convert_to_utf8(request->GetUrl());
|
||||||
oc::string data = convert_to_utf8(request->GetData());
|
ByteString data = convert_to_utf8(request->GetData());
|
||||||
|
|
||||||
Vector<oc::string> headers;
|
Vector<ByteString> headers;
|
||||||
headers.reserve(request->GetHeaders().size());
|
headers.reserve(request->GetHeaders().size());
|
||||||
for (const auto& pair : request->GetHeaders())
|
for (const auto& pair : request->GetHeaders())
|
||||||
{
|
{
|
||||||
|
|
@ -340,12 +340,12 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
|
|
||||||
response->SetResponseCode(response_code);
|
response->SetResponseCode(response_code);
|
||||||
response->SetHeader(oc::string_to_wide(response_header));
|
response->SetHeader(MultiByteToWide(response_header));
|
||||||
response->SetData(convert_from_utf8(response_data));
|
response->SetData(convert_from_utf8(response_data));
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
response->SetSucceed(false);
|
response->SetSucceed(false);
|
||||||
response->SetError(oc::string_to_wide(error_message));
|
response->SetError(MultiByteToWide(error_message));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,20 @@ 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 Singleton<HttpClient>
|
||||||
, public ComponentBase
|
, public ComponentBase
|
||||||
|
|
@ -35,18 +49,34 @@ namespace kiwano
|
||||||
friend Singleton<HttpClient>;
|
friend Singleton<HttpClient>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 发送HTTP请求
|
||||||
|
/// @param[in] request HTTP请求
|
||||||
|
/// @details 发送请求后,无论结束或失败都将调用请求的响应回调函数
|
||||||
void Send(HttpRequestPtr request);
|
void Send(HttpRequestPtr request);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置连接超时时长
|
||||||
void SetTimeoutForConnect(Duration timeout);
|
void SetTimeoutForConnect(Duration timeout);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取连接超时时长
|
||||||
Duration GetTimeoutForConnect() const;
|
Duration GetTimeoutForConnect() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置读取超时时长
|
||||||
void SetTimeoutForRead(Duration timeout);
|
void SetTimeoutForRead(Duration timeout);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取读取超时时长
|
||||||
Duration GetTimeoutForRead() const;
|
Duration GetTimeoutForRead() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置SSL证书地址
|
||||||
void SetSSLVerification(String const& root_certificate_path);
|
void SetSSLVerification(String const& root_certificate_path);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取SSL证书地址
|
||||||
String const& GetSSLVerification() const;
|
String const& GetSSLVerification() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -59,10 +89,7 @@ namespace kiwano
|
||||||
|
|
||||||
void NetworkThread();
|
void NetworkThread();
|
||||||
|
|
||||||
void Perform(
|
void Perform(HttpRequestPtr request, HttpResponsePtr response);
|
||||||
HttpRequestPtr request,
|
|
||||||
HttpResponsePtr response
|
|
||||||
);
|
|
||||||
|
|
||||||
void DispatchResponseCallback();
|
void DispatchResponseCallback();
|
||||||
|
|
||||||
|
|
@ -81,6 +108,8 @@ namespace kiwano
|
||||||
std::condition_variable_any sleep_condition_;
|
std::condition_variable_any sleep_condition_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
inline void HttpClient::SetTimeoutForConnect(Duration timeout)
|
inline void HttpClient::SetTimeoutForConnect(Duration timeout)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -31,46 +31,88 @@ namespace kiwano
|
||||||
|
|
||||||
KGE_DECLARE_SMART_PTR(HttpRequest);
|
KGE_DECLARE_SMART_PTR(HttpRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup Network
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief HTTP请求
|
||||||
|
*/
|
||||||
class KGE_API HttpRequest
|
class KGE_API HttpRequest
|
||||||
: public ObjectBase
|
: public ObjectBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using ResponseCallback = Function<void(HttpRequest*, HttpResponse*)>;
|
/// \~chinese
|
||||||
|
/// @brief 响应回调函数
|
||||||
|
using ResponseCallback = Function<void(HttpRequest* /* request */, HttpResponse* /* response */)>;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 请求类型
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
Unknown,
|
Unknown, ///< 未知
|
||||||
Get,
|
Get, ///< HTTP GET请求
|
||||||
Post,
|
Post, ///< HTTP POST请求
|
||||||
Put,
|
Put, ///< HTTP PUT请求
|
||||||
Delete
|
Delete ///< HTTP DELETE请求
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpRequest();
|
HttpRequest();
|
||||||
|
|
||||||
HttpRequest(Type type);
|
HttpRequest(Type type);
|
||||||
|
|
||||||
// 请求地址
|
/// \~chinese
|
||||||
|
/// @brief 设置请求地址
|
||||||
void SetUrl(String const& url);
|
void SetUrl(String const& url);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置请求类型
|
||||||
|
void SetType(Type type);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置请求携带的数据
|
||||||
|
void SetData(String const& data);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置请求携带的JSON数据
|
||||||
|
void SetJsonData(Json const& json);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置HTTP头
|
||||||
|
void SetHeaders(Map<String, String> const& headers);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置HTTP头
|
||||||
|
void SetHeader(String const& field, String const& content);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置响应回调函数
|
||||||
|
void SetResponseCallback(ResponseCallback const& callback);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取请求地址
|
||||||
String const& GetUrl() const;
|
String const& GetUrl() const;
|
||||||
|
|
||||||
// 请求类型
|
/// \~chinese
|
||||||
void SetType(Type type);
|
/// @brief 获取请求类型
|
||||||
Type GetType() const;
|
Type GetType() const;
|
||||||
|
|
||||||
// 请求数据
|
/// \~chinese
|
||||||
void SetData(String const& data);
|
/// @brief 获取请求数据
|
||||||
void SetJsonData(Json const& json);
|
|
||||||
String const& GetData() const;
|
String const& GetData() const;
|
||||||
|
|
||||||
// 请求头
|
/// \~chinese
|
||||||
void SetHeaders(Map<String, String> const& headers);
|
/// @brief 获取HTTP头
|
||||||
void SetHeader(String const& field, String const& content);
|
|
||||||
Map<String, String>& GetHeaders();
|
Map<String, String>& GetHeaders();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取HTTP头
|
||||||
String const& GetHeader(String const& header) const;
|
String const& GetHeader(String const& header) const;
|
||||||
|
|
||||||
// 响应回调
|
/// \~chinese
|
||||||
void SetResponseCallback(ResponseCallback const& callback);
|
/// @brief 获取响应回调函数
|
||||||
ResponseCallback const& GetResponseCallback() const;
|
ResponseCallback const& GetResponseCallback() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -81,6 +123,8 @@ namespace kiwano
|
||||||
ResponseCallback response_cb_;
|
ResponseCallback response_cb_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
inline HttpRequest::HttpRequest() : type_(Type::Unknown) {}
|
inline HttpRequest::HttpRequest() : type_(Type::Unknown) {}
|
||||||
|
|
||||||
inline HttpRequest::HttpRequest(Type type) : type_(type) {}
|
inline HttpRequest::HttpRequest(Type type) : type_(type) {}
|
||||||
|
|
|
||||||
|
|
@ -27,33 +27,63 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
KGE_DECLARE_SMART_PTR(HttpResponse);
|
KGE_DECLARE_SMART_PTR(HttpResponse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup Network
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief HTTP响应
|
||||||
|
*/
|
||||||
class KGE_API HttpResponse
|
class KGE_API HttpResponse
|
||||||
: public ObjectBase
|
: public ObjectBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpResponse(HttpRequestPtr request);
|
HttpResponse(HttpRequestPtr request);
|
||||||
|
|
||||||
// 获取请求
|
/// \~chinese
|
||||||
|
/// @brief 获取对应的HTTP请求
|
||||||
HttpRequestPtr GetRequest() const;
|
HttpRequestPtr GetRequest() const;
|
||||||
|
|
||||||
// 响应状态
|
/// \~chinese
|
||||||
|
/// @brief 获取响应状态
|
||||||
bool IsSucceed() const;
|
bool IsSucceed() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取HTTP状态码
|
||||||
|
long GetResponseCode() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取响应头
|
||||||
|
String GetHeader() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取响应数据
|
||||||
|
String const& GetData() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取错误信息
|
||||||
|
String const& GetError() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置响应状态
|
||||||
void SetSucceed(bool succeed);
|
void SetSucceed(bool succeed);
|
||||||
|
|
||||||
// 响应状态码
|
/// \~chinese
|
||||||
long GetResponseCode() const;
|
/// @brief 设置HTTP状态码
|
||||||
void SetResponseCode(long response_code);
|
void SetResponseCode(long response_code);
|
||||||
|
|
||||||
// 响应头
|
/// \~chinese
|
||||||
String GetHeader() const;
|
/// @brief 设置响应头
|
||||||
void SetHeader(String const& response_header);
|
void SetHeader(String const& response_header);
|
||||||
|
|
||||||
// 响应数据
|
/// \~chinese
|
||||||
String const& GetData() const;
|
/// @brief 设置响应数据
|
||||||
void SetData(String const& response_data);
|
void SetData(String const& response_data);
|
||||||
|
|
||||||
// 错误信息
|
/// \~chinese
|
||||||
String const& GetError() const;
|
/// @brief 设置错误信息
|
||||||
void SetError(String const& error_buffer);
|
void SetError(String const& error_buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -66,6 +96,8 @@ namespace kiwano
|
||||||
String error_buffer_;
|
String error_buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
inline HttpResponse::HttpResponse(HttpRequestPtr request) : request_(request), succeed_(false), response_code_(0) {}
|
inline HttpResponse::HttpResponse(HttpRequestPtr request) : request_(request), succeed_(false), response_code_(0) {}
|
||||||
|
|
||||||
inline HttpRequestPtr HttpResponse::GetRequest() const { return request_; }
|
inline HttpRequestPtr HttpResponse::GetRequest() const { return request_; }
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ namespace kiwano
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \~chinese
|
* \~chinese
|
||||||
* \defgroup Actors 角色
|
* \defgroup Actors 基础角色
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -63,8 +63,13 @@ namespace kiwano
|
||||||
friend IntrusiveList<ActorPtr>;
|
friend IntrusiveList<ActorPtr>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Children = IntrusiveList<ActorPtr>;
|
/// \~chinese
|
||||||
using UpdateCallback = Function<void(Duration)>;
|
/// @brief 子成员列表
|
||||||
|
using Children = IntrusiveList<ActorPtr>;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 角色更新回调函数
|
||||||
|
using UpdateCallback = Function<void(Duration)>;
|
||||||
|
|
||||||
Actor();
|
Actor();
|
||||||
|
|
||||||
|
|
@ -395,15 +400,15 @@ namespace kiwano
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 更新自身和所有子节点
|
/// @brief 更新自身和所有子角色
|
||||||
virtual void Update(Duration dt);
|
virtual void Update(Duration dt);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 渲染自身和所有子节点
|
/// @brief 渲染自身和所有子角色
|
||||||
virtual void Render(RenderTarget* rt);
|
virtual void Render(RenderTarget* rt);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 绘制自身和所有子节点的边界
|
/// @brief 绘制自身和所有子角色的边界
|
||||||
virtual void RenderBorder(RenderTarget* rt);
|
virtual void RenderBorder(RenderTarget* rt);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
|
|
@ -415,15 +420,15 @@ namespace kiwano
|
||||||
virtual void PrepareToRender(RenderTarget* rt);
|
virtual void PrepareToRender(RenderTarget* rt);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 更新自己的二维变换,并通知所有子节点
|
/// @brief 更新自己的二维变换,并通知所有子角色
|
||||||
void UpdateTransform() const;
|
void UpdateTransform() const;
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 更新自己和所有子节点的透明度
|
/// @brief 更新自己和所有子角色的透明度
|
||||||
void UpdateOpacity();
|
void UpdateOpacity();
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 将所有子节点按Z轴顺序排序
|
/// @brief 将所有子角色按Z轴顺序排序
|
||||||
void Reorder();
|
void Reorder();
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace kiwano
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 绘制所有子节点的边界
|
/// @brief 绘制所有子角色的边界
|
||||||
void RenderBorder(RenderTarget* rt) override;
|
void RenderBorder(RenderTarget* rt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,12 @@ namespace kiwano
|
||||||
return IsValid();
|
return IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Library::Load(ByteString const& lib)
|
||||||
|
{
|
||||||
|
instance_ = ::LoadLibraryA(lib.c_str());
|
||||||
|
return IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
bool Library::IsValid() const
|
bool Library::IsValid() const
|
||||||
{
|
{
|
||||||
return instance_ != nullptr;
|
return instance_ != nullptr;
|
||||||
|
|
@ -59,10 +65,13 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC Library::GetProcess(String const& proc_name)
|
FARPROC Library::GetProcess(ByteString const& proc_name)
|
||||||
{
|
{
|
||||||
KGE_ASSERT(instance_ != nullptr);
|
KGE_ASSERT(instance_ != nullptr);
|
||||||
return GetProcAddress(instance_, oc::wide_to_string(proc_name).c_str());
|
|
||||||
|
if (!IsValid())
|
||||||
|
return nullptr;
|
||||||
|
return GetProcAddress(instance_, proc_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,11 @@ namespace kiwano
|
||||||
/// @param lib DLL文件路径
|
/// @param lib DLL文件路径
|
||||||
bool Load(String const& lib);
|
bool Load(String const& lib);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 加载DLL
|
||||||
|
/// @param lib DLL文件路径
|
||||||
|
bool Load(ByteString const& lib);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 是否有效
|
/// @brief 是否有效
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
@ -58,13 +63,13 @@ namespace kiwano
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 检索指定的DLL中的输出库函数地址
|
/// @brief 检索指定的DLL中的输出库函数地址
|
||||||
/// @param proc_name 函数名
|
/// @param proc_name 函数名
|
||||||
FARPROC GetProcess(String const& proc_name);
|
FARPROC GetProcess(ByteString const& proc_name);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 检索指定的DLL中的输出库函数地址
|
/// @brief 检索指定的DLL中的输出库函数地址
|
||||||
/// @param proc_name 函数名
|
/// @param proc_name 函数名
|
||||||
template <typename _Proc>
|
template <typename _Proc>
|
||||||
inline _Proc GetProcess(String const& proc_name)
|
inline _Proc GetProcess(ByteString const& proc_name)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<_Proc>(GetProcess(proc_name));
|
return reinterpret_cast<_Proc>(GetProcess(proc_name));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,32 +201,29 @@ namespace kiwano
|
||||||
|
|
||||||
void Logger::Prepare(Level level, StringStream& sstream)
|
void Logger::Prepare(Level level, StringStream& sstream)
|
||||||
{
|
{
|
||||||
String prompt;
|
String prefix;
|
||||||
|
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case Level::Info:
|
case Level::Info:
|
||||||
prompt = L"[INFO] ";
|
prefix = L"[INFO] ";
|
||||||
break;
|
break;
|
||||||
case Level::System:
|
case Level::System:
|
||||||
prompt = L"[SYSTEM] ";
|
prefix = L"[SYSTEM] ";
|
||||||
break;
|
break;
|
||||||
case Level::Warning:
|
case Level::Warning:
|
||||||
prompt = L"[WARNING] ";
|
prefix = L"[WARN] ";
|
||||||
break;
|
break;
|
||||||
case Level::Error:
|
case Level::Error:
|
||||||
prompt = L"[ERROR] ";
|
prefix = L"[ERROR] ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefix
|
|
||||||
sstream << L"[KIWANO] " << prompt;
|
|
||||||
|
|
||||||
// Timestamp
|
// Timestamp
|
||||||
time_t unix = std::time(nullptr);
|
time_t unix = std::time(nullptr);
|
||||||
std::tm tmbuf;
|
std::tm tmbuf;
|
||||||
localtime_s(&tmbuf, &unix);
|
localtime_s(&tmbuf, &unix);
|
||||||
sstream << std::put_time(&tmbuf, L"%H:%M:%S ");
|
sstream << prefix << std::put_time(&tmbuf, L"%H:%M:%S ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Output(Level level, StringStream& sstream)
|
void Logger::Output(Level level, StringStream& sstream)
|
||||||
|
|
|
||||||
|
|
@ -78,18 +78,6 @@ namespace kiwano
|
||||||
/// @brief 控制台颜色
|
/// @brief 控制台颜色
|
||||||
using ConsoleColor = Function<OutputStream& (OutputStream&)>;
|
using ConsoleColor = Function<OutputStream& (OutputStream&)>;
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 显示或关闭控制台
|
|
||||||
void ShowConsole(bool show);
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 启用日志
|
|
||||||
void Enable();
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 禁用日志
|
|
||||||
void Disable();
|
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 打印日志
|
/// @brief 打印日志
|
||||||
/// @param level 日志级别
|
/// @param level 日志级别
|
||||||
|
|
@ -110,6 +98,19 @@ namespace kiwano
|
||||||
template <typename ..._Args>
|
template <typename ..._Args>
|
||||||
void Println(Level level, _Args&& ... args);
|
void Println(Level level, _Args&& ... args);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 显示或关闭控制台
|
||||||
|
/// @note 此操作会重置输出流
|
||||||
|
void ShowConsole(bool show);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 启用日志
|
||||||
|
void Enable();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 禁用日志
|
||||||
|
void Disable();
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取输出流
|
/// @brief 获取输出流
|
||||||
std::wostream& GetOutputStream();
|
std::wostream& GetOutputStream();
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,10 @@ namespace kiwano
|
||||||
/// @brief 字符串容器
|
/// @brief 字符串容器
|
||||||
using String = oc::wstring;
|
using String = oc::wstring;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 窄字符串容器
|
||||||
|
using ByteString = oc::string;
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 字符串流
|
/// @brief 字符串流
|
||||||
using StringStream = std::wstringstream;
|
using StringStream = std::wstringstream;
|
||||||
|
|
@ -149,4 +153,14 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
return oc::closure(ptr, func);
|
return oc::closure(ptr, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ByteString WideToMultiByte(const String& str)
|
||||||
|
{
|
||||||
|
return oc::wide_to_string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline String MultiByteToWide(const ByteString& str)
|
||||||
|
{
|
||||||
|
return oc::string_to_wide(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,13 +128,7 @@ namespace kiwano
|
||||||
uint32_t screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top;
|
uint32_t screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top;
|
||||||
|
|
||||||
uint32_t win_width, win_height;
|
uint32_t win_width, win_height;
|
||||||
AdjustWindow(
|
AdjustWindow(width, height, GetWindowStyle(), &win_width, &win_height);
|
||||||
width,
|
|
||||||
height,
|
|
||||||
GetWindowStyle(),
|
|
||||||
&win_width,
|
|
||||||
&win_height
|
|
||||||
);
|
|
||||||
|
|
||||||
left = monitor_info_ex.rcWork.left + (screenw - win_width) / 2;
|
left = monitor_info_ex.rcWork.left + (screenw - win_width) / 2;
|
||||||
top = monitor_info_ex.rcWork.top + (screenh - win_height) / 2;
|
top = monitor_info_ex.rcWork.top + (screenh - win_height) / 2;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
// 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/macros.h>
|
||||||
|
#include <kiwano/core/Logger.h>
|
||||||
|
#include <kiwano/core/Library.h>
|
||||||
|
#include <dbghelp.h>
|
||||||
|
|
||||||
|
namespace kiwano
|
||||||
|
{
|
||||||
|
namespace win32
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// SymInitialize()
|
||||||
|
typedef BOOL(__stdcall* PFN_SymInitialize)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess);
|
||||||
|
|
||||||
|
// SymCleanup()
|
||||||
|
typedef BOOL(__stdcall* PFN_SymCleanup)(IN HANDLE hProcess);
|
||||||
|
|
||||||
|
// SymGetLineFromAddr64()
|
||||||
|
typedef BOOL(__stdcall* PFN_SymGetLineFromAddr64)(IN HANDLE hProcess, IN DWORD64 dwAddr,
|
||||||
|
OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line);
|
||||||
|
|
||||||
|
// SymGetSymFromAddr64()
|
||||||
|
typedef BOOL(__stdcall* PFN_SymGetSymFromAddr64)(IN HANDLE hProcess, IN DWORD64 dwAddr,
|
||||||
|
OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol);
|
||||||
|
|
||||||
|
// StackWalk64()
|
||||||
|
typedef BOOL(__stdcall* PFN_StackWalk64)(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
|
||||||
|
LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
|
||||||
|
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
|
||||||
|
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
|
||||||
|
|
||||||
|
// SymFunctionTableAccess64()
|
||||||
|
typedef PVOID(__stdcall* PFN_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase);
|
||||||
|
|
||||||
|
// SymGetModuleBase64()
|
||||||
|
typedef DWORD64(__stdcall* PFN_SymGetModuleBase64)(IN HANDLE hProcess, IN DWORD64 dwAddr);
|
||||||
|
|
||||||
|
struct DbgHelp
|
||||||
|
{
|
||||||
|
Library dbgLib;
|
||||||
|
PFN_SymInitialize SymInitialize;
|
||||||
|
PFN_SymCleanup SymCleanup;
|
||||||
|
PFN_SymGetLineFromAddr64 SymGetLineFromAddr64;
|
||||||
|
PFN_SymGetSymFromAddr64 SymGetSymFromAddr64;
|
||||||
|
PFN_StackWalk64 StackWalk64;
|
||||||
|
PFN_SymFunctionTableAccess64 SymFunctionTableAccess64;
|
||||||
|
PFN_SymGetModuleBase64 SymGetModuleBase64;
|
||||||
|
|
||||||
|
DbgHelp()
|
||||||
|
: SymInitialize(nullptr)
|
||||||
|
, SymCleanup(nullptr)
|
||||||
|
, SymGetLineFromAddr64(nullptr)
|
||||||
|
, SymGetSymFromAddr64(nullptr)
|
||||||
|
, StackWalk64(nullptr)
|
||||||
|
, SymFunctionTableAccess64(nullptr)
|
||||||
|
, SymGetModuleBase64(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Load()
|
||||||
|
{
|
||||||
|
if (IsValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!dbgLib.Load("dbghelp.dll"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SymInitialize = dbgLib.GetProcess<PFN_SymInitialize>("SymInitialize");
|
||||||
|
SymCleanup = dbgLib.GetProcess<PFN_SymCleanup>("SymCleanup");
|
||||||
|
SymGetLineFromAddr64 = dbgLib.GetProcess<PFN_SymGetLineFromAddr64>("SymGetLineFromAddr64");
|
||||||
|
SymGetSymFromAddr64 = dbgLib.GetProcess<PFN_SymGetSymFromAddr64>("SymGetSymFromAddr64");
|
||||||
|
StackWalk64 = dbgLib.GetProcess<PFN_StackWalk64>("StackWalk64");
|
||||||
|
SymFunctionTableAccess64 = dbgLib.GetProcess<PFN_SymFunctionTableAccess64>("SymFunctionTableAccess64");
|
||||||
|
SymGetModuleBase64 = dbgLib.GetProcess<PFN_SymGetModuleBase64>("SymGetModuleBase64");
|
||||||
|
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
dbgLib.Free();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const
|
||||||
|
{
|
||||||
|
return SymInitialize && SymCleanup && SymGetLineFromAddr64 && SymGetSymFromAddr64
|
||||||
|
&& StackWalk64 && SymFunctionTableAccess64 && SymGetModuleBase64;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DbgHelp g_DbgHelp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintErrorCode(LPCWSTR lpszFunction)
|
||||||
|
{
|
||||||
|
KGE_ERROR(L"%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintCallStackOnContext(PCONTEXT pContext)
|
||||||
|
{
|
||||||
|
if (!g_DbgHelp.Load())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pContext == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DWORD dwMachineType;
|
||||||
|
STACKFRAME64 sf;
|
||||||
|
HANDLE hProcess = GetCurrentProcess();
|
||||||
|
HANDLE hThread = GetCurrentThread();
|
||||||
|
|
||||||
|
ZeroMemory(&sf, sizeof(sf));
|
||||||
|
|
||||||
|
sf.AddrPC.Mode = AddrModeFlat;
|
||||||
|
sf.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
sf.AddrStack.Mode = AddrModeFlat;
|
||||||
|
sf.AddrBStore.Mode = AddrModeFlat;
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
|
dwMachineType = IMAGE_FILE_MACHINE_I386;
|
||||||
|
sf.AddrPC.Offset = pContext->Eip;
|
||||||
|
sf.AddrFrame.Offset = pContext->Ebp;
|
||||||
|
sf.AddrStack.Offset = pContext->Esp;
|
||||||
|
#elif _M_X64
|
||||||
|
dwMachineType = IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
sf.AddrPC.Offset = pContext->Rip;
|
||||||
|
sf.AddrFrame.Offset = pContext->Rsp;
|
||||||
|
sf.AddrStack.Offset = pContext->Rsp;
|
||||||
|
#elif _M_IA64
|
||||||
|
dwMachineType = IMAGE_FILE_MACHINE_IA64;
|
||||||
|
sf.AddrPC.Offset = pContext->StIIP;
|
||||||
|
sf.AddrFrame.Offset = pContext->IntSp;
|
||||||
|
sf.AddrBStore.Offset = pContext->RsBSP;
|
||||||
|
sf.AddrStack.Offset = pContext->IntSp;
|
||||||
|
#else
|
||||||
|
#error "Platform not supported!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr int STACKWALK_MAX_NAMELEN = 1024;
|
||||||
|
BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
|
||||||
|
|
||||||
|
KGE_ERROR(L"========== Stack trace ==========");
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!g_DbgHelp.StackWalk64(dwMachineType, hProcess, hThread, &sf, pContext, NULL,
|
||||||
|
g_DbgHelp.SymFunctionTableAccess64, g_DbgHelp.SymGetModuleBase64, NULL))
|
||||||
|
{
|
||||||
|
PrintErrorCode(L"StackWalk64");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sf.AddrFrame.Offset == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(symbolBuffer, sizeof(symbolBuffer));
|
||||||
|
|
||||||
|
IMAGEHLP_SYMBOL64* pSymbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(symbolBuffer);
|
||||||
|
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
|
||||||
|
pSymbol->MaxNameLength = STACKWALK_MAX_NAMELEN;
|
||||||
|
|
||||||
|
DWORD64 dwDisplacement;
|
||||||
|
if (!g_DbgHelp.SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, &dwDisplacement, pSymbol))
|
||||||
|
{
|
||||||
|
PrintErrorCode(L"SymGetSymFromAddr64");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMAGEHLP_LINE64 lineInfo;
|
||||||
|
ZeroMemory(&lineInfo, sizeof(IMAGEHLP_LINE64));
|
||||||
|
lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||||
|
|
||||||
|
DWORD dwLineDisplacement;
|
||||||
|
if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
|
||||||
|
{
|
||||||
|
String functionName = MultiByteToWide(pSymbol->Name);
|
||||||
|
String fileName = MultiByteToWide(lineInfo.FileName);
|
||||||
|
KGE_ERROR(L"%s (%d): %s", fileName.c_str(), lineInfo.LineNumber, functionName.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String functionName = MultiByteToWide(pSymbol->Name);
|
||||||
|
KGE_ERROR(L"(filename not available): %s", functionName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sf.AddrReturn.Offset == 0)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintCallStack()
|
||||||
|
{
|
||||||
|
CONTEXT ctx;
|
||||||
|
HANDLE hProcess = GetCurrentProcess();
|
||||||
|
|
||||||
|
if (!g_DbgHelp.Load())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_DbgHelp.SymInitialize(hProcess, NULL, TRUE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
RtlCaptureContext(&ctx);
|
||||||
|
|
||||||
|
PrintCallStackOnContext(&ctx);
|
||||||
|
|
||||||
|
g_DbgHelp.SymCleanup(hProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,22 +21,37 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <kiwano/macros.h>
|
#include <kiwano/macros.h>
|
||||||
#include <3rd-party/StackWalker/StackWalker.h>
|
#include <kiwano/core/Logger.h>
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
namespace win32
|
namespace win32
|
||||||
{
|
{
|
||||||
|
void PrintCallStack();
|
||||||
|
|
||||||
|
void PrintCallStackOnContext(PCONTEXT pContext);
|
||||||
|
|
||||||
inline void ThrowIfFailed(HRESULT hr)
|
inline void ThrowIfFailed(HRESULT hr)
|
||||||
{
|
{
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
StackWalker().ShowCallstack();
|
PrintCallStack();
|
||||||
|
|
||||||
static char buffer[1024 + 1];
|
static char buffer[32];
|
||||||
sprintf_s(buffer, "Failed with HRESULT of %08X", hr);
|
sprintf_s(buffer, "Failed with HRESULT of %08X", hr);
|
||||||
throw std::runtime_error(buffer);
|
throw std::runtime_error(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void WarnIfFailed(HRESULT hr)
|
||||||
|
{
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
PrintCallStack();
|
||||||
|
|
||||||
|
KGE_WARN(L"Failed with HRESULT of %08X", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,10 @@ namespace kiwano
|
||||||
, PathFileExistsW(nullptr)
|
, PathFileExistsW(nullptr)
|
||||||
, SHCreateMemStream(nullptr)
|
, SHCreateMemStream(nullptr)
|
||||||
{
|
{
|
||||||
if (shlwapi.Load(L"shlwapi.dll"))
|
if (shlwapi.Load("shlwapi.dll"))
|
||||||
{
|
{
|
||||||
PathFileExistsW = shlwapi.GetProcess<PFN_PathFileExistsW>(L"PathFileExistsW");
|
PathFileExistsW = shlwapi.GetProcess<PFN_PathFileExistsW>("PathFileExistsW");
|
||||||
SHCreateMemStream = shlwapi.GetProcess<PFN_SHCreateMemStream>(L"SHCreateMemStream");
|
SHCreateMemStream = shlwapi.GetProcess<PFN_SHCreateMemStream>("SHCreateMemStream");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue