mirror of https://github.com/axmolengine/axmol.git
Merge branch 'v3' into v3FrameBufferObject
This commit is contained in:
commit
c22a8e81ce
|
@ -116,6 +116,7 @@ tests/*/publish/
|
|||
|
||||
# Android
|
||||
project.properties
|
||||
*.iml
|
||||
|
||||
# Ignore prebuilt libraries folder
|
||||
/external/*
|
||||
|
|
3
AUTHORS
3
AUTHORS
|
@ -1123,6 +1123,9 @@ Developers:
|
|||
Fixed crash on AssetsManager
|
||||
Fixed memory leak of WebView on iOS
|
||||
Fixed crahed that if url contains illegal characters on Android
|
||||
|
||||
tankorsmash
|
||||
Fixed the bug that ProgressTimer::setSprite() doesn't take effect
|
||||
|
||||
Retired Core Developers:
|
||||
WenSheng Yang
|
||||
|
|
10
CHANGELOG
10
CHANGELOG
|
@ -1,20 +1,28 @@
|
|||
cocos2d-x-3.7 ??
|
||||
[NEW] 3rd: updated rapidjson to v1.0.2
|
||||
[NEW] 3d: added physics3d support
|
||||
[NEW] Audio: added support on WP8.1, now it supports wav format
|
||||
[NEW] C++: added ActionFloat
|
||||
[NEW] C++: support physical keyboard on WinRT
|
||||
[NEW] FileUtils: checked filename case characters on windows
|
||||
[NEW] FileUitls: added supporting loading files that which file path include utf-8 characters
|
||||
[NEW] PhysicsShape: added sensor property
|
||||
|
||||
[NEW] Scale9Sprite: added Android 9-patch image support
|
||||
|
||||
[FIX] 3rd: fix PIE link error on iOS caused by libpng and libtiff
|
||||
[FIX] AssetsManager: crashed issue
|
||||
[FIX] Audio: can not play large ogg files on windows
|
||||
[FIX] EaseRateAction: no way to create an `EaseRateAction` instance
|
||||
[FIX] Label: crashed if invoking `setString(text` after `getLetter(letterIndex)` and `letterIndex` is greater than the length of text
|
||||
[FIX] Label: position is wrong if label content is changed after invoking `getLetter(letterIndex)`
|
||||
[FIX] Label: shadow effect cause OpenGL error on iOS
|
||||
[FIX] Label: outline effect doesn't match characters well
|
||||
[FIX] ProgressTimer: `setSprite()` doesn't take effect
|
||||
[FIX] Sprite3D: setGLProgram() does not work
|
||||
[FIX] Sprite3D: transition breaks when there is a Sprite3D in the scene
|
||||
[FIX] Terrain: terrain is on top of particles, particles can not be seen
|
||||
[FIX] TextureCache: unbindImageAsync failed to unbind all asynchronous callback for a specified bound image
|
||||
[FIX] TileMap: crashed if a layer contains nothing
|
||||
[FIX] WebView: memory leak on iOS
|
||||
[FIX] WebView: crashed if url contains illegal characters on Android
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ $ bin/lua-empty-test/lua-empty-test
|
|||
|
||||
* For Windows
|
||||
|
||||
Open the `cocos2d-x/build/cocos2d-win32.vc2013.sln`
|
||||
Open the `cocos2d-x/build/cocos2d-win32.sln`
|
||||
|
||||
* For Windows 8.1 Universal Apps (Phone and Store)
|
||||
|
||||
|
|
|
@ -45,6 +45,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjscocos2d.Windows", "..\
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjscocos2d.WindowsPhone", "..\cocos\scripting\js-bindings\proj.win8.1-universal\libjscocos2d\libjscocos2d.WindowsPhone\libjscocos2d.WindowsPhone.vcxproj", "{CA082EC4-17CE-430B-8207-D1E947A5D1E9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libbullet", "libbullet", "{9A66AB4C-057B-4675-849D-5D69B98C728C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet.Shared", "..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems", "{16AF311F-74CA-45A3-A82D-6334200FB124}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet.Windows", "..\external\bullet\proj.win8.1-universal\libbullet.Windows\libbullet.Windows.vcxproj", "{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet.WindowsPhone", "..\external\bullet\proj.win8.1-universal\libbullet.WindowsPhone\libbullet.WindowsPhone.vcxproj", "{E35634BD-B91B-4A6D-B957-96F56DD065F9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
..\tests\js-tests\project\proj.win8.1-universal\App.Shared\js-tests.Shared.vcxitems*{ae6763f6-1549-441e-afb5-377be1c776dc}*SharedItemsImports = 9
|
||||
|
@ -53,7 +61,10 @@ Global
|
|||
..\tests\js-tests\project\proj.win8.1-universal\App.Shared\js-tests.Shared.vcxitems*{70914fc8-7709-4cd6-b86b-c63fde5478db}*SharedItemsImports = 4
|
||||
..\cocos\editor-support\spine\proj.win8.1-universal\libSpine.Shared\libSpine.Shared.vcxitems*{cc1da216-a80d-4be4-b309-acb6af313aff}*SharedItemsImports = 4
|
||||
..\external\Box2D\proj.win8.1-universal\libbox2d.Shared\libbox2d.Shared.vcxitems*{4a3c6ba8-c227-498b-aa21-40bda27b461f}*SharedItemsImports = 9
|
||||
..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems*{e35634bd-b91b-4a6d-b957-96f56dd065f9}*SharedItemsImports = 4
|
||||
..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems*{ec2b1292-2d8c-4feb-a84b-2550b32c1ae7}*SharedItemsImports = 4
|
||||
..\cocos\editor-support\spine\proj.win8.1-universal\libSpine.Shared\libSpine.Shared.vcxitems*{adafd00d-a0d6-46ef-9f0b-ea2880bfe1de}*SharedItemsImports = 9
|
||||
..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems*{16af311f-74ca-45a3-a82d-6334200fb124}*SharedItemsImports = 9
|
||||
..\cocos\scripting\js-bindings\proj.win8.1-universal\libjscocos2d\libjscocos2d.Shared\libjscocos2d.Shared.vcxitems*{ca082ec4-17ce-430b-8207-d1e947a5d1e9}*SharedItemsImports = 4
|
||||
..\cocos\2d\libcocos2d_8_1\libcocos2d_8_1\libcocos2d_8_1.Shared\libcocos2d_8_1.Shared.vcxitems*{5d6f020f-7e72-4494-90a0-2df11d235df9}*SharedItemsImports = 9
|
||||
..\cocos\scripting\js-bindings\proj.win8.1-universal\libjscocos2d\libjscocos2d.Shared\libjscocos2d.Shared.vcxitems*{bea66276-51dd-4c53-92a8-f3d1fea50892}*SharedItemsImports = 9
|
||||
|
@ -192,6 +203,28 @@ Global
|
|||
{CA082EC4-17CE-430B-8207-D1E947A5D1E9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CA082EC4-17CE-430B-8207-D1E947A5D1E9}.Release|Win32.Build.0 = Release|Win32
|
||||
{CA082EC4-17CE-430B-8207-D1E947A5D1E9}.Release|x64.ActiveCfg = Release|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|x64.Build.0 = Debug|x64
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|ARM.Build.0 = Release|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|Win32.Build.0 = Release|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|x64.ActiveCfg = Release|x64
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|x64.Build.0 = Release|x64
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|ARM.Build.0 = Release|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|Win32.Build.0 = Release|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -214,5 +247,9 @@ Global
|
|||
{BEA66276-51DD-4C53-92A8-F3D1FEA50892} = {60DCAEA9-E344-40C0-B90C-82FB8E671BD5}
|
||||
{BCF5546D-66A0-4998-AFD6-C5514F618930} = {60DCAEA9-E344-40C0-B90C-82FB8E671BD5}
|
||||
{CA082EC4-17CE-430B-8207-D1E947A5D1E9} = {60DCAEA9-E344-40C0-B90C-82FB8E671BD5}
|
||||
{9A66AB4C-057B-4675-849D-5D69B98C728C} = {85630454-74EA-4B5B-9B62-0E459B4476CB}
|
||||
{16AF311F-74CA-45A3-A82D-6334200FB124} = {9A66AB4C-057B-4675-849D-5D69B98C728C}
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7} = {9A66AB4C-057B-4675-849D-5D69B98C728C}
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9} = {9A66AB4C-057B-4675-849D-5D69B98C728C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -45,6 +45,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloCpp.Windows", "..\test
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloCpp.WindowsPhone", "..\tests\cpp-empty-test\proj.win8.1-universal\HelloCpp.WindowsPhone\HelloCpp.WindowsPhone.vcxproj", "{396FE85E-BB05-4B92-BCCB-F89AED4EA41A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libbullet", "libbullet", "{0500043C-7E95-4351-97D6-0382A8C92DD3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet.Shared", "..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems", "{16AF311F-74CA-45A3-A82D-6334200FB124}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet.Windows", "..\external\bullet\proj.win8.1-universal\libbullet.Windows\libbullet.Windows.vcxproj", "{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet.WindowsPhone", "..\external\bullet\proj.win8.1-universal\libbullet.WindowsPhone\libbullet.WindowsPhone.vcxproj", "{E35634BD-B91B-4A6D-B957-96F56DD065F9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
..\cocos\2d\libcocos2d_8_1\libcocos2d_8_1\libcocos2d_8_1.Shared\libcocos2d_8_1.Shared.vcxitems*{9335005f-678e-4e8e-9b84-50037216aec8}*SharedItemsImports = 4
|
||||
|
@ -52,9 +60,12 @@ Global
|
|||
..\tests\cpp-empty-test\proj.win8.1-universal\HelloCpp.Shared\HelloCpp.Shared.vcxitems*{a3ad93e4-0b2f-4c58-9181-69bed2e42e3e}*SharedItemsImports = 9
|
||||
..\cocos\editor-support\spine\proj.win8.1-universal\libSpine.Shared\libSpine.Shared.vcxitems*{cc1da216-a80d-4be4-b309-acb6af313aff}*SharedItemsImports = 4
|
||||
..\external\Box2D\proj.win8.1-universal\libbox2d.Shared\libbox2d.Shared.vcxitems*{4a3c6ba8-c227-498b-aa21-40bda27b461f}*SharedItemsImports = 9
|
||||
..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems*{e35634bd-b91b-4a6d-b957-96f56dd065f9}*SharedItemsImports = 4
|
||||
..\tests\cpp-empty-test\proj.win8.1-universal\HelloCpp.Shared\HelloCpp.Shared.vcxitems*{79a8fcda-4b12-4dd1-b676-ff148d651638}*SharedItemsImports = 4
|
||||
..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems*{ec2b1292-2d8c-4feb-a84b-2550b32c1ae7}*SharedItemsImports = 4
|
||||
..\cocos\editor-support\spine\proj.win8.1-universal\libSpine.Shared\libSpine.Shared.vcxitems*{adafd00d-a0d6-46ef-9f0b-ea2880bfe1de}*SharedItemsImports = 9
|
||||
..\tests\cpp-tests\proj.win8.1-universal\cpp-tests.Shared\cpp-tests.Shared.vcxitems*{be3a1791-5bce-4cea-92cd-0e2d86dde27a}*SharedItemsImports = 9
|
||||
..\external\bullet\proj.win8.1-universal\libbullet.Shared\libbullet.Shared.vcxitems*{16af311f-74ca-45a3-a82d-6334200fb124}*SharedItemsImports = 9
|
||||
..\cocos\2d\libcocos2d_8_1\libcocos2d_8_1\libcocos2d_8_1.Shared\libcocos2d_8_1.Shared.vcxitems*{5d6f020f-7e72-4494-90a0-2df11d235df9}*SharedItemsImports = 9
|
||||
..\external\Box2D\proj.win8.1-universal\libbox2d.Shared\libbox2d.Shared.vcxitems*{3b26a12d-3a44-47ea-82d2-282660fc844d}*SharedItemsImports = 4
|
||||
..\cocos\2d\libcocos2d_8_1\libcocos2d_8_1\libcocos2d_8_1.Shared\libcocos2d_8_1.Shared.vcxitems*{22f3b9df-1209-4574-8331-003966f562bf}*SharedItemsImports = 4
|
||||
|
@ -202,6 +213,28 @@ Global
|
|||
{396FE85E-BB05-4B92-BCCB-F89AED4EA41A}.Release|Win32.Build.0 = Release|Win32
|
||||
{396FE85E-BB05-4B92-BCCB-F89AED4EA41A}.Release|Win32.Deploy.0 = Release|Win32
|
||||
{396FE85E-BB05-4B92-BCCB-F89AED4EA41A}.Release|x64.ActiveCfg = Release|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Debug|x64.Build.0 = Debug|x64
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|ARM.Build.0 = Release|ARM
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|Win32.Build.0 = Release|Win32
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|x64.ActiveCfg = Release|x64
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7}.Release|x64.Build.0 = Release|x64
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|ARM.Build.0 = Release|ARM
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|Win32.Build.0 = Release|Win32
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -224,5 +257,9 @@ Global
|
|||
{A3AD93E4-0B2F-4C58-9181-69BED2E42E3E} = {B70EF25E-E352-4020-BCDF-388973E44637}
|
||||
{79A8FCDA-4B12-4DD1-B676-FF148D651638} = {B70EF25E-E352-4020-BCDF-388973E44637}
|
||||
{396FE85E-BB05-4B92-BCCB-F89AED4EA41A} = {B70EF25E-E352-4020-BCDF-388973E44637}
|
||||
{0500043C-7E95-4351-97D6-0382A8C92DD3} = {85630454-74EA-4B5B-9B62-0E459B4476CB}
|
||||
{16AF311F-74CA-45A3-A82D-6334200FB124} = {0500043C-7E95-4351-97D6-0382A8C92DD3}
|
||||
{EC2B1292-2D8C-4FEB-A84B-2550B32C1AE7} = {0500043C-7E95-4351-97D6-0382A8C92DD3}
|
||||
{E35634BD-B91B-4A6D-B957-96F56DD065F9} = {0500043C-7E95-4351-97D6-0382A8C92DD3}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -821,7 +821,7 @@
|
|||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/.. $(SRCROOT)/../cocos $(SRCROOT)/../cocos/base $(SRCROOT)/../cocos/physics $(SRCROOT)/../cocos/math/kazmath $(SRCROOT)/../cocos/2d $(SRCROOT)/../cocos/gui $(SRCROOT)/../cocos/network $(SRCROOT)/../cocos/audio/include $(SRCROOT)/../cocos/editor-support $(SRCROOT)/../extensions $(SRCROOT)/../external $(SRCROOT)/../external/chipmunk/include/chipmunk $(SRCROOT)/../cocos/scripting/js-bindings/auto $(SRCROOT)/../cocos/scripting/js-bindings/manual";
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/.. $(SRCROOT)/../cocos $(SRCROOT)/../cocos/base $(SRCROOT)/../cocos/2d $(SRCROOT)/../cocos/gui $(SRCROOT)/../cocos/network $(SRCROOT)/../cocos/audio/include $(SRCROOT)/../cocos/editor-support $(SRCROOT)/../extensions $(SRCROOT)/../external $(SRCROOT)/../external/chipmunk/include/chipmunk $(SRCROOT)/../cocos/scripting/js-bindings/auto $(SRCROOT)/../cocos/scripting/js-bindings/manual";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -845,7 +845,7 @@
|
|||
HEADER_SEARCH_PATHS = "";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/.. $(SRCROOT)/../cocos $(SRCROOT)/../cocos/base $(SRCROOT)/../cocos/physics $(SRCROOT)/../cocos/math/kazmath $(SRCROOT)/../cocos/2d $(SRCROOT)/../cocos/gui $(SRCROOT)/../cocos/network $(SRCROOT)/../cocos/audio/include $(SRCROOT)/../cocos/editor-support $(SRCROOT)/../extensions $(SRCROOT)/../external $(SRCROOT)/../external/chipmunk/include/chipmunk $(SRCROOT)/../cocos/scripting/js-bindings/auto $(SRCROOT)/../cocos/scripting/js-bindings/manual";
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/.. $(SRCROOT)/../cocos $(SRCROOT)/../cocos/base $(SRCROOT)/../cocos/2d $(SRCROOT)/../cocos/gui $(SRCROOT)/../cocos/network $(SRCROOT)/../cocos/audio/include $(SRCROOT)/../cocos/editor-support $(SRCROOT)/../extensions $(SRCROOT)/../external $(SRCROOT)/../external/chipmunk/include/chipmunk $(SRCROOT)/../cocos/scripting/js-bindings/auto $(SRCROOT)/../cocos/scripting/js-bindings/manual";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
|
|
@ -1190,6 +1190,10 @@
|
|||
1AC0269D1914068200FA920D /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; };
|
||||
29031E0719BFE8D400EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0619BFE8D400EFA1DF /* libchipmunk.a */; };
|
||||
29031E0919BFE8DE00EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0819BFE8DE00EFA1DF /* libchipmunk.a */; };
|
||||
291901431B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
|
||||
291901441B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
|
||||
291901451B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
|
||||
291901461B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
|
||||
292DB13D19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
|
||||
292DB13E19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
|
||||
292DB13F19B4574100A80320 /* UIEditBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13019B4574100A80320 /* UIEditBox.h */; };
|
||||
|
@ -3925,6 +3929,8 @@
|
|||
2905FA1318CF08D100240AA3 /* UIWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIWidget.cpp; sourceTree = "<group>"; };
|
||||
2905FA1418CF08D100240AA3 /* UIWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIWidget.h; sourceTree = "<group>"; };
|
||||
29080DEB191B82CE0066F8DF /* UIDeprecated.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIDeprecated.h; sourceTree = "<group>"; };
|
||||
291901411B05895600F8B4BA /* CCNinePatchImageParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCNinePatchImageParser.h; path = ../base/CCNinePatchImageParser.h; sourceTree = "<group>"; };
|
||||
291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCNinePatchImageParser.cpp; path = ../base/CCNinePatchImageParser.cpp; sourceTree = "<group>"; };
|
||||
292DB12F19B4574100A80320 /* UIEditBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIEditBox.cpp; sourceTree = "<group>"; };
|
||||
292DB13019B4574100A80320 /* UIEditBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEditBox.h; sourceTree = "<group>"; };
|
||||
292DB13119B4574100A80320 /* UIEditBoxImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEditBoxImpl.h; sourceTree = "<group>"; };
|
||||
|
@ -5626,6 +5632,8 @@
|
|||
1A5700A2180BC5E60088DEC7 /* base */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
291901411B05895600F8B4BA /* CCNinePatchImageParser.h */,
|
||||
291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */,
|
||||
505385001B01887A00793096 /* CCProperties.h */,
|
||||
505385011B01887A00793096 /* CCProperties.cpp */,
|
||||
B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */,
|
||||
|
@ -9417,6 +9425,7 @@
|
|||
50ABBE211925AB6F00A911A9 /* atitc.h in Headers */,
|
||||
15AE19A519AAD39600C27E9E /* TextFieldReader.h in Headers */,
|
||||
B665E3401AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h in Headers */,
|
||||
291901431B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */,
|
||||
B24AA98B195A675C007B4522 /* CCFastTMXTiledMap.h in Headers */,
|
||||
B665E3A01AA80A6500DDB1C5 /* CCPUPositionEmitter.h in Headers */,
|
||||
B29594B61926D5EC003EEF37 /* CCMeshCommand.h in Headers */,
|
||||
|
@ -10220,6 +10229,7 @@
|
|||
50ABBE481925AB6F00A911A9 /* CCEvent.h in Headers */,
|
||||
5027253B190BF1B900AAF4ED /* cocos2d.h in Headers */,
|
||||
15AE1A9719AAD40300C27E9E /* b2Draw.h in Headers */,
|
||||
291901441B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */,
|
||||
3E6176691960F89B00DE83F5 /* CCController.h in Headers */,
|
||||
B6CAB43E1AF9AA1A00B9B856 /* btGpuDefines.h in Headers */,
|
||||
3823841D1A2590D2002C4610 /* ComAudioReader.h in Headers */,
|
||||
|
@ -10693,6 +10703,7 @@
|
|||
50ED2BD919BE5D5D00A0AB90 /* CCEventListenerController.cpp in Sources */,
|
||||
B665E2321AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp in Sources */,
|
||||
B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */,
|
||||
291901451B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */,
|
||||
15AE19A419AAD39600C27E9E /* TextFieldReader.cpp in Sources */,
|
||||
50ED2BDB19BE76D500A0AB90 /* UIVideoPlayer-ios.mm in Sources */,
|
||||
B665E32A1AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp in Sources */,
|
||||
|
@ -11653,6 +11664,7 @@
|
|||
15AE19AA19AAD39700C27E9E /* ListViewReader.cpp in Sources */,
|
||||
1A5701C8180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */,
|
||||
1A5701CC180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */,
|
||||
291901461B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */,
|
||||
B665E39B1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp in Sources */,
|
||||
382384291A2590F9002C4610 /* NodeReader.cpp in Sources */,
|
||||
15AE193419AAD35100C27E9E /* CCActionObject.cpp in Sources */,
|
||||
|
|
|
@ -125,9 +125,9 @@ public:
|
|||
* @param t Duration in seconds.
|
||||
* @param radius The start radius.
|
||||
* @param deltaRadius The delta radius.
|
||||
* @param angleZ The start Angel in Z.
|
||||
* @param angleZ The start angle in Z.
|
||||
* @param deltaAngleZ The delta angle in Z.
|
||||
* @param angleX The start Angel in X.
|
||||
* @param angleX The start angle in X.
|
||||
* @param deltaAngleX The delta angle in X.
|
||||
* @return An OrbitCamera.
|
||||
*/
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
*
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param drawLineToCenter Whether or not draw the line from the origin to center.
|
||||
* @param scaleX The scale value in x.
|
||||
|
@ -131,7 +131,7 @@ public:
|
|||
*
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param drawLineToCenter Whether or not draw the line from the origin to center.
|
||||
* @param color Set the circle color.
|
||||
|
@ -216,7 +216,7 @@ public:
|
|||
/** Draws a solid circle given the center, radius and number of segments.
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param scaleX The scale value in x.
|
||||
* @param scaleY The scale value in y.
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
/** Draws a solid circle given the center, radius and number of segments.
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param color The solid circle color.
|
||||
* @js NA
|
||||
|
|
|
@ -153,7 +153,7 @@ namespace DrawPrimitives
|
|||
*
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param drawLineToCenter Whether or not draw the line from the origin to center.
|
||||
* @param scaleX The scale value in x.
|
||||
|
@ -165,7 +165,7 @@ namespace DrawPrimitives
|
|||
*
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param drawLineToCenter Whether or not draw the line from the origin to center.
|
||||
*/
|
||||
|
@ -174,7 +174,7 @@ namespace DrawPrimitives
|
|||
/** Draws a solid circle given the center, radius and number of segments.
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @param scaleX The scale value in x.
|
||||
* @param scaleY The scale value in y.
|
||||
|
@ -185,7 +185,7 @@ namespace DrawPrimitives
|
|||
/** Draws a solid circle given the center, radius and number of segments.
|
||||
* @param center The circle center point.
|
||||
* @param radius The circle rotate of radius.
|
||||
* @param angle The circle angel.
|
||||
* @param angle The circle angle.
|
||||
* @param segments The number of segments.
|
||||
* @js NA
|
||||
*/
|
||||
|
|
|
@ -101,6 +101,9 @@ TMXTiledMap::~TMXTiledMap()
|
|||
TMXLayer * TMXTiledMap::parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
|
||||
{
|
||||
TMXTilesetInfo *tileset = tilesetForLayer(layerInfo, mapInfo);
|
||||
if (tileset == nullptr)
|
||||
return nullptr;
|
||||
|
||||
TMXLayer *layer = TMXLayer::create(tileset, layerInfo, mapInfo);
|
||||
|
||||
// tell the layerinfo to release the ownership of the tiles map.
|
||||
|
@ -170,6 +173,10 @@ void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
|
|||
if (layerInfo->_visible)
|
||||
{
|
||||
TMXLayer *child = parseLayer(layerInfo, mapInfo);
|
||||
if (child == nullptr) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
addChild(child, idx, idx);
|
||||
|
||||
// update content size with the max size
|
||||
|
|
|
@ -1314,9 +1314,12 @@ uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFl
|
|||
_normalizedPositionDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
//remove this two line given that isVisitableByVisitingCamera should not affect the calculation of transform given that we are visiting scene
|
||||
//without involving view and projection matrix.
|
||||
|
||||
if (!isVisitableByVisitingCamera())
|
||||
return parentFlags;
|
||||
// if (!isVisitableByVisitingCamera())
|
||||
// return parentFlags;
|
||||
|
||||
uint32_t flags = parentFlags;
|
||||
flags |= (_transformUpdated ? FLAGS_TRANSFORM_DIRTY : 0);
|
||||
|
|
|
@ -115,6 +115,8 @@ void ProgressTimer::setSprite(Sprite *sprite)
|
|||
CC_SAFE_FREE(_vertexData);
|
||||
_vertexDataCount = 0;
|
||||
}
|
||||
|
||||
updateProgress();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -598,8 +598,8 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
if(_insideBounds)
|
||||
#endif
|
||||
{
|
||||
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform, flags);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
_trianglesCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, getRenderedTriangles(), transform, flags);
|
||||
renderer->addCommand(&_trianglesCommand);
|
||||
|
||||
#if CC_SPRITE_DEBUG_DRAW
|
||||
_debugDrawNode->clear();
|
||||
|
@ -614,6 +614,17 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
}
|
||||
}
|
||||
|
||||
TrianglesCommand::Triangles Sprite::getRenderedTriangles() const
|
||||
{
|
||||
static unsigned short indices[6] = {0, 1, 2, 3, 2, 1};
|
||||
TrianglesCommand::Triangles result;
|
||||
result.indices = indices;
|
||||
result.verts = (V3F_C4B_T2F*)&_quad;
|
||||
result.vertCount = 4;
|
||||
result.indexCount = 6;
|
||||
return result;
|
||||
}
|
||||
|
||||
// MARK: visit, draw, transform
|
||||
|
||||
void Sprite::addChild(Node *child, int zOrder, int tag)
|
||||
|
@ -993,6 +1004,10 @@ bool Sprite::isFrameDisplayed(SpriteFrame *frame) const
|
|||
|
||||
SpriteFrame* Sprite::getSpriteFrame() const
|
||||
{
|
||||
if(nullptr != this->_spriteFrame)
|
||||
{
|
||||
return this->_spriteFrame;
|
||||
}
|
||||
return SpriteFrame::createWithTexture(_texture,
|
||||
CC_RECT_POINTS_TO_PIXELS(_rect),
|
||||
_rectRotated,
|
||||
|
|
|
@ -33,7 +33,7 @@ THE SOFTWARE.
|
|||
#include "2d/CCDrawNode.h"
|
||||
#include "base/CCProtocols.h"
|
||||
#include "renderer/CCTextureAtlas.h"
|
||||
#include "renderer/CCQuadCommand.h"
|
||||
#include "renderer/CCTrianglesCommand.h"
|
||||
#include "renderer/CCCustomCommand.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
@ -538,7 +538,8 @@ protected:
|
|||
virtual void updateBlendFunc();
|
||||
virtual void setReorderChildDirtyRecursively();
|
||||
virtual void setDirtyRecursively(bool value);
|
||||
|
||||
|
||||
TrianglesCommand::Triangles getRenderedTriangles() const;
|
||||
//
|
||||
// Data used when the sprite is rendered using a SpriteSheet
|
||||
//
|
||||
|
@ -557,7 +558,7 @@ protected:
|
|||
BlendFunc _blendFunc; /// It's required for TextureProtocol inheritance
|
||||
Texture2D* _texture; /// Texture2D object that is used to render the sprite
|
||||
SpriteFrame* _spriteFrame;
|
||||
QuadCommand _quadCommand; /// quad command
|
||||
TrianglesCommand _trianglesCommand; ///
|
||||
#if CC_SPRITE_DEBUG_DRAW
|
||||
DrawNode *_debugDrawNode;
|
||||
#endif //CC_SPRITE_DEBUG_DRAW
|
||||
|
|
|
@ -39,7 +39,7 @@ THE SOFTWARE.
|
|||
#include "base/CCDirector.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCTextureCache.h"
|
||||
|
||||
#include "base/CCNinePatchImageParser.h"
|
||||
|
||||
#include "deprecated/CCString.h"
|
||||
|
||||
|
@ -104,6 +104,10 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
|
|||
// check the format
|
||||
CCASSERT(format >=0 && format <= 3, "format is not supported for SpriteFrameCache addSpriteFramesWithDictionary:textureFilename:");
|
||||
|
||||
auto textureFileName = Director::getInstance()->getTextureCache()->getTextureFilePath(texture);
|
||||
auto image = new Image();
|
||||
image->initWithImageFile(textureFileName);
|
||||
NinePatchImageParser parser(image);
|
||||
for (auto iter = framesDict.begin(); iter != framesDict.end(); ++iter)
|
||||
{
|
||||
ValueMap& frameDict = iter->second.asValueMap();
|
||||
|
@ -183,7 +187,7 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
|
|||
|
||||
_spriteFramesAliases[oneAlias] = Value(spriteFrameName);
|
||||
}
|
||||
|
||||
|
||||
// create frame
|
||||
spriteFrame = SpriteFrame::createWithTexture(texture,
|
||||
Rect(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height),
|
||||
|
@ -192,9 +196,16 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
|
|||
spriteSourceSize);
|
||||
}
|
||||
|
||||
bool flag = NinePatchImageParser::isNinePatchImage(spriteFrameName);
|
||||
if(flag)
|
||||
{
|
||||
parser.setSpriteFrameInfo(spriteFrame->getRectInPixels(), spriteFrame->isRotated());
|
||||
texture->addSpriteFrameCapInset(spriteFrame, parser.parseCapInset());
|
||||
}
|
||||
// add sprite frame
|
||||
_spriteFrames.insert(spriteFrameName, spriteFrame);
|
||||
}
|
||||
CC_SAFE_DELETE(image);
|
||||
}
|
||||
|
||||
void SpriteFrameCache::addSpriteFramesWithFile(const std::string& plist, Texture2D *texture)
|
||||
|
@ -327,13 +338,14 @@ void SpriteFrameCache::removeUnusedSpriteFrames()
|
|||
if( spriteFrame->getReferenceCount() == 1 )
|
||||
{
|
||||
toRemoveFrames.push_back(iter->first);
|
||||
spriteFrame->getTexture()->removeSpriteFrameCapInset(spriteFrame);
|
||||
CCLOG("cocos2d: SpriteFrameCache: removing unused frame: %s", iter->first.c_str());
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
_spriteFrames.erase(toRemoveFrames);
|
||||
|
||||
|
||||
// FIXME:. Since we don't know the .plist file that originated the frame, we must remove all .plist from the cache
|
||||
if( removed )
|
||||
{
|
||||
|
|
|
@ -102,6 +102,9 @@ TMXTiledMap::~TMXTiledMap()
|
|||
TMXLayer * TMXTiledMap::parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
|
||||
{
|
||||
TMXTilesetInfo *tileset = tilesetForLayer(layerInfo, mapInfo);
|
||||
if (tileset == nullptr)
|
||||
return nullptr;
|
||||
|
||||
TMXLayer *layer = TMXLayer::create(tileset, layerInfo, mapInfo);
|
||||
|
||||
// tell the layerinfo to release the ownership of the tiles map.
|
||||
|
@ -171,9 +174,12 @@ void TMXTiledMap::buildWithMapInfo(TMXMapInfo* mapInfo)
|
|||
|
||||
auto& layers = mapInfo->getLayers();
|
||||
for(const auto &layerInfo : layers) {
|
||||
if (layerInfo->_visible)
|
||||
{
|
||||
if (layerInfo->_visible) {
|
||||
TMXLayer *child = parseLayer(layerInfo, mapInfo);
|
||||
if (child == nullptr) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
addChild(child, idx, idx);
|
||||
|
||||
// update content size with the max size
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>opengl32.lib;glew32.lib;libzlib.lib;libpng.lib;libjpeg.lib;libtiff.lib;libwebp.lib;libiconv.lib;glfw3.lib;freetype250.lib;winmm.lib;ws2_32.lib;libchipmunk.lib;libbox2d.lib;libSpine.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>opengl32.lib;glew32.lib;libzlib.lib;libwebp.lib;libiconv.lib;freetype250.lib;winmm.lib;ws2_32.lib;libbox2d.lib;libSpine.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
|
|
|
@ -432,6 +432,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClCompile Include="..\base\CCEventTouch.cpp" />
|
||||
<ClCompile Include="..\base\ccFPSImages.c" />
|
||||
<ClCompile Include="..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="..\base\CCNS.cpp" />
|
||||
<ClCompile Include="..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="..\base\CCProperties.cpp" />
|
||||
|
@ -995,6 +996,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClInclude Include="..\base\CCIMEDispatcher.h" />
|
||||
<ClInclude Include="..\base\ccMacros.h" />
|
||||
<ClInclude Include="..\base\CCMap.h" />
|
||||
<ClInclude Include="..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="..\base\CCNS.h" />
|
||||
<ClInclude Include="..\base\CCProfiling.h" />
|
||||
<ClInclude Include="..\base\CCProperties.h" />
|
||||
|
|
|
@ -1872,6 +1872,9 @@
|
|||
<ClCompile Include="..\renderer\CCVertexAttribBinding.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\physics\CCPhysicsBody.h">
|
||||
|
@ -3662,6 +3665,9 @@
|
|||
<ClInclude Include="..\renderer\CCVertexAttribBinding.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\CCNinePatchImageParser.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\math\Mat4.inl">
|
||||
|
|
|
@ -236,6 +236,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\include\Export.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\include\SimpleAudioEngine.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\Audio.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioCachePlayer.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioEngine-winrt.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioSourceReader.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\MediaStreamer.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\allocator\CCAllocatorBase.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\allocator\CCAllocatorDiagnostics.h" />
|
||||
|
@ -282,6 +285,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccMacros.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCMap.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h" />
|
||||
|
@ -442,6 +446,14 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\network\HttpResponse.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\network\SocketIO.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\network\WebSocket.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3D.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DComponent.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DConstraint.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DDebugDrawer.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DObject.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DShape.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DWorld.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysicsSprite3D.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsBody.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsContact.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsHelper.h" />
|
||||
|
@ -830,11 +842,15 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\3d\CCSprite3DMaterial.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\3d\CCTerrain.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\3d\CCTextureCube.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\AudioEngine.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\Audio.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<ForcedIncludeFiles>
|
||||
</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioCachePlayer.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioEngine-winrt.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioSourceReader.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\MediaStreamer.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<ForcedIncludeFiles>
|
||||
|
@ -883,6 +899,7 @@
|
|||
</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp" />
|
||||
|
@ -892,7 +909,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCScriptSupport.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCTouch.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccTypes.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCUserDefault.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCUserDefault-winrt.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccUTF8.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccUtils.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCValue.cpp" />
|
||||
|
@ -1019,6 +1036,14 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\network\HttpClient.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\network\SocketIO.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\network\WebSocket.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3D.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DComponent.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DConstraint.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DDebugDrawer.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DObject.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DShape.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DWorld.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysicsSprite3D.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsBody.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsContact.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsJoint.cpp" />
|
||||
|
@ -1222,4 +1247,7 @@
|
|||
<None Include="$(MSBuildThisFileDirectory)..\..\..\libcocos2d.vcxproj.filters" />
|
||||
<None Include="$(MSBuildThisFileDirectory)..\..\..\libcocos2d_wp8.vcxproj.filters" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1791,6 +1791,42 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\renderer\CCVertexAttribBinding.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3D.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DComponent.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DConstraint.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DDebugDrawer.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DObject.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DShape.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DWorld.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysicsSprite3D.h">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\include\AudioEngine.h">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioCachePlayer.h">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioEngine-winrt.h">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioSourceReader.h">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\cocos2d.cpp" />
|
||||
|
@ -2776,9 +2812,6 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccTypes.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCUserDefault.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccUTF8.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
|
@ -3405,6 +3438,45 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\renderer\CCVertexAttribBinding.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\AudioEngine.cpp">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioCachePlayer.cpp">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioEngine-winrt.cpp">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\audio\winrt\AudioSourceReader.cpp">
|
||||
<Filter>audioengine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3D.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DComponent.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DConstraint.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DDebugDrawer.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DObject.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DShape.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DWorld.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysicsSprite3D.cpp">
|
||||
<Filter>physics3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCUserDefault-winrt.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="2d">
|
||||
|
@ -3662,6 +3734,12 @@
|
|||
<Filter Include="external\poly2tri\sweep">
|
||||
<UniqueIdentifier>{932c5f6e-07b3-4b34-97ae-2f3d42024149}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="audioengine">
|
||||
<UniqueIdentifier>{bd1a6214-d6e0-4341-a1fc-79da99b55e35}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="physics3d">
|
||||
<UniqueIdentifier>{e6f8ab69-f66f-48be-a40f-e33c08e77516}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)..\..\..\cocos2d.def" />
|
||||
|
@ -3777,4 +3855,9 @@
|
|||
<Filter>3d</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CMakeLists.txt">
|
||||
<Filter>physics3d</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -30,6 +30,9 @@
|
|||
<ProjectReference Include="..\..\..\..\..\external\Box2D\proj.win8.1-universal\libbox2d.Windows\libbox2d.Windows.vcxproj">
|
||||
<Project>{3b26a12d-3a44-47ea-82d2-282660fc844d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\..\external\bullet\proj.win8.1-universal\libbullet.Windows\libbullet.Windows.vcxproj">
|
||||
<Project>{ec2b1292-2d8c-4feb-a84b-2550b32c1ae7}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\editor-support\spine\proj.win8.1-universal\libSpine.Windows\libSpine.Windows.vcxproj">
|
||||
<Project>{f3550fe0-c795-44f6-8feb-093eb68143ae}</Project>
|
||||
</ProjectReference>
|
||||
|
@ -157,7 +160,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\winrt_8.1\freetype2;$(EngineRoot)external\websockets\include\winrt_8.1;$(EngineRoot)external\curl\include\winrt_8.1;$(EngineRoot)external\tiff\include\winrt_8.1;$(EngineRoot)external\jpeg\include\winrt_8.1;$(EngineRoot)external\png\include\winrt_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -177,7 +180,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\winrt_8.1\freetype2;$(EngineRoot)external\websockets\include\winrt_8.1;$(EngineRoot)external\curl\include\winrt_8.1;$(EngineRoot)external\tiff\include\winrt_8.1;$(EngineRoot)external\jpeg\include\winrt_8.1;$(EngineRoot)external\png\include\winrt_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -197,7 +200,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\winrt_8.1\freetype2;$(EngineRoot)external\websockets\include\winrt_8.1;$(EngineRoot)external\curl\include\winrt_8.1;$(EngineRoot)external\tiff\include\winrt_8.1;$(EngineRoot)external\jpeg\include\winrt_8.1;$(EngineRoot)external\png\include\winrt_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -217,7 +220,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\winrt_8.1\freetype2;$(EngineRoot)external\websockets\include\winrt_8.1;$(EngineRoot)external\curl\include\winrt_8.1;$(EngineRoot)external\tiff\include\winrt_8.1;$(EngineRoot)external\jpeg\include\winrt_8.1;$(EngineRoot)external\png\include\winrt_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -237,7 +240,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\winrt_8.1\freetype2;$(EngineRoot)external\websockets\include\winrt_8.1;$(EngineRoot)external\curl\include\winrt_8.1;$(EngineRoot)external\tiff\include\winrt_8.1;$(EngineRoot)external\jpeg\include\winrt_8.1;$(EngineRoot)external\png\include\winrt_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -257,7 +260,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\winrt_8.1\freetype2;$(EngineRoot)external\websockets\include\winrt_8.1;$(EngineRoot)external\curl\include\winrt_8.1;$(EngineRoot)external\tiff\include\winrt_8.1;$(EngineRoot)external\jpeg\include\winrt_8.1;$(EngineRoot)external\png\include\winrt_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
<ProjectReference Include="..\..\..\..\..\external\Box2D\proj.win8.1-universal\libbox2d.WindowsPhone\libbox2d.WindowsPhone.vcxproj">
|
||||
<Project>{22f798d8-bfff-4754-996f-a5395343d5ec}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\..\external\bullet\proj.win8.1-universal\libbullet.WindowsPhone\libbullet.WindowsPhone.vcxproj">
|
||||
<Project>{e35634bd-b91b-4a6d-b957-96f56dd065f9}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\editor-support\spine\proj.win8.1-universal\libSpine.WindowsPhone\libSpine.WindowsPhone.vcxproj">
|
||||
<Project>{cc1da216-a80d-4be4-b309-acb6af313aff}</Project>
|
||||
</ProjectReference>
|
||||
|
@ -111,7 +114,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\wp_8.1\freetype2;$(EngineRoot)external\websockets\include\wp_8.1;$(EngineRoot)external\curl\include\wp_8.1;$(EngineRoot)external\tiff\include\wp_8.1;$(EngineRoot)external\jpeg\include\wp_8.1;$(EngineRoot)external\png\include\wp_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -131,7 +134,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\wp_8.1\freetype2;$(EngineRoot)external\websockets\include\wp_8.1;$(EngineRoot)external\curl\include\wp_8.1;$(EngineRoot)external\tiff\include\wp_8.1;$(EngineRoot)external\jpeg\include\wp_8.1;$(EngineRoot)external\png\include\wp_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -151,7 +154,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\wp_8.1\freetype2;$(EngineRoot)external\websockets\include\wp_8.1;$(EngineRoot)external\curl\include\wp_8.1;$(EngineRoot)external\tiff\include\wp_8.1;$(EngineRoot)external\jpeg\include\wp_8.1;$(EngineRoot)external\png\include\wp_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;_DEBUG;COCOS2D_DEBUG=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
@ -171,7 +174,7 @@
|
|||
<AdditionalOptions>/Zm384 /bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\zlib\include;$(EngineRoot)external\freetype2\include\wp_8.1\freetype2;$(EngineRoot)external\websockets\include\wp_8.1;$(EngineRoot)external\curl\include\wp_8.1;$(EngineRoot)external\tiff\include\wp_8.1;$(EngineRoot)external\jpeg\include\wp_8.1;$(EngineRoot)external\png\include\wp_8.1;$(EngineRoot)external\protobuf-lite\src;$(EngineRoot)external\protobuf-lite\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>CC_WINDOWS_PHONE_8_1;_USRDLL;_LIB;COCOS2DXWIN32_EXPORTS;_USE3DDLL;_EXPORT_DLL_;_USRSTUDIODLL;_USREXDLL;_USEGUIDLL;CC_ENABLE_CHIPMUNK_INTEGRATION=1;CC_ENABLE_BULLET_INTEGRATION=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4056;4244;4251;4756;4453;28204;</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4056;4244;4251;4756;4453;28204;4099;</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libGLESv2.lib;libEGL.lib;ws2_32.lib;libwebsockets.lib;libcurl.lib;chipmunk.lib;zlib.lib;freetype.lib;sqlite3.lib;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib;dxguid.lib;xaudio2.lib;mfcore.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
|
|
@ -230,10 +230,10 @@ void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
{
|
||||
//FIXME: frustum culling here
|
||||
flags |= Node::FLAGS_RENDER_AS_3D;
|
||||
_quadCommand.init(0, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _modelViewTransform, flags);
|
||||
_quadCommand.setTransparent(true);
|
||||
_quadCommand.set3D(true);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
_trianglesCommand.init(0, _texture->getName(), getGLProgramState(), _blendFunc, getRenderedTriangles(), _modelViewTransform, flags);
|
||||
_trianglesCommand.setTransparent(true);
|
||||
_trianglesCommand.set3D(true);
|
||||
renderer->addCommand(&_trianglesCommand);
|
||||
}
|
||||
|
||||
void BillBoard::setMode( Mode mode )
|
||||
|
|
|
@ -701,7 +701,7 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
{
|
||||
#if CC_USE_CULLING
|
||||
// camera clipping
|
||||
if(!Camera::getVisitingCamera()->isVisibleInFrustum(&this->getAABB()))
|
||||
if(Camera::getVisitingCamera() && !Camera::getVisitingCamera()->isVisibleInFrustum(&this->getAABB()))
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ USING_NS_CC;
|
|||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCGLProgramStateCache.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "2d/CCCamera.h"
|
||||
|
||||
|
@ -79,6 +80,12 @@ bool Terrain::initProperties()
|
|||
auto state = GLProgramState::create(shader);
|
||||
|
||||
setGLProgramState(state);
|
||||
|
||||
_stateBlock->setBlend(false);
|
||||
_stateBlock->setDepthWrite(true);
|
||||
_stateBlock->setDepthTest(true);
|
||||
_stateBlock->setCullFace(true);
|
||||
|
||||
setDrawWire(false);
|
||||
setIsEnableFrustumCull(true);
|
||||
setAnchorPoint(Vec2(0,0));
|
||||
|
@ -104,34 +111,16 @@ void Terrain::onDraw(const Mat4 &transform, uint32_t flags)
|
|||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
}
|
||||
#endif
|
||||
GLboolean blendCheck = glIsEnabled(GL_BLEND);
|
||||
if(blendCheck)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
_stateBlock->bind();
|
||||
|
||||
GL::enableVertexAttribs(1<<_positionLocation | 1 << _texcordLocation | 1<<_normalLocation);
|
||||
glProgram->setUniformsForBuiltins(transform);
|
||||
GLboolean depthMaskCheck;
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMaskCheck);
|
||||
if(!depthMaskCheck)
|
||||
{
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
GLboolean CullFaceCheck =glIsEnabled(GL_CULL_FACE);
|
||||
if(!CullFaceCheck)
|
||||
{
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
GLboolean depthTestCheck;
|
||||
depthTestCheck = glIsEnabled(GL_DEPTH_TEST);
|
||||
if(!depthTestCheck)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
if(!_alphaMap)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D,_detailMapTextures[0]->getName());
|
||||
GL::bindTexture2D(_detailMapTextures[0]->getName());
|
||||
glUniform1i(_detailMapLocation[0],0);
|
||||
glUniform1i(_alphaIsHasAlphaMapLocation,0);
|
||||
}else
|
||||
|
@ -139,7 +128,7 @@ void Terrain::onDraw(const Mat4 &transform, uint32_t flags)
|
|||
for(int i =0;i<_maxDetailMapValue;i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0+i);
|
||||
glBindTexture(GL_TEXTURE_2D,_detailMapTextures[i]->getName());
|
||||
GL::bindTexture2D(_detailMapTextures[i]->getName());
|
||||
glUniform1i(_detailMapLocation[i],i);
|
||||
|
||||
glUniform1f(_detailMapSizeLocation[i],_terrainData._detailMaps[i]._detailMapSize);
|
||||
|
@ -148,7 +137,7 @@ void Terrain::onDraw(const Mat4 &transform, uint32_t flags)
|
|||
glUniform1i(_alphaIsHasAlphaMapLocation,1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_2D,_alphaMap->getName());
|
||||
GL::bindTexture2D(_alphaMap->getName());
|
||||
glUniform1i(_alphaMapLocation,4);
|
||||
}
|
||||
|
||||
|
@ -180,28 +169,7 @@ void Terrain::onDraw(const Mat4 &transform, uint32_t flags)
|
|||
_isCameraViewChanged = false;
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if(depthTestCheck)
|
||||
{
|
||||
}else
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
if(depthMaskCheck)
|
||||
{
|
||||
}else
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
if(CullFaceCheck)
|
||||
{
|
||||
}else
|
||||
{
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
if(blendCheck)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||
if(_isDrawWire)//reset state.
|
||||
{
|
||||
|
@ -260,8 +228,12 @@ bool Terrain::initHeightMap(const char * heightMap)
|
|||
}
|
||||
|
||||
Terrain::Terrain()
|
||||
: _alphaMap(nullptr)
|
||||
, _stateBlock(nullptr)
|
||||
{
|
||||
_alphaMap = nullptr;
|
||||
_stateBlock = RenderState::StateBlock::create();
|
||||
CC_SAFE_RETAIN(_stateBlock);
|
||||
|
||||
_customCommand.setTransparent(false);
|
||||
_customCommand.set3D(true);
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
|
@ -453,6 +425,8 @@ void Terrain::setIsEnableFrustumCull(bool bool_value)
|
|||
|
||||
Terrain::~Terrain()
|
||||
{
|
||||
CC_SAFE_RELEASE(_stateBlock);
|
||||
|
||||
_alphaMap->release();
|
||||
_heightMapImage->release();
|
||||
delete _quadRoot;
|
||||
|
@ -832,7 +806,6 @@ void Terrain::reload()
|
|||
}
|
||||
}
|
||||
|
||||
CCLOG("recreate");
|
||||
initTextures();
|
||||
_chunkLodIndicesSet.clear();
|
||||
_chunkLodIndicesSkirtSet.clear();
|
||||
|
|
|
@ -24,15 +24,18 @@ THE SOFTWARE.
|
|||
#ifndef CC_TERRAIN_H
|
||||
#define CC_TERRAIN_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "2d/CCNode.h"
|
||||
#include "2d/CCCamera.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCCustomCommand.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "3d/CCAABB.h"
|
||||
#include "3d/CCRay.h"
|
||||
#include <vector>
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
#include "base/CCEventDispatcher.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
/**
|
||||
|
@ -81,7 +84,7 @@ NS_CC_BEGIN
|
|||
* We can use ray-terrain intersection to pick a point of the terrain;
|
||||
* Also we can get an arbitrary point of the terrain's height and normal vector for convenience .
|
||||
**/
|
||||
class CC_DLL Terrain :public Node
|
||||
class CC_DLL Terrain : public Node
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -433,6 +436,7 @@ protected:
|
|||
ChunkIndices insertIndicesLOD(int neighborLod[4], int selfLod, GLushort * indices, int size);
|
||||
|
||||
ChunkIndices insertIndicesLODSkirt(int selfLod, GLushort * indices, int size);
|
||||
|
||||
protected:
|
||||
std::vector <ChunkLODIndices> _chunkLodIndicesSet;
|
||||
std::vector<ChunkLODIndicesSkirt> _chunkLodIndicesSkirtSet;
|
||||
|
@ -469,6 +473,9 @@ protected:
|
|||
GLint _alphaMapLocation;
|
||||
GLint _alphaIsHasAlphaMapLocation;
|
||||
GLint _detailMapSizeLocation[4];
|
||||
|
||||
RenderState::StateBlock* _stateBlock;
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
EventListenerCustom* _backToForegroundListener;
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,7 @@ math/TransformUtils.cpp \
|
|||
math/Vec2.cpp \
|
||||
math/Vec3.cpp \
|
||||
math/Vec4.cpp \
|
||||
base/CCNinePatchImageParser.cpp \
|
||||
base/CCAsyncTaskPool.cpp \
|
||||
base/CCAutoreleasePool.cpp \
|
||||
base/CCConfiguration.cpp \
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
|
||||
#include "audio/include/AudioEngine.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
@ -36,6 +36,8 @@
|
|||
#include "apple/AudioEngine-inl.h"
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
#include "win32/AudioEngine-win32.h"
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
#include "winrt/AudioEngine-winrt.h"
|
||||
#endif
|
||||
|
||||
#define TIME_DELAY_PRECISION 0.0001
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
|
||||
#ifndef __AUDIO_ENGINE_H_
|
||||
#define __AUDIO_ENGINE_H_
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#endif
|
||||
#include "CCPlatformMacros.h"
|
||||
|
||||
#define QUEUEBUFFER_NUM 3
|
||||
#define QUEUEBUFFER_NUM 5
|
||||
#define QUEUEBUFFER_TIME_STEP 0.1f
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace cocos2d {
|
|||
for (int index = 0; index < _numThread; ++index) {
|
||||
_tasks.push_back(nullptr);
|
||||
_threads.push_back( std::thread( std::bind(&AudioEngineThreadPool::threadFunc,this,index) ) );
|
||||
_threads[index].detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,7 @@ namespace cocos2d {
|
|||
if (targetIndex == -1) {
|
||||
_tasks.push_back(task);
|
||||
_threads.push_back( std::thread( std::bind(&AudioEngineThreadPool::threadFunc,this,_numThread) ) );
|
||||
|
||||
_threads[_numThread].detach();
|
||||
_numThread++;
|
||||
}
|
||||
_taskMutex.unlock();
|
||||
|
@ -212,16 +213,14 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
|
|||
auto it = _audioCaches.find(filePath);
|
||||
if (it == _audioCaches.end()) {
|
||||
audioCache = &_audioCaches[filePath];
|
||||
|
||||
auto ext = filePath.substr(filePath.rfind('.'));
|
||||
transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
|
||||
auto ext = strchr(filePath.c_str(), '.');
|
||||
bool eraseCache = true;
|
||||
if (ext.compare(".ogg") == 0){
|
||||
|
||||
if (_stricmp(ext, ".ogg") == 0){
|
||||
audioCache->_fileFormat = AudioCache::FileFormat::OGG;
|
||||
eraseCache = false;
|
||||
}
|
||||
else if (ext.compare(".mp3") == 0){
|
||||
else if (_stricmp(ext, ".mp3") == 0){
|
||||
audioCache->_fileFormat = AudioCache::FileFormat::MP3;
|
||||
|
||||
if (MPG123_LAZYINIT){
|
||||
|
@ -239,7 +238,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
|
|||
}
|
||||
}
|
||||
else{
|
||||
log("unsupported media type:%s\n",ext.c_str());
|
||||
log("unsupported media type:%s\n", ext);
|
||||
}
|
||||
|
||||
if (eraseCache){
|
||||
|
@ -380,7 +379,14 @@ bool AudioEngineImpl::stop(int audioID)
|
|||
alSourcei(player._alSource, AL_BUFFER, NULL);
|
||||
|
||||
_alSourceUsed[player._alSource] = false;
|
||||
_audioPlayers.erase(audioID);
|
||||
if (player._streamingSource)
|
||||
{
|
||||
player.notifyExitThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
_audioPlayers.erase(audioID);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -394,7 +400,19 @@ void AudioEngineImpl::stopAll()
|
|||
_alSourceUsed[_alSources[index]] = false;
|
||||
}
|
||||
|
||||
_audioPlayers.clear();
|
||||
for (auto it = _audioPlayers.begin(); it != _audioPlayers.end();)
|
||||
{
|
||||
auto& player = it->second;
|
||||
if (player._streamingSource)
|
||||
{
|
||||
player.notifyExitThread();
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = _audioPlayers.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AudioEngineImpl::getDuration(int audioID)
|
||||
|
@ -498,7 +516,11 @@ void AudioEngineImpl::update(float dt)
|
|||
auto& player = it->second;
|
||||
alGetSourcei(player._alSource, AL_SOURCE_STATE, &sourceState);
|
||||
|
||||
if (player._ready && sourceState == AL_STOPPED) {
|
||||
if (player._readForRemove)
|
||||
{
|
||||
it = _audioPlayers.erase(it);
|
||||
}
|
||||
else if (player._ready && sourceState == AL_STOPPED) {
|
||||
_alSourceUsed[player._alSource] = false;
|
||||
if (player._finishCallbak) {
|
||||
auto& audioInfo = AudioEngine::_audioIDInfoMap[audioID];
|
||||
|
@ -507,7 +529,15 @@ void AudioEngineImpl::update(float dt)
|
|||
|
||||
AudioEngine::remove(audioID);
|
||||
|
||||
it = _audioPlayers.erase(it);
|
||||
if (player._streamingSource)
|
||||
{
|
||||
player.notifyExitThread();
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = _audioPlayers.erase(it);
|
||||
}
|
||||
}
|
||||
else{
|
||||
++it;
|
||||
|
|
|
@ -42,6 +42,7 @@ AudioPlayer::AudioPlayer()
|
|||
, _finishCallbak(nullptr)
|
||||
, _ready(false)
|
||||
, _audioCache(nullptr)
|
||||
, _readForRemove(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -59,13 +60,17 @@ AudioPlayer::AudioPlayer(const AudioPlayer& player)
|
|||
|
||||
AudioPlayer::~AudioPlayer()
|
||||
{
|
||||
_exitThread = true;
|
||||
if (_audioCache && _audioCache->_queBufferFrames > 0) {
|
||||
alDeleteBuffers(QUEUEBUFFER_NUM, _bufferIds);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::notifyExitThread()
|
||||
{
|
||||
if (_audioCache && _audioCache->_queBufferFrames > 0) {
|
||||
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||
_exitThread = true;
|
||||
_sleepCondition.notify_all();
|
||||
if (_rotateBufferThread.joinable()) {
|
||||
_rotateBufferThread.join();
|
||||
}
|
||||
alDeleteBuffers(3, _bufferIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,11 +99,9 @@ bool AudioPlayer::play2d(AudioCache* cache)
|
|||
alSourcei(_alSource, AL_LOOPING, AL_FALSE);
|
||||
|
||||
auto alError = alGetError();
|
||||
alGenBuffers(3, _bufferIds);
|
||||
alGenBuffers(QUEUEBUFFER_NUM, _bufferIds);
|
||||
alError = alGetError();
|
||||
if (alError == AL_NO_ERROR) {
|
||||
_rotateBufferThread = std::thread(&AudioPlayer::rotateBufferThread,this, _audioCache->_queBufferFrames * QUEUEBUFFER_NUM + 1);
|
||||
|
||||
for (int index = 0; index < QUEUEBUFFER_NUM; ++index) {
|
||||
alBufferData(_bufferIds[index], _audioCache->_alBufferFormat, _audioCache->_queBuffers[index], _audioCache->_queBufferSize[index], _audioCache->_sampleRate);
|
||||
}
|
||||
|
@ -110,13 +113,22 @@ bool AudioPlayer::play2d(AudioCache* cache)
|
|||
}
|
||||
}
|
||||
|
||||
alSourcePlay(_alSource);
|
||||
_ready = true;
|
||||
auto alError = alGetError();
|
||||
if (_streamingSource)
|
||||
{
|
||||
_rotateBufferThread = std::thread(&AudioPlayer::rotateBufferThread, this, _audioCache->_queBufferFrames * QUEUEBUFFER_NUM + 1);
|
||||
_rotateBufferThread.detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourcePlay(_alSource);
|
||||
|
||||
if (alError != AL_NO_ERROR) {
|
||||
log("%s:alSourcePlay error code:%x\n", __FUNCTION__,alError);
|
||||
return false;
|
||||
auto alError = alGetError();
|
||||
if (alError != AL_NO_ERROR) {
|
||||
log("%s:alSourcePlay error code:%x\n", __FUNCTION__, alError);
|
||||
return false;
|
||||
}
|
||||
|
||||
_ready = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -177,9 +189,13 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
|
|||
break;
|
||||
}
|
||||
|
||||
alSourcePlay(_alSource);
|
||||
|
||||
while (!_exitThread) {
|
||||
alGetSourcei(_alSource, AL_SOURCE_STATE, &sourceState);
|
||||
if (sourceState == AL_PLAYING) {
|
||||
_ready = true;
|
||||
|
||||
alGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &bufferProcessed);
|
||||
while (bufferProcessed > 0) {
|
||||
bufferProcessed--;
|
||||
|
@ -250,11 +266,13 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
|
|||
}
|
||||
}
|
||||
|
||||
if (_exitThread){
|
||||
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||
if (_exitThread)
|
||||
{
|
||||
break;
|
||||
}
|
||||
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||
_sleepCondition.wait_for(lk,std::chrono::milliseconds(75));
|
||||
|
||||
_sleepCondition.wait_for(lk,std::chrono::milliseconds(35));
|
||||
}
|
||||
ExitBufferThread:
|
||||
switch (audioFileFormat)
|
||||
|
@ -272,6 +290,7 @@ ExitBufferThread:
|
|||
break;
|
||||
}
|
||||
free(tmpBuffer);
|
||||
_readForRemove = true;
|
||||
}
|
||||
|
||||
bool AudioPlayer::setLoop(bool loop)
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <AL/al.h>
|
||||
#endif
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "AudioCache.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
namespace experimental{
|
||||
|
@ -55,7 +56,8 @@ public:
|
|||
bool setTime(float time);
|
||||
float getTime() { return _currTime;}
|
||||
bool setLoop(bool loop);
|
||||
|
||||
void notifyExitThread();
|
||||
|
||||
protected:
|
||||
void rotateBufferThread(int offsetFrame);
|
||||
bool play2d(AudioCache* cache);
|
||||
|
@ -73,11 +75,12 @@ protected:
|
|||
float _currTime;
|
||||
bool _timeDirty;
|
||||
bool _streamingSource;
|
||||
ALuint _bufferIds[3];
|
||||
ALuint _bufferIds[QUEUEBUFFER_NUM];
|
||||
std::thread _rotateBufferThread;
|
||||
std::mutex _sleepMutex;
|
||||
std::condition_variable _sleepCondition;
|
||||
bool _exitThread;
|
||||
bool _exitThread;
|
||||
bool _readForRemove;
|
||||
|
||||
friend class AudioEngineImpl;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,568 @@
|
|||
/*
|
||||
* cocos2d-x http://www.cocos2d-x.org
|
||||
*
|
||||
* Copyright (c) 2010-2011 - cocos2d-x community
|
||||
*
|
||||
* Portions Copyright (c) Microsoft Open Technologies, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
|
||||
#include "AudioCachePlayer.h"
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace cocos2d::experimental;
|
||||
|
||||
inline void ThrowIfFailed(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr)) {
|
||||
// Set a breakpoint on this line to catch XAudio2 API errors.
|
||||
throw Platform::Exception::CreateException(hr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// AudioCache
|
||||
AudioCache::AudioCache()
|
||||
: _isReady(false)
|
||||
, _fileFullPath("")
|
||||
, _srcReader(nullptr)
|
||||
, _fileFormat(FileFormat::UNKNOWN)
|
||||
{
|
||||
_callbacks.clear();
|
||||
memset(&_audInfo, 0, sizeof(AudioInfo));
|
||||
}
|
||||
|
||||
AudioCache::AudioCache(const AudioCache& obj)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
AudioCache& AudioCache::operator=(const AudioCache& rhs)
|
||||
{
|
||||
// TODO
|
||||
return *this;
|
||||
}
|
||||
|
||||
AudioCache::~AudioCache()
|
||||
{
|
||||
_callbacks.clear();
|
||||
|
||||
if (nullptr != _srcReader) {
|
||||
delete _srcReader;
|
||||
_srcReader = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCache::readDataTask()
|
||||
{
|
||||
std::wstring path(_fileFullPath.begin(), _fileFullPath.end());
|
||||
|
||||
if (nullptr != _srcReader) {
|
||||
delete _srcReader;
|
||||
_srcReader = nullptr;
|
||||
}
|
||||
|
||||
switch (_fileFormat)
|
||||
{
|
||||
case FileFormat::WAV:
|
||||
_srcReader = new (std::nothrow) WAVReader();
|
||||
if (_srcReader->initialize(_fileFullPath)) {
|
||||
_audInfo._totalAudioBytes = _srcReader->getTotalAudioBytes();
|
||||
_audInfo._wfx = _srcReader->getWaveFormatInfo();
|
||||
_isReady = true;
|
||||
invokeCallbacks();
|
||||
}
|
||||
break;
|
||||
|
||||
case FileFormat::OGG:
|
||||
break;
|
||||
|
||||
case FileFormat::MP3:
|
||||
break;
|
||||
|
||||
case FileFormat::UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCache::addCallback(const std::function<void()> &callback)
|
||||
{
|
||||
_cbMutex.lock();
|
||||
if (_isReady) {
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
_callbacks.push_back(callback);
|
||||
}
|
||||
_cbMutex.unlock();
|
||||
}
|
||||
|
||||
void AudioCache::invokeCallbacks()
|
||||
{
|
||||
_cbMutex.lock();
|
||||
auto cnt = _callbacks.size();
|
||||
for (size_t ind = 0; ind < cnt; ind++)
|
||||
{
|
||||
_callbacks[ind]();
|
||||
}
|
||||
_callbacks.clear();
|
||||
_cbMutex.unlock();
|
||||
}
|
||||
|
||||
bool AudioCache::getChunk(AudioDataChunk& chunk)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (nullptr != _srcReader) {
|
||||
ret = _srcReader->consumeChunk(chunk);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioCache::doBuffering()
|
||||
{
|
||||
if (isStreamingSource()){
|
||||
_srcReader->produceChunk();
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioCache::isStreamingSource()
|
||||
{
|
||||
if (nullptr != _srcReader) {
|
||||
return _srcReader->isStreamingSource();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AudioCache::seek(const float ratio)
|
||||
{
|
||||
if (nullptr != _srcReader){
|
||||
_srcReader->seekTo(ratio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// AudioPlayer
|
||||
AudioPlayer::AudioPlayer()
|
||||
: _loop(false)
|
||||
, _ready(false)
|
||||
, _current(0.0)
|
||||
, _volume(0.0)
|
||||
, _duration(0.0)
|
||||
, _cache(nullptr)
|
||||
, _totalSamples(0)
|
||||
, _samplesOffset(0)
|
||||
, _criticalError(false)
|
||||
, _isStreaming(false)
|
||||
, _finishCallback(nullptr)
|
||||
, _xaMasterVoice(nullptr)
|
||||
, _xaSourceVoice(nullptr)
|
||||
, _state(AudioPlayerState::INITIALZING)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
AudioPlayer::~AudioPlayer()
|
||||
{
|
||||
free();
|
||||
}
|
||||
|
||||
void AudioPlayer::stop()
|
||||
{
|
||||
_stop();
|
||||
}
|
||||
|
||||
void AudioPlayer::pause()
|
||||
{
|
||||
_stop(true);
|
||||
}
|
||||
|
||||
bool AudioPlayer::update()
|
||||
{
|
||||
if (_criticalError){
|
||||
free();
|
||||
init();
|
||||
}
|
||||
|
||||
if (_cache != nullptr) {
|
||||
_cache->doBuffering();
|
||||
}
|
||||
|
||||
//log("bufferQueued: %d, _current: %f", _cachedBufferQ.size(), _current);
|
||||
return _criticalError;
|
||||
}
|
||||
|
||||
void AudioPlayer::resume()
|
||||
{
|
||||
_play(true);
|
||||
}
|
||||
|
||||
bool AudioPlayer::isInError()
|
||||
{
|
||||
return _criticalError;
|
||||
}
|
||||
|
||||
float AudioPlayer::getDuration()
|
||||
{
|
||||
if (nullptr == _cache) {
|
||||
return _duration;
|
||||
}
|
||||
|
||||
auto fmt = _cache->_audInfo._wfx;
|
||||
|
||||
if (!fmt.nChannels) {
|
||||
return _duration;
|
||||
}
|
||||
|
||||
if ((int)_duration <= 0)
|
||||
{
|
||||
switch (fmt.wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
case WAVE_FORMAT_ADPCM:
|
||||
_duration = (float(_cache->_audInfo._totalAudioBytes / ((fmt.wBitsPerSample / 8) * fmt.nChannels)) / fmt.nSamplesPerSec) * 1000;
|
||||
_totalSamples = fmt.nSamplesPerSec * _duration / 1000;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _duration;
|
||||
}
|
||||
|
||||
float AudioPlayer::getCurrentTime()
|
||||
{
|
||||
_stMutex.lock();
|
||||
auto samplesPlayed = getSourceVoiceState().SamplesPlayed;
|
||||
//log("_samplesOffset: %lu, samplesPlayed: %lu, _current: %f", (UINT32)_samplesOffset, (UINT32)samplesPlayed, _current);
|
||||
_current += ((samplesPlayed - _samplesOffset) / (float)_totalSamples) * _duration;
|
||||
_current = _current > _duration ? 0.0 : _current;
|
||||
_samplesOffset = samplesPlayed;
|
||||
_stMutex.unlock();
|
||||
return _current;
|
||||
}
|
||||
|
||||
bool AudioPlayer::setTime(float time)
|
||||
{
|
||||
bool ret = true;
|
||||
_stop();
|
||||
|
||||
if (!_isStreaming) {
|
||||
auto fmt = _cache->_audInfo._wfx;
|
||||
int seek = (time / _duration) * _totalSamples;
|
||||
seek -= (seek % (fmt.nChannels * fmt.nBlockAlign));
|
||||
|
||||
_xaBuffer.LoopCount = 0;
|
||||
_xaBuffer.PlayBegin = seek;
|
||||
_xaBuffer.PlayLength = _totalSamples - seek;
|
||||
|
||||
if (_xaBuffer.PlayBegin >= _totalSamples) {
|
||||
_xaBuffer.PlayBegin = _totalSamples - (fmt.nChannels * fmt.nBlockAlign);
|
||||
_xaBuffer.PlayLength = (fmt.nChannels * fmt.nBlockAlign);
|
||||
}
|
||||
}
|
||||
|
||||
_stMutex.lock();
|
||||
_samplesOffset = getSourceVoiceState().SamplesPlayed;
|
||||
_current = time;
|
||||
_stMutex.unlock();
|
||||
_play();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioPlayer::setVolume(float volume)
|
||||
{
|
||||
if (_xaMasterVoice != nullptr){
|
||||
if (FAILED(_xaMasterVoice->SetVolume(volume))) {
|
||||
error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioPlayer::play2d(AudioCache* cache)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (cache != nullptr)
|
||||
{
|
||||
_cache = cache;
|
||||
if (nullptr == _xaSourceVoice && _ready) {
|
||||
|
||||
XAUDIO2_SEND_DESCRIPTOR descriptors[1];
|
||||
descriptors[0].pOutputVoice = _xaMasterVoice;
|
||||
descriptors[0].Flags = 0;
|
||||
XAUDIO2_VOICE_SENDS sends = { 0 };
|
||||
sends.SendCount = 1;
|
||||
sends.pSends = descriptors;
|
||||
ThrowIfFailed(_xaEngine->CreateSourceVoice(&_xaSourceVoice, &cache->_audInfo._wfx, 0, 1.0, this, &sends));
|
||||
}
|
||||
|
||||
_isStreaming = _cache->isStreamingSource();
|
||||
_duration = getDuration();
|
||||
ret = _play();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioPlayer::init()
|
||||
{
|
||||
memset(&_xaBuffer, 0, sizeof(_xaBuffer));
|
||||
ThrowIfFailed(XAudio2Create(_xaEngine.ReleaseAndGetAddressOf()));
|
||||
|
||||
#if defined(_DEBUG)
|
||||
XAUDIO2_DEBUG_CONFIGURATION debugConfig = { 0 };
|
||||
debugConfig.BreakMask = XAUDIO2_LOG_ERRORS;
|
||||
debugConfig.TraceMask = XAUDIO2_LOG_ERRORS;
|
||||
_xaEngine->SetDebugConfiguration(&debugConfig);
|
||||
#endif
|
||||
|
||||
_xaEngine->RegisterForCallbacks(this);
|
||||
ThrowIfFailed(_xaEngine->CreateMasteringVoice(&_xaMasterVoice, XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE, 0, nullptr, nullptr, AudioCategory_GameMedia));
|
||||
_ready = true;
|
||||
_state = AudioPlayerState::READY;
|
||||
}
|
||||
|
||||
void AudioPlayer::free()
|
||||
{
|
||||
_stop();
|
||||
memset(&_xaBuffer, 0, sizeof(_xaBuffer));
|
||||
|
||||
if (_xaEngine) {
|
||||
_xaEngine->StopEngine();
|
||||
}
|
||||
|
||||
if (_xaSourceVoice != nullptr) {
|
||||
_xaSourceVoice->DestroyVoice();
|
||||
_xaSourceVoice = nullptr;
|
||||
}
|
||||
|
||||
if (_xaMasterVoice != nullptr) {
|
||||
_xaMasterVoice->DestroyVoice();
|
||||
_xaMasterVoice = nullptr;
|
||||
}
|
||||
|
||||
while (!_cachedBufferQ.empty()) {
|
||||
popBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioPlayer::_play(bool resume)
|
||||
{
|
||||
do {
|
||||
if (!resume) {
|
||||
_cache->seek(_current / _duration);
|
||||
submitBuffers();
|
||||
}
|
||||
|
||||
if (_state == AudioPlayerState::PAUSED && !resume || nullptr == _xaSourceVoice) break;
|
||||
|
||||
if (FAILED(_xaSourceVoice->Start())) {
|
||||
error();
|
||||
}
|
||||
else {
|
||||
_state = AudioPlayerState::PLAYING;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
return !_criticalError;
|
||||
}
|
||||
|
||||
void AudioPlayer::_stop(bool pause)
|
||||
{
|
||||
if (_xaSourceVoice != nullptr) {
|
||||
|
||||
if (FAILED(_xaSourceVoice->Stop())) {
|
||||
error();
|
||||
}
|
||||
else {
|
||||
if (!pause) {
|
||||
_xaSourceVoice->FlushSourceBuffers();
|
||||
if (_state != AudioPlayerState::PAUSED) _state = AudioPlayerState::STOPPED;
|
||||
}
|
||||
else {
|
||||
_state = AudioPlayerState::PAUSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::error()
|
||||
{
|
||||
_criticalError = true;
|
||||
_ready = false;
|
||||
_state = AudioPlayerState::ERRORED;
|
||||
}
|
||||
|
||||
void AudioPlayer::popBuffer()
|
||||
{
|
||||
_bqMutex.lock();
|
||||
if (!_cachedBufferQ.empty()) {
|
||||
delete[] _cachedBufferQ.front()._data;
|
||||
_cachedBufferQ.pop();
|
||||
}
|
||||
_bqMutex.unlock();
|
||||
}
|
||||
|
||||
bool AudioPlayer::submitBuffers()
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
_bqMutex.lock();
|
||||
do {
|
||||
if (nullptr == _xaSourceVoice) break;
|
||||
if (!_cachedBufferQ.size() || (_isStreaming && _cachedBufferQ.size() < QUEUEBUFFER_NUM)) {
|
||||
AudioDataChunk chunk;
|
||||
if (_cache->getChunk(chunk)) {
|
||||
_xaBuffer.AudioBytes = chunk._dataSize;
|
||||
_xaBuffer.pAudioData = chunk._data;
|
||||
_xaBuffer.Flags = chunk._endOfStream ? XAUDIO2_END_OF_STREAM : 0;
|
||||
_cachedBufferQ.push(chunk);
|
||||
ret = SUCCEEDED(_xaSourceVoice->SubmitSourceBuffer(&_xaBuffer));
|
||||
if (!_isStreaming) break;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!_isStreaming) {
|
||||
ret = SUCCEEDED(_xaSourceVoice->SubmitSourceBuffer(&_xaBuffer));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while (ret);
|
||||
_bqMutex.unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioPlayer::updateState()
|
||||
{
|
||||
if (!_isStreaming) {
|
||||
_stMutex.lock();
|
||||
_samplesOffset = getSourceVoiceState().SamplesPlayed;
|
||||
_stMutex.unlock();
|
||||
}
|
||||
else {
|
||||
if (_cachedBufferQ.size() > getSourceVoiceState(true).BuffersQueued) {
|
||||
popBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::onBufferRunOut()
|
||||
{
|
||||
_stMutex.lock();
|
||||
_samplesOffset = 0;
|
||||
_current = 0.0;
|
||||
_xaBuffer.PlayBegin = _xaBuffer.PlayLength = 0;
|
||||
_stMutex.unlock();
|
||||
|
||||
if (!_loop) {
|
||||
_stop();
|
||||
//invokeFinishCallback();
|
||||
}
|
||||
else {
|
||||
_play();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::invokeFinishCallback()
|
||||
{
|
||||
if (_finishCallback) {
|
||||
_finishCallback(0, "");
|
||||
}
|
||||
}
|
||||
|
||||
XAUDIO2_VOICE_STATE AudioPlayer::getSourceVoiceState(bool fast)
|
||||
{
|
||||
XAUDIO2_VOICE_STATE state;
|
||||
memset(&state, 0, sizeof(XAUDIO2_VOICE_STATE));
|
||||
|
||||
if (_xaSourceVoice != nullptr) {
|
||||
_xaSourceVoice->GetState(&state, fast ? XAUDIO2_VOICE_NOSAMPLESPLAYED : 0);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
// IXAudio2EngineCallback
|
||||
void AudioPlayer::OnProcessingPassStart()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioPlayer::OnProcessingPassEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioPlayer::OnCriticalError(HRESULT err)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(err);
|
||||
error();
|
||||
}
|
||||
|
||||
// IXAudio2VoiceCallback
|
||||
void AudioPlayer::OnVoiceProcessingPassStart(UINT32 uBytesRequired)
|
||||
{
|
||||
if (uBytesRequired && _isStreaming){
|
||||
submitBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::OnVoiceProcessingPassEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioPlayer::OnStreamEnd()
|
||||
{
|
||||
onBufferRunOut();
|
||||
}
|
||||
|
||||
void AudioPlayer::OnBufferStart(void* pBufferContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pBufferContext);
|
||||
}
|
||||
|
||||
void AudioPlayer::OnBufferEnd(void* pBufferContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pBufferContext);
|
||||
updateState();
|
||||
}
|
||||
|
||||
void AudioPlayer::OnLoopEnd(void* pBufferContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pBufferContext);
|
||||
|
||||
if (!_loop) {
|
||||
_stop();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::OnVoiceError(void* pBufferContext, HRESULT err)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pBufferContext);
|
||||
UNREFERENCED_PARAMETER(err);
|
||||
error();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* cocos2d-x http://www.cocos2d-x.org
|
||||
*
|
||||
* Copyright (c) 2010-2011 - cocos2d-x community
|
||||
*
|
||||
* Portions Copyright (c) Microsoft Open Technologies, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
|
||||
#ifndef __AUDIO_CACHE_PLAYER_H_
|
||||
#define __AUDIO_CACHE_PLAYER_H_
|
||||
|
||||
#include "AudioSourceReader.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
namespace experimental{
|
||||
|
||||
typedef struct AudioInfo
|
||||
{
|
||||
size_t _totalAudioBytes;
|
||||
WAVEFORMATEX _wfx;
|
||||
} AudioInfo;
|
||||
|
||||
enum class AudioPlayerState
|
||||
{
|
||||
ERRORED = -1,
|
||||
INITIALZING,
|
||||
READY,
|
||||
PLAYING,
|
||||
PAUSED,
|
||||
STOPPED
|
||||
};
|
||||
|
||||
class AudioCache
|
||||
{
|
||||
public:
|
||||
AudioCache();
|
||||
~AudioCache();
|
||||
|
||||
void readDataTask();
|
||||
void addCallback(const std::function<void()> &callback);
|
||||
bool getChunk(AudioDataChunk& chunk);
|
||||
void doBuffering();
|
||||
bool isStreamingSource();
|
||||
void seek(const float ratio);
|
||||
|
||||
protected:
|
||||
AudioCache(const AudioCache&);
|
||||
AudioCache& operator=(const AudioCache&);
|
||||
void invokeCallbacks();
|
||||
|
||||
private:
|
||||
bool _isReady;
|
||||
AudioInfo _audInfo;
|
||||
std::mutex _cbMutex;
|
||||
FileFormat _fileFormat;
|
||||
std::string _fileFullPath;
|
||||
AudioSourceReader *_srcReader;
|
||||
std::vector<std::function<void()>> _callbacks;
|
||||
|
||||
|
||||
friend class AudioPlayer;
|
||||
friend class AudioEngineImpl;
|
||||
};
|
||||
|
||||
|
||||
class AudioPlayer : public IXAudio2EngineCallback, IXAudio2VoiceCallback
|
||||
{
|
||||
public:
|
||||
AudioPlayer();
|
||||
virtual ~AudioPlayer();
|
||||
|
||||
void stop();
|
||||
void pause();
|
||||
bool update();
|
||||
void resume();
|
||||
bool isInError();
|
||||
float getDuration();
|
||||
float getCurrentTime();
|
||||
bool setTime(float time);
|
||||
void setVolume(float volume);
|
||||
bool play2d(AudioCache* cache);
|
||||
AudioPlayerState getState() { return _state; }
|
||||
|
||||
protected:
|
||||
AudioPlayer(AudioPlayer&);
|
||||
AudioPlayer& operator=(AudioPlayer&);
|
||||
|
||||
void init();
|
||||
void free();
|
||||
void error();
|
||||
void popBuffer();
|
||||
void updateState();
|
||||
bool submitBuffers();
|
||||
void onBufferRunOut();
|
||||
void invokeFinishCallback();
|
||||
void _stop(bool pause = false);
|
||||
bool _play(bool resume = false);
|
||||
XAUDIO2_VOICE_STATE getSourceVoiceState(bool fast = false);
|
||||
|
||||
// IXAudio2EngineCallback
|
||||
STDMETHOD_(void, OnProcessingPassStart) () override;
|
||||
STDMETHOD_(void, OnProcessingPassEnd) () override;
|
||||
STDMETHOD_(void, OnCriticalError) (HRESULT error) override;
|
||||
|
||||
// IXAudio2VoiceCallback
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32 uBytesRequired) override;
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd) () override;
|
||||
STDMETHOD_(void, OnStreamEnd) () override;
|
||||
STDMETHOD_(void, OnBufferStart) (void* pBufferContext) override;
|
||||
STDMETHOD_(void, OnBufferEnd) (void* pBufferContext) override;
|
||||
STDMETHOD_(void, OnLoopEnd) (void* pBufferContext) override;
|
||||
STDMETHOD_(void, OnVoiceError) (void *pBufferContext, HRESULT error) override;
|
||||
|
||||
private:
|
||||
bool _loop;
|
||||
bool _ready;
|
||||
float _volume;
|
||||
float _current;
|
||||
float _duration;
|
||||
bool _criticalError;
|
||||
bool _isStreaming;
|
||||
UINT64 _totalSamples;
|
||||
UINT64 _samplesOffset;
|
||||
|
||||
XAUDIO2_BUFFER _xaBuffer;
|
||||
IXAudio2SourceVoice *_xaSourceVoice;
|
||||
IXAudio2MasteringVoice *_xaMasterVoice;
|
||||
Microsoft::WRL::ComPtr<IXAudio2> _xaEngine;
|
||||
|
||||
AudioCache *_cache;
|
||||
std::mutex _stMutex;
|
||||
std::mutex _bqMutex;
|
||||
AudioPlayerState _state;
|
||||
std::queue<AudioDataChunk> _cachedBufferQ;
|
||||
std::function<void(int, const std::string &)> _finishCallback;
|
||||
|
||||
|
||||
friend class AudioEngineImpl;
|
||||
};
|
||||
|
||||
}
|
||||
NS_CC_END
|
||||
#endif // __AUDIO_CACHE_PLAYER_H_
|
||||
#endif
|
||||
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* cocos2d-x http://www.cocos2d-x.org
|
||||
*
|
||||
* Copyright (c) 2010-2011 - cocos2d-x community
|
||||
*
|
||||
* Portions Copyright (c) Microsoft Open Technologies, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
|
||||
#include "AudioEngine-winrt.h"
|
||||
#include <condition_variable>
|
||||
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace cocos2d::experimental;
|
||||
|
||||
|
||||
namespace cocos2d {
|
||||
namespace experimental {
|
||||
class AudioEngineThreadPool
|
||||
{
|
||||
public:
|
||||
AudioEngineThreadPool()
|
||||
: _running(true)
|
||||
, _numThread(6)
|
||||
{
|
||||
_threads.reserve(_numThread);
|
||||
_tasks.reserve(_numThread);
|
||||
|
||||
for (int index = 0; index < _numThread; ++index) {
|
||||
_tasks.push_back(nullptr);
|
||||
_threads.push_back(std::thread(std::bind(&AudioEngineThreadPool::threadFunc, this, index)));
|
||||
}
|
||||
}
|
||||
|
||||
void addTask(const std::function<void()> &task){
|
||||
_taskMutex.lock();
|
||||
int targetIndex = -1;
|
||||
for (int index = 0; index < _numThread; ++index) {
|
||||
if (_tasks[index] == nullptr) {
|
||||
targetIndex = index;
|
||||
_tasks[index] = task;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (targetIndex == -1) {
|
||||
_tasks.push_back(task);
|
||||
_threads.push_back(std::thread(std::bind(&AudioEngineThreadPool::threadFunc, this, _numThread)));
|
||||
|
||||
_numThread++;
|
||||
}
|
||||
_taskMutex.unlock();
|
||||
_sleepCondition.notify_all();
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
_running = false;
|
||||
_sleepCondition.notify_all();
|
||||
|
||||
for (int index = 0; index < _numThread; ++index) {
|
||||
_threads[index].join();
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool _running;
|
||||
std::vector<std::thread> _threads;
|
||||
std::vector< std::function<void()> > _tasks;
|
||||
|
||||
void threadFunc(int index)
|
||||
{
|
||||
while (_running) {
|
||||
std::function<void()> task = nullptr;
|
||||
_taskMutex.lock();
|
||||
task = _tasks[index];
|
||||
_taskMutex.unlock();
|
||||
|
||||
if (nullptr == task)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||
_sleepCondition.wait(lk);
|
||||
continue;
|
||||
}
|
||||
|
||||
task();
|
||||
|
||||
_taskMutex.lock();
|
||||
_tasks[index] = nullptr;
|
||||
_taskMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
int _numThread;
|
||||
|
||||
std::mutex _taskMutex;
|
||||
std::mutex _sleepMutex;
|
||||
std::condition_variable _sleepCondition;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
AudioEngineImpl::AudioEngineImpl()
|
||||
: _lazyInitLoop(true)
|
||||
, _currentAudioID(0)
|
||||
, _threadPool(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AudioEngineImpl::~AudioEngineImpl()
|
||||
{
|
||||
_audioCaches.clear();
|
||||
|
||||
if (_threadPool) {
|
||||
_threadPool->destroy();
|
||||
delete _threadPool;
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioEngineImpl::init()
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (nullptr == _threadPool) {
|
||||
_threadPool = new (std::nothrow) AudioEngineThreadPool();
|
||||
}
|
||||
|
||||
ret = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int AudioEngineImpl::play2d(const std::string &filePath, bool loop, float volume)
|
||||
{
|
||||
AudioCache* audioCache = nullptr;
|
||||
auto it = _audioCaches.find(filePath);
|
||||
if (it == _audioCaches.end()) {
|
||||
audioCache = &_audioCaches[filePath];
|
||||
|
||||
auto ext = filePath.substr(filePath.rfind('.'));
|
||||
transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
|
||||
bool eraseCache = true;
|
||||
|
||||
if (ext.compare(".wav") == 0){
|
||||
audioCache->_fileFormat = FileFormat::WAV;
|
||||
eraseCache = false;
|
||||
}
|
||||
else if (ext.compare(".ogg") == 0){
|
||||
audioCache->_fileFormat = FileFormat::OGG;
|
||||
//eraseCache = false; //TODO add support for OGG
|
||||
}
|
||||
else if (ext.compare(".mp3") == 0){
|
||||
audioCache->_fileFormat = FileFormat::MP3;
|
||||
//eraseCache = false; //TODO add support for MP3
|
||||
}
|
||||
else{
|
||||
log("unsupported media type:%s\n", ext.c_str());
|
||||
eraseCache = false;
|
||||
}
|
||||
|
||||
if (eraseCache){
|
||||
_audioCaches.erase(filePath);
|
||||
return AudioEngine::INVALID_AUDIO_ID;
|
||||
}
|
||||
|
||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
audioCache->_fileFullPath = fullPath;
|
||||
_threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache));
|
||||
}
|
||||
else {
|
||||
audioCache = &it->second;
|
||||
}
|
||||
|
||||
auto player = &_audioPlayers[_currentAudioID];
|
||||
player->_loop = loop;
|
||||
player->_volume = volume;
|
||||
audioCache->addCallback(std::bind(&AudioEngineImpl::_play2d, this, audioCache, _currentAudioID));
|
||||
|
||||
if (_lazyInitLoop) {
|
||||
_lazyInitLoop = false;
|
||||
|
||||
auto scheduler = cocos2d::Director::getInstance()->getScheduler();
|
||||
scheduler->schedule(schedule_selector(AudioEngineImpl::update), this, 0.05f, false);
|
||||
}
|
||||
|
||||
return _currentAudioID++;
|
||||
}
|
||||
|
||||
void AudioEngineImpl::_play2d(AudioCache *cache, int audioID)
|
||||
{
|
||||
if (cache->_isReady){
|
||||
auto playerIt = _audioPlayers.find(audioID);
|
||||
if (playerIt != _audioPlayers.end()) {
|
||||
if (playerIt->second.play2d(cache)) {
|
||||
AudioEngine::_audioIDInfoMap[audioID].state = AudioEngine::AudioState::PLAYING;
|
||||
}
|
||||
else{
|
||||
_threadMutex.lock();
|
||||
_toRemoveAudioIDs.push_back(audioID);
|
||||
_threadMutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
_threadMutex.lock();
|
||||
_toRemoveCaches.push_back(cache);
|
||||
_toRemoveAudioIDs.push_back(audioID);
|
||||
_threadMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEngineImpl::setVolume(int audioID, float volume)
|
||||
{
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready){
|
||||
player.setVolume(volume);
|
||||
}
|
||||
|
||||
if (player.isInError()) {
|
||||
log("%s: audio id = %d, error.\n", __FUNCTION__, audioID);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEngineImpl::setLoop(int audioID, bool loop)
|
||||
{
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
player._loop = loop;
|
||||
}
|
||||
|
||||
if (player.isInError()) {
|
||||
log("%s: audio id = %d, error.\n", __FUNCTION__, audioID);
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioEngineImpl::pause(int audioID)
|
||||
{
|
||||
bool ret = false;
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
player.pause();
|
||||
AudioEngine::_audioIDInfoMap[audioID].state = AudioEngine::AudioState::PAUSED;
|
||||
}
|
||||
|
||||
ret = !player.isInError();
|
||||
|
||||
if (!ret) {
|
||||
log("%s: audio id = %d, error.\n", __FUNCTION__, audioID);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AudioEngineImpl::resume(int audioID)
|
||||
{
|
||||
bool ret = false;
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
player.resume();
|
||||
AudioEngine::_audioIDInfoMap[audioID].state = AudioEngine::AudioState::PLAYING;
|
||||
}
|
||||
|
||||
ret = !player.isInError();
|
||||
|
||||
if (!ret) {
|
||||
log("%s: audio id = %d, error.\n", __FUNCTION__, audioID);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AudioEngineImpl::stop(int audioID)
|
||||
{
|
||||
bool ret = false;
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
player.stop();
|
||||
ret = !player.isInError();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
log("%s: audio id = %d, error.\n", __FUNCTION__, audioID);
|
||||
}
|
||||
|
||||
_audioPlayers.erase(audioID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioEngineImpl::stopAll()
|
||||
{
|
||||
for (auto &player : _audioPlayers) {
|
||||
player.second.stop();
|
||||
}
|
||||
|
||||
_audioPlayers.clear();
|
||||
}
|
||||
|
||||
float AudioEngineImpl::getDuration(int audioID)
|
||||
{
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
return player.getDuration();
|
||||
}
|
||||
else {
|
||||
return AudioEngine::TIME_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
float AudioEngineImpl::getCurrentTime(int audioID)
|
||||
{
|
||||
float ret = 0.0f;
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
ret = player.getCurrentTime();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AudioEngineImpl::setCurrentTime(int audioID, float time)
|
||||
{
|
||||
bool ret = false;
|
||||
auto& player = _audioPlayers[audioID];
|
||||
|
||||
if (player._ready) {
|
||||
ret = player.setTime(time);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
log("%s: audio id = %d, error.\n", __FUNCTION__, audioID);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioEngineImpl::setFinishCallback(int audioID, const std::function<void(int, const std::string &)> &callback)
|
||||
{
|
||||
_audioPlayers[audioID]._finishCallback = callback;
|
||||
}
|
||||
|
||||
void AudioEngineImpl::update(float dt)
|
||||
{
|
||||
int audioID;
|
||||
|
||||
if (_threadMutex.try_lock()) {
|
||||
size_t removeAudioCount = _toRemoveAudioIDs.size();
|
||||
for (size_t index = 0; index < removeAudioCount; ++index) {
|
||||
audioID = _toRemoveAudioIDs[index];
|
||||
auto playerIt = _audioPlayers.find(audioID);
|
||||
if (playerIt != _audioPlayers.end()) {
|
||||
if (playerIt->second._finishCallback) {
|
||||
auto& audioInfo = AudioEngine::_audioIDInfoMap[audioID];
|
||||
playerIt->second._finishCallback(audioID, *audioInfo.filePath);
|
||||
}
|
||||
_audioPlayers.erase(audioID);
|
||||
AudioEngine::remove(audioID);
|
||||
}
|
||||
}
|
||||
|
||||
size_t removeCacheCount = _toRemoveCaches.size();
|
||||
for (size_t index = 0; index < removeCacheCount; ++index) {
|
||||
auto itEnd = _audioCaches.end();
|
||||
for (auto it = _audioCaches.begin(); it != itEnd; ++it) {
|
||||
if (&it->second == _toRemoveCaches[index]) {
|
||||
_audioCaches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_threadMutex.unlock();
|
||||
}
|
||||
|
||||
for (auto it = _audioPlayers.begin(); it != _audioPlayers.end();) {
|
||||
audioID = it->first;
|
||||
auto& player = it->second;
|
||||
|
||||
if (player._ready && player._state == AudioPlayerState::STOPPED) {
|
||||
if (player._finishCallback) {
|
||||
auto& audioInfo = AudioEngine::_audioIDInfoMap[audioID];
|
||||
player._finishCallback(audioID, *audioInfo.filePath);
|
||||
}
|
||||
|
||||
AudioEngine::remove(audioID);
|
||||
it = _audioPlayers.erase(it);
|
||||
}
|
||||
else{
|
||||
player.update();
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (_audioPlayers.empty()){
|
||||
_lazyInitLoop = true;
|
||||
|
||||
auto scheduler = cocos2d::Director::getInstance()->getScheduler();
|
||||
scheduler->unschedule(schedule_selector(AudioEngineImpl::update), this);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEngineImpl::uncache(const std::string &filePath)
|
||||
{
|
||||
_audioCaches.erase(filePath);
|
||||
}
|
||||
|
||||
void AudioEngineImpl::uncacheAll()
|
||||
{
|
||||
_audioCaches.clear();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* cocos2d-x http://www.cocos2d-x.org
|
||||
*
|
||||
* Copyright (c) 2010-2011 - cocos2d-x community
|
||||
*
|
||||
* Portions Copyright (c) Microsoft Open Technologies, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
|
||||
#ifndef __AUDIO_ENGINE_WINRT_H_
|
||||
#define __AUDIO_ENGINE_WINRT_H_
|
||||
|
||||
#define NEAR near
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/CCRef.h"
|
||||
#include "AudioEngine.h"
|
||||
#include "AudioCachePlayer.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
namespace experimental{
|
||||
#define MAX_AUDIOINSTANCES 32
|
||||
|
||||
|
||||
class AudioEngineThreadPool;
|
||||
|
||||
class CC_DLL AudioEngineImpl : public cocos2d::Ref
|
||||
{
|
||||
public:
|
||||
AudioEngineImpl();
|
||||
~AudioEngineImpl();
|
||||
|
||||
bool init();
|
||||
int play2d(const std::string &fileFullPath, bool loop, float volume);
|
||||
void setVolume(int audioID, float volume);
|
||||
void setLoop(int audioID, bool loop);
|
||||
bool pause(int audioID);
|
||||
bool resume(int audioID);
|
||||
bool stop(int audioID);
|
||||
void stopAll();
|
||||
float getDuration(int audioID);
|
||||
float getCurrentTime(int audioID);
|
||||
bool setCurrentTime(int audioID, float time);
|
||||
void setFinishCallback(int audioID, const std::function<void(int, const std::string &)> &callback);
|
||||
void uncache(const std::string& filePath);
|
||||
void uncacheAll();
|
||||
void update(float dt);
|
||||
|
||||
private:
|
||||
void _play2d(AudioCache *cache, int audioID);
|
||||
|
||||
private:
|
||||
std::unordered_map<int, AudioPlayer> _audioPlayers;
|
||||
std::unordered_map<std::string, AudioCache> _audioCaches;
|
||||
std::vector<AudioCache*> _toRemoveCaches;
|
||||
|
||||
std::mutex _threadMutex;
|
||||
std::vector<int> _toRemoveAudioIDs;
|
||||
bool _lazyInitLoop;
|
||||
int _currentAudioID;
|
||||
AudioEngineThreadPool* _threadPool;
|
||||
};
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
#endif // __AUDIO_ENGINE_WINRT_H_
|
||||
#endif
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* cocos2d-x http://www.cocos2d-x.org
|
||||
*
|
||||
* Copyright (c) 2010-2011 - cocos2d-x community
|
||||
*
|
||||
* Portions Copyright (c) Microsoft Open Technologies, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
|
||||
#include "AudioSourceReader.h"
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace cocos2d::experimental;
|
||||
|
||||
|
||||
// AudioFileReader
|
||||
AudioSourceReader::AudioSourceReader() :
|
||||
_isStreaming(false)
|
||||
, _filePath("")
|
||||
, _audioSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
AudioSourceReader::~AudioSourceReader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// WAVFileReader
|
||||
WAVReader::WAVReader() :
|
||||
_bytesRead(0)
|
||||
, _isDirty(false)
|
||||
, _streamer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
WAVReader::~WAVReader()
|
||||
{
|
||||
flushChunks();
|
||||
}
|
||||
|
||||
bool WAVReader::initialize(const std::string& filePath)
|
||||
{
|
||||
bool ret = false;
|
||||
_isStreaming = false;
|
||||
_filePath = filePath;
|
||||
|
||||
do {
|
||||
auto fileSize = FileUtils::getInstance()->getFileSize(_filePath);
|
||||
|
||||
if (fileSize <= 0)
|
||||
break;
|
||||
|
||||
flushChunks();
|
||||
|
||||
_rwMutex.lock();
|
||||
_streamer = ref new MediaStreamer;
|
||||
_streamer->Initialize(std::wstring(_filePath.begin(), _filePath.end()).c_str(), true);
|
||||
_rwMutex.unlock();
|
||||
_wfx = _streamer->GetOutputWaveFormatEx();
|
||||
UINT32 dataSize = _streamer->GetMaxStreamLengthInBytes();
|
||||
|
||||
if (dataSize <= 0)
|
||||
break;
|
||||
|
||||
_audioSize = dataSize;
|
||||
if (_audioSize <= PCMDATA_CACHEMAXSIZE) {
|
||||
produceChunk();
|
||||
}
|
||||
else {
|
||||
_isStreaming = true;
|
||||
for (int i = 0; i < QUEUEBUFFER_NUM; i++) {
|
||||
produceChunk();
|
||||
}
|
||||
}
|
||||
|
||||
ret = true;
|
||||
} while (false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WAVReader::consumeChunk(AudioDataChunk& chunk)
|
||||
{
|
||||
bool ret = false;
|
||||
_isDirty = true;
|
||||
|
||||
_rwMutex.lock();
|
||||
if (_chnkQ.size() > 0) {
|
||||
chunk = _chnkQ.front();
|
||||
if (_isStreaming) {
|
||||
_chnkQ.pop();
|
||||
}
|
||||
else{
|
||||
// copy for future requests
|
||||
auto cpy = new (std::nothrow) unsigned char[chunk._dataSize];
|
||||
memcpy(cpy, chunk._data, chunk._dataSize);
|
||||
_chnkQ.front()._data = cpy;
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
_rwMutex.unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WAVReader::produceChunk()
|
||||
{
|
||||
_rwMutex.lock();
|
||||
int chunkSize = _audioSize;
|
||||
|
||||
do {
|
||||
if (!_isStreaming && _chnkQ.size() || _chnkQ.size() >= QUEUEBUFFER_NUM) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (_isStreaming) {
|
||||
chunkSize = std::min(CHUNK_SIZE_MAX, _audioSize - _bytesRead);
|
||||
}
|
||||
|
||||
if (!chunkSize && !_chnkQ.size()) {
|
||||
auto alignment = _wfx.nChannels * _wfx.nBlockAlign;
|
||||
_bytesRead -= alignment;
|
||||
chunkSize = alignment;
|
||||
}
|
||||
|
||||
UINT retSize = 0;
|
||||
AudioDataChunk chunk = { 0 };
|
||||
chunk._data = new (std::nothrow) unsigned char[chunkSize];
|
||||
_streamer->ReadChunk(chunk._data, _bytesRead, chunkSize, &retSize);
|
||||
|
||||
if (retSize <= 0) {
|
||||
delete[] chunk._data;
|
||||
chunk._data = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
_bytesRead += retSize;
|
||||
chunk._dataSize = retSize;
|
||||
chunk._seqNo = ((float)_bytesRead / _audioSize) * ((float)_audioSize / CHUNK_SIZE_MAX);
|
||||
chunk._endOfStream = (_bytesRead >= _audioSize);
|
||||
_chnkQ.push(chunk);
|
||||
} while (false);
|
||||
_rwMutex.unlock();
|
||||
}
|
||||
|
||||
void WAVReader::seekTo(const float ratio)
|
||||
{
|
||||
if (_isStreaming) {
|
||||
_bytesRead = ratio * _audioSize;
|
||||
|
||||
if (!_bytesRead && !_isDirty && _chnkQ.size()) // already in 0.0 position
|
||||
return;
|
||||
|
||||
flushChunks();
|
||||
|
||||
switch (_wfx.wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
case WAVE_FORMAT_ADPCM: {
|
||||
auto alignment = _wfx.nChannels * _wfx.nBlockAlign;
|
||||
_bytesRead = _bytesRead >= _audioSize ? (_audioSize - alignment) : _bytesRead - (_bytesRead % alignment);
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < QUEUEBUFFER_NUM; i++) {
|
||||
produceChunk();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WAVReader::flushChunks()
|
||||
{
|
||||
_rwMutex.lock();
|
||||
while (!_chnkQ.empty()) {
|
||||
delete[] _chnkQ.front()._data;
|
||||
_chnkQ.pop();
|
||||
}
|
||||
_rwMutex.unlock();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* cocos2d-x http://www.cocos2d-x.org
|
||||
*
|
||||
* Copyright (c) 2010-2011 - cocos2d-x community
|
||||
*
|
||||
* Portions Copyright (c) Microsoft Open Technologies, Inc.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
|
||||
|
||||
#ifndef __AUDIO_SOURCE_READER_H_
|
||||
#define __AUDIO_SOURCE_READER_H_
|
||||
|
||||
#define NEAR near
|
||||
#include "MediaStreamer.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
namespace experimental{
|
||||
|
||||
const UINT PCMDATA_CACHEMAXSIZE = 2621440;
|
||||
const UINT QUEUEBUFFER_NUM = 4;
|
||||
const UINT CHUNK_SIZE_MAX = PCMDATA_CACHEMAXSIZE / QUEUEBUFFER_NUM;
|
||||
|
||||
enum class FileFormat
|
||||
{
|
||||
UNKNOWN,
|
||||
WAV,
|
||||
MP3,
|
||||
OGG
|
||||
};
|
||||
|
||||
typedef struct AudioDataChunk
|
||||
{
|
||||
size_t _dataSize;
|
||||
unsigned char *_data;
|
||||
bool _endOfStream;
|
||||
int _seqNo;
|
||||
} AudioDataChunk;
|
||||
|
||||
|
||||
class AudioSourceReader
|
||||
{
|
||||
public:
|
||||
AudioSourceReader();
|
||||
virtual ~AudioSourceReader();
|
||||
|
||||
bool isStreamingSource() { return _isStreaming; }
|
||||
std::string getFilePath() { return _filePath; }
|
||||
virtual size_t getTotalAudioBytes() { return _audioSize; }
|
||||
|
||||
virtual bool initialize(const std::string& filePath) = 0;
|
||||
virtual FileFormat getFileFormat() = 0;
|
||||
virtual bool consumeChunk(AudioDataChunk& chunk) = 0;
|
||||
virtual void produceChunk() = 0;
|
||||
virtual void seekTo(const float ratio) = 0;
|
||||
virtual const WAVEFORMATEX& getWaveFormatInfo() { return _wfx; }
|
||||
|
||||
protected:
|
||||
bool _isStreaming;
|
||||
std::string _filePath;
|
||||
size_t _audioSize;
|
||||
WAVEFORMATEX _wfx;
|
||||
};
|
||||
|
||||
class WAVReader : public AudioSourceReader
|
||||
{
|
||||
public:
|
||||
WAVReader();
|
||||
~WAVReader();
|
||||
|
||||
bool initialize(const std::string& filePath) override;
|
||||
FileFormat getFileFormat() override { return FileFormat::WAV; }
|
||||
bool consumeChunk(AudioDataChunk& chunk) override;
|
||||
void produceChunk() override;
|
||||
void seekTo(const float ratio) override;
|
||||
|
||||
protected:
|
||||
void enqueueChunk(const AudioDataChunk& chunk);
|
||||
void flushChunks();
|
||||
|
||||
private:
|
||||
bool _isDirty;
|
||||
size_t _bytesRead;
|
||||
std::mutex _rwMutex;
|
||||
MediaStreamer^ _streamer;
|
||||
std::queue<AudioDataChunk> _chnkQ;
|
||||
};
|
||||
|
||||
class MP3Reader : public AudioSourceReader
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
NS_CC_END
|
||||
#endif // __AUDIO_SOURCE_READER_H_
|
||||
#endif
|
||||
|
|
@ -39,6 +39,8 @@ using namespace Concurrency;
|
|||
((uint32)(byte)(ch2) << 16) | ((uint32)(byte)(ch3) << 24 ))
|
||||
#endif /* defined(MAKEFOURCC) */
|
||||
|
||||
const int FMT_CHUNK_MAX = 256;
|
||||
|
||||
inline void ThrowIfFailed(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
|
@ -50,6 +52,8 @@ inline void ThrowIfFailed(HRESULT hr)
|
|||
|
||||
MediaStreamer::MediaStreamer() :
|
||||
m_offset(0)
|
||||
, m_dataLen(0)
|
||||
, m_filename(nullptr)
|
||||
{
|
||||
ZeroMemory(&m_waveFormat, sizeof(m_waveFormat));
|
||||
m_location = Package::Current->InstalledLocation;
|
||||
|
@ -59,9 +63,13 @@ MediaStreamer::MediaStreamer() :
|
|||
MediaStreamer::~MediaStreamer()
|
||||
{
|
||||
}
|
||||
Platform::Array<byte>^ MediaStreamer::ReadData(
|
||||
_In_ Platform::String^ filename
|
||||
)
|
||||
|
||||
Platform::Array<byte>^ MediaStreamer::ReadData(_In_ Platform::String^ filename)
|
||||
{
|
||||
return ReadData(filename, 0, 0);
|
||||
}
|
||||
|
||||
Platform::Array<byte>^ MediaStreamer::ReadData(_In_ Platform::String^ filename, uint32 from, uint32 length)
|
||||
{
|
||||
CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {0};
|
||||
extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
|
||||
|
@ -72,26 +80,16 @@ Platform::Array<byte>^ MediaStreamer::ReadData(
|
|||
extendedParams.hTemplateFile = nullptr;
|
||||
|
||||
Wrappers::FileHandle file(
|
||||
CreateFile2(
|
||||
filename->Data(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
OPEN_EXISTING,
|
||||
&extendedParams
|
||||
)
|
||||
CreateFile2(filename->Data(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extendedParams)
|
||||
);
|
||||
|
||||
if (file.Get()==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
throw ref new Platform::FailureException();
|
||||
}
|
||||
|
||||
FILE_STANDARD_INFO fileInfo = {0};
|
||||
if (!GetFileInformationByHandleEx(
|
||||
file.Get(),
|
||||
FileStandardInfo,
|
||||
&fileInfo,
|
||||
sizeof(fileInfo)
|
||||
))
|
||||
FILE_STANDARD_INFO fileInfo = { 0 };
|
||||
if (!GetFileInformationByHandleEx(file.Get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
|
||||
{
|
||||
throw ref new Platform::FailureException();
|
||||
}
|
||||
|
@ -101,15 +99,21 @@ Platform::Array<byte>^ MediaStreamer::ReadData(
|
|||
throw ref new Platform::OutOfMemoryException();
|
||||
}
|
||||
|
||||
Platform::Array<byte>^ fileData = ref new Platform::Array<byte>(fileInfo.EndOfFile.LowPart);
|
||||
from += m_offset;
|
||||
length = (length == 0 || from + length > fileInfo.EndOfFile.LowPart) ? fileInfo.EndOfFile.LowPart - from : length;
|
||||
Platform::Array<byte>^ fileData = ref new Platform::Array<byte>(length);
|
||||
|
||||
if (!ReadFile(
|
||||
file.Get(),
|
||||
fileData->Data,
|
||||
fileData->Length,
|
||||
nullptr,
|
||||
nullptr
|
||||
) )
|
||||
if (from)
|
||||
{
|
||||
LARGE_INTEGER pos = { 0 };
|
||||
pos.QuadPart = from;
|
||||
if (!SetFilePointerEx(file.Get(), pos, nullptr, FILE_BEGIN))
|
||||
{
|
||||
throw ref new Platform::FailureException();
|
||||
}
|
||||
}
|
||||
|
||||
if (!ReadFile(file.Get(), fileData->Data, fileData->Length, nullptr, nullptr))
|
||||
{
|
||||
throw ref new Platform::FailureException();
|
||||
}
|
||||
|
@ -117,9 +121,9 @@ Platform::Array<byte>^ MediaStreamer::ReadData(
|
|||
return fileData;
|
||||
}
|
||||
|
||||
void MediaStreamer::Initialize(__in const WCHAR* url)
|
||||
void MediaStreamer::Initialize(__in const WCHAR* url, bool lazy)
|
||||
{
|
||||
|
||||
m_filename = ref new Platform::String(url);
|
||||
WCHAR filePath[MAX_PATH] = {0};
|
||||
if ((wcslen(url) > 1 && url[1] == ':'))
|
||||
{
|
||||
|
@ -139,8 +143,7 @@ void MediaStreamer::Initialize(__in const WCHAR* url)
|
|||
wcscat_s(filePath, url);
|
||||
}
|
||||
|
||||
|
||||
Platform::Array<byte>^ data = ReadData(ref new Platform::String(filePath));
|
||||
Platform::Array<byte>^ data = lazy ? ReadData(ref new Platform::String(filePath), 0, FMT_CHUNK_MAX) : ReadData(ref new Platform::String(filePath));
|
||||
UINT32 length = data->Length;
|
||||
const byte * dataPtr = data->Data;
|
||||
UINT32 offset = 0;
|
||||
|
@ -197,22 +200,45 @@ void MediaStreamer::Initialize(__in const WCHAR* url)
|
|||
|
||||
// Locate the 'data' chunk and copy its contents to a buffer.
|
||||
ThrowIfFailed(ReadChunk(MAKEFOURCC('d', 'a', 't', 'a'), chunkSize, chunkPos));
|
||||
m_data.resize(chunkSize);
|
||||
CopyMemory(m_data.data(), &dataPtr[chunkPos], chunkSize);
|
||||
m_dataLen = chunkSize;
|
||||
m_offset = chunkPos;
|
||||
|
||||
m_offset = 0;
|
||||
if (!lazy)
|
||||
{
|
||||
m_data.resize(chunkSize);
|
||||
CopyMemory(m_data.data(), &dataPtr[chunkPos], chunkSize);
|
||||
m_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaStreamer::ReadAll(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength)
|
||||
{
|
||||
UINT32 toCopy = m_data.size() - m_offset;
|
||||
if (toCopy > maxBufferSize) toCopy = maxBufferSize;
|
||||
if (!m_data.size())
|
||||
{
|
||||
ReadChunk(buffer, 0, m_dataLen, bufferLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 toCopy = m_data.size() - m_offset;
|
||||
if (toCopy > maxBufferSize) toCopy = maxBufferSize;
|
||||
|
||||
CopyMemory(buffer, m_data.data(), toCopy);
|
||||
*bufferLength = toCopy;
|
||||
CopyMemory(buffer, m_data.data(), toCopy);
|
||||
*bufferLength = toCopy;
|
||||
|
||||
m_offset += toCopy;
|
||||
if (m_offset > m_data.size()) m_offset = m_data.size();
|
||||
m_offset += toCopy;
|
||||
if (m_offset > m_data.size()) m_offset = m_data.size();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaStreamer::ReadChunk(uint8* buffer, uint32 from, uint32 length, uint32* bytesRead)
|
||||
{
|
||||
Platform::Array<byte>^ data = ReadData(m_filename, from, length);
|
||||
*bytesRead = data->Length;
|
||||
|
||||
if (*bytesRead > 0)
|
||||
{
|
||||
CopyMemory(buffer, (byte*)data->Data, data->Length);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaStreamer::Restart()
|
||||
|
|
|
@ -29,9 +29,12 @@ private:
|
|||
uint32 m_maxStreamLengthInBytes;
|
||||
std::vector<byte> m_data;
|
||||
UINT32 m_offset;
|
||||
Platform::Array<byte>^ ReadData(
|
||||
_In_ Platform::String^ filename
|
||||
);
|
||||
UINT32 m_dataLen;
|
||||
Platform::String^ m_filename;
|
||||
|
||||
Platform::Array<byte>^ ReadData(_In_ Platform::String^ filename);
|
||||
Platform::Array<byte>^ ReadData(_In_ Platform::String^ filename, uint32 from, uint32 length);
|
||||
|
||||
internal:
|
||||
Windows::Storage::StorageFolder^ m_location;
|
||||
Platform::String^ m_locationPath;
|
||||
|
@ -49,10 +52,11 @@ internal:
|
|||
|
||||
UINT32 GetMaxStreamLengthInBytes()
|
||||
{
|
||||
return m_data.size();
|
||||
return m_dataLen;
|
||||
}
|
||||
|
||||
void Initialize(_In_ const WCHAR* url);
|
||||
void ReadAll(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength);
|
||||
void Initialize(_In_ const WCHAR* url, bool lazy = false);
|
||||
void ReadAll(uint8* buffer, uint32 maxBufferSize, uint32* bufferLength);
|
||||
void ReadChunk(uint8* buffer, uint32 from, uint32 length, uint32* bytesRead);
|
||||
void Restart();
|
||||
};
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
|
||||
#include "SimpleAudioEngine.h"
|
||||
#include "Audio.h"
|
||||
#include "cocos2d.h"
|
||||
|
||||
#include <map>
|
||||
//#include "CCCommon.h"
|
||||
using namespace std;
|
||||
USING_NS_CC;
|
||||
|
||||
namespace CocosDenshion {
|
||||
|
||||
|
@ -81,7 +83,8 @@ void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop)
|
|||
return;
|
||||
}
|
||||
|
||||
sharedAudioController()->PlayBackgroundMusic(pszFilePath, bLoop);
|
||||
string fullPath = CCFileUtils::getInstance()->fullPathForFilename(pszFilePath);
|
||||
sharedAudioController()->PlayBackgroundMusic(fullPath.c_str(), bLoop);
|
||||
}
|
||||
|
||||
void SimpleAudioEngine::stopBackgroundMusic(bool bReleaseData)
|
||||
|
@ -121,8 +124,8 @@ bool SimpleAudioEngine::isBackgroundMusicPlaying()
|
|||
unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop,float pitch, float pan, float gain)
|
||||
{
|
||||
unsigned int sound;
|
||||
sharedAudioController()->PlaySoundEffect(pszFilePath, bLoop, sound);
|
||||
// TODO: need to support playEffect parameters
|
||||
string fullPath = CCFileUtils::getInstance()->fullPathForFilename(pszFilePath);
|
||||
sharedAudioController()->PlaySoundEffect(fullPath.c_str(), bLoop, sound); // TODO: need to support playEffect parameters
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
@ -133,7 +136,8 @@ void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
|
|||
|
||||
void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
|
||||
{
|
||||
sharedAudioController()->PreloadSoundEffect(pszFilePath);
|
||||
string fullPath = CCFileUtils::getInstance()->fullPathForFilename(pszFilePath);
|
||||
sharedAudioController()->PreloadSoundEffect(fullPath.c_str());
|
||||
}
|
||||
|
||||
void SimpleAudioEngine::pauseEffect(unsigned int nSoundId)
|
||||
|
@ -168,7 +172,8 @@ void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath)
|
|||
|
||||
void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
|
||||
{
|
||||
sharedAudioController()->UnloadSoundEffect(pszFilePath);
|
||||
string fullPath = CCFileUtils::getInstance()->fullPathForFilename(pszFilePath);
|
||||
sharedAudioController()->UnloadSoundEffect(fullPath.c_str());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -354,10 +354,6 @@ bool Console::listenOnTCP(int port)
|
|||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
WSADATA wsaData;
|
||||
n = WSAStartup(MAKEWORD(2, 2),&wsaData);
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
|
||||
CCLogIPAddresses();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( (n = getaddrinfo(nullptr, serv, &hints, &res)) != 0) {
|
||||
|
@ -446,7 +442,10 @@ void Console::stop()
|
|||
{
|
||||
if( _running ) {
|
||||
_endThread = true;
|
||||
_thread.join();
|
||||
if (_thread.joinable())
|
||||
{
|
||||
_thread.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1056,6 +1055,17 @@ void Console::addClient()
|
|||
_maxfd = std::max(_maxfd,fd);
|
||||
|
||||
sendPrompt(fd);
|
||||
|
||||
/**
|
||||
* A SIGPIPE is sent to a process if it tried to write to socket that had been shutdown for
|
||||
* writing or isn't connected (anymore) on iOS.
|
||||
*
|
||||
* The default behaviour for this signal is to end the process.So we make the process ignore SIGPIPE.
|
||||
*/
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
|
||||
int set = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1155,14 +1165,16 @@ void Console::loop()
|
|||
|
||||
/* Any message for the remote console ? send it! */
|
||||
if( !_DebugStrings.empty() ) {
|
||||
_DebugStringsMutex.lock();
|
||||
for(const auto &str : _DebugStrings) {
|
||||
for(const auto &fd : _fds) {
|
||||
send(fd, str.c_str(), str.length(),0);
|
||||
if (_DebugStringsMutex.try_lock())
|
||||
{
|
||||
for (const auto &str : _DebugStrings) {
|
||||
for (auto fd : _fds) {
|
||||
send(fd, str.c_str(), str.length(), 0);
|
||||
}
|
||||
}
|
||||
_DebugStrings.clear();
|
||||
_DebugStringsMutex.unlock();
|
||||
}
|
||||
_DebugStrings.clear();
|
||||
_DebugStringsMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,12 +81,12 @@ public:
|
|||
*
|
||||
* @return The scroll data of x axis.
|
||||
*/
|
||||
inline float getScrollX() { return _scrollX; };
|
||||
inline float getScrollX() const { return _scrollX; };
|
||||
/** Get mouse scroll data of y axis.
|
||||
*
|
||||
* @return The scroll data of y axis.
|
||||
*/
|
||||
inline float getScrollY() { return _scrollY; };
|
||||
inline float getScrollY() const { return _scrollY; };
|
||||
|
||||
/** Set the cursor position.
|
||||
*
|
||||
|
@ -118,19 +118,19 @@ public:
|
|||
* @return The mouse button.
|
||||
* @js getButton
|
||||
*/
|
||||
inline int getMouseButton() { return _mouseButton; };
|
||||
inline int getMouseButton() const { return _mouseButton; };
|
||||
/** Get the cursor position of x axis.
|
||||
*
|
||||
* @return The x coordinate of cursor position.
|
||||
* @js getLocationX
|
||||
*/
|
||||
inline float getCursorX() { return _x; };
|
||||
inline float getCursorX() const { return _x; };
|
||||
/** Get the cursor position of y axis.
|
||||
*
|
||||
* @return The y coordinate of cursor position.
|
||||
* @js getLocationY
|
||||
*/
|
||||
inline float getCursorY() { return _y; };
|
||||
inline float getCursorY() const { return _y; };
|
||||
|
||||
/** Returns the current touch location in OpenGL coordinates.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2015 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "CCNinePatchImageParser.h"
|
||||
#include "platform/CCImage.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
NinePatchImageParser::~NinePatchImageParser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
NinePatchImageParser::NinePatchImageParser(Image* image)
|
||||
{
|
||||
this->_image = image;
|
||||
this->_imageFrame = Rect(0,0,image->getWidth(), image->getHeight());
|
||||
CCASSERT(image->getRenderFormat()==Texture2D::PixelFormat::RGBA8888,
|
||||
"unsupported format, currently only supports rgba8888");
|
||||
this->_isRotated = false;
|
||||
}
|
||||
|
||||
NinePatchImageParser::NinePatchImageParser(Image* image, const Rect& frame, bool rotated)
|
||||
{
|
||||
this->_image = image;
|
||||
CCASSERT(image->getRenderFormat()==Texture2D::PixelFormat::RGBA8888,
|
||||
"unsupported format, currently only supports rgba8888");
|
||||
this->_imageFrame = frame;
|
||||
this->_isRotated = rotated;
|
||||
}
|
||||
|
||||
int NinePatchImageParser::getFrameHeight()const
|
||||
{
|
||||
if (_isRotated)
|
||||
{
|
||||
return _imageFrame.size.width;
|
||||
}
|
||||
return _imageFrame.size.height;
|
||||
}
|
||||
|
||||
int NinePatchImageParser::getFrameWidth()const
|
||||
{
|
||||
if (_isRotated)
|
||||
{
|
||||
return _imageFrame.size.height;
|
||||
}
|
||||
return _imageFrame.size.width;
|
||||
}
|
||||
|
||||
int NinePatchImageParser::getPixelOriginOffset(Direction direction)const
|
||||
{
|
||||
int imageWidth = _image->getWidth();
|
||||
int frameWidth = this->getFrameWidth();
|
||||
|
||||
int topLineLeftOffset = (int)_imageFrame.origin.y * imageWidth * 4 + (int)_imageFrame.origin.x * 4;
|
||||
if(direction == Direction::HORIZONTAL)
|
||||
{
|
||||
return topLineLeftOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_isRotated)
|
||||
{
|
||||
return topLineLeftOffset + (frameWidth - 1) * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return topLineLeftOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vec2 NinePatchImageParser::parseHorizontalMargin()const
|
||||
{
|
||||
unsigned char* data = _image->getData();
|
||||
|
||||
data = data + this->getPixelOriginOffset(Direction::HORIZONTAL);
|
||||
unsigned char lastPixel = *(data + 3);
|
||||
int x1 = 0;
|
||||
int x2 = 0;
|
||||
|
||||
int length = _imageFrame.origin.x + this->getFrameWidth();
|
||||
for(int i = (int)_imageFrame.origin.x; i <= length ; i++)
|
||||
{
|
||||
unsigned char pixel = *(data + (i - (int)_imageFrame.origin.x) * 4 +3);
|
||||
if(pixel != lastPixel)
|
||||
{
|
||||
if (pixel > 0)
|
||||
{
|
||||
x1 = (i - (int)_imageFrame.origin.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = (i - (int)_imageFrame.origin.x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastPixel = pixel;
|
||||
}
|
||||
return Vec2(x1,x2);
|
||||
}
|
||||
|
||||
Vec2 NinePatchImageParser::parseVerticalMargin()const
|
||||
{
|
||||
unsigned char* data = _image->getData();
|
||||
int imageWidth = _image->getWidth();
|
||||
|
||||
int y1 = 0;
|
||||
int y2 = 0;
|
||||
|
||||
data = data + this->getPixelOriginOffset(Direction::VERTICAL);
|
||||
unsigned char lastPixel = *(data + 3);
|
||||
|
||||
int length = (int)(_imageFrame.origin.y + this->getFrameHeight());
|
||||
for(int i = _imageFrame.origin.y; i <= length; i++)
|
||||
{
|
||||
unsigned char pixel = *(data + (i - (int)_imageFrame.origin.y) * imageWidth * 4 + 3);
|
||||
if(pixel != lastPixel)
|
||||
{
|
||||
if(pixel > 0)
|
||||
{
|
||||
y1 = (i - (int)_imageFrame.origin.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
y2 = (i - (int)_imageFrame.origin.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastPixel = pixel;
|
||||
}
|
||||
return Vec2(y1,y2);
|
||||
}
|
||||
|
||||
Rect NinePatchImageParser::parseCapInset() const
|
||||
{
|
||||
Rect capInsets;
|
||||
Vec2 horizontalLine = this->parseHorizontalMargin();
|
||||
Vec2 verticalLine = this->parseVerticalMargin();
|
||||
|
||||
if(_isRotated)
|
||||
{
|
||||
capInsets = Rect(verticalLine.y,
|
||||
_imageFrame.size.height - horizontalLine.y,
|
||||
verticalLine.y - verticalLine.x,
|
||||
horizontalLine.y - horizontalLine.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
capInsets = Rect(horizontalLine.x,
|
||||
verticalLine.x,
|
||||
horizontalLine.y - horizontalLine.x,
|
||||
verticalLine.y - verticalLine.x);
|
||||
}
|
||||
|
||||
capInsets = Rect(capInsets.origin.x / CC_CONTENT_SCALE_FACTOR(),
|
||||
capInsets.origin.y / CC_CONTENT_SCALE_FACTOR(),
|
||||
capInsets.size.width / CC_CONTENT_SCALE_FACTOR(),
|
||||
capInsets.size.height / CC_CONTENT_SCALE_FACTOR());
|
||||
return capInsets;
|
||||
}
|
||||
|
||||
void NinePatchImageParser::setSpriteFrameInfo( const cocos2d::Rect& frameRect, bool rotated )
|
||||
{
|
||||
this->_imageFrame = frameRect;
|
||||
this->_isRotated = rotated;
|
||||
}
|
||||
|
||||
bool NinePatchImageParser::isNinePatchImage(const std::string& filepath)
|
||||
{
|
||||
size_t length = filepath.length();
|
||||
if(length <7 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(filepath.compare(length-6, 6, ".9.png") == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NS_CC_END
|
|
@ -0,0 +1,114 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2015 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "platform/CCPlatformMacros.h"
|
||||
#include "math/CCGeometry.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class Image;
|
||||
class SpriteFrame;
|
||||
|
||||
|
||||
/**
|
||||
* A class for paring Android .9 patch image.
|
||||
* For more about Android .9 patch image format, please refer to
|
||||
* http://developer.android.com/tools/help/draw9patch.html
|
||||
*
|
||||
* The class could parse a single .9 patch image and produce the capInsets
|
||||
* as well as a sprite atlas and store all the capInsets infos in a Texture2D.
|
||||
* Note:
|
||||
* - Currently only PixelFormat::RGBA8888 is supported.
|
||||
* - TexturePacker Trim mode is not supported at the moment.
|
||||
*/
|
||||
|
||||
class CC_DLL NinePatchImageParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Determines whether a filename contains ".9.png" suffix.
|
||||
* @param filename A 9-patch image name.
|
||||
*
|
||||
* @return If the filename contains ".9.png", then return true, otherwise false.
|
||||
*/
|
||||
static bool isNinePatchImage(const std::string& filename);
|
||||
|
||||
/**
|
||||
* Instantiate a NinePatchImageParser with a Image object.
|
||||
*
|
||||
* @param image A Image object pointer.
|
||||
*
|
||||
* @return A NinePatchImageParser instance.
|
||||
*/
|
||||
NinePatchImageParser(Image* image);
|
||||
|
||||
/**
|
||||
* Instantiate a NinePatchImageParser with a Image object and the spriteFrame info.
|
||||
* The spriteFrame contains the frame rect in the image atlas and whether it
|
||||
* is rotated or not.
|
||||
*
|
||||
* @param image A Image object pointer.
|
||||
* @param frameRect The sprite frame rect in the image atlas.
|
||||
* @param ratated Whether is sprite frame is rotated in the image atlas.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
NinePatchImageParser(Image* image, const Rect& frameRect, bool ratated);
|
||||
|
||||
/**
|
||||
* Change the sprite frame info.
|
||||
* It is useful when parsing multiple sprite frame with only on NinePatchImageParser.
|
||||
*
|
||||
* @param frameRect The sprite frame rect in the image atlas.
|
||||
* @param rotated Whether is sprite frame is rotated in the image atlas.
|
||||
*/
|
||||
void setSpriteFrameInfo(const Rect& frameRect, bool rotated);
|
||||
|
||||
/**
|
||||
* Default destructor.
|
||||
*/
|
||||
virtual ~NinePatchImageParser();
|
||||
|
||||
/**
|
||||
* Parsing the image data and extract the capInsets info.
|
||||
* @return The capInsets Rect.
|
||||
*/
|
||||
Rect parseCapInset()const;
|
||||
private:
|
||||
enum class Direction
|
||||
{
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
};
|
||||
int getPixelOriginOffset(Direction direction)const;
|
||||
Vec2 parseHorizontalMargin()const;
|
||||
Vec2 parseVerticalMargin()const;
|
||||
int getFrameWidth()const;
|
||||
int getFrameHeight()const;
|
||||
|
||||
Image* _image;
|
||||
Rect _imageFrame;
|
||||
bool _isRotated;
|
||||
};
|
||||
|
||||
NS_CC_END
|
|
@ -85,7 +85,7 @@ Properties::Properties(Data* data, ssize_t* dataIdx, const std::string& name, co
|
|||
rewind();
|
||||
}
|
||||
|
||||
Properties* Properties::createWithoutAutorelease(const std::string& url)
|
||||
Properties* Properties::createNonRefCounted(const std::string& url)
|
||||
{
|
||||
if (url.size() == 0)
|
||||
{
|
||||
|
@ -419,24 +419,25 @@ signed char Properties::readChar()
|
|||
|
||||
char* Properties::readLine(char* output, int num)
|
||||
{
|
||||
int idx=0;
|
||||
|
||||
if (eof())
|
||||
return nullptr;
|
||||
|
||||
// little optimization: avoid uneeded dereferences
|
||||
ssize_t dataIdx = *_dataIdx;
|
||||
const ssize_t dataIdx = *_dataIdx;
|
||||
int i;
|
||||
|
||||
while (dataIdx<_data->_size && _data->_bytes[dataIdx]!='\n' && idx-1<num)
|
||||
for (i=0; i<num && dataIdx+i < _data->_size; i++)
|
||||
{
|
||||
dataIdx++; idx++;
|
||||
auto c = _data->_bytes[dataIdx+i];
|
||||
if (c == '\n')
|
||||
break;
|
||||
output[i] = c;
|
||||
}
|
||||
|
||||
memcpy(output, &_data->_bytes[*_dataIdx], idx);
|
||||
output[idx] = '\0';
|
||||
output[i] = '\0';
|
||||
|
||||
// restore value
|
||||
*_dataIdx = dataIdx;
|
||||
*_dataIdx = dataIdx+i;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ class Data;
|
|||
|
||||
@verbatim
|
||||
// Create the top-level Properties object.
|
||||
Properties* properties = Properties::createWithoutAutorelease("example.properties");
|
||||
Properties* properties = Properties::createNonRefCounted("example.properties");
|
||||
// Retrieve the "spriteTexture" namespace.
|
||||
Properties* spriteTexture = properties->getNamespace("spriteTexture");
|
||||
|
||||
|
@ -187,7 +187,7 @@ public:
|
|||
* @return The created Properties or NULL if there was an error.
|
||||
* @script{create}
|
||||
*/
|
||||
static Properties* createWithoutAutorelease(const std::string& url);
|
||||
static Properties* createNonRefCounted(const std::string& url);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
|
@ -579,7 +579,7 @@ private:
|
|||
bool seekFromCurrent(int offset);
|
||||
bool eof();
|
||||
|
||||
// Called after createWithoutAutorelease(); copies info from parents into derived namespaces.
|
||||
// Called after createNonRefCounted(); copies info from parents into derived namespaces.
|
||||
void resolveInheritance(const char* id = NULL);
|
||||
|
||||
// Called by resolveInheritance().
|
||||
|
|
|
@ -0,0 +1,334 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 "base/CCUserDefault.h"
|
||||
#include "platform/CCCommon.h"
|
||||
#include "base/base64.h"
|
||||
#include "base/ccUtils.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
#include "CCWinRTUtils.h"
|
||||
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace std;
|
||||
|
||||
#define XML_FILE_NAME "UserDefault.xml"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
||||
/**
|
||||
* WinRT implementation of UserDefault
|
||||
*/
|
||||
|
||||
UserDefault* UserDefault::_userDefault = nullptr;
|
||||
string UserDefault::_filePath = string("");
|
||||
bool UserDefault::_isFilePathInitialized = false;
|
||||
|
||||
UserDefault::~UserDefault()
|
||||
{
|
||||
}
|
||||
|
||||
UserDefault::UserDefault()
|
||||
{
|
||||
}
|
||||
|
||||
Platform::Object^ getPlatformKeyValue(const char* pKey)
|
||||
{
|
||||
// check key
|
||||
if (!pKey)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
|
||||
auto key = PlatformStringFromString(pKey);
|
||||
auto values = localSettings->Values;
|
||||
|
||||
if (values->HasKey(key))
|
||||
{
|
||||
return values->Lookup(key);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setPlatformKeyValue(const char* pKey, PropertyValue^ value)
|
||||
{
|
||||
// check key
|
||||
if (!pKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
|
||||
auto values = localSettings->Values;
|
||||
values->Insert(PlatformStringFromString(pKey), value);
|
||||
}
|
||||
|
||||
bool UserDefault::getBoolForKey(const char* pKey)
|
||||
{
|
||||
return getBoolForKey(pKey, false);
|
||||
}
|
||||
|
||||
bool UserDefault::getBoolForKey(const char* pKey, bool defaultValue)
|
||||
{
|
||||
bool ret = defaultValue;
|
||||
auto value = getPlatformKeyValue(pKey);
|
||||
if (value)
|
||||
{
|
||||
ret = safe_cast<bool>(value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UserDefault::getIntegerForKey(const char* pKey)
|
||||
{
|
||||
return getIntegerForKey(pKey, 0);
|
||||
}
|
||||
|
||||
int UserDefault::getIntegerForKey(const char* pKey, int defaultValue)
|
||||
{
|
||||
int ret = defaultValue;
|
||||
auto value = getPlatformKeyValue(pKey);
|
||||
if (value)
|
||||
{
|
||||
ret = safe_cast<int>(value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float UserDefault::getFloatForKey(const char* pKey)
|
||||
{
|
||||
return getFloatForKey(pKey, 0.0f);
|
||||
}
|
||||
|
||||
float UserDefault::getFloatForKey(const char* pKey, float defaultValue)
|
||||
{
|
||||
float ret = (float)getDoubleForKey(pKey, (double)defaultValue);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
double UserDefault::getDoubleForKey(const char* pKey)
|
||||
{
|
||||
return getDoubleForKey(pKey, 0.0);
|
||||
}
|
||||
|
||||
double UserDefault::getDoubleForKey(const char* pKey, double defaultValue)
|
||||
{
|
||||
double ret = defaultValue;
|
||||
auto value = getPlatformKeyValue(pKey);
|
||||
if (value)
|
||||
{
|
||||
ret = safe_cast<double>(value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string UserDefault::getStringForKey(const char* pKey)
|
||||
{
|
||||
return getStringForKey(pKey, "");
|
||||
}
|
||||
|
||||
string UserDefault::getStringForKey(const char* pKey, const std::string & defaultValue)
|
||||
{
|
||||
string ret = defaultValue;
|
||||
auto value = getPlatformKeyValue(pKey);
|
||||
if (value)
|
||||
{
|
||||
auto result = safe_cast<Platform::String^>(value);
|
||||
ret = PlatformStringToString(result);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Data UserDefault::getDataForKey(const char* pKey)
|
||||
{
|
||||
return getDataForKey(pKey, Data::Null);
|
||||
}
|
||||
|
||||
Data UserDefault::getDataForKey(const char* pKey, const Data& defaultValue)
|
||||
{
|
||||
Data ret = defaultValue;
|
||||
std::string encodedData = getStringForKey(pKey,"");
|
||||
|
||||
if (!encodedData.empty())
|
||||
{
|
||||
unsigned char* decodedData = nullptr;
|
||||
int decodedDataLen = base64Decode((unsigned char*) encodedData.c_str(), (unsigned int) encodedData.length(), &decodedData);
|
||||
if (decodedData && decodedDataLen > 0)
|
||||
{
|
||||
ret.fastSet(decodedData, decodedDataLen);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UserDefault::setBoolForKey(const char* pKey, bool value)
|
||||
{
|
||||
// check key
|
||||
if (!pKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setPlatformKeyValue(pKey, dynamic_cast<PropertyValue^>(PropertyValue::CreateBoolean(value)));
|
||||
}
|
||||
|
||||
void UserDefault::setIntegerForKey(const char* pKey, int value)
|
||||
{
|
||||
// check key
|
||||
if (! pKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setPlatformKeyValue(pKey, dynamic_cast<PropertyValue^>(PropertyValue::CreateInt32(value)));
|
||||
}
|
||||
|
||||
void UserDefault::setFloatForKey(const char* pKey, float value)
|
||||
{
|
||||
setDoubleForKey(pKey, value);
|
||||
}
|
||||
|
||||
void UserDefault::setDoubleForKey(const char* pKey, double value)
|
||||
{
|
||||
// check key
|
||||
if (! pKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setPlatformKeyValue(pKey, dynamic_cast<PropertyValue^>(PropertyValue::CreateDouble(value)));
|
||||
}
|
||||
|
||||
void UserDefault::setStringForKey(const char* pKey, const std::string & value)
|
||||
{
|
||||
// check key
|
||||
if (! pKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setPlatformKeyValue(pKey, dynamic_cast<PropertyValue^>(PropertyValue::CreateString(PlatformStringFromString(value))));
|
||||
}
|
||||
|
||||
void UserDefault::setDataForKey(const char* pKey, const Data& value) {
|
||||
// check key
|
||||
if (! pKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char *encodedData = 0;
|
||||
base64Encode(value.getBytes(), static_cast<unsigned int>(value.getSize()), &encodedData);
|
||||
|
||||
setPlatformKeyValue(pKey, dynamic_cast<PropertyValue^>(PropertyValue::CreateString(PlatformStringFromString(encodedData))));
|
||||
|
||||
if (encodedData)
|
||||
free(encodedData);
|
||||
}
|
||||
|
||||
UserDefault* UserDefault::getInstance()
|
||||
{
|
||||
if (!_userDefault)
|
||||
{
|
||||
initXMLFilePath();
|
||||
|
||||
// only create xml file one time
|
||||
// the file exists after the program exit
|
||||
if ((!isXMLFileExist()) && (!createXMLFile()))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_userDefault = new (std::nothrow) UserDefault();
|
||||
}
|
||||
|
||||
return _userDefault;
|
||||
}
|
||||
|
||||
void UserDefault::destroyInstance()
|
||||
{
|
||||
CC_SAFE_DELETE(_userDefault);
|
||||
}
|
||||
|
||||
void UserDefault::setDelegate(UserDefault *delegate)
|
||||
{
|
||||
if (_userDefault)
|
||||
delete _userDefault;
|
||||
|
||||
_userDefault = delegate;
|
||||
}
|
||||
|
||||
|
||||
// FIXME:: deprecated
|
||||
UserDefault* UserDefault::sharedUserDefault()
|
||||
{
|
||||
return UserDefault::getInstance();
|
||||
}
|
||||
|
||||
// FIXME:: deprecated
|
||||
void UserDefault::purgeSharedUserDefault()
|
||||
{
|
||||
return UserDefault::destroyInstance();
|
||||
}
|
||||
|
||||
bool UserDefault::isXMLFileExist()
|
||||
{
|
||||
//return FileUtils::getInstance()->isFileExist(_filePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UserDefault::initXMLFilePath()
|
||||
{
|
||||
if (! _isFilePathInitialized)
|
||||
{
|
||||
_filePath += FileUtils::getInstance()->getWritablePath() + XML_FILE_NAME;
|
||||
_isFilePathInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// create new xml file
|
||||
bool UserDefault::createXMLFile()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const string& UserDefault::getXMLFilePath()
|
||||
{
|
||||
return _filePath;
|
||||
}
|
||||
|
||||
void UserDefault::flush()
|
||||
{
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif // (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
|
@ -237,7 +237,7 @@ public:
|
|||
* @js NA
|
||||
*/
|
||||
static const std::string& getXMLFilePath();
|
||||
/** All supported platforms other iOS & Android use xml file to save values. This function checks whether the xml file exists or not.
|
||||
/** All supported platforms other iOS & Android and CC_PLATFORM_WINRT use xml file to save values. This function checks whether the xml file exists or not.
|
||||
* @return True if the xml file exists, flase if not.
|
||||
* @js NA
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,7 @@ set(COCOS_BASE_SRC
|
|||
base/CCController.cpp
|
||||
base/CCData.cpp
|
||||
base/CCDataVisitor.cpp
|
||||
base/CCNinePatchImageParser.cpp
|
||||
base/CCDirector.cpp
|
||||
base/CCEvent.cpp
|
||||
base/CCEventAcceleration.cpp
|
||||
|
|
|
@ -254,7 +254,8 @@ THE SOFTWARE.
|
|||
|
||||
/** Use 3d physics integration API. */
|
||||
#ifndef CC_USE_3D_PHYSICS
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
#define CC_USE_3D_PHYSICS 1
|
||||
#define CC_USE_3D_PHYSICS 1
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -183,7 +183,7 @@ ActionTimeline* ActionTimelineCache::loadAnimationActionWithContent(const std::s
|
|||
doc.Parse<0>(content.c_str());
|
||||
if (doc.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n", doc.GetParseError());
|
||||
CCLOG("GetParseError %d\n", doc.GetParseError());
|
||||
}
|
||||
|
||||
const rapidjson::Value& json = DICTOOL->getSubDictionary_json(doc, ACTION);
|
||||
|
|
|
@ -376,7 +376,7 @@ Node* CSLoader::loadNodeWithContent(const std::string& content)
|
|||
doc.Parse<0>(content.c_str());
|
||||
if (doc.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n", doc.GetParseError());
|
||||
CCLOG("GetParseError %d\n", doc.GetParseError());
|
||||
}
|
||||
|
||||
// cocos2dx version mono editor is based on
|
||||
|
@ -724,7 +724,7 @@ Node* CSLoader::loadWidget(const rapidjson::Value& json)
|
|||
customJsonDict.Parse<0>(customProperty);
|
||||
if (customJsonDict.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n", customJsonDict.GetParseError());
|
||||
CCLOG("GetParseError %d\n", customJsonDict.GetParseError());
|
||||
}
|
||||
|
||||
widgetPropertiesReader->setPropsForAllCustomWidgetFromJsonDictionary(classname, widget, customJsonDict);
|
||||
|
|
|
@ -1247,7 +1247,7 @@ void DataReaderHelper::addDataFromJsonCache(const std::string& fileContent, Data
|
|||
|
||||
json.ParseStream<0>(stream);
|
||||
if (json.HasParseError()) {
|
||||
CCLOG("GetParseError %s\n",json.GetParseError());
|
||||
CCLOG("GetParseError %d\n",json.GetParseError());
|
||||
}
|
||||
|
||||
dataInfo->contentScale = DICTOOL->getFloatValue_json(json, CONTENT_SCALE, 1.0f);
|
||||
|
|
|
@ -212,7 +212,7 @@ Widget* GUIReader::widgetFromJsonFile(const char *fileName)
|
|||
jsonDict.Parse<0>(contentStr.c_str());
|
||||
if (jsonDict.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n",jsonDict.GetParseError());
|
||||
CCLOG("GetParseError %d\n",jsonDict.GetParseError());
|
||||
}
|
||||
Widget* widget = nullptr;
|
||||
const char* fileVersion = DICTOOL->getStringValue_json(jsonDict, "version");
|
||||
|
@ -1373,7 +1373,7 @@ Widget* WidgetPropertiesReader0300::widgetFromBinary(CocoLoader* cocoLoader, st
|
|||
customJsonDict.Parse<0>(customProperty);
|
||||
if (customJsonDict.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n", customJsonDict.GetParseError());
|
||||
CCLOG("GetParseError %d\n", customJsonDict.GetParseError());
|
||||
}
|
||||
setPropsForAllCustomWidgetFromJsonDictionary(classname, widget, customJsonDict);
|
||||
}else{
|
||||
|
@ -1474,7 +1474,7 @@ Widget* WidgetPropertiesReader0300::widgetFromJsonDictionary(const rapidjson::Va
|
|||
customJsonDict.Parse<0>(customProperty);
|
||||
if (customJsonDict.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n", customJsonDict.GetParseError());
|
||||
CCLOG("GetParseError %d\n", customJsonDict.GetParseError());
|
||||
}
|
||||
setPropsForAllCustomWidgetFromJsonDictionary(classname, widget, customJsonDict);
|
||||
}else{
|
||||
|
|
|
@ -236,7 +236,7 @@ void TriggerMng::buildJson(rapidjson::Document &document, cocostudio::CocoLoader
|
|||
{
|
||||
if (str2 != nullptr)
|
||||
{
|
||||
action.AddMember("classname", str2, allocator);
|
||||
action.AddMember("classname", rapidjson::Value(str2,allocator), allocator);
|
||||
}
|
||||
}
|
||||
else if (key2.compare("dataitems") == 0)
|
||||
|
@ -257,7 +257,7 @@ void TriggerMng::buildJson(rapidjson::Document &document, cocostudio::CocoLoader
|
|||
{
|
||||
if (str3 != nullptr)
|
||||
{
|
||||
dataitem.AddMember("key", str3, allocator);
|
||||
dataitem.AddMember("key", rapidjson::Value(str3,allocator), allocator);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -265,7 +265,7 @@ void TriggerMng::buildJson(rapidjson::Document &document, cocostudio::CocoLoader
|
|||
rapidjson::Type type = pDataItemArray[i5].GetType(pCocoLoader);
|
||||
if (type == rapidjson::kStringType)
|
||||
{
|
||||
dataitem.AddMember("value", str3, allocator);
|
||||
dataitem.AddMember("value", rapidjson::Value(str3,allocator), allocator);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -312,7 +312,7 @@ void TriggerMng::buildJson(rapidjson::Document &document, cocostudio::CocoLoader
|
|||
{
|
||||
if (str4 != nullptr)
|
||||
{
|
||||
cond.AddMember("classname", str4, allocator);
|
||||
cond.AddMember("classname", rapidjson::Value(str4,allocator), allocator);
|
||||
}
|
||||
}
|
||||
else if (key4.compare("dataitems") == 0)
|
||||
|
@ -333,7 +333,7 @@ void TriggerMng::buildJson(rapidjson::Document &document, cocostudio::CocoLoader
|
|||
{
|
||||
if (str5 != nullptr)
|
||||
{
|
||||
dataitem.AddMember("key", str5, allocator);
|
||||
dataitem.AddMember("key", rapidjson::Value(str5,allocator), allocator);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -341,7 +341,7 @@ void TriggerMng::buildJson(rapidjson::Document &document, cocostudio::CocoLoader
|
|||
rapidjson::Type type = pDataItemArray[i9].GetType(pCocoLoader);
|
||||
if (type == rapidjson::kStringType)
|
||||
{
|
||||
dataitem.AddMember("value", str5, allocator);
|
||||
dataitem.AddMember("value", rapidjson::Value(str5,allocator), allocator);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -154,12 +154,12 @@ void ArmatureNodeReader::setPropsWithFlatBuffers(cocos2d::Node *node,
|
|||
fileExist = false;
|
||||
}
|
||||
|
||||
if (!fileExist)
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", filepath.c_str())->getCString());
|
||||
custom->addChild(label);
|
||||
}
|
||||
//if (!fileExist)
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", filepath.c_str())->getCString());
|
||||
// custom->addChild(label);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -706,12 +706,12 @@ namespace cocostudio
|
|||
{
|
||||
button->loadTextureNormal(normalTexturePath, (Widget::TextureResType)normalType);
|
||||
}
|
||||
else if (!normalTexturePath.empty())
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", normalErrorFilePath.c_str())->getCString());
|
||||
button->addChild(label);
|
||||
}
|
||||
//else if (!normalTexturePath.empty())
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", normalErrorFilePath.c_str())->getCString());
|
||||
// button->addChild(label);
|
||||
//}
|
||||
|
||||
bool pressedFileExist = false;
|
||||
std::string pressedErrorFilePath = "";
|
||||
|
@ -770,12 +770,12 @@ namespace cocostudio
|
|||
{
|
||||
button->loadTexturePressed(pressedTexturePath, (Widget::TextureResType)pressedType);
|
||||
}
|
||||
else if (!pressedTexturePath.empty())
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", pressedErrorFilePath.c_str())->getCString());
|
||||
button->addChild(label);
|
||||
}
|
||||
//else if (!pressedTexturePath.empty())
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", pressedErrorFilePath.c_str())->getCString());
|
||||
// button->addChild(label);
|
||||
//}
|
||||
|
||||
bool disabledFileExist = false;
|
||||
std::string disabledErrorFilePath = "";
|
||||
|
@ -834,12 +834,12 @@ namespace cocostudio
|
|||
{
|
||||
button->loadTextureDisabled(disabledTexturePath, (Widget::TextureResType)disabledType);
|
||||
}
|
||||
else if (!disabledTexturePath.empty())
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", disabledErrorFilePath.c_str())->getCString());
|
||||
button->addChild(label);
|
||||
}
|
||||
//else if (!disabledTexturePath.empty())
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", disabledErrorFilePath.c_str())->getCString());
|
||||
// button->addChild(label);
|
||||
//}
|
||||
|
||||
std::string titleText = options->text()->c_str();
|
||||
button->setTitleText(titleText);
|
||||
|
@ -873,12 +873,12 @@ namespace cocostudio
|
|||
{
|
||||
button->setTitleFontName(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
button->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// button->addChild(label);
|
||||
//}
|
||||
}
|
||||
|
||||
bool displaystate = options->displaystate() != 0;
|
||||
|
|
|
@ -491,12 +491,12 @@ namespace cocostudio
|
|||
{
|
||||
checkBox->loadTextureBackGround(backGroundTexturePath, (Widget::TextureResType)backGroundType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", backGroundErrorFilePath.c_str())->getCString());
|
||||
checkBox->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", backGroundErrorFilePath.c_str())->getCString());
|
||||
// checkBox->addChild(label);
|
||||
//}
|
||||
|
||||
//load background selected image
|
||||
bool backGroundSelectedfileExist = false;
|
||||
|
@ -556,12 +556,12 @@ namespace cocostudio
|
|||
{
|
||||
checkBox->loadTextureBackGroundSelected(backGroundSelectedTexturePath, (Widget::TextureResType)backGroundSelectedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", backGroundSelectedErrorFilePath.c_str())->getCString());
|
||||
checkBox->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", backGroundSelectedErrorFilePath.c_str())->getCString());
|
||||
// checkBox->addChild(label);
|
||||
//}
|
||||
|
||||
//load frontCross image
|
||||
bool frontCrossFileExist = false;
|
||||
|
@ -621,12 +621,12 @@ namespace cocostudio
|
|||
{
|
||||
checkBox->loadTextureFrontCross(frontCrossFileName, (Widget::TextureResType)frontCrossType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", frontCrossErrorFilePath.c_str())->getCString());
|
||||
checkBox->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", frontCrossErrorFilePath.c_str())->getCString());
|
||||
// checkBox->addChild(label);
|
||||
//}
|
||||
|
||||
//load backGroundBoxDisabledData
|
||||
bool backGroundBoxDisabledFileExist = false;
|
||||
|
@ -686,12 +686,12 @@ namespace cocostudio
|
|||
{
|
||||
checkBox->loadTextureBackGroundDisabled(backGroundDisabledFileName, (Widget::TextureResType)backGroundDisabledType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", backGroundBoxDisabledErrorFilePath.c_str())->getCString());
|
||||
checkBox->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", backGroundBoxDisabledErrorFilePath.c_str())->getCString());
|
||||
// checkBox->addChild(label);
|
||||
//}
|
||||
|
||||
///load frontCrossDisabledData
|
||||
bool frontCrossDisabledFileExist = false;
|
||||
|
@ -751,12 +751,12 @@ namespace cocostudio
|
|||
{
|
||||
checkBox->loadTextureFrontCrossDisabled(frontCrossDisabledFileName, (Widget::TextureResType)frontCrossDisabledType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", frontCrossDisabledErrorFilePath.c_str())->getCString());
|
||||
checkBox->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", frontCrossDisabledErrorFilePath.c_str())->getCString());
|
||||
// checkBox->addChild(label);
|
||||
//}
|
||||
|
||||
bool selectedstate = options->selectedState() != 0;
|
||||
checkBox->setSelected(selectedstate);
|
||||
|
|
|
@ -238,15 +238,15 @@ namespace cocostudio
|
|||
setPropsWithFlatBuffers(tmx, (Table*)gameMapOptions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node* node = Node::create();
|
||||
setPropsWithFlatBuffers(node, (Table*)gameMapOptions);
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
node->addChild(label);
|
||||
return node;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// Node* node = Node::create();
|
||||
// setPropsWithFlatBuffers(node, (Table*)gameMapOptions);
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// node->addChild(label);
|
||||
// return node;
|
||||
//}
|
||||
|
||||
return tmx;
|
||||
}
|
||||
|
|
|
@ -353,12 +353,12 @@ namespace cocostudio
|
|||
{
|
||||
imageView->loadTexture(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
imageView->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// imageView->addChild(label);
|
||||
//}
|
||||
|
||||
bool scale9Enabled = options->scale9Enabled() != 0;
|
||||
imageView->setScale9Enabled(scale9Enabled);
|
||||
|
|
|
@ -190,12 +190,21 @@ namespace cocostudio
|
|||
|
||||
/* adapt screen gui */
|
||||
float w = 0, h = 0;
|
||||
bool adaptScrenn = DICTOOL->getBooleanValue_json(options, P_AdaptScreen);
|
||||
if (adaptScrenn)
|
||||
bool adaptScrennExsit = DICTOOL->checkObjectExist_json(options, P_AdaptScreen);
|
||||
if (adaptScrennExsit)
|
||||
{
|
||||
Size screenSize = CCDirector::getInstance()->getWinSize();
|
||||
w = screenSize.width;
|
||||
h = screenSize.height;
|
||||
bool adaptScrenn = DICTOOL->getBooleanValue_json(options, P_AdaptScreen);
|
||||
if (adaptScrenn)
|
||||
{
|
||||
Size screenSize = Director::getInstance()->getWinSize();
|
||||
w = screenSize.width;
|
||||
h = screenSize.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = DICTOOL->getFloatValue_json(options, P_Width);
|
||||
h = DICTOOL->getFloatValue_json(options, P_Height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -300,7 +309,11 @@ namespace cocostudio
|
|||
panel->setBackGroundImageCapInsets(Rect(cx, cy, cw, ch));
|
||||
}
|
||||
|
||||
panel->setLayoutType((Layout::Type)DICTOOL->getIntValue_json(options, P_LayoutType));
|
||||
bool layoutTypeExsit = DICTOOL->checkObjectExist_json(options, P_LayoutType);
|
||||
if (layoutTypeExsit)
|
||||
{
|
||||
panel->setLayoutType((Layout::Type)DICTOOL->getIntValue_json(options, P_LayoutType));
|
||||
}
|
||||
|
||||
int bgimgcr = DICTOOL->getIntValue_json(options, P_ColorR,255);
|
||||
int bgimgcg = DICTOOL->getIntValue_json(options, P_ColorG,255);
|
||||
|
@ -662,12 +675,12 @@ namespace cocostudio
|
|||
{
|
||||
panel->setBackGroundImage(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
panel->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// panel->addChild(label);
|
||||
//}
|
||||
}
|
||||
|
||||
auto widgetOptions = options->widgetOptions();
|
||||
|
|
|
@ -490,12 +490,12 @@ namespace cocostudio
|
|||
{
|
||||
listView->setBackGroundImage(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
listView->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// listView->addChild(label);
|
||||
//}
|
||||
}
|
||||
|
||||
auto widgetOptions = options->widgetOptions();
|
||||
|
|
|
@ -303,12 +303,12 @@ namespace cocostudio
|
|||
{
|
||||
loadingBar->loadTexture(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
loadingBar->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// loadingBar->addChild(label);
|
||||
//}
|
||||
|
||||
int direction = options->direction();
|
||||
loadingBar->setDirection(LoadingBar::Direction(direction));
|
||||
|
|
|
@ -403,12 +403,12 @@ namespace cocostudio
|
|||
{
|
||||
pageView->setBackGroundImage(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
pageView->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// pageView->addChild(label);
|
||||
//}
|
||||
}
|
||||
|
||||
auto widgetOptions = options->widgetOptions();
|
||||
|
|
|
@ -208,15 +208,15 @@ namespace cocostudio
|
|||
particle->setPositionType(ParticleSystem::PositionType::GROUPED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node* node = Node::create();
|
||||
setPropsWithFlatBuffers(node, (Table*)particleOptions);
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
node->addChild(label);
|
||||
return node;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// Node* node = Node::create();
|
||||
// setPropsWithFlatBuffers(node, (Table*)particleOptions);
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// node->addChild(label);
|
||||
// return node;
|
||||
//}
|
||||
|
||||
return particle;
|
||||
}
|
||||
|
|
|
@ -489,12 +489,12 @@ namespace cocostudio
|
|||
{
|
||||
scrollView->setBackGroundImage(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
scrollView->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// scrollView->addChild(label);
|
||||
//}
|
||||
}
|
||||
|
||||
auto widgetOptions = options->widgetOptions();
|
||||
|
|
|
@ -525,12 +525,12 @@ namespace cocostudio
|
|||
{
|
||||
slider->loadBarTexture(imageFileName, (Widget::TextureResType)imageFileNameType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", imageErrorFilePath.c_str())->getCString());
|
||||
slider->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", imageErrorFilePath.c_str())->getCString());
|
||||
// slider->addChild(label);
|
||||
//}
|
||||
|
||||
//loading normal slider ball texture
|
||||
bool normalFileExist = false;
|
||||
|
@ -590,12 +590,12 @@ namespace cocostudio
|
|||
{
|
||||
slider->loadSlidBallTextureNormal(normalFileName, (Widget::TextureResType)normalType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", normalErrorFilePath.c_str())->getCString());
|
||||
slider->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", normalErrorFilePath.c_str())->getCString());
|
||||
// slider->addChild(label);
|
||||
//}
|
||||
|
||||
//loading slider ball press texture
|
||||
bool pressedFileExist = false;
|
||||
|
@ -655,12 +655,12 @@ namespace cocostudio
|
|||
{
|
||||
slider->loadSlidBallTexturePressed(pressedFileName, (Widget::TextureResType)pressedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", pressedErrorFilePath.c_str())->getCString());
|
||||
slider->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", pressedErrorFilePath.c_str())->getCString());
|
||||
// slider->addChild(label);
|
||||
//}
|
||||
|
||||
//loading silder ball disable texture
|
||||
bool disabledFileExist = false;
|
||||
|
@ -720,12 +720,12 @@ namespace cocostudio
|
|||
{
|
||||
slider->loadSlidBallTextureDisabled(disabledFileName, (Widget::TextureResType)disabledType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", disabledErrorFilePath.c_str())->getCString());
|
||||
slider->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", disabledErrorFilePath.c_str())->getCString());
|
||||
// slider->addChild(label);
|
||||
//}
|
||||
|
||||
//load slider progress texture
|
||||
bool progressFileExist = false;
|
||||
|
@ -785,12 +785,12 @@ namespace cocostudio
|
|||
{
|
||||
slider->loadProgressBarTexture(progressBarFileName, (Widget::TextureResType)progressBarType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", progressErrorFilePath.c_str())->getCString());
|
||||
slider->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", progressErrorFilePath.c_str())->getCString());
|
||||
// slider->addChild(label);
|
||||
//}
|
||||
|
||||
bool displaystate = options->displaystate() != 0;
|
||||
slider->setBright(displaystate);
|
||||
|
|
|
@ -226,12 +226,12 @@ namespace cocostudio
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (!fileExist)
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
sprite->addChild(label);
|
||||
}
|
||||
//if (!fileExist)
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// sprite->addChild(label);
|
||||
//}
|
||||
|
||||
auto f_blendFunc = options->blendFunc();
|
||||
if (f_blendFunc)
|
||||
|
|
|
@ -275,12 +275,12 @@ namespace cocostudio
|
|||
fileExist = false;
|
||||
}
|
||||
|
||||
if (!fileExist)
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
labelAtlas->addChild(label);
|
||||
}
|
||||
//if (!fileExist)
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// labelAtlas->addChild(label);
|
||||
//}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -218,11 +218,11 @@ namespace cocostudio
|
|||
fileExist = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorContent = "missed";
|
||||
fileExist = false;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// errorContent = "missed";
|
||||
// fileExist = false;
|
||||
//}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -235,10 +235,13 @@ namespace cocostudio
|
|||
}
|
||||
else
|
||||
{
|
||||
errorFilePath = path;
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s %s", errorFilePath.c_str(), errorContent.c_str())->getCString());
|
||||
labelBMFont->addChild(label);
|
||||
if (!errorContent.empty())
|
||||
{
|
||||
errorFilePath = path;
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s %s", errorFilePath.c_str(), errorContent.c_str())->getCString());
|
||||
labelBMFont->addChild(label);
|
||||
}
|
||||
}
|
||||
|
||||
std::string text = options->text()->c_str();
|
||||
|
|
|
@ -332,12 +332,12 @@ namespace cocostudio
|
|||
{
|
||||
textField->setFontName(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto label = Label::create();
|
||||
label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
textField->addChild(label);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto label = Label::create();
|
||||
// label->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// textField->addChild(label);
|
||||
//}
|
||||
}
|
||||
|
||||
auto widgetReader = WidgetReader::getInstance();
|
||||
|
|
|
@ -440,12 +440,12 @@ namespace cocostudio
|
|||
{
|
||||
label->setFontName(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto alert = Label::create();
|
||||
alert->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
label->addChild(alert);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// auto alert = Label::create();
|
||||
// alert->setString(__String::createWithFormat("%s missed", errorFilePath.c_str())->getCString());
|
||||
// label->addChild(alert);
|
||||
//}
|
||||
}
|
||||
|
||||
bool outlineEnabled = options->outlineEnabled();
|
||||
|
|
|
@ -160,12 +160,22 @@ namespace cocostudio
|
|||
|
||||
/* adapt screen */
|
||||
float w = 0, h = 0;
|
||||
bool adaptScrenn = DICTOOL->getBooleanValue_json(options, P_AdaptScreen);
|
||||
if (adaptScrenn)
|
||||
bool adaptScrennExsit = DICTOOL->checkObjectExist_json(options, P_AdaptScreen);
|
||||
if (adaptScrennExsit)
|
||||
{
|
||||
Size screenSize = CCDirector::getInstance()->getWinSize();
|
||||
w = screenSize.width;
|
||||
h = screenSize.height;
|
||||
bool adaptScrenn = DICTOOL->getBooleanValue_json(options, P_AdaptScreen);
|
||||
if (adaptScrenn)
|
||||
{
|
||||
Size screenSize = Director::getInstance()->getWinSize();
|
||||
w = screenSize.width;
|
||||
h = screenSize.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = DICTOOL->getFloatValue_json(options, P_Width);
|
||||
h = DICTOOL->getFloatValue_json(options, P_Height);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -145,6 +146,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -162,6 +164,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -179,6 +182,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -196,6 +200,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -213,6 +218,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\winrt_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -110,6 +111,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -127,6 +129,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -144,6 +147,7 @@
|
|||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(EngineRoot)external\wp_8.1-specific\angle\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -26,17 +26,12 @@
|
|||
|
||||
#include "HttpClient.h"
|
||||
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <condition_variable>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCScheduler.h"
|
||||
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "platform/android/jni/JniHelper.h"
|
||||
|
||||
|
@ -49,24 +44,7 @@ typedef HttpRequestHeaders::iterator HttpRequestHeadersIter;
|
|||
typedef std::vector<std::string> HttpCookies;
|
||||
typedef HttpCookies::iterator HttpCookiesIter;
|
||||
|
||||
static std::mutex s_requestQueueMutex;
|
||||
static std::mutex s_responseQueueMutex;
|
||||
static std::mutex s_cookieFileMutex;
|
||||
|
||||
static std::condition_variable_any s_sleepCondition;
|
||||
|
||||
static Vector<HttpRequest*>* s_requestQueue = nullptr;
|
||||
static Vector<HttpResponse*>* s_responseQueue = nullptr;
|
||||
|
||||
static HttpClient *s_httpClient = nullptr; // pointer to singleton
|
||||
|
||||
static std::string s_responseMessage = "";
|
||||
|
||||
static std::string s_cookieFilename = "";
|
||||
|
||||
static std::string s_sslCaFilename = "";
|
||||
|
||||
static HttpRequest *s_requestSentinel = new HttpRequest;
|
||||
static HttpClient* _httpClient = nullptr; // pointer to singleton
|
||||
|
||||
|
||||
struct CookiesInfo
|
||||
|
@ -98,16 +76,16 @@ size_t writeHeaderData(void* buffer, size_t sizes,HttpResponse* response)
|
|||
return sizes;
|
||||
}
|
||||
|
||||
static void processResponse(HttpResponse* response, std::string& responseMessage);
|
||||
|
||||
class HttpURLConnection
|
||||
{
|
||||
public:
|
||||
HttpURLConnection():_httpURLConnection(nullptr),
|
||||
_requestmethod(""),
|
||||
_responseCookies(""),
|
||||
_cookieFileName(""),
|
||||
_contentLength(0)
|
||||
HttpURLConnection(HttpClient* httpClient)
|
||||
:_httpURLConnection(nullptr)
|
||||
,_client(httpClient)
|
||||
,_requestmethod("")
|
||||
,_responseCookies("")
|
||||
,_cookieFileName("")
|
||||
,_contentLength(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -120,7 +98,7 @@ public:
|
|||
void setRequestMethod(const char* method)
|
||||
{
|
||||
_requestmethod = method;
|
||||
|
||||
|
||||
JniMethodInfo methodInfo;
|
||||
if (JniHelper::getStaticMethodInfo(methodInfo,
|
||||
"org/cocos2dx/lib/Cocos2dxHttpURLConnection",
|
||||
|
@ -139,7 +117,9 @@ public:
|
|||
{
|
||||
createHttpURLConnection(request->getUrl());
|
||||
if(!configure())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/* get custom header data (if set) */
|
||||
HttpRequestHeaders headers=request->getHeaders();
|
||||
if(!headers.empty())
|
||||
|
@ -259,15 +239,15 @@ public:
|
|||
size_t saveResponseCookies(const char* responseCookies, size_t count)
|
||||
{
|
||||
if (nullptr == responseCookies || strlen(responseCookies) == 0 || count == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_cookieFileName.empty())
|
||||
{
|
||||
_cookieFileName = FileUtils::getInstance()->getWritablePath() + "cookieFile.txt";
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(s_cookieFileMutex);
|
||||
|
||||
FILE* fp = fopen(_cookieFileName.c_str(), "w");
|
||||
if (nullptr == fp)
|
||||
{
|
||||
|
@ -307,7 +287,9 @@ public:
|
|||
char* getResponseContent(HttpResponse* response)
|
||||
{
|
||||
if (nullptr == response)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* content = nullptr;
|
||||
JniMethodInfo methodInfo;
|
||||
|
@ -447,14 +429,14 @@ private:
|
|||
|
||||
void addCookiesForRequestHeader()
|
||||
{
|
||||
if(s_cookieFilename.empty())
|
||||
if(_client->getCookieFilename().empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cookieFileName = FileUtils::getInstance()->fullPathForFilename(s_cookieFilename.c_str());
|
||||
_cookieFileName = FileUtils::getInstance()->fullPathForFilename(_client->getCookieFilename());
|
||||
|
||||
std::lock_guard<std::mutex> lock(s_cookieFileMutex);
|
||||
|
||||
std::string cookiesInfo = FileUtils::getInstance()->getStringFromFile(_cookieFileName.c_str());
|
||||
std::string cookiesInfo = FileUtils::getInstance()->getStringFromFile(_cookieFileName);
|
||||
|
||||
if (cookiesInfo.empty())
|
||||
return;
|
||||
|
@ -550,10 +532,10 @@ private:
|
|||
|
||||
void setVerifySSL()
|
||||
{
|
||||
if(s_sslCaFilename.empty())
|
||||
if(_client->getSSLVerification().empty())
|
||||
return;
|
||||
|
||||
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(s_sslCaFilename.c_str());
|
||||
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(_client->getSSLVerification());
|
||||
|
||||
JniMethodInfo methodInfo;
|
||||
if (JniHelper::getStaticMethodInfo(methodInfo,
|
||||
|
@ -572,13 +554,16 @@ private:
|
|||
bool configure()
|
||||
{
|
||||
if(nullptr == _httpURLConnection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HttpClient* instnace = HttpClient::getInstance();
|
||||
if(nullptr == instnace)
|
||||
if(nullptr == _client)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
setReadAndConnectTimeout(instnace->getTimeoutForRead() * 1000, instnace->getTimeoutForConnect() * 1000);
|
||||
setReadAndConnectTimeout(_client->getTimeoutForRead() * 1000, _client->getTimeoutForConnect() * 1000);
|
||||
|
||||
setVerifySSL();
|
||||
|
||||
|
@ -587,7 +572,7 @@ private:
|
|||
|
||||
char* getBufferFromJString(jstring jstr, JNIEnv* env)
|
||||
{
|
||||
if (nullptr == jstr)
|
||||
if (nullptr == jstr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -595,7 +580,7 @@ private:
|
|||
const char* str = nullptr;
|
||||
char* ret = nullptr;
|
||||
str = env->GetStringUTFChars(jstr, nullptr);
|
||||
if (nullptr != str)
|
||||
if (nullptr != str)
|
||||
{
|
||||
ret = strdup(str);
|
||||
}
|
||||
|
@ -605,9 +590,9 @@ private:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int getCStrFromJByteArray(jbyteArray jba, JNIEnv* env, char** ppData)
|
||||
int getCStrFromJByteArray(jbyteArray jba, JNIEnv* env, char** ppData)
|
||||
{
|
||||
if (nullptr == jba)
|
||||
if (nullptr == jba)
|
||||
{
|
||||
*ppData = nullptr;
|
||||
return 0;
|
||||
|
@ -628,6 +613,7 @@ private:
|
|||
return _responseCookies;
|
||||
}
|
||||
private:
|
||||
HttpClient* _client;
|
||||
jobject _httpURLConnection;
|
||||
std::string _requestmethod;
|
||||
std::string _responseCookies;
|
||||
|
@ -637,13 +623,13 @@ private:
|
|||
};
|
||||
|
||||
// Process Response
|
||||
static void processResponse(HttpResponse* response, std::string& responseMessage)
|
||||
void HttpClient::processResponse(HttpResponse* response, char* responseMessage)
|
||||
{
|
||||
auto request = response->getHttpRequest();
|
||||
HttpRequest::Type requestType = request->getRequestType();
|
||||
|
||||
if (HttpRequest::Type::GET != requestType &&
|
||||
HttpRequest::Type::POST != requestType &&
|
||||
if (HttpRequest::Type::GET != requestType &&
|
||||
HttpRequest::Type::POST != requestType &&
|
||||
HttpRequest::Type::PUT != requestType &&
|
||||
HttpRequest::Type::DELETE != requestType)
|
||||
{
|
||||
|
@ -654,7 +640,7 @@ static void processResponse(HttpResponse* response, std::string& responseMessage
|
|||
long responseCode = -1;
|
||||
int retValue = 0;
|
||||
|
||||
HttpURLConnection urlConnection;
|
||||
HttpURLConnection urlConnection(this);
|
||||
if(!urlConnection.init(request))
|
||||
{
|
||||
response->setSucceed(false);
|
||||
|
@ -718,24 +704,24 @@ static void processResponse(HttpResponse* response, std::string& responseMessage
|
|||
//content len
|
||||
int contentLength = urlConnection.getResponseHeaderByKeyInt("Content-Length");
|
||||
char* contentInfo = urlConnection.getResponseContent(response);
|
||||
if (nullptr != contentInfo) {
|
||||
// response->setResponseDataString(contentInfo, contentLength);
|
||||
if (nullptr != contentInfo)
|
||||
{
|
||||
std::vector<char> * recvBuffer = (std::vector<char>*)response->getResponseData();
|
||||
recvBuffer->clear();
|
||||
recvBuffer->insert(recvBuffer->begin(), (char*)contentInfo, ((char*)contentInfo) + urlConnection.getContentLength());
|
||||
}
|
||||
free(contentInfo);
|
||||
|
||||
responseMessage = urlConnection.getResponseMessage();
|
||||
strcpy(responseMessage, urlConnection.getResponseMessage());
|
||||
urlConnection.disconnect();
|
||||
|
||||
// write data to HttpResponse
|
||||
response->setResponseCode(responseCode);
|
||||
|
||||
if (responseCode == -1)
|
||||
if (responseCode == -1)
|
||||
{
|
||||
response->setSucceed(false);
|
||||
response->setErrorBuffer(responseMessage.c_str());
|
||||
response->setErrorBuffer(responseMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -746,174 +732,209 @@ static void processResponse(HttpResponse* response, std::string& responseMessage
|
|||
// Worker thread
|
||||
void HttpClient::networkThread()
|
||||
{
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
|
||||
increaseThreadCount();
|
||||
|
||||
while (true)
|
||||
{
|
||||
HttpRequest *request;
|
||||
|
||||
// step 1: send http request if the requestQueue isn't empty
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
while (s_requestQueue->empty()) {
|
||||
s_sleepCondition.wait(s_requestQueueMutex);
|
||||
std::lock_guard<std::mutex> lock(_requestQueueMutex);
|
||||
while (_requestQueue.empty()) {
|
||||
_sleepCondition.wait(_requestQueueMutex);
|
||||
}
|
||||
request = s_requestQueue->at(0);
|
||||
s_requestQueue->erase(0);
|
||||
request = _requestQueue.at(0);
|
||||
_requestQueue.erase(0);
|
||||
}
|
||||
|
||||
if (request == s_requestSentinel) {
|
||||
if (request == _requestSentinel) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Create a HttpResponse object, the default setting is http access failed
|
||||
HttpResponse *response = new (std::nothrow) HttpResponse(request);
|
||||
processResponse(response, s_responseMessage);
|
||||
processResponse(response, _responseMessage);
|
||||
|
||||
// add response packet into queue
|
||||
s_responseQueueMutex.lock();
|
||||
s_responseQueue->pushBack(response);
|
||||
s_responseQueueMutex.unlock();
|
||||
_responseQueueMutex.lock();
|
||||
_responseQueue.pushBack(response);
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (nullptr != s_httpClient) {
|
||||
scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
_schedulerMutex.lock();
|
||||
if (nullptr != _scheduler)
|
||||
{
|
||||
_scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
}
|
||||
_schedulerMutex.unlock();
|
||||
}
|
||||
|
||||
// cleanup: if worker thread received quit signal, clean up un-completed request queue
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->clear();
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
|
||||
if (s_requestQueue != nullptr) {
|
||||
delete s_requestQueue;
|
||||
s_requestQueue = nullptr;
|
||||
delete s_responseQueue;
|
||||
s_responseQueue = nullptr;
|
||||
}
|
||||
_requestQueueMutex.lock();
|
||||
_requestQueue.clear();
|
||||
_requestQueueMutex.unlock();
|
||||
|
||||
_responseQueueMutex.lock();
|
||||
_responseQueue.clear();
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
decreaseThreadCountAndMayDeleteThis();
|
||||
}
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThreadAlone(HttpRequest* request, HttpResponse* response)
|
||||
{
|
||||
std::string responseMessage = "";
|
||||
increaseThreadCount();
|
||||
|
||||
char responseMessage[RESPONSE_BUFFER_SIZE] = { 0 };
|
||||
processResponse(response, responseMessage);
|
||||
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
scheduler->performFunctionInCocosThread([response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
_schedulerMutex.lock();
|
||||
if (_scheduler != nullptr)
|
||||
{
|
||||
_scheduler->performFunctionInCocosThread([this, response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(s_httpClient, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(s_httpClient, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(this, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(this, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
}
|
||||
_schedulerMutex.unlock();
|
||||
decreaseThreadCountAndMayDeleteThis();
|
||||
}
|
||||
|
||||
// HttpClient implementation
|
||||
HttpClient* HttpClient::getInstance()
|
||||
{
|
||||
if (s_httpClient == nullptr) {
|
||||
s_httpClient = new (std::nothrow) HttpClient();
|
||||
if (_httpClient == nullptr)
|
||||
{
|
||||
_httpClient = new (std::nothrow) HttpClient();
|
||||
}
|
||||
|
||||
return s_httpClient;
|
||||
return _httpClient;
|
||||
}
|
||||
|
||||
void HttpClient::destroyInstance()
|
||||
{
|
||||
CC_SAFE_DELETE(s_httpClient);
|
||||
if (_httpClient == nullptr)
|
||||
{
|
||||
CCLOG("HttpClient singleton is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
CCLOG("HttpClient::destroyInstance ...");
|
||||
|
||||
auto thiz = _httpClient;
|
||||
_httpClient = nullptr;
|
||||
|
||||
thiz->_scheduler->unscheduleAllForTarget(thiz);
|
||||
|
||||
thiz->_schedulerMutex.lock();
|
||||
thiz->_scheduler = nullptr;
|
||||
thiz->_schedulerMutex.unlock();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(thiz->_requestQueueMutex);
|
||||
thiz->_requestQueue.pushBack(thiz->_requestSentinel);
|
||||
}
|
||||
thiz->_sleepCondition.notify_one();
|
||||
|
||||
thiz->decreaseThreadCountAndMayDeleteThis();
|
||||
CCLOG("HttpClient::destroyInstance() finished!");
|
||||
}
|
||||
|
||||
void HttpClient::enableCookies(const char* cookieFile) {
|
||||
if (cookieFile) {
|
||||
s_cookieFilename = std::string(cookieFile);
|
||||
void HttpClient::enableCookies(const char* cookieFile)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_cookieFileMutex);
|
||||
if (cookieFile)
|
||||
{
|
||||
_cookieFilename = std::string(cookieFile);
|
||||
}
|
||||
else {
|
||||
s_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
else
|
||||
{
|
||||
_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::setSSLVerification(const std::string& caFile)
|
||||
{
|
||||
s_sslCaFilename = caFile;
|
||||
std::lock_guard<std::mutex> lock(_sslCaFileMutex);
|
||||
_sslCaFilename = caFile;
|
||||
}
|
||||
|
||||
HttpClient::HttpClient()
|
||||
: _timeoutForConnect(30)
|
||||
, _timeoutForRead(60)
|
||||
, _isInited(false)
|
||||
, _threadCount(0)
|
||||
, _requestSentinel(new HttpRequest())
|
||||
, _cookie(nullptr)
|
||||
{
|
||||
CCLOG("In the constructor of HttpClient!");
|
||||
increaseThreadCount();
|
||||
_scheduler = Director::getInstance()->getScheduler();
|
||||
}
|
||||
|
||||
HttpClient::~HttpClient()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
s_requestQueue->pushBack(s_requestSentinel);
|
||||
}
|
||||
s_sleepCondition.notify_one();
|
||||
}
|
||||
|
||||
s_httpClient = nullptr;
|
||||
CCLOG("In the destructor of HttpClient!");
|
||||
CC_SAFE_DELETE(_requestSentinel);
|
||||
}
|
||||
|
||||
//Lazy create semaphore & mutex & thread
|
||||
bool HttpClient::lazyInitThreadSemphore()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
if (_isInited)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
|
||||
s_requestQueue = new (std::nothrow) Vector<HttpRequest*>();
|
||||
s_responseQueue = new (std::nothrow) Vector<HttpResponse*>();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
|
||||
t.detach();
|
||||
_isInited = true;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Add a get task to queue
|
||||
void HttpClient::send(HttpRequest* request)
|
||||
{
|
||||
if (false == lazyInitThreadSemphore())
|
||||
if (!lazyInitThreadSemphore())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!request)
|
||||
if (nullptr == request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
request->retain();
|
||||
|
||||
if (nullptr != s_requestQueue) {
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->pushBack(request);
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
s_sleepCondition.notify_one();
|
||||
}
|
||||
_requestQueueMutex.lock();
|
||||
_requestQueue.pushBack(request);
|
||||
_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
_sleepCondition.notify_one();
|
||||
}
|
||||
|
||||
void HttpClient::sendImmediate(HttpRequest* request)
|
||||
{
|
||||
if(!request)
|
||||
if(nullptr == request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -931,20 +952,17 @@ void HttpClient::dispatchResponseCallbacks()
|
|||
{
|
||||
// log("CCHttpClient::dispatchResponseCallbacks is running");
|
||||
//occurs when cocos thread fires but the network thread has already quited
|
||||
if (nullptr == s_responseQueue) {
|
||||
return;
|
||||
}
|
||||
HttpResponse* response = nullptr;
|
||||
|
||||
s_responseQueueMutex.lock();
|
||||
_responseQueueMutex.lock();
|
||||
|
||||
if (!s_responseQueue->empty())
|
||||
if (!_responseQueue.empty())
|
||||
{
|
||||
response = s_responseQueue->at(0);
|
||||
s_responseQueue->erase(0);
|
||||
response = _responseQueue.at(0);
|
||||
_responseQueue.erase(0);
|
||||
}
|
||||
|
||||
s_responseQueueMutex.unlock();
|
||||
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (response)
|
||||
{
|
||||
|
@ -968,6 +986,66 @@ void HttpClient::dispatchResponseCallbacks()
|
|||
}
|
||||
}
|
||||
|
||||
void HttpClient::increaseThreadCount()
|
||||
{
|
||||
_threadCountMutex.lock();
|
||||
++_threadCount;
|
||||
_threadCountMutex.unlock();
|
||||
}
|
||||
|
||||
void HttpClient::decreaseThreadCountAndMayDeleteThis()
|
||||
{
|
||||
bool needDeleteThis = false;
|
||||
_threadCountMutex.lock();
|
||||
--_threadCount;
|
||||
if (0 == _threadCount)
|
||||
{
|
||||
needDeleteThis = true;
|
||||
}
|
||||
|
||||
_threadCountMutex.unlock();
|
||||
if (needDeleteThis)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::setTimeoutForConnect(int value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForConnectMutex);
|
||||
_timeoutForConnect = value;
|
||||
}
|
||||
|
||||
int HttpClient::getTimeoutForConnect()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForConnectMutex);
|
||||
return _timeoutForConnect;
|
||||
}
|
||||
|
||||
void HttpClient::setTimeoutForRead(int value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForReadMutex);
|
||||
_timeoutForRead = value;
|
||||
}
|
||||
|
||||
int HttpClient::getTimeoutForRead()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForReadMutex);
|
||||
return _timeoutForRead;
|
||||
}
|
||||
|
||||
const std::string& HttpClient::getCookieFilename()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_cookieFileMutex);
|
||||
return _cookieFilename;
|
||||
}
|
||||
|
||||
const std::string& HttpClient::getSSLVerification()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_sslCaFileMutex);
|
||||
return _sslCaFilename;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -26,56 +26,26 @@
|
|||
|
||||
#include "HttpClient.h"
|
||||
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#import "HttpAsynConnection.h"
|
||||
#include "HttpCookie.h"
|
||||
|
||||
#include "base/CCVector.h"
|
||||
#import "network/HttpAsynConnection.h"
|
||||
#include "network/HttpCookie.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCScheduler.h"
|
||||
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
namespace network {
|
||||
|
||||
static std::mutex s_requestQueueMutex;
|
||||
static std::mutex s_responseQueueMutex;
|
||||
|
||||
static std::condition_variable_any s_SleepCondition;
|
||||
|
||||
static Vector<HttpRequest*>* s_requestQueue = nullptr;
|
||||
static Vector<HttpResponse*>* s_responseQueue = nullptr;
|
||||
|
||||
static HttpClient *s_HttpClient = nullptr; // pointer to singleton
|
||||
|
||||
static HttpCookie *s_cookie = nullptr;
|
||||
|
||||
static const int ERROR_SIZE = 256;
|
||||
static HttpClient *_httpClient = nullptr; // pointer to singleton
|
||||
|
||||
static char s_errorBuffer[ERROR_SIZE] = {0};
|
||||
|
||||
static std::string s_cookieFilename = "";
|
||||
|
||||
static std::string s_sslCaFilename = "";
|
||||
|
||||
|
||||
static int processTask(HttpRequest *request, NSString *requestType, void *stream, long *errorCode, void *headerStream, char *errorBuffer);
|
||||
|
||||
static void processResponse(HttpResponse* response, char* errorBuffer);
|
||||
|
||||
static HttpRequest *s_requestSentinel = new HttpRequest;
|
||||
static int processTask(HttpClient* client, HttpRequest *request, NSString *requestType, void *stream, long *errorCode, void *headerStream, char *errorBuffer);
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThread()
|
||||
{
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
{
|
||||
increaseThreadCount();
|
||||
|
||||
while (true) @autoreleasepool {
|
||||
|
||||
|
@ -83,77 +53,90 @@ void HttpClient::networkThread()
|
|||
|
||||
// step 1: send http request if the requestQueue isn't empty
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
while (s_requestQueue->empty()) {
|
||||
s_SleepCondition.wait(s_requestQueueMutex);
|
||||
std::lock_guard<std::mutex> lock(_requestQueueMutex);
|
||||
while (_requestQueue.empty()) {
|
||||
_sleepCondition.wait(_requestQueueMutex);
|
||||
}
|
||||
request = s_requestQueue->at(0);
|
||||
s_requestQueue->erase(0);
|
||||
request = _requestQueue.at(0);
|
||||
_requestQueue.erase(0);
|
||||
}
|
||||
|
||||
if (request == s_requestSentinel) {
|
||||
if (request == _requestSentinel) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Create a HttpResponse object, the default setting is http access failed
|
||||
HttpResponse *response = new (std::nothrow) HttpResponse(request);
|
||||
|
||||
processResponse(response, s_errorBuffer);
|
||||
processResponse(response, _responseMessage);
|
||||
|
||||
// add response packet into queue
|
||||
s_responseQueueMutex.lock();
|
||||
s_responseQueue->pushBack(response);
|
||||
s_responseQueueMutex.unlock();
|
||||
_responseQueueMutex.lock();
|
||||
_responseQueue.pushBack(response);
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (nullptr != s_HttpClient) {
|
||||
scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
_schedulerMutex.lock();
|
||||
if (nullptr != _scheduler)
|
||||
{
|
||||
_scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
}
|
||||
_schedulerMutex.unlock();
|
||||
}
|
||||
|
||||
// cleanup: if worker thread received quit signal, clean up un-completed request queue
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->clear();
|
||||
s_requestQueueMutex.unlock();
|
||||
_requestQueueMutex.lock();
|
||||
_requestQueue.clear();
|
||||
_requestQueueMutex.unlock();
|
||||
|
||||
_responseQueueMutex.lock();
|
||||
_responseQueue.clear();
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (s_requestQueue != nullptr) {
|
||||
delete s_requestQueue;
|
||||
s_requestQueue = nullptr;
|
||||
delete s_responseQueue;
|
||||
s_responseQueue = nullptr;
|
||||
}
|
||||
|
||||
decreaseThreadCountAndMayDeleteThis();
|
||||
}
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThreadAlone(HttpRequest* request, HttpResponse* response)
|
||||
{
|
||||
char errorBuffer[ERROR_SIZE] = { 0 };
|
||||
processResponse(response, errorBuffer);
|
||||
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
scheduler->performFunctionInCocosThread([response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(s_HttpClient, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(s_HttpClient, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
increaseThreadCount();
|
||||
|
||||
char responseMessage[RESPONSE_BUFFER_SIZE] = { 0 };
|
||||
processResponse(response, responseMessage);
|
||||
|
||||
_schedulerMutex.lock();
|
||||
if (nullptr != _scheduler)
|
||||
{
|
||||
_scheduler->performFunctionInCocosThread([this, response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(this, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(this, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
}
|
||||
_schedulerMutex.unlock();
|
||||
decreaseThreadCountAndMayDeleteThis();
|
||||
}
|
||||
|
||||
//Process Request
|
||||
static int processTask(HttpRequest *request, NSString* requestType, void *stream, long *responseCode, void *headerStream, char *errorBuffer)
|
||||
static int processTask(HttpClient* client, HttpRequest* request, NSString* requestType, void* stream, long* responseCode, void* headerStream, char* errorBuffer)
|
||||
{
|
||||
if (nullptr == client)
|
||||
{
|
||||
strcpy(errorBuffer, "client object is invalid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//create request with url
|
||||
NSString* urlstring = [NSString stringWithUTF8String:request->getUrl()];
|
||||
NSURL *url = [NSURL URLWithString:urlstring];
|
||||
|
@ -199,9 +182,10 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
|
|||
}
|
||||
|
||||
//read cookie propertities from file and set cookie
|
||||
if(!s_cookieFilename.empty())
|
||||
std::string cookieFilename = client->getCookieFilename();
|
||||
if(!cookieFilename.empty() && nullptr != client->getCookie())
|
||||
{
|
||||
const CookiesInfo* cookieInfo = s_cookie->getMatchCookie(request->getUrl());
|
||||
const CookiesInfo* cookieInfo = client->getCookie()->getMatchCookie(request->getUrl());
|
||||
if(cookieInfo != nullptr)
|
||||
{
|
||||
NSString *domain = [NSString stringWithCString:cookieInfo->domain.c_str() encoding:[NSString defaultCStringEncoding]];
|
||||
|
@ -227,12 +211,13 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
|
|||
httpAsynConn.srcURL = urlstring;
|
||||
httpAsynConn.sslFile = nil;
|
||||
|
||||
if(!s_sslCaFilename.empty())
|
||||
std::string sslCaFileName = client->getSSLVerification();
|
||||
if(!sslCaFileName.empty())
|
||||
{
|
||||
long len = s_sslCaFilename.length();
|
||||
long pos = s_sslCaFilename.rfind('.', len-1);
|
||||
long len = sslCaFileName.length();
|
||||
long pos = sslCaFileName.rfind('.', len-1);
|
||||
|
||||
httpAsynConn.sslFile = [NSString stringWithUTF8String:s_sslCaFilename.substr(0, pos-1).c_str()];
|
||||
httpAsynConn.sslFile = [NSString stringWithUTF8String:sslCaFileName.substr(0, pos-1).c_str()];
|
||||
}
|
||||
[httpAsynConn startRequest:nsrequest];
|
||||
|
||||
|
@ -259,7 +244,7 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
|
|||
*responseCode = httpAsynConn.responseCode;
|
||||
|
||||
//add cookie to cookies vector
|
||||
if(!s_cookieFilename.empty())
|
||||
if(!cookieFilename.empty())
|
||||
{
|
||||
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpAsynConn.responseHeader forURL:url];
|
||||
for (NSHTTPCookie *cookie in cookies)
|
||||
|
@ -282,7 +267,7 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
|
|||
cookieInfo.value = [value cStringUsingEncoding: NSUTF8StringEncoding];
|
||||
cookieInfo.tailmatch = true;
|
||||
|
||||
s_cookie->updateOrAddCookie(&cookieInfo);
|
||||
client->getCookie()->updateOrAddCookie(&cookieInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,131 +298,112 @@ static int processTask(HttpRequest *request, NSString* requestType, void *stream
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Process Response
|
||||
static void processResponse(HttpResponse* response, char* errorBuffer)
|
||||
{
|
||||
auto request = response->getHttpRequest();
|
||||
long responseCode = -1;
|
||||
int retValue = 0;
|
||||
NSString* requestType = nil;
|
||||
|
||||
// Process the request -> get response packet
|
||||
switch (request->getRequestType())
|
||||
{
|
||||
case HttpRequest::Type::GET: // HTTP GET
|
||||
requestType = @"GET";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::POST: // HTTP POST
|
||||
requestType = @"POST";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::PUT:
|
||||
requestType = @"PUT";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::DELETE:
|
||||
requestType = @"DELETE";
|
||||
break;
|
||||
|
||||
default:
|
||||
CCASSERT(true, "CCHttpClient: unknown request type, only GET and POSt are supported");
|
||||
break;
|
||||
}
|
||||
|
||||
retValue = processTask(request,
|
||||
requestType,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
response->getResponseHeader(),
|
||||
errorBuffer);
|
||||
|
||||
// write data to HttpResponse
|
||||
response->setResponseCode(responseCode);
|
||||
|
||||
if (retValue != 0)
|
||||
{
|
||||
response->setSucceed(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
response->setSucceed(false);
|
||||
response->setErrorBuffer(errorBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// HttpClient implementation
|
||||
HttpClient* HttpClient::getInstance()
|
||||
{
|
||||
if (s_HttpClient == nullptr) {
|
||||
s_HttpClient = new (std::nothrow) HttpClient();
|
||||
if (_httpClient == nullptr)
|
||||
{
|
||||
_httpClient = new (std::nothrow) HttpClient();
|
||||
}
|
||||
|
||||
return s_HttpClient;
|
||||
return _httpClient;
|
||||
}
|
||||
|
||||
void HttpClient::destroyInstance()
|
||||
{
|
||||
CC_SAFE_DELETE(s_HttpClient);
|
||||
}
|
||||
|
||||
void HttpClient::enableCookies(const char* cookieFile) {
|
||||
if (cookieFile) {
|
||||
s_cookieFilename = std::string(cookieFile);
|
||||
s_cookieFilename = FileUtils::getInstance()->fullPathForFilename(s_cookieFilename);
|
||||
}
|
||||
else {
|
||||
s_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
if (nullptr == _httpClient)
|
||||
{
|
||||
CCLOG("HttpClient singleton is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
s_cookie = new(std::nothrow)HttpCookie;
|
||||
s_cookie->setCookieFileName(s_cookieFilename);
|
||||
s_cookie->readFile();
|
||||
CCLOG("HttpClient::destroyInstance begin");
|
||||
|
||||
auto thiz = _httpClient;
|
||||
_httpClient = nullptr;
|
||||
|
||||
thiz->_scheduler->unscheduleAllForTarget(thiz);
|
||||
thiz->_schedulerMutex.lock();
|
||||
thiz->_scheduler = nullptr;
|
||||
thiz->_schedulerMutex.unlock();
|
||||
|
||||
thiz->_requestQueueMutex.lock();
|
||||
thiz->_requestQueue.pushBack(thiz->_requestSentinel);
|
||||
thiz->_requestQueueMutex.unlock();
|
||||
|
||||
thiz->_sleepCondition.notify_one();
|
||||
thiz->decreaseThreadCountAndMayDeleteThis();
|
||||
|
||||
CCLOG("HttpClient::destroyInstance() finished!");
|
||||
}
|
||||
|
||||
void HttpClient::enableCookies(const char* cookieFile)
|
||||
{
|
||||
_cookieFileMutex.lock();
|
||||
if (cookieFile)
|
||||
{
|
||||
_cookieFilename = std::string(cookieFile);
|
||||
_cookieFilename = FileUtils::getInstance()->fullPathForFilename(_cookieFilename);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
}
|
||||
_cookieFileMutex.unlock();
|
||||
|
||||
if (nullptr == _cookie)
|
||||
{
|
||||
_cookie = new(std::nothrow)HttpCookie;
|
||||
}
|
||||
_cookie->setCookieFileName(_cookieFilename);
|
||||
_cookie->readFile();
|
||||
}
|
||||
|
||||
void HttpClient::setSSLVerification(const std::string& caFile)
|
||||
{
|
||||
s_sslCaFilename = caFile;
|
||||
std::lock_guard<std::mutex> lock(_sslCaFileMutex);
|
||||
_sslCaFilename = caFile;
|
||||
}
|
||||
|
||||
HttpClient::HttpClient()
|
||||
: _timeoutForConnect(30)
|
||||
, _timeoutForRead(60)
|
||||
, _isInited(false)
|
||||
, _threadCount(0)
|
||||
, _requestSentinel(new HttpRequest())
|
||||
, _cookie(nullptr)
|
||||
{
|
||||
|
||||
CCLOG("In the constructor of HttpClient!");
|
||||
memset(_responseMessage, 0, sizeof(char) * RESPONSE_BUFFER_SIZE);
|
||||
_scheduler = Director::getInstance()->getScheduler();
|
||||
increaseThreadCount();
|
||||
}
|
||||
|
||||
|
||||
HttpClient::~HttpClient()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
s_requestQueue->pushBack(s_requestSentinel);
|
||||
}
|
||||
s_SleepCondition.notify_one();
|
||||
}
|
||||
|
||||
s_HttpClient = nullptr;
|
||||
|
||||
if(!s_cookieFilename.empty())
|
||||
CC_SAFE_DELETE(_requestSentinel);
|
||||
if (!_cookieFilename.empty() && nullptr != _cookie)
|
||||
{
|
||||
s_cookie->writeFile();
|
||||
//delete s_cookie;
|
||||
_cookie->writeFile();
|
||||
CC_SAFE_DELETE(_cookie);
|
||||
}
|
||||
//s_cookie = nullptr;
|
||||
CCLOG("HttpClient destructor");
|
||||
}
|
||||
|
||||
//Lazy create semaphore & mutex & thread
|
||||
bool HttpClient::lazyInitThreadSemphore()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
if (_isInited)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
|
||||
s_requestQueue = new (std::nothrow) Vector<HttpRequest*>();
|
||||
s_responseQueue = new (std::nothrow) Vector<HttpResponse*>();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
|
||||
t.detach();
|
||||
_isInited = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -458,14 +424,12 @@ void HttpClient::send(HttpRequest* request)
|
|||
|
||||
request->retain();
|
||||
|
||||
if (nullptr != s_requestQueue) {
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->pushBack(request);
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
s_SleepCondition.notify_one();
|
||||
}
|
||||
_requestQueueMutex.lock();
|
||||
_requestQueue.pushBack(request);
|
||||
_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
_sleepCondition.notify_one();
|
||||
}
|
||||
|
||||
void HttpClient::sendImmediate(HttpRequest* request)
|
||||
|
@ -488,20 +452,14 @@ void HttpClient::dispatchResponseCallbacks()
|
|||
{
|
||||
// log("CCHttpClient::dispatchResponseCallbacks is running");
|
||||
//occurs when cocos thread fires but the network thread has already quited
|
||||
if (nullptr == s_responseQueue) {
|
||||
return;
|
||||
}
|
||||
HttpResponse* response = nullptr;
|
||||
|
||||
s_responseQueueMutex.lock();
|
||||
|
||||
if (!s_responseQueue->empty())
|
||||
_responseQueueMutex.lock();
|
||||
if (!_responseQueue.empty())
|
||||
{
|
||||
response = s_responseQueue->at(0);
|
||||
s_responseQueue->erase(0);
|
||||
response = _responseQueue.at(0);
|
||||
_responseQueue.erase(0);
|
||||
}
|
||||
|
||||
s_responseQueueMutex.unlock();
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (response)
|
||||
{
|
||||
|
@ -524,7 +482,122 @@ void HttpClient::dispatchResponseCallbacks()
|
|||
request->release();
|
||||
}
|
||||
}
|
||||
|
||||
// Process Response
|
||||
void HttpClient::processResponse(HttpResponse* response, char* responseMessage)
|
||||
{
|
||||
auto request = response->getHttpRequest();
|
||||
long responseCode = -1;
|
||||
int retValue = 0;
|
||||
NSString* requestType = nil;
|
||||
|
||||
// Process the request -> get response packet
|
||||
switch (request->getRequestType())
|
||||
{
|
||||
case HttpRequest::Type::GET: // HTTP GET
|
||||
requestType = @"GET";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::POST: // HTTP POST
|
||||
requestType = @"POST";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::PUT:
|
||||
requestType = @"PUT";
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::DELETE:
|
||||
requestType = @"DELETE";
|
||||
break;
|
||||
|
||||
default:
|
||||
CCASSERT(true, "CCHttpClient: unknown request type, only GET and POSt are supported");
|
||||
break;
|
||||
}
|
||||
|
||||
retValue = processTask(this,
|
||||
request,
|
||||
requestType,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
response->getResponseHeader(),
|
||||
responseMessage);
|
||||
|
||||
// write data to HttpResponse
|
||||
response->setResponseCode(responseCode);
|
||||
|
||||
if (retValue != 0)
|
||||
{
|
||||
response->setSucceed(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
response->setSucceed(false);
|
||||
response->setErrorBuffer(responseMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpClient::increaseThreadCount()
|
||||
{
|
||||
_threadCountMutex.lock();
|
||||
++_threadCount;
|
||||
_threadCountMutex.unlock();
|
||||
}
|
||||
|
||||
void HttpClient::decreaseThreadCountAndMayDeleteThis()
|
||||
{
|
||||
bool needDeleteThis = false;
|
||||
_threadCountMutex.lock();
|
||||
--_threadCount;
|
||||
if (0 == _threadCount)
|
||||
{
|
||||
needDeleteThis = true;
|
||||
}
|
||||
|
||||
_threadCountMutex.unlock();
|
||||
if (needDeleteThis)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::setTimeoutForConnect(int value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForConnectMutex);
|
||||
_timeoutForConnect = value;
|
||||
}
|
||||
|
||||
int HttpClient::getTimeoutForConnect()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForConnectMutex);
|
||||
return _timeoutForConnect;
|
||||
}
|
||||
|
||||
void HttpClient::setTimeoutForRead(int value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForReadMutex);
|
||||
_timeoutForRead = value;
|
||||
}
|
||||
|
||||
int HttpClient::getTimeoutForRead()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForReadMutex);
|
||||
return _timeoutForRead;
|
||||
}
|
||||
|
||||
const std::string& HttpClient::getCookieFilename()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_cookieFileMutex);
|
||||
return _cookieFilename;
|
||||
}
|
||||
|
||||
const std::string& HttpClient::getSSLVerification()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_sslCaFileMutex);
|
||||
return _sslCaFilename;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -25,48 +25,24 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "HttpClient.h"
|
||||
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCScheduler.h"
|
||||
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
namespace network {
|
||||
|
||||
static std::mutex s_requestQueueMutex;
|
||||
static std::mutex s_responseQueueMutex;
|
||||
|
||||
static std::condition_variable_any s_SleepCondition;
|
||||
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||
typedef int int32_t;
|
||||
#endif
|
||||
|
||||
static Vector<HttpRequest*>* s_requestQueue = nullptr;
|
||||
static Vector<HttpResponse*>* s_responseQueue = nullptr;
|
||||
|
||||
static HttpClient *s_pHttpClient = nullptr; // pointer to singleton
|
||||
|
||||
static char s_errorBuffer[CURL_ERROR_SIZE] = {0};
|
||||
static HttpClient* _httpClient = nullptr; // pointer to singleton
|
||||
|
||||
typedef size_t (*write_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
|
||||
static std::string s_cookieFilename = "";
|
||||
|
||||
static std::string s_sslCaFilename = "";
|
||||
|
||||
// Callback function used by libcurl for collect response data
|
||||
static size_t writeData(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
|
@ -94,19 +70,16 @@ static size_t writeHeaderData(void *ptr, size_t size, size_t nmemb, void *stream
|
|||
}
|
||||
|
||||
|
||||
static int processGetTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
|
||||
static int processPostTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
|
||||
static int processPutTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
|
||||
static int processDeleteTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
|
||||
static int processGetTask(HttpClient* client, HttpRequest* request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char* errorBuffer);
|
||||
static int processPostTask(HttpClient* client, HttpRequest* request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char* errorBuffer);
|
||||
static int processPutTask(HttpClient* client, HttpRequest* request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char* errorBuffer);
|
||||
static int processDeleteTask(HttpClient* client, HttpRequest* request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char* errorBuffer);
|
||||
// int processDownloadTask(HttpRequest *task, write_callback callback, void *stream, int32_t *errorCode);
|
||||
static void processResponse(HttpResponse* response, char* errorBuffer);
|
||||
|
||||
static HttpRequest *s_requestSentinel = new HttpRequest;
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThread()
|
||||
{
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
{
|
||||
increaseThreadCount();
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -114,15 +87,16 @@ void HttpClient::networkThread()
|
|||
|
||||
// step 1: send http request if the requestQueue isn't empty
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
while (s_requestQueue->empty()) {
|
||||
s_SleepCondition.wait(s_requestQueueMutex);
|
||||
std::lock_guard<std::mutex> lock(_requestQueueMutex);
|
||||
while (_requestQueue.empty())
|
||||
{
|
||||
_sleepCondition.wait(_requestQueueMutex);
|
||||
}
|
||||
request = s_requestQueue->at(0);
|
||||
s_requestQueue->erase(0);
|
||||
request = _requestQueue.at(0);
|
||||
_requestQueue.erase(0);
|
||||
}
|
||||
|
||||
if (request == s_requestSentinel) {
|
||||
if (request == _requestSentinel) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -131,62 +105,70 @@ void HttpClient::networkThread()
|
|||
// Create a HttpResponse object, the default setting is http access failed
|
||||
HttpResponse *response = new (std::nothrow) HttpResponse(request);
|
||||
|
||||
processResponse(response, s_errorBuffer);
|
||||
processResponse(response, _responseMessage);
|
||||
|
||||
|
||||
// add response packet into queue
|
||||
s_responseQueueMutex.lock();
|
||||
s_responseQueue->pushBack(response);
|
||||
s_responseQueueMutex.unlock();
|
||||
_responseQueueMutex.lock();
|
||||
_responseQueue.pushBack(response);
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (nullptr != s_pHttpClient) {
|
||||
scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
}
|
||||
_schedulerMutex.lock();
|
||||
if (nullptr != _scheduler)
|
||||
{
|
||||
_scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HttpClient::dispatchResponseCallbacks, this));
|
||||
}
|
||||
_schedulerMutex.unlock();
|
||||
}
|
||||
|
||||
// cleanup: if worker thread received quit signal, clean up un-completed request queue
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->clear();
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
|
||||
if (s_requestQueue != nullptr) {
|
||||
delete s_requestQueue;
|
||||
s_requestQueue = nullptr;
|
||||
delete s_responseQueue;
|
||||
s_responseQueue = nullptr;
|
||||
}
|
||||
_requestQueueMutex.lock();
|
||||
_requestQueue.clear();
|
||||
_requestQueueMutex.unlock();
|
||||
|
||||
_responseQueueMutex.lock();
|
||||
_responseQueue.clear();
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
decreaseThreadCountAndMayDeleteThis();
|
||||
}
|
||||
|
||||
// Worker thread
|
||||
void HttpClient::networkThreadAlone(HttpRequest* request, HttpResponse* response)
|
||||
{
|
||||
char errorBuffer[CURL_ERROR_SIZE] = { 0 };
|
||||
processResponse(response, errorBuffer);
|
||||
increaseThreadCount();
|
||||
|
||||
auto scheduler = Director::getInstance()->getScheduler();
|
||||
scheduler->performFunctionInCocosThread([response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
char responseMessage[RESPONSE_BUFFER_SIZE] = { 0 };
|
||||
processResponse(response, responseMessage);
|
||||
|
||||
_schedulerMutex.lock();
|
||||
if (nullptr != _scheduler)
|
||||
{
|
||||
_scheduler->performFunctionInCocosThread([this, response, request]{
|
||||
const ccHttpRequestCallback& callback = request->getCallback();
|
||||
Ref* pTarget = request->getTarget();
|
||||
SEL_HttpResponse pSelector = request->getSelector();
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(s_pHttpClient, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(s_pHttpClient, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(this, response);
|
||||
}
|
||||
else if (pTarget && pSelector)
|
||||
{
|
||||
(pTarget->*pSelector)(this, response);
|
||||
}
|
||||
response->release();
|
||||
// do not release in other thread
|
||||
request->release();
|
||||
});
|
||||
}
|
||||
_schedulerMutex.unlock();
|
||||
|
||||
decreaseThreadCountAndMayDeleteThis();
|
||||
}
|
||||
|
||||
//Configure curl's timeout property
|
||||
static bool configureCURL(CURL *handle, char *errorBuffer)
|
||||
static bool configureCURL(HttpClient* client, CURL* handle, char* errorBuffer)
|
||||
{
|
||||
if (!handle) {
|
||||
return false;
|
||||
|
@ -205,13 +187,15 @@ static bool configureCURL(CURL *handle, char *errorBuffer)
|
|||
if (code != CURLE_OK) {
|
||||
return false;
|
||||
}
|
||||
if (s_sslCaFilename.empty()) {
|
||||
|
||||
std::string sslCaFilename = client->getSSLVerification();
|
||||
if (sslCaFilename.empty()) {
|
||||
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
} else {
|
||||
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 2L);
|
||||
curl_easy_setopt(handle, CURLOPT_CAINFO, s_sslCaFilename.c_str());
|
||||
curl_easy_setopt(handle, CURLOPT_CAINFO, sslCaFilename.c_str());
|
||||
}
|
||||
|
||||
// FIXED #3224: The subthread of CCHttpClient interrupts main thread if timeout comes.
|
||||
|
@ -255,11 +239,11 @@ public:
|
|||
* @param callback Response write callback
|
||||
* @param stream Response write stream
|
||||
*/
|
||||
bool init(HttpRequest *request, write_callback callback, void *stream, write_callback headerCallback, void *headerStream, char *errorBuffer)
|
||||
bool init(HttpClient* client, HttpRequest* request, write_callback callback, void* stream, write_callback headerCallback, void* headerStream, char* errorBuffer)
|
||||
{
|
||||
if (!_curl)
|
||||
return false;
|
||||
if (!configureCURL(_curl, errorBuffer))
|
||||
if (!configureCURL(client, _curl, errorBuffer))
|
||||
return false;
|
||||
|
||||
/* get custom header data (if set) */
|
||||
|
@ -273,11 +257,12 @@ public:
|
|||
if (!setOption(CURLOPT_HTTPHEADER, _headers))
|
||||
return false;
|
||||
}
|
||||
if (!s_cookieFilename.empty()) {
|
||||
if (!setOption(CURLOPT_COOKIEFILE, s_cookieFilename.c_str())) {
|
||||
std::string cookieFilename = client->getCookieFilename();
|
||||
if (!cookieFilename.empty()) {
|
||||
if (!setOption(CURLOPT_COOKIEFILE, cookieFilename.c_str())) {
|
||||
return false;
|
||||
}
|
||||
if (!setOption(CURLOPT_COOKIEJAR, s_cookieFilename.c_str())) {
|
||||
if (!setOption(CURLOPT_COOKIEJAR, cookieFilename.c_str())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -307,20 +292,20 @@ public:
|
|||
};
|
||||
|
||||
//Process Get Request
|
||||
static int processGetTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
|
||||
static int processGetTask(HttpClient* client, HttpRequest* request, write_callback callback, void* stream, long* responseCode, write_callback headerCallback, void* headerStream, char* errorBuffer)
|
||||
{
|
||||
CURLRaii curl;
|
||||
bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
bool ok = curl.init(client, request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
&& curl.setOption(CURLOPT_FOLLOWLOCATION, true)
|
||||
&& curl.perform(responseCode);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
//Process POST Request
|
||||
static int processPostTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
|
||||
static int processPostTask(HttpClient* client, HttpRequest* request, write_callback callback, void* stream, long* responseCode, write_callback headerCallback, void* headerStream, char* errorBuffer)
|
||||
{
|
||||
CURLRaii curl;
|
||||
bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
bool ok = curl.init(client, request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
&& curl.setOption(CURLOPT_POST, 1)
|
||||
&& curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData())
|
||||
&& curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize())
|
||||
|
@ -329,10 +314,10 @@ static int processPostTask(HttpRequest *request, write_callback callback, void *
|
|||
}
|
||||
|
||||
//Process PUT Request
|
||||
static int processPutTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
|
||||
static int processPutTask(HttpClient* client, HttpRequest* request, write_callback callback, void* stream, long* responseCode, write_callback headerCallback, void* headerStream, char* errorBuffer)
|
||||
{
|
||||
CURLRaii curl;
|
||||
bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
bool ok = curl.init(client, request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
&& curl.setOption(CURLOPT_CUSTOMREQUEST, "PUT")
|
||||
&& curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData())
|
||||
&& curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize())
|
||||
|
@ -341,146 +326,105 @@ static int processPutTask(HttpRequest *request, write_callback callback, void *s
|
|||
}
|
||||
|
||||
//Process DELETE Request
|
||||
static int processDeleteTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
|
||||
static int processDeleteTask(HttpClient* client, HttpRequest* request, write_callback callback, void* stream, long* responseCode, write_callback headerCallback, void* headerStream, char* errorBuffer)
|
||||
{
|
||||
CURLRaii curl;
|
||||
bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
bool ok = curl.init(client, request, callback, stream, headerCallback, headerStream, errorBuffer)
|
||||
&& curl.setOption(CURLOPT_CUSTOMREQUEST, "DELETE")
|
||||
&& curl.setOption(CURLOPT_FOLLOWLOCATION, true)
|
||||
&& curl.perform(responseCode);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
// Process Response
|
||||
static void processResponse(HttpResponse* response, char* errorBuffer)
|
||||
{
|
||||
auto request = response->getHttpRequest();
|
||||
long responseCode = -1;
|
||||
int retValue = 0;
|
||||
|
||||
// Process the request -> get response packet
|
||||
switch (request->getRequestType())
|
||||
{
|
||||
case HttpRequest::Type::GET: // HTTP GET
|
||||
retValue = processGetTask(request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
errorBuffer);
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::POST: // HTTP POST
|
||||
retValue = processPostTask(request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
errorBuffer);
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::PUT:
|
||||
retValue = processPutTask(request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
errorBuffer);
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::DELETE:
|
||||
retValue = processDeleteTask(request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
errorBuffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
CCASSERT(true, "CCHttpClient: unknown request type, only GET and POSt are supported");
|
||||
break;
|
||||
}
|
||||
|
||||
// write data to HttpResponse
|
||||
response->setResponseCode(responseCode);
|
||||
|
||||
if (retValue != 0)
|
||||
{
|
||||
response->setSucceed(false);
|
||||
response->setErrorBuffer(errorBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
response->setSucceed(true);
|
||||
}
|
||||
}
|
||||
|
||||
// HttpClient implementation
|
||||
HttpClient* HttpClient::getInstance()
|
||||
{
|
||||
if (s_pHttpClient == nullptr) {
|
||||
s_pHttpClient = new (std::nothrow) HttpClient();
|
||||
if (_httpClient == nullptr)
|
||||
{
|
||||
_httpClient = new (std::nothrow) HttpClient();
|
||||
}
|
||||
|
||||
return s_pHttpClient;
|
||||
return _httpClient;
|
||||
}
|
||||
|
||||
void HttpClient::destroyInstance()
|
||||
{
|
||||
CC_SAFE_DELETE(s_pHttpClient);
|
||||
if (nullptr == _httpClient)
|
||||
{
|
||||
CCLOG("HttpClient singleton is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
CCLOG("HttpClient::destroyInstance begin");
|
||||
auto thiz = _httpClient;
|
||||
_httpClient = nullptr;
|
||||
|
||||
thiz->_scheduler->unscheduleAllForTarget(thiz);
|
||||
thiz->_schedulerMutex.lock();
|
||||
thiz->_scheduler = nullptr;
|
||||
thiz->_schedulerMutex.unlock();
|
||||
|
||||
thiz->_requestQueueMutex.lock();
|
||||
thiz->_requestQueue.pushBack(thiz->_requestSentinel);
|
||||
thiz->_requestQueueMutex.unlock();
|
||||
|
||||
thiz->_sleepCondition.notify_one();
|
||||
thiz->decreaseThreadCountAndMayDeleteThis();
|
||||
|
||||
CCLOG("HttpClient::destroyInstance() finished!");
|
||||
}
|
||||
|
||||
void HttpClient::enableCookies(const char* cookieFile) {
|
||||
if (cookieFile) {
|
||||
s_cookieFilename = std::string(cookieFile);
|
||||
void HttpClient::enableCookies(const char* cookieFile)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_cookieFileMutex);
|
||||
if (cookieFile)
|
||||
{
|
||||
_cookieFilename = std::string(cookieFile);
|
||||
}
|
||||
else {
|
||||
s_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
else
|
||||
{
|
||||
_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::setSSLVerification(const std::string& caFile)
|
||||
{
|
||||
s_sslCaFilename = caFile;
|
||||
std::lock_guard<std::mutex> lock(_sslCaFileMutex);
|
||||
_sslCaFilename = caFile;
|
||||
}
|
||||
|
||||
HttpClient::HttpClient()
|
||||
: _timeoutForConnect(30)
|
||||
, _timeoutForRead(60)
|
||||
, _isInited(false)
|
||||
, _threadCount(0)
|
||||
, _requestSentinel(new HttpRequest())
|
||||
, _cookie(nullptr)
|
||||
{
|
||||
CCLOG("In the constructor of HttpClient!");
|
||||
memset(_responseMessage, 0, RESPONSE_BUFFER_SIZE * sizeof(char));
|
||||
_scheduler = Director::getInstance()->getScheduler();
|
||||
increaseThreadCount();
|
||||
}
|
||||
|
||||
HttpClient::~HttpClient()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||
s_requestQueue->pushBack(s_requestSentinel);
|
||||
}
|
||||
s_SleepCondition.notify_one();
|
||||
}
|
||||
|
||||
s_pHttpClient = nullptr;
|
||||
CC_SAFE_DELETE(_requestSentinel);
|
||||
CCLOG("HttpClient destructor");
|
||||
}
|
||||
|
||||
//Lazy create semaphore & mutex & thread
|
||||
bool HttpClient::lazyInitThreadSemphore()
|
||||
{
|
||||
if (s_requestQueue != nullptr) {
|
||||
if (_isInited)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
|
||||
s_requestQueue = new (std::nothrow) Vector<HttpRequest*>();
|
||||
s_responseQueue = new (std::nothrow) Vector<HttpResponse*>();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
|
||||
t.detach();
|
||||
_isInited = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -500,15 +444,13 @@ void HttpClient::send(HttpRequest* request)
|
|||
}
|
||||
|
||||
request->retain();
|
||||
|
||||
if (nullptr != s_requestQueue) {
|
||||
s_requestQueueMutex.lock();
|
||||
s_requestQueue->pushBack(request);
|
||||
s_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
s_SleepCondition.notify_one();
|
||||
}
|
||||
|
||||
_requestQueueMutex.lock();
|
||||
_requestQueue.pushBack(request);
|
||||
_requestQueueMutex.unlock();
|
||||
|
||||
// Notify thread start to work
|
||||
_sleepCondition.notify_one();
|
||||
}
|
||||
|
||||
void HttpClient::sendImmediate(HttpRequest* request)
|
||||
|
@ -531,20 +473,15 @@ void HttpClient::dispatchResponseCallbacks()
|
|||
{
|
||||
// log("CCHttpClient::dispatchResponseCallbacks is running");
|
||||
//occurs when cocos thread fires but the network thread has already quited
|
||||
if (nullptr == s_responseQueue) {
|
||||
return;
|
||||
}
|
||||
HttpResponse* response = nullptr;
|
||||
|
||||
s_responseQueueMutex.lock();
|
||||
|
||||
if (!s_responseQueue->empty())
|
||||
_responseQueueMutex.lock();
|
||||
if (!_responseQueue.empty())
|
||||
{
|
||||
response = s_responseQueue->at(0);
|
||||
s_responseQueue->erase(0);
|
||||
response = _responseQueue.at(0);
|
||||
_responseQueue.erase(0);
|
||||
}
|
||||
|
||||
s_responseQueueMutex.unlock();
|
||||
_responseQueueMutex.unlock();
|
||||
|
||||
if (response)
|
||||
{
|
||||
|
@ -568,6 +505,134 @@ void HttpClient::dispatchResponseCallbacks()
|
|||
}
|
||||
}
|
||||
|
||||
// Process Response
|
||||
void HttpClient::processResponse(HttpResponse* response, char* responseMessage)
|
||||
{
|
||||
auto request = response->getHttpRequest();
|
||||
long responseCode = -1;
|
||||
int retValue = 0;
|
||||
|
||||
// Process the request -> get response packet
|
||||
switch (request->getRequestType())
|
||||
{
|
||||
case HttpRequest::Type::GET: // HTTP GET
|
||||
retValue = processGetTask(this, request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
responseMessage);
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::POST: // HTTP POST
|
||||
retValue = processPostTask(this, request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
responseMessage);
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::PUT:
|
||||
retValue = processPutTask(this, request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
responseMessage);
|
||||
break;
|
||||
|
||||
case HttpRequest::Type::DELETE:
|
||||
retValue = processDeleteTask(this, request,
|
||||
writeData,
|
||||
response->getResponseData(),
|
||||
&responseCode,
|
||||
writeHeaderData,
|
||||
response->getResponseHeader(),
|
||||
responseMessage);
|
||||
break;
|
||||
|
||||
default:
|
||||
CCASSERT(true, "CCHttpClient: unknown request type, only GET and POSt are supported");
|
||||
break;
|
||||
}
|
||||
|
||||
// write data to HttpResponse
|
||||
response->setResponseCode(responseCode);
|
||||
if (retValue != 0)
|
||||
{
|
||||
response->setSucceed(false);
|
||||
response->setErrorBuffer(responseMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
response->setSucceed(true);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::increaseThreadCount()
|
||||
{
|
||||
_threadCountMutex.lock();
|
||||
++_threadCount;
|
||||
_threadCountMutex.unlock();
|
||||
}
|
||||
|
||||
void HttpClient::decreaseThreadCountAndMayDeleteThis()
|
||||
{
|
||||
bool needDeleteThis = false;
|
||||
_threadCountMutex.lock();
|
||||
--_threadCount;
|
||||
if (0 == _threadCount)
|
||||
{
|
||||
needDeleteThis = true;
|
||||
}
|
||||
|
||||
_threadCountMutex.unlock();
|
||||
if (needDeleteThis)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::setTimeoutForConnect(int value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForConnectMutex);
|
||||
_timeoutForConnect = value;
|
||||
}
|
||||
|
||||
int HttpClient::getTimeoutForConnect()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForConnectMutex);
|
||||
return _timeoutForConnect;
|
||||
}
|
||||
|
||||
void HttpClient::setTimeoutForRead(int value)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForReadMutex);
|
||||
_timeoutForRead = value;
|
||||
}
|
||||
|
||||
int HttpClient::getTimeoutForRead()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_timeoutForReadMutex);
|
||||
return _timeoutForRead;
|
||||
}
|
||||
|
||||
const std::string& HttpClient::getCookieFilename()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_cookieFileMutex);
|
||||
return _cookieFilename;
|
||||
}
|
||||
|
||||
const std::string& HttpClient::getSSLVerification()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_sslCaFileMutex);
|
||||
return _sslCaFilename;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -27,8 +27,13 @@
|
|||
#ifndef __CCHTTPCLIENT_H__
|
||||
#define __CCHTTPCLIENT_H__
|
||||
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCScheduler.h"
|
||||
#include "network/HttpRequest.h"
|
||||
#include "network/HttpResponse.h"
|
||||
#include "network/HttpCookie.h"
|
||||
|
||||
/**
|
||||
* @addtogroup core
|
||||
|
@ -38,6 +43,8 @@
|
|||
NS_CC_BEGIN
|
||||
|
||||
namespace network {
|
||||
|
||||
|
||||
|
||||
/** Singleton that handles asynchrounous http requests.
|
||||
*
|
||||
|
@ -48,6 +55,11 @@ namespace network {
|
|||
class CC_DLL HttpClient
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The buffer size of _responseMessage
|
||||
*/
|
||||
static const int RESPONSE_BUFFER_SIZE = 256;
|
||||
|
||||
/**
|
||||
* Get instance of HttpClient.
|
||||
*
|
||||
|
@ -67,12 +79,26 @@ public:
|
|||
*/
|
||||
void enableCookies(const char* cookieFile);
|
||||
|
||||
/**
|
||||
* Get the cookie filename
|
||||
*
|
||||
* @return the cookie filename
|
||||
*/
|
||||
const std::string& getCookieFilename();
|
||||
|
||||
/**
|
||||
* Set root certificate path for SSL verification.
|
||||
*
|
||||
* @param caFile a full path of root certificate.if it is empty, SSL verification is disabled.
|
||||
*/
|
||||
void setSSLVerification(const std::string& caFile);
|
||||
|
||||
/**
|
||||
* Get ths ssl CA filename
|
||||
*
|
||||
* @return the ssl CA filename
|
||||
*/
|
||||
const std::string& getSSLVerification();
|
||||
|
||||
/**
|
||||
* Add a get request to task queue
|
||||
|
@ -89,38 +115,40 @@ public:
|
|||
please make sure request->_requestData is clear before calling "sendImmediate" here.
|
||||
*/
|
||||
void sendImmediate(HttpRequest* request);
|
||||
|
||||
|
||||
/**
|
||||
* Set the timeout value for connecting.
|
||||
*
|
||||
* @param value the timeout value for connecting.
|
||||
*/
|
||||
inline void setTimeoutForConnect(int value) {_timeoutForConnect = value;};
|
||||
void setTimeoutForConnect(int value);
|
||||
|
||||
/**
|
||||
* Get the timeout value for connecting.
|
||||
*
|
||||
* @return int the timeout value for connecting.
|
||||
*/
|
||||
inline int getTimeoutForConnect() {return _timeoutForConnect;}
|
||||
|
||||
int getTimeoutForConnect();
|
||||
|
||||
/**
|
||||
* Set the timeout value for reading.
|
||||
*
|
||||
* @param value the timeout value for reading.
|
||||
*/
|
||||
inline void setTimeoutForRead(int value) {_timeoutForRead = value;};
|
||||
|
||||
void setTimeoutForRead(int value);
|
||||
|
||||
/**
|
||||
* Get the timeout value for reading.
|
||||
*
|
||||
* @return int the timeout value for reading.
|
||||
*/
|
||||
inline int getTimeoutForRead() {return _timeoutForRead;};
|
||||
|
||||
int getTimeoutForRead();
|
||||
|
||||
HttpCookie* getCookie() const {return _cookie; }
|
||||
|
||||
std::mutex& getCookieFileMutex() {return _cookieFileMutex;}
|
||||
|
||||
std::mutex& getSSLCaFileMutex() {return _sslCaFileMutex;}
|
||||
private:
|
||||
HttpClient();
|
||||
virtual ~HttpClient();
|
||||
|
@ -136,9 +164,44 @@ private:
|
|||
/** Poll function called from main thread to dispatch callbacks when http requests finished **/
|
||||
void dispatchResponseCallbacks();
|
||||
|
||||
void processResponse(HttpResponse* response, char* responseMessage);
|
||||
void increaseThreadCount();
|
||||
void decreaseThreadCountAndMayDeleteThis();
|
||||
|
||||
private:
|
||||
bool _isInited;
|
||||
|
||||
int _timeoutForConnect;
|
||||
std::mutex _timeoutForConnectMutex;
|
||||
|
||||
int _timeoutForRead;
|
||||
std::mutex _timeoutForReadMutex;
|
||||
|
||||
int _threadCount;
|
||||
std::mutex _threadCountMutex;
|
||||
|
||||
Scheduler* _scheduler;
|
||||
std::mutex _schedulerMutex;
|
||||
|
||||
Vector<HttpRequest*> _requestQueue;
|
||||
std::mutex _requestQueueMutex;
|
||||
|
||||
Vector<HttpResponse*> _responseQueue;
|
||||
std::mutex _responseQueueMutex;
|
||||
|
||||
std::string _cookieFilename;
|
||||
std::mutex _cookieFileMutex;
|
||||
|
||||
std::string _sslCaFilename;
|
||||
std::mutex _sslCaFileMutex;
|
||||
|
||||
HttpCookie* _cookie;
|
||||
|
||||
std::condition_variable_any _sleepCondition;
|
||||
|
||||
char _responseMessage[RESPONSE_BUFFER_SIZE];
|
||||
|
||||
HttpRequest* _requestSentinel;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -148,4 +211,4 @@ NS_CC_END
|
|||
// end group
|
||||
/// @}
|
||||
|
||||
#endif //__CCHTTPREQUEST_H__
|
||||
#endif //__CCHTTPCLIENT_H__
|
||||
|
|
|
@ -941,23 +941,6 @@ std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& dir
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string FileUtils::searchFullPathForFilename(const std::string& filename) const
|
||||
{
|
||||
if (isAbsolutePath(filename))
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
std::string path = fullPathForFilename(filename);
|
||||
if (0 == path.compare(filename))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
bool FileUtils::isFileExist(const std::string& filename) const
|
||||
{
|
||||
if (isAbsolutePath(filename))
|
||||
|
@ -966,7 +949,7 @@ bool FileUtils::isFileExist(const std::string& filename) const
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string fullpath = searchFullPathForFilename(filename);
|
||||
std::string fullpath = fullPathForFilename(filename);
|
||||
if (fullpath.empty())
|
||||
return false;
|
||||
else
|
||||
|
@ -1327,7 +1310,7 @@ long FileUtils::getFileSize(const std::string &filepath)
|
|||
std::string fullpath = filepath;
|
||||
if (!isAbsolutePath(filepath))
|
||||
{
|
||||
fullpath = searchFullPathForFilename(filepath);
|
||||
fullpath = fullPathForFilename(filepath);
|
||||
if (fullpath.empty())
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -478,16 +478,6 @@ protected:
|
|||
*/
|
||||
virtual std::string getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const;
|
||||
|
||||
/**
|
||||
* Returns the fullpath for a given filename.
|
||||
* This is an alternative for fullPathForFilename
|
||||
* It returns empty string instead of the original filename when no file found for the given name.
|
||||
* @param filename The file name to look up for
|
||||
* @return The full path for the file, if not found, the return value will be an empty string
|
||||
*/
|
||||
virtual std::string searchFullPathForFilename(const std::string& filename) const;
|
||||
|
||||
|
||||
/** Dictionary used to lookup filenames based on a key.
|
||||
* It is used internally by the following methods:
|
||||
*
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.cocos2dx.lib">
|
||||
|
||||
<application android:allowBackup="true">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,29 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "22.0.1"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 10
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
sourceSets.main {
|
||||
java.srcDirs = ['../java/src','../ControllerManualAdapter/src']
|
||||
manifest.srcFile "AndroidManifest.xml"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: '../ControllerManualAdapter/libs', include: ['*.jar'])
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1,7 @@
|
|||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.cocos2dx.lib">
|
||||
|
||||
<application android:allowBackup="true" android:label="libcocos2dx">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,29 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "22.0.1"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 10
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
sourceSets.main {
|
||||
java.srcDir "../java/src"
|
||||
manifest.srcFile "AndroidManifest.xml"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -60,6 +60,20 @@ THE SOFTWARE.
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if _MSC_VER > 1800
|
||||
#pragma comment(lib,"libpng-2015.lib")
|
||||
#pragma comment(lib,"libjpeg-2015.lib")
|
||||
#pragma comment(lib,"libtiff-2015.lib")
|
||||
#pragma comment(lib,"glfw3-2015.lib")
|
||||
#pragma comment(lib,"libchipmunk-2015.lib")
|
||||
#else
|
||||
#pragma comment(lib,"libpng.lib")
|
||||
#pragma comment(lib,"libjpeg.lib")
|
||||
#pragma comment(lib,"libtiff.lib")
|
||||
#pragma comment(lib,"glfw3.lib")
|
||||
#pragma comment(lib,"libchipmunk.lib")
|
||||
#endif
|
||||
|
||||
#endif //s CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
|
||||
#endif /* __CCPLATFORMDEFINE_H__*/
|
||||
|
|
|
@ -134,7 +134,10 @@ bool CCFileUtilsWinRT::isAbsolutePath(const std::string& strPath) const
|
|||
|
||||
static Data getData(const std::string& filename, bool forString)
|
||||
{
|
||||
CCASSERT(!filename.empty(), "Invalid filename!");
|
||||
if (filename.empty())
|
||||
{
|
||||
CCASSERT(!filename.empty(), "Invalid filename!");
|
||||
}
|
||||
|
||||
Data ret;
|
||||
unsigned char* buffer = nullptr;
|
||||
|
|
|
@ -104,6 +104,7 @@ Platform::String^ PlatformStringFromString(const std::string& s)
|
|||
return ref new Platform::String(ws.data(), ws.length());
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
|
||||
float ConvertDipsToPixels(float dips)
|
||||
{
|
||||
|
@ -115,7 +116,7 @@ float getScaledDPIValue(float v) {
|
|||
auto dipFactor = DisplayProperties::LogicalDpi / 96.0f;
|
||||
return v * dipFactor;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CC_DLL CCLogIPAddresses()
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue