[engine] [cocos2d-x] [jsb-adapter] 适配引擎 v2.4.12 版本

This commit is contained in:
SmallMain 2023-10-30 22:32:32 +08:00
parent 2508616ad9
commit 0092eb9f05
787 changed files with 206249 additions and 422 deletions

908
cocos2d-x/CMakeLists.txt Normal file
View File

@ -0,0 +1,908 @@
set(CC_PLATFORM_OPENHARMONY 14)
add_definitions(-DCC_PLATFORM_OPENHARMONY=${CC_PLATFORM_OPENHARMONY})
set(CC_PLATFORM ${CC_PLATFORM_OPENHARMONY})
add_definitions(-DOPENHARMONY=${CC_PLATFORM_OPENHARMONY})
add_definitions(-DCC_PLATFORM=${CC_PLATFORM})
set(CMAKE_CXX_FLAGS "-fvisibility=hidden -fvisibility-inlines-hidden ${CMAKE_CXX_FLAGS}")
if("${OHOS_ARCH}" STREQUAL "armeabi-v7a")
set(CMAKE_CXX_FLAGS "-march=armv7a ${CMAKE_CXX_FLAGS}")
endif()
MESSAGE(STATUS "platform: ${CMAKE_SYSTEM_NAME}")
################################# engine source code ##################################
set(CC_COCOS_SOURCES)
set(ENGINE_NAME cocos_engine)
# Should be enable someday in the future
# set(CMAKE_CXX_FLAGS "${WERROR_FLAGS}")
################################# options ############################################
option(CC_USE_GFX_RENDERER "GFX Render" ON)
option(CC_USE_VIDEO "Enable VideoPlayer Component" ON)
option(CC_USE_WEBVIEW "Enable WebView Component" ON)
option(CC_USE_AUDIO "Enable Audio" ON)
option(CC_USE_SOCKET "Enable WebSocket & SocketIO" ON)
option(CC_USE_WEBSOCKET_SERVER "Enable WebSocket Server" OFF)
option(CC_USE_MIDDLEWARE "Enable Middleware" ON)
option(CC_USE_SPINE "Enable Spine" ON)
option(CC_USE_DRAGONBONES "Enable Dragonbones" ON)
option(CC_USE_SE_NAPI "Enable Dragonbones" ON)
option(CC_USE_PARTICLE "Enable Particle" ON)
################################# external source code ################################
set(EXTERNAL_ROOT ${CMAKE_CURRENT_LIST_DIR}/external)
if(NOT EXISTS ${EXTERNAL_ROOT}/CMakeLists.txt)
message(FATAL_ERROR "Please download external libraries! File ${CMAKE_CURRENT_LIST_DIR}/external/CMakeLists.txt not exist!")
endif()
include_directories(${EXTERNAL_ROOT}/sources)
include(${EXTERNAL_ROOT}/CMakeLists.txt)
################################# cocos engine source code ################################
##### cocos2d
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/cocos2d.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/cocos2d.h
)
##### platform
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCPlatformDefine.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/CCPlatformDefine-openharmony.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/WorkerMessageQueue.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/WorkerMessageQueue.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/FileUtils-openharmony.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/FileUtils-openharmony.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/CCGL-openharmony.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/CCDevice-openharmony.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/OpenHarmonyPlatform.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/OpenHarmonyPlatform.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/render/egl_core.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/render/egl_core.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCDevice.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCApplication.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCCanvasRenderingContext2D.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCFileUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCFileUtils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCGL.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCImage.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCImage.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCPlatformConfig.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCSAXParser.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCSAXParser.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/CCStdC.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/AppDelegate.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/AppDelegate.h
)
##### base
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/base/astc.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/astc.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/base64.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/base64.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCAutoreleasePool.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCAutoreleasePool.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccCArray.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccCArray.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccConfig.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCConfiguration.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCConfiguration.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCGLUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCGLUtils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCLog.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCLog.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccMacros.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCMap.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccRandom.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccRandom.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCRef.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCRef.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCRefPtr.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCRenderTexture.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCRenderTexture.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCScheduler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCScheduler.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCThreadPool.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCThreadPool.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccTypes.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccTypes.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccUTF8.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccUTF8.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ccUtils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCValue.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCValue.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/CCVector.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/csscolorparser.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/csscolorparser.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/etc1.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/etc1.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/etc2.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/etc2.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/pvr.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/pvr.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/TGAlib.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/TGAlib.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/uthash.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/utlist.h
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ZipUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/base/ZipUtils.h
)
##### 2d
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCFontAtlas.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCFontAtlas.h
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCFontFreetype.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCFontFreetype.h
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCLabelLayout.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCLabelLayout.h
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCTTFLabelAtlasCache.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCTTFLabelAtlasCache.h
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCTTFLabelRenderer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCTTFLabelRenderer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCTTFTypes.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/2d/CCTTFTypes.h
)
##### math
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/math/CCGeometry.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/CCGeometry.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/CCMath.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/CCMathBase.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/CCVertex.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/CCVertex.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Mat3.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Mat3.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Mat4.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Mat4.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/MathUtil.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/MathUtil.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Quaternion.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Quaternion.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Vec2.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Vec2.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Vec3.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Vec3.h
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Vec4.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/math/Vec4.h
)
##### network
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/network/CCDownloader.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/CCDownloader.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/CCDownloader-curl.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/CCDownloader-curl.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/CCIDownloaderImpl.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/HttpClient.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/HttpClient.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/HttpCookie.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/HttpCookie.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/HttpRequest.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/HttpResponse.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/Uri.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/Uri.h
)
##### js-bindg event
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/event/CustomEventTypes.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/event/EventDispatcher.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/event/EventDispatcher.h
)
##### jswrapper
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/config.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/config.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/HandleObject.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/HandleObject.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/MappingUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/MappingUtils.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/Object.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/RefCounter.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/RefCounter.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/SeApi.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/State.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/State.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/Value.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/Value.hpp
)
##### napi script engine
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/Class.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/Class.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/CommonHeader.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/HelperMacros.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/HelperMacros.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/native_common.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/Object.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/Object.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/ScriptEngine.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/ScriptEngine.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/SeApi.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/Utils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi/Utils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/napi/NapiHelper.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/napi/NapiHelper.h
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/napi/NapiInit.cpp
)
##### CCDevice CCApplication modules:screensystem
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/modules/CCApplication-openharmony.cpp
)
##### js-bindings manual
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_classtype.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_classtype.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_cocos2dx_manual.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_cocos2dx_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_cocos2dx_network_manual.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_cocos2dx_network_manual.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_conversions.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_conversions.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_global.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_global.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_helper.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_helper.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_module_register.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_module_register.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_node.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_opengl_manual.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_opengl_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_opengl_utils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_opengl_utils.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_platform.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_websocket.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_websocket.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_xmlhttprequest.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_xmlhttprequest.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_platform_openharmony.cpp
)
##### js-bindings auto
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_editor_support_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_editor_support_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_extension_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_extension_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_network_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_network_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_particle_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_webview_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_gfx_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_gfx_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_renderer_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_cocos2dx_extension_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_spine_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_dragonbones_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_dragonbones_manual.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_webview_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_audioengine_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_websocket.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_socketio.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_websocket_server.hpp
)
##### canvas rendering
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/modules/CCCanvasRenderingContext2D-openharmony.cpp
)
##### localstorage
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/storage/local-storage/LocalStorage.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/storage/local-storage/LocalStorage.h
)
##### edit-box
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/ui/edit-box/EditBox.h
${CMAKE_CURRENT_LIST_DIR}/cocos/ui/edit-box/EditBox-openharmony.h
${CMAKE_CURRENT_LIST_DIR}/cocos/ui/edit-box/EditBox-openharmony.cpp
)
##### editor-support
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/IOBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/IOBuffer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/IOTypedArray.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/IOTypedArray.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/MeshBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/MeshBuffer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/middleware-adapter.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/middleware-adapter.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/MiddlewareMacro.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/MiddlewareManager.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/MiddlewareManager.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/TypedArrayPool.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/TypedArrayPool.h
)
##### extensions
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/extensions/cocos-ext.h
${CMAKE_CURRENT_LIST_DIR}/extensions/ExtensionExport.h
${CMAKE_CURRENT_LIST_DIR}/extensions/ExtensionMacros.h
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/AssetsManagerEx.cpp
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/AssetsManagerEx.h
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/CCAsyncTaskPool.cpp
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/CCAsyncTaskPool.h
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/CCEventAssetsManagerEx.cpp
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/CCEventAssetsManagerEx.h
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/Manifest.cpp
${CMAKE_CURRENT_LIST_DIR}/extensions/assets-manager/Manifest.h
)
##### USE_GFX_RENDERER
if(CC_USE_GFX_RENDERER)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/Types.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/Types.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/Macro.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/DeviceGraphics.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/DeviceGraphics.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/FrameBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/FrameBuffer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/GFX.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/GFX.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/GFXUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/GFXUtils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/GraphicsHandle.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/GraphicsHandle.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/IndexBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/IndexBuffer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/Program.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/Program.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/RenderBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/RenderBuffer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/RenderTarget.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/RenderTarget.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/State.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/State.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/Texture.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/Texture.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/Texture2D.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/Texture2D.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/VertexBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/VertexBuffer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/VertexFormat.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx/VertexFormat.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/BaseRenderer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/BaseRenderer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Camera.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Camera.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Config.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Config.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Effect.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Effect.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/EffectBase.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/EffectBase.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/EffectVariant.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/EffectVariant.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/ForwardRenderer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/ForwardRenderer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/INode.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/InputAssembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/InputAssembler.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Light.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Light.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Model.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Model.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Pass.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Pass.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/ProgramLib.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/ProgramLib.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Renderer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/RendererUtils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/RendererUtils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Scene.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Scene.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Technique.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/Technique.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/View.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer/View.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/Assembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/Assembler.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/AssemblerBase.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/AssemblerBase.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/AssemblerSprite.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/AssemblerSprite.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/CustomAssembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/CustomAssembler.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/MaskAssembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/MaskAssembler.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/MeshAssembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/MeshAssembler.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/Particle3DAssembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/Particle3DAssembler.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/RenderData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/RenderData.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/RenderDataList.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/RenderDataList.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SimpleSprite2D.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SimpleSprite2D.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SimpleSprite3D.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SimpleSprite3D.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SlicedSprite2D.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SlicedSprite2D.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SlicedSprite3D.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/SlicedSprite3D.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/TiledMapAssembler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler/TiledMapAssembler.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/MemPool.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/MemPool.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/MeshBuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/MeshBuffer.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/ModelBatcher.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/ModelBatcher.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/NodeMemPool.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/NodeMemPool.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/NodeProxy.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/NodeProxy.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/ParallelTask.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/ParallelTask.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/RenderFlow.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/RenderFlow.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/scene-bindings.h
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/StencilManager.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/StencilManager.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/memop/RecyclePool.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_gfx_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_renderer_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_renderer_manual.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_gfx_manual.cpp
)
endif() # USE_GFX_RENDERER
##### CC_USE_SPINE
if(CC_USE_SPINE)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Animation.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Animation.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AnimationState.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AnimationState.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AnimationStateData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AnimationStateData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Atlas.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Atlas.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AtlasAttachmentLoader.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AtlasAttachmentLoader.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Attachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Attachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AttachmentLoader.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AttachmentLoader.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AttachmentTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AttachmentTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/AttachmentType.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/BlendMode.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Bone.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Bone.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/BoneData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/BoneData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/BoundingBoxAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/BoundingBoxAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ClippingAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ClippingAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Color.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ColorTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ColorTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Constraint.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Constraint.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ConstraintData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ConstraintData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ContainerUtil.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/CurveTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/CurveTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Debug.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/DeformTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/DeformTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/dll.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/DrawOrderTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/DrawOrderTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Event.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Event.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/EventData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/EventData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/EventTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/EventTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Extension.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Extension.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/HashMap.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/HasRendererObject.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/IkConstraint.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/IkConstraint.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/IkConstraintData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/IkConstraintData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/IkConstraintTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/IkConstraintTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Json.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Json.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/LinkedMesh.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/LinkedMesh.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/MathUtil.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/MathUtil.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/MeshAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/MeshAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/MixBlend.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/MixDirection.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraint.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraint.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintMixTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintMixTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintPositionTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintPositionTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintSpacingTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PathConstraintSpacingTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PointAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PointAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Pool.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/PositionMode.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RegionAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RegionAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RotateMode.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RotateTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RotateTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RTTI.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/RTTI.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ScaleTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ScaleTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ShearTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/ShearTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Skeleton.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Skeleton.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonBinary.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonBinary.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonBounds.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonBounds.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonClipping.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonClipping.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonJson.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SkeletonJson.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Skin.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Skin.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Slot.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Slot.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SlotData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SlotData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SpacingMode.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/spine.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SpineObject.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SpineObject.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/SpineString.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TextureLoader.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TextureLoader.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Timeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Timeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TimelineType.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformConstraint.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformConstraint.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformConstraintData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformConstraintData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformConstraintTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformConstraintTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TransformMode.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TranslateTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TranslateTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Triangulator.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Triangulator.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TwoColorTimeline.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/TwoColorTimeline.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Updatable.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Updatable.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Vector.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/VertexAttachment.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/VertexAttachment.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/VertexEffect.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/VertexEffect.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine/Vertices.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/AttachmentVertices.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/AttachmentVertices.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/AttachUtil.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/AttachUtil.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonAnimation.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonCache.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonCache.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonCacheMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonCacheMgr.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonDataMgr.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/SkeletonRenderer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/spine-cocos2dx.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/spine-cocos2dx.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/VertexEffectDelegate.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support/VertexEffectDelegate.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_spine_manual.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.cpp
)
endif() # CC_USE_SPINE
##### CC_USE_DRAGONBONES
if(CC_USE_DRAGONBONES)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/DragonBonesHeaders.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/Animation.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/Animation.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/AnimationState.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/AnimationState.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/BaseTimelineState.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/BaseTimelineState.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/IAnimatable.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/TimelineState.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/TimelineState.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/WorldClock.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/animation/WorldClock.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Armature.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Armature.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Bone.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Bone.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Constraint.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Constraint.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/DeformVertices.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/DeformVertices.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/IArmatureProxy.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Slot.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/Slot.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/TransformObject.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/armature/TransformObject.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/core/BaseObject.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/core/BaseObject.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/core/DragonBones.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/core/DragonBones.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/event/EventObject.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/event/EventObject.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/event/IEventDispatcher.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/factory/BaseFactory.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/factory/BaseFactory.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/ColorTransform.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/Matrix.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/Point.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/Point.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/Rectangle.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/Transform.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/geom/Transform.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/AnimationConfig.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/AnimationConfig.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/AnimationData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/AnimationData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/ArmatureData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/ArmatureData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/BoundingBoxData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/BoundingBoxData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/CanvasData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/CanvasData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/ConstraintData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/ConstraintData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/DisplayData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/DisplayData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/DragonBonesData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/DragonBonesData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/SkinData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/SkinData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/TextureAtlasData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/TextureAtlasData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/UserData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/model/UserData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/parser/BinaryDataParser.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/parser/BinaryDataParser.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/parser/DataParser.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/parser/DataParser.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/parser/JSONDataParser.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones/parser/JSONDataParser.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/ArmatureCache.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/ArmatureCache.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/ArmatureCacheMgr.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/ArmatureCacheMgr.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/AttachUtil.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/AttachUtil.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCArmatureCacheDisplay.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCArmatureCacheDisplay.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCArmatureDisplay.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCArmatureDisplay.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCDragonBonesHeaders.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCFactory.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCFactory.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCSlot.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCSlot.h
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCTextureAtlasData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/dragonbones-creator-support/CCTextureAtlasData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_dragonbones_manual.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_dragonbones_auto.cpp
)
endif() # CC_USE_DRAGONBONES
##### USE_WEBVIEW
if(CC_USE_WEBVIEW)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_webview_auto.hpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_webview_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/ui/webview/WebViewImpl-openharmony.h
${CMAKE_CURRENT_LIST_DIR}/cocos/ui/webview/WebViewImpl-openharmony.cpp
)
endif() # USE_WEBVIEW
##### USE_AUDIO
if(CC_USE_AUDIO)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_audioengine_auto.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/AudioEngine.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AssetFd.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AssetFd.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioBufferProvider.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoder.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoder.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderMp3.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderMp3.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderOgg.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderOgg.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderProvider.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderProvider.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderSLES.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderSLES.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderWav.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioDecoderWav.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioEngine-inl.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioEngine-inl.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioMixer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioMixer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioMixerController.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioMixerController.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioMixerOps.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioPlayerProvider.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioPlayerProvider.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioResampler.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioResampler.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioResamplerCubic.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioResamplerCubic.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/AudioResamplerPublic.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/IAudioPlayer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/ICallerThreadUtils.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/IVolumeProvider.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/mp3reader.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/mp3reader.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/OpenSLHelper.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmAudioPlayer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmAudioPlayer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmAudioService.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmAudioService.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmBufferProvider.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmBufferProvider.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmData.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/PcmData.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/tinysndfile.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/tinysndfile.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/Track.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/Track.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/UrlAudioPlayer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/UrlAudioPlayer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/format.c
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/minifloat.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/primitives.c
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/include/audio_utils/format.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/include/audio_utils/minifloat.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/include/audio_utils/primitives.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/audio_utils/private/private.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/cutils/bitops.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/cutils/log.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/utils/Compat.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/utils/Errors.h
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/utils/Utils.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android/utils/Utils.h
)
endif() # USE_AUDIO
##### USE_SOCKET
if(CC_USE_SOCKET)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/network/SocketIO.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/SocketIO.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/WebSocket.h
${CMAKE_CURRENT_LIST_DIR}/cocos/network/WebSocket-libwebsockets.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/WebSocketServer.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/network/WebSocketServer.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_socketio.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_websocket.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/manual/jsb_websocket_server.cpp
)
endif() # USE_SOCKET
##### USE_PARTICLE
if(CC_USE_PARTICLE)
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/particle/ParticleSimulator.cpp
${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/particle/ParticleSimulator.h
${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/auto/jsb_cocos2dx_particle_auto.cpp
)
endif() # USE_PARTICLE
##### external source
list(APPEND CC_COCOS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/external/sources/xxtea/xxtea.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/xxtea/xxtea.h
${CMAKE_CURRENT_LIST_DIR}/external/sources/tinyxml2/tinyxml2.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/tinyxml2/tinyxml2.h
${CMAKE_CURRENT_LIST_DIR}/external/sources/unzip/ioapi_mem.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/unzip/ioapi_mem.h
${CMAKE_CURRENT_LIST_DIR}/external/sources/unzip/ioapi.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/unzip/ioapi.h
${CMAKE_CURRENT_LIST_DIR}/external/sources/unzip/unzip.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/unzip/unzip.h
${CMAKE_CURRENT_LIST_DIR}/external/sources/ConvertUTF/ConvertUTFWrapper.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/ConvertUTF/ConvertUTF.c
${CMAKE_CURRENT_LIST_DIR}/external/sources/ConvertUTF/ConvertUTF.h
${CMAKE_CURRENT_LIST_DIR}/external/sources/edtaa3func/edtaa3func.cpp
${CMAKE_CURRENT_LIST_DIR}/external/sources/edtaa3func/edtaa3func.h
)
##### External sources
list(APPEND CC_COCOS_SOURCES ${CC_EXTERNAL_SOURCES})
################################# cc_apply_definations ###################################
function(cc_apply_definations target)
target_compile_definitions(${target} PUBLIC
$<IF:$<BOOL:${CC_USE_GFX_RENDERER}>,USE_GFX_RENDERER=1,USE_GFX_RENDERER=0>
$<IF:$<BOOL:${CC_USE_VIDEO}>,USE_VIDEO=1,USE_VIDEO=0>
$<IF:$<BOOL:${CC_USE_WEBVIEW}>,USE_WEBVIEW=1,USE_WEBVIEW=0>
$<IF:$<BOOL:${CC_USE_AUDIO}>,USE_AUDIO=1,USE_AUDIO=0>
$<IF:$<BOOL:${CC_USE_SOCKET}>,USE_SOCKET=1,USE_SOCKET=0>
$<IF:$<BOOL:${CC_USE_WEBSOCKET_SERVER}>,USE_WEBSOCKET_SERVER=1,USE_WEBSOCKET_SERVER=0>
$<IF:$<BOOL:${CC_USE_MIDDLEWARE}>,USE_MIDDLEWARE=1,USE_MIDDLEWARE=0>
$<IF:$<BOOL:${CC_USE_SPINE}>,USE_SPINE=1,USE_SPINE=0>
$<IF:$<BOOL:${CC_USE_DRAGONBONES}>,USE_DRAGONBONES=1,USE_DRAGONBONES=0>
$<IF:$<BOOL:${CC_USE_SE_NAPI}>,USE_SE_NAPI=1,USE_SE_NAPI=0>
$<IF:$<BOOL:${CC_USE_PARTICLE}>,USE_PARTICLE=1,USE_PARTICLE=0>
)
endfunction()
include_directories(${CC_EXTERNAL_INCLUDES})
include_directories(${CMAKE_CURRENT_LIST_DIR})
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/2d)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/audio/android)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/base)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/editor-support/spine-creator-support)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/math)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/network)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/platform)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/renderer)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/gfx)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/renderer)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/memop)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/renderer/scene/assembler)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/storage/local-storage)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/ui/edit-box)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/ui/webview)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/scripting/js-bindings/jswrapper/napi)
include_directories(${CMAKE_CURRENT_LIST_DIR}/cocos/platform/openharmony/napi)

View File

@ -635,6 +635,10 @@
04FB24122328D42A0021DD02 /* ArmatureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 04FB24072328D42A0021DD02 /* ArmatureCache.h */; };
04FB24132328D42A0021DD02 /* CCArmatureCacheDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 04FB24082328D42A0021DD02 /* CCArmatureCacheDisplay.cpp */; };
04FB24142328D42A0021DD02 /* CCArmatureCacheDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 04FB24082328D42A0021DD02 /* CCArmatureCacheDisplay.cpp */; };
0F07F55D28FD38900035F34D /* astc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F07F55B28FD388F0035F34D /* astc.cpp */; };
0F07F55E28FD38900035F34D /* astc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F07F55B28FD388F0035F34D /* astc.cpp */; };
0F07F55F28FD38900035F34D /* astc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F07F55C28FD388F0035F34D /* astc.h */; };
0F07F56028FD38900035F34D /* astc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F07F55C28FD388F0035F34D /* astc.h */; };
1A14FD912080B4E300E10ABE /* CCGLUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A14FD8F2080B4E300E10ABE /* CCGLUtils.cpp */; };
1A14FD922080B4E300E10ABE /* CCGLUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A14FD8F2080B4E300E10ABE /* CCGLUtils.cpp */; };
1A14FD932080B4E300E10ABE /* CCGLUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A14FD902080B4E300E10ABE /* CCGLUtils.h */; };
@ -1820,6 +1824,8 @@
051C017021E2F85C00D4A347 /* CCModuleConfigIOS.release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CCModuleConfigIOS.release.xcconfig; sourceTree = "<group>"; };
051C017121E2F86900D4A347 /* CCModuleConfigMac.release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CCModuleConfigMac.release.xcconfig; sourceTree = "<group>"; };
051C017221E2F86900D4A347 /* CCModuleConfigMac.debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CCModuleConfigMac.debug.xcconfig; sourceTree = "<group>"; };
0F07F55B28FD388F0035F34D /* astc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = astc.cpp; sourceTree = "<group>"; };
0F07F55C28FD388F0035F34D /* astc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = astc.h; sourceTree = "<group>"; };
1551A33F158F2AB200E66CFE /* libcocos2d Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libcocos2d Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; };
1551A342158F2AB200E66CFE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1A14FD8F2080B4E300E10ABE /* CCGLUtils.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CCGLUtils.cpp; sourceTree = "<group>"; };
@ -3506,6 +3512,8 @@
46FDDAE9202ADDCE00931238 /* base */ = {
isa = PBXGroup;
children = (
0F07F55B28FD388F0035F34D /* astc.cpp */,
0F07F55C28FD388F0035F34D /* astc.h */,
4DCEC124233236D60020F8E3 /* etc2.cpp */,
4DCEC125233236D60020F8E3 /* etc2.h */,
46FDDAFD202ADDCE00931238 /* base64.cpp */,
@ -3919,6 +3927,7 @@
04F0A928234F14BE002C3533 /* Pool.h in Headers */,
046B688C219FA61200B33469 /* MiddlewareManager.h in Headers */,
BAEA45551E279D5C00FA219F /* tinydir.h in Headers */,
0F07F55F28FD38900035F34D /* astc.h in Headers */,
046B689221A00F5600B33469 /* IOTypedArray.h in Headers */,
46FDDAB7202ACC6A00931238 /* IndexBuffer.h in Headers */,
4617864520522469008256E1 /* HttpAsynConnection-apple.h in Headers */,
@ -4531,6 +4540,7 @@
046E06C82185B49F00B24E2D /* DisplayData.h in Headers */,
50ABBD4F1925AB0000A911A9 /* MathUtil.h in Headers */,
1A28FF561F20AFAB007A1D9D /* SRIOConsumerPool.h in Headers */,
0F07F56028FD38900035F34D /* astc.h in Headers */,
04F0A95F234F14BE002C3533 /* TimelineType.h in Headers */,
1A28FF7E1F20AFAB007A1D9D /* SRMutex.h in Headers */,
403ACADD20CE542900BB433D /* jsb_module_register.hpp in Headers */,
@ -4956,6 +4966,7 @@
046E066C2185B41B00B24E2D /* Slot.cpp in Sources */,
50ABC0151926664800A911A9 /* CCImage.cpp in Sources */,
046E06D12185B49F00B24E2D /* DisplayData.cpp in Sources */,
0F07F55D28FD38900035F34D /* astc.cpp in Sources */,
ED18118023D6A97000DED444 /* CCTTFTypes.cpp in Sources */,
46AE400B2092F3A600F3A228 /* env.cc in Sources */,
46FDDAD3202ACC6A00931238 /* Texture2D.cpp in Sources */,
@ -5086,6 +5097,7 @@
468A968322F43F5A005034BE /* Utils.cpp in Sources */,
421EA5822372BB0E009F3FE0 /* Particle3DAssembler.cpp in Sources */,
04355817217EADF300B9C056 /* IOBuffer.cpp in Sources */,
0F07F55E28FD38900035F34D /* astc.cpp in Sources */,
46FDDB7C202ADDCE00931238 /* CCRef.cpp in Sources */,
046E06F82189990700B24E2D /* middleware-adapter.cpp in Sources */,
04F0AA0D234F14BE002C3533 /* Updatable.cpp in Sources */,

View File

@ -25,6 +25,7 @@
<ClCompile Include="..\cocos\audio\win32\AudioDecoderOgg.cpp" />
<ClCompile Include="..\cocos\audio\win32\AudioEngine-win32.cpp" />
<ClCompile Include="..\cocos\audio\win32\AudioPlayer.cpp" />
<ClCompile Include="..\cocos\base\astc.cpp" />
<ClCompile Include="..\cocos\base\base64.cpp" />
<ClCompile Include="..\cocos\base\CCAutoreleasePool.cpp" />
<ClCompile Include="..\cocos\base\ccCArray.cpp" />
@ -325,6 +326,7 @@
<ClInclude Include="..\cocos\audio\win32\AudioEngine-win32.h" />
<ClInclude Include="..\cocos\audio\win32\AudioMacros.h" />
<ClInclude Include="..\cocos\audio\win32\AudioPlayer.h" />
<ClInclude Include="..\cocos\base\astc.h" />
<ClInclude Include="..\cocos\base\base64.h" />
<ClInclude Include="..\cocos\base\CCAutoreleasePool.h" />
<ClInclude Include="..\cocos\base\ccCArray.h" />

View File

@ -41,6 +41,7 @@ base/ccRandom.cpp \
base/ccTypes.cpp \
base/ccUTF8.cpp \
base/ccUtils.cpp \
base/astc.cpp \
base/etc1.cpp \
base/etc2.cpp \
base/pvr.cpp \

View File

@ -34,7 +34,7 @@
#include <thread>
#include <mutex>
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "audio/android/AudioEngine-inl.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#include "audio/apple/AudioEngine-inl.h"
@ -365,7 +365,7 @@ void AudioEngine::onPause(const CustomEvent &event) {
}
}
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
if (_audioEngineImpl) {
_audioEngineImpl->onPause();
}
@ -384,7 +384,7 @@ void AudioEngine::onResume(const CustomEvent &event) {
}
_breakAudioID.clear();
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
if (_audioEngineImpl) {
_audioEngineImpl->onResume();
}

View File

@ -27,6 +27,8 @@ THE SOFTWARE.
#include "audio/android/AudioDecoderSLES.h"
#include "platform/CCFileUtils.h"
#include "platform/CCPlatformDefine.h"
#include "audio/android/utils/Compat.h"
#include <thread>
#include <mutex>
@ -86,7 +88,7 @@ public:
thiz->prefetchCallback(caller, event);
}
static void decPlayCallback(SLAndroidSimpleBufferQueueItf queueItf, void *context)
static void decPlayCallback(CCSLBufferQueueItf queueItf, void *context)
{
AudioDecoderSLES *thiz = reinterpret_cast<AudioDecoderSLES *>(context);
thiz->decodeToPcmCallback(queueItf);
@ -144,13 +146,14 @@ bool AudioDecoderSLES::init(SLEngineItf engineItf, const std::string &url, int b
bool AudioDecoderSLES::decodeToPcm()
{
SLresult result;
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
SLresult result;
/* Objects this application uses: one audio player */
SLObjectItf player;
/* Interfaces for the audio player */
SLAndroidSimpleBufferQueueItf decBuffQueueItf;
CCSLBufferQueueItf decBuffQueueItf;
SLPrefetchStatusItf prefetchItf;
SLPlayItf playItf;
SLMetadataExtractionItf mdExtrItf;
@ -463,6 +466,7 @@ bool AudioDecoderSLES::decodeToPcm()
std::string info = _result.toString();
ALOGI("Original audio info: %s, total size: %d", info.c_str(), (int)_result.pcmBuffer->size());
#endif
return true;
}
@ -585,7 +589,7 @@ void AudioDecoderSLES::decodeProgressCallback(SLPlayItf caller, SLuint32 event)
//-----------------------------------------------------------------
/* Callback for decoding buffer queue events */
void AudioDecoderSLES::decodeToPcmCallback(SLAndroidSimpleBufferQueueItf queueItf)
void AudioDecoderSLES::decodeToPcmCallback(CCSLBufferQueueItf queueItf)
{
_isDecodingCallbackInvoked = true;
ALOGV("%s ...", __FUNCTION__);

View File

@ -26,6 +26,8 @@ THE SOFTWARE.
#pragma once
#include "audio/android/AudioDecoder.h"
#include "audio/android/utils/Compat.h"
#include "platform/CCPlatformDefine.h"
#include <mutex>
#include <condition_variable>
@ -44,7 +46,7 @@ private:
void queryAudioInfo();
void signalEos();
void decodeToPcmCallback(SLAndroidSimpleBufferQueueItf queueItf);
void decodeToPcmCallback(CCSLBufferQueueItf queueItf);
void prefetchCallback(SLPrefetchStatusItf caller, SLuint32 event);
void decodeProgressCallback(SLPlayItf caller, SLuint32 event);

View File

@ -22,7 +22,6 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#define LOG_TAG "AudioEngineImpl"
@ -30,11 +29,14 @@
#include <unistd.h>
// for native asset manager
#include <sys/types.h>
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <unordered_map>
#include <android/log.h>
#endif
#include <sys/types.h>
#include <thread>
#include <mutex>
@ -42,9 +44,13 @@
#include "platform/CCApplication.h"
#include "base/CCScheduler.h"
#include "base/ccUTF8.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "platform/android/CCFileUtils-android.h"
#include "platform/android/jni/JniImp.h"
#include "platform/android/jni/JniHelper.h"
#include "platform/android/jni/JniImp.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "cocos/platform/openharmony/FileUtils-openharmony.h"
#endif
#include "audio/android/IAudioPlayer.h"
#include "audio/android/ICallerThreadUtils.h"
@ -57,6 +63,28 @@
using namespace cocos2d;
// Audio focus values synchronized with which in cocos/platform/android/java/src/com/cocos/lib/CocosNativeActivity.java
namespace {
AudioEngineImpl *gAudioImpl = nullptr;
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
int bufferSizeInFrames = getDeviceAudioBufferSizeInFramesJNI();
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// TODO(hack) : There is currently a bug in the opensles module,
// so openharmony must configure a fixed size, otherwise the callback will be suspended
int bufferSizeInFrames = 2048;
#endif
int outputSampleRate = 44100;
void getAudioInfo() {
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
outputSampleRate = getDeviceSampleRateJNI();
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// In openharmony, setting to 48K does not cause audio delays
outputSampleRate = 48000;
#endif
}
} // namespace
// Audio focus values synchronized with which in cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
static const int AUDIOFOCUS_GAIN = 0;
static const int AUDIOFOCUS_LOST = 1;
@ -93,6 +121,7 @@ static CallerThreadUtils __callerThreadUtils;
static int fdGetter(const std::string& url, off_t* start, off_t* length)
{
int fd = -1;
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
if (cocos2d::FileUtilsAndroid::getObbFile() != nullptr)
{
fd = getObbAssetFileDescriptorJNI(url.c_str(), start, length);
@ -104,7 +133,14 @@ static int fdGetter(const std::string& url, off_t* start, off_t* length)
fd = AAsset_openFileDescriptor(asset, start, length);
AAsset_close(asset);
}
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
FileUtilsOpenHarmony* fileUtils = static_cast<FileUtilsOpenHarmony*>(FileUtils::getInstance());
if(fileUtils) {
RawFileDescriptor descriptor;
fileUtils->getRawFileDescriptor(url, descriptor);
fd = descriptor.fd;
}
#endif
if (fd <= 0)
{
ALOGE("Failed to open file descriptor for '%s'", url.c_str());
@ -124,6 +160,7 @@ AudioEngineImpl::AudioEngineImpl()
{
__callerThreadUtils.setCallerThreadId(std::this_thread::get_id());
__impl = this;
getAudioInfo();
}
AudioEngineImpl::~AudioEngineImpl()
@ -173,7 +210,7 @@ bool AudioEngineImpl::init()
result = (*_outputMixObject)->Realize(_outputMixObject, SL_BOOLEAN_FALSE);
if(SL_RESULT_SUCCESS != result){ ERRORLOG("realize the output mix fail"); break; }
_audioPlayerProvider = new AudioPlayerProvider(_engineEngine, _outputMixObject, getDeviceSampleRateJNI(), getDeviceAudioBufferSizeInFramesJNI(), fdGetter, &__callerThreadUtils);
_audioPlayerProvider = new AudioPlayerProvider(_engineEngine, _outputMixObject, outputSampleRate, bufferSizeInFrames, fdGetter, &__callerThreadUtils);
ret = true;
}while (false);
@ -462,5 +499,3 @@ void cocos_audioengine_focus_change(int focusChange)
__impl->setAudioFocusForAllPlayers(false);
}
}
#endif

View File

@ -22,13 +22,18 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#ifndef __AUDIO_ENGINE_INL_H_
#define __AUDIO_ENGINE_INL_H_
#include "platform/CCPlatformConfig.h"
#include <SLES/OpenSLES.h>
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <SLES/OpenSLES_Android.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <SLES/OpenSLES_Platform.h>
#endif
#include <string>
#include <unordered_map>
#include <functional>
@ -101,5 +106,3 @@ private:
#endif // __AUDIO_ENGINE_INL_H_
NS_CC_END
#endif

View File

@ -26,6 +26,7 @@
#include "audio/android/AudioResampler.h"
#include "audio/android/audio.h"
#include "audio/android/utils/Compat.h"
// IDEA: This is actually unity gain, which might not be max in future, expressed in U.12
#define MAX_GAIN_INT AudioMixer::UNITY_GAIN_INT

View File

@ -36,7 +36,12 @@ THE SOFTWARE.
#include "audio/android/ICallerThreadUtils.h"
#include "audio/android/utils/Utils.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <sys/system_properties.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "cocos/platform/CCFileUtils.h"
#include "cocos/platform/openharmony/FileUtils-openharmony.h"
#endif
#include <stdlib.h>
#include <algorithm> // for std::find_if
@ -45,6 +50,8 @@ namespace cocos2d {
static int getSystemAPILevel()
{
static int __systemApiLevel = -1;
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
if (__systemApiLevel > 0)
{
return __systemApiLevel;
@ -61,6 +68,10 @@ static int getSystemAPILevel()
}
__systemApiLevel = apiLevel;
return apiLevel;
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// TODO(qgh): On the openharmony platform, pcm streaming must be used
return std::numeric_limits<int>::max();
#endif
}
struct AudioFileIndicator
@ -354,7 +365,7 @@ AudioPlayerProvider::AudioFileInfo AudioPlayerProvider::getFileInfo(
long fileSize = 0;
off_t start = 0, length = 0;
int assetFd = -1;
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
if (audioFilePath[0] != '/')
{
std::string relativePath;
@ -399,7 +410,19 @@ AudioPlayerProvider::AudioFileInfo AudioPlayerProvider::getFileInfo(
info.assetFd = std::make_shared<AssetFd>(assetFd);
info.start = start;
info.length = fileSize;
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
FileUtilsOpenHarmony* fileUtils = static_cast<FileUtilsOpenHarmony*>(FileUtils::getInstance());
if(!fileUtils) {
return info;
}
RawFileDescriptor descriptor;
fileUtils->getRawFileDescriptor(audioFilePath, descriptor);
info.url = audioFilePath;
info.assetFd = std::make_shared<AssetFd>(descriptor.fd);
info.start = descriptor.start;
info.length = descriptor.length;
#endif
ALOGV("(%s) file size: %ld", audioFilePath.c_str(), fileSize);
return info;
@ -407,6 +430,10 @@ AudioPlayerProvider::AudioFileInfo AudioPlayerProvider::getFileInfo(
bool AudioPlayerProvider::isSmallFile(const AudioFileInfo &info)
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// TODO(qgh): OpenHarmony system does not support this function yet
return true;
#endif
//REFINE: If file size is smaller than 100k, we think it's a small file. This value should be set by developers.
AudioFileInfo &audioFileInfo = const_cast<AudioFileInfo &>(info);
size_t judgeCount = sizeof(__audioFileIndicator) / sizeof(__audioFileIndicator[0]);
@ -490,7 +517,12 @@ UrlAudioPlayer *AudioPlayerProvider::createUrlAudioPlayer(
return nullptr;
}
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
SLuint32 locatorType = info.assetFd->getFd() > 0 ? SL_DATALOCATOR_ANDROIDFD : SL_DATALOCATOR_URI;
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
SLuint32 locatorType = SL_DATALOCATOR_URI;
#endif
auto urlPlayer = new (std::nothrow) UrlAudioPlayer(_engineItf, _outputMixObject, _callerThreadUtils);
bool ret = urlPlayer->prepare(info.url, locatorType, info.assetFd, info.start, info.length);
if (!ret)

View File

@ -17,9 +17,14 @@
#pragma once
#include <stdint.h>
#include <sys/types.h>
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <android/log.h>
#include <sys/system_properties.h>
#include <sys/types.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <hilog/log.h>
#endif
#include "audio/android/AudioBufferProvider.h"

View File

@ -28,7 +28,11 @@ THE SOFTWARE.
#include "audio/android/cutils/log.h"
#include <SLES/OpenSLES.h>
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <SLES/OpenSLES_Android.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <SLES/OpenSLES_Platform.h>
#endif
#include <functional>
#include <string>

View File

@ -27,6 +27,7 @@ THE SOFTWARE.
#include "audio/android/PcmAudioService.h"
#include "audio/android/AudioMixerController.h"
#include "audio/android/utils/Compat.h"
namespace cocos2d {
@ -37,11 +38,18 @@ static std::vector<char> __silenceData;
class SLPcmAudioPlayerCallbackProxy
{
public:
static void samplePlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
PcmAudioService *thiz = reinterpret_cast<PcmAudioService *>(context);
thiz->bqFetchBufferCallback(bq);
}
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
static void samplePlayerCallback(CCSLBufferQueueItf bq, void *context, SLuint32 size) {
auto *thiz = reinterpret_cast<PcmAudioService *>(context);
thiz->bqFetchBufferCallback(bq);
}
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
static void samplePlayerCallback(CCSLBufferQueueItf bq, void *context) {
PcmAudioService *thiz = reinterpret_cast<PcmAudioService *>(context);
thiz->bqFetchBufferCallback(bq);
}
#endif
};
PcmAudioService::PcmAudioService(SLEngineItf engineItf, SLObjectItf outputMixObject)
@ -60,6 +68,12 @@ PcmAudioService::~PcmAudioService()
bool PcmAudioService::enqueue()
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// We need to call this interface in openharmony, otherwise there will be noise
SLuint8 *buffer = nullptr;
SLuint32 size = 0;
(*_bufferQueueItf)->GetBuffer(_bufferQueueItf, &buffer, &size);
#endif
if (_controller->hasPlayingTacks())
{
if (_controller->isPaused())
@ -86,7 +100,7 @@ bool PcmAudioService::enqueue()
return true;
}
void PcmAudioService::bqFetchBufferCallback(SLAndroidSimpleBufferQueueItf bq)
void PcmAudioService::bqFetchBufferCallback(CCSLBufferQueueItf bq)
{
// IDEA: PcmAudioService instance may be destroyed, we need to find a way to wait...
// It's in sub thread
@ -117,10 +131,8 @@ bool PcmAudioService::init(AudioMixerController* controller, int numChannels, in
SL_BYTEORDER_LITTLEENDIAN
};
SLDataLocator_AndroidSimpleBufferQueue locBufQueue = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
AUDIO_PLAYER_BUFFER_COUNT
};
SLDataLocator_BufferQueue locBufQueue = {SL_DATALOCATOR_BUFFERQUEUE, AUDIO_PLAYER_BUFFER_COUNT};
SLDataSource source = {&locBufQueue, &formatPcm};
SLDataLocator_OutputMix locOutmix = {
@ -132,7 +144,7 @@ bool PcmAudioService::init(AudioMixerController* controller, int numChannels, in
const SLInterfaceID ids[] = {
SL_IID_PLAY,
SL_IID_VOLUME,
SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
CC_SL_IDD_BUFFER_QUEUE,
};
const SLboolean req[] = {
@ -156,8 +168,8 @@ bool PcmAudioService::init(AudioMixerController* controller, int numChannels, in
r = (*_playObj)->GetInterface(_playObj, SL_IID_VOLUME, &_volumeItf);
SL_RETURN_VAL_IF_FAILED(r, false, "GetInterface SL_IID_VOLUME failed");
r = (*_playObj)->GetInterface(_playObj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &_bufferQueueItf);
SL_RETURN_VAL_IF_FAILED(r, false, "GetInterface SL_IID_ANDROIDSIMPLEBUFFERQUEUE failed");
r = (*_playObj)->GetInterface(_playObj, CC_SL_IDD_BUFFER_QUEUE, &_bufferQueueItf);
SL_RETURN_VAL_IF_FAILED(r, false, "GetInterface CC_SL_IDD_BUFFER_QUEUE failed");
r = (*_bufferQueueItf)->RegisterCallback(_bufferQueueItf,
SLPcmAudioPlayerCallbackProxy::samplePlayerCallback,
@ -169,6 +181,13 @@ bool PcmAudioService::init(AudioMixerController* controller, int numChannels, in
__silenceData.resize(_numChannels * _bufferSizeInBytes, 0x00);
}
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// We need to call this interface in openharmony, otherwise there will be noise
SLuint8 *buffer = nullptr;
SLuint32 size = 0;
(*_bufferQueueItf)->GetBuffer(_bufferQueueItf, &buffer, &size);
#endif
r = (*_bufferQueueItf)->Enqueue(_bufferQueueItf, __silenceData.data(), __silenceData.size());
SL_RETURN_VAL_IF_FAILED(r, false, "_bufferQueueItf Enqueue failed");

View File

@ -28,6 +28,7 @@ THE SOFTWARE.
#include "audio/android/IAudioPlayer.h"
#include "audio/android/OpenSLHelper.h"
#include "audio/android/PcmData.h"
#include "audio/android/utils/Compat.h"
#include <mutex>
#include <condition_variable>
@ -54,7 +55,7 @@ private:
bool enqueue();
void bqFetchBufferCallback(SLAndroidSimpleBufferQueueItf bq);
void bqFetchBufferCallback(CCSLBufferQueueItf bq);
void pause();
void resume();
@ -66,7 +67,7 @@ private:
SLObjectItf _playObj;
SLPlayItf _playItf;
SLVolumeItf _volumeItf;
SLAndroidSimpleBufferQueueItf _bufferQueueItf;
CCSLBufferQueueItf _bufferQueueItf;
int _numChannels;
int _sampleRate;

View File

@ -27,6 +27,7 @@ THE SOFTWARE.
#include "audio/android/UrlAudioPlayer.h"
#include "audio/android/ICallerThreadUtils.h"
#include "platform/CCPlatformDefine.h"
#include <math.h>
#include <algorithm> // for std::find
@ -70,7 +71,7 @@ UrlAudioPlayer::UrlAudioPlayer(SLEngineItf engineItf, SLObjectItf outputMixObjec
__playerContainerMutex.lock();
__playerContainer.push_back(this);
ALOGV("Current UrlAudioPlayer instance count: %d", (int)__playerContainer.size());
ALOGV("Current UrlAudioPlayer instance count: %d", (int)__playerContainer.size());
__playerContainerMutex.unlock();
_callerThreadId = callerThreadUtils->getCallerThreadId();
@ -78,7 +79,7 @@ UrlAudioPlayer::UrlAudioPlayer(SLEngineItf engineItf, SLObjectItf outputMixObjec
UrlAudioPlayer::~UrlAudioPlayer()
{
ALOGV("~UrlAudioPlayer(): %p", this);
ALOGV("~UrlAudioPlayer(): %p", this);
__playerContainerMutex.lock();
@ -297,6 +298,7 @@ bool UrlAudioPlayer::prepare(const std::string &url, SLuint32 locatorType, std::
_url = url;
_assetFd = assetFd;
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
const char* locatorTypeStr= "UNKNOWN";
if (locatorType == SL_DATALOCATOR_ANDROIDFD)
locatorTypeStr = "SL_DATALOCATOR_ANDROIDFD";
@ -308,8 +310,7 @@ bool UrlAudioPlayer::prepare(const std::string &url, SLuint32 locatorType, std::
return false;
}
ALOGV("UrlAudioPlayer::prepare: %s, %s, %d, %d, %d", _url.c_str(), locatorTypeStr, _assetFd->getFd(), start,
length);
ALOGV("UrlAudioPlayer::prepare: %s, %s, %d, %d, %d", _url.c_str(), locatorTypeStr, _assetFd->getFd(), start, length);
SLDataSource audioSrc;
SLDataFormat_MIME formatMime = {SL_DATAFORMAT_MIME, nullptr, SL_CONTAINERTYPE_UNSPECIFIED};
@ -375,6 +376,7 @@ bool UrlAudioPlayer::prepare(const std::string &url, SLuint32 locatorType, std::
setVolume(1.0f);
#endif
return true;
}

View File

@ -28,7 +28,6 @@ THE SOFTWARE.
// ----------------------------------------------------------------------------
#include <stdint.h>
#include <android/log.h>
#include "audio/android/cutils/bitops.h"
#define PROPERTY_VALUE_MAX 256

View File

@ -18,7 +18,11 @@
#define COCOS_AUDIO_FORMAT_H
#include <stdint.h>
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <sys/cdefs.h>
#endif
#include "audio/android/audio.h"
__BEGIN_DECLS

View File

@ -18,7 +18,10 @@
#define COCOS_AUDIO_MINIFLOAT_H
#include <stdint.h>
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <sys/cdefs.h>
#endif
__BEGIN_DECLS

View File

@ -19,7 +19,10 @@
#include <stdint.h>
#include <stdlib.h>
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <sys/cdefs.h>
#endif
__BEGIN_DECLS

View File

@ -20,7 +20,10 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <sys/cdefs.h>
#endif
__BEGIN_DECLS

View File

@ -33,7 +33,12 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "platform/CCPlatformDefine.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <android/log.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <hilog/log.h>
#endif
#ifdef __cplusplus
@ -86,7 +91,11 @@ extern "C" {
* Simplified macro to send a verbose log message using the current LOG_TAG.
*/
#ifndef ALOGV
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#define __ALOGV(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
#endif
#if LOG_NDEBUG
#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
#else
@ -392,16 +401,29 @@ extern "C" {
* is -inverted- from the normal assert() semantics.
*/
#ifndef LOG_ALWAYS_FATAL_IF
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
: (void)0 )
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
((void)0 )
#endif
#endif
#ifndef LOG_ALWAYS_FATAL
#define LOG_ALWAYS_FATAL(...) \
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#define LOG_ALWAYS_FATAL(...) \
( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
// #define LOG_ALWAYS_FATAL(...) ((void)0)
#define LOG_ALWAYS_FATAL(...) ((void) OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#endif
#endif
/*
* Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
@ -424,7 +446,6 @@ extern "C" {
#ifndef LOG_FATAL
#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
#endif
#endif
/*
@ -447,16 +468,25 @@ extern "C" {
* The second argument may be NULL or "" to indicate the "global" tag.
*/
#ifndef ALOG
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#define ALOG(priority, tag, ...) \
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#define ALOG(priority, tag, ...) \
LOG_PRI(priority, tag, __VA_ARGS__)
#endif
#endif
/*
* Log macro that allows you to specify a number for the priority.
*/
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
android_printLog(priority, tag, __VA_ARGS__)
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#define LOG_PRI(priority, tag, ...) \
android_printLog(priority, tag, __VA_ARGS__)
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#define LOG_PRI(priority, tag, ...) ((void) OH_LOG_Print(LOG_APP, priority, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#endif
#endif
/*

View File

@ -23,7 +23,10 @@
// no guarantee that it will stay exactly source-code compatible with other libraries.
#include <stdio.h>
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <sys/cdefs.h>
#endif
__BEGIN_DECLS

View File

@ -17,7 +17,15 @@
#ifndef COCOS_LIB_UTILS_COMPAT_H
#define COCOS_LIB_UTILS_COMPAT_H
#include "platform/CCPlatformDefine.h"
#include <SLES/OpenSLES.h>
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <SLES/OpenSLES_OpenHarmony.h>
#include <SLES/OpenSLES_Platform.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include <SLES/OpenSLES_Android.h>
#include <unistd.h>
#endif
#if defined(__APPLE__)
@ -85,4 +93,13 @@ static inline ssize_t pwrite64(int fd, const void* buf, size_t nbytes, off64_t o
#define OS_PATH_SEPARATOR '/'
#endif
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
typedef SLOHBufferQueueItf CCSLBufferQueueItf;
#define CC_SL_IDD_BUFFER_QUEUE SL_IID_OH_BUFFERQUEUE
#define __unused
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
typedef SLAndroidSimpleBufferQueueItf CCSLBufferQueueItf;
#define CC_SL_IDD_BUFFER_QUEUE SL_IID_ANDROIDSIMPLEBUFFERQUEUE
#endif
#endif /* COCOS_LIB_UTILS_COMPAT_H */

View File

@ -23,7 +23,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "audio/android/utils/Utils.h"
#include "platform/CCPlatformDefine.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "platform/android/jni/JniHelper.h"
#endif
#ifndef JCLS_HELPER
#define JCLS_HELPER "org/cocos2dx/lib/Cocos2dxHelper"
@ -33,7 +36,12 @@ namespace cocos2d {
int getSDKVersion()
{
return JniHelper::callStaticIntMethod(JCLS_HELPER, "getSDKVersion");
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
return JniHelper::callStaticIntMethod(JCLS_HELPER, "getSDKVersion");
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
//TODO: openharmony未实现
return 0;
#endif
}
} // end of namespace cocos2d

View File

@ -48,6 +48,7 @@ Configuration::Configuration()
, _supportsETC2(false)
, _supportsS3TC(false)
, _supportsATITC(false)
, _supportsASTC(false)
, _supportsNPOT(false)
, _supportsBGRA8888(false)
, _supportsDiscardFramebuffer(false)
@ -153,6 +154,9 @@ void Configuration::gatherGPUInfo()
_supportsPVRTC = checkForGLExtension("GL_IMG_texture_compression_pvrtc");
_valueDict["gl.supports_PVRTC"] = Value(_supportsPVRTC);
_supportsASTC = checkForGLExtension("texture_compression_astc");
_valueDict["gl.supports_ASTC"] = Value(_supportsASTC);
_supportsNPOT = true;
_valueDict["gl.supports_NPOT"] = Value(_supportsNPOT);
@ -282,6 +286,11 @@ bool Configuration::supportsETC2() const
return _supportsETC2;
}
bool Configuration::supportsASTC() const
{
return _supportsASTC;
}
bool Configuration::supportsS3TC() const
{
#ifdef GL_EXT_texture_compression_s3tc

View File

@ -112,6 +112,13 @@ public:
*/
bool supportsETC2() const;
/** Whether or not ASTC Texture Compressed is supported.
*
*
* @return Is true if supports ASTC Texture Compressed.
*/
bool supportsASTC() const;
/** Whether or not S3TC Texture Compressed is supported.
*
* @return Is true if supports S3TC Texture Compressed.
@ -264,6 +271,7 @@ protected:
bool _supportsPVRTC;
bool _supportsETC1;
bool _supportsETC2;
bool _supportsASTC;
bool _supportsS3TC;
bool _supportsATITC;
bool _supportsNPOT;

View File

@ -94,6 +94,10 @@ namespace
} while (pos < len);
fflush(stdout);
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <stdarg.h>
#include <hilog/log.h>
OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "HMG_LOG", "%{public}s", buf);
#else
// Linux, Mac, iOS, etc
fprintf(stdout, "%s", buf);

View File

@ -473,7 +473,7 @@ void RenderTexture::initFramebuffer()
ccActiveOffScreenFramebuffer(_FBO);
// set up depth buffer and stencil buffer
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
if(Configuration::getInstance()->supportsOESPackedDepthStencil())
{
//create and attach depth buffer

View File

@ -32,6 +32,9 @@
#include <android/log.h>
#define LOG_TAG "ThreadPool"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,__VA_ARGS__)
#elif OPENHARMONY
#include <hilog/log.h>
#define LOGD(...) ((void) OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#else
#define LOGD(...) printf(__VA_ARGS__)
#endif

View File

@ -38,6 +38,8 @@ THE SOFTWARE.
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
// for import ssize_t on win32 platform
#include "platform/CCStdC.h"
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "platform/openharmony/FileUtils-openharmony.h"
#endif
/**

View File

@ -0,0 +1,66 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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/astc.h"
#include "platform/CCImage.h"
static const unsigned int MAGIC = 0x5CA1AB13;
static const astc_byte ASTC_HEADER_SIZE_X_BEGIN = 7;
static const astc_byte ASTC_HEADER_SIZE_Y_BEGIN = 10;
static const astc_byte ASTC_HEADER_SIZE_Z_BEGIN = 13;
bool astcIsValid(const astc_byte* pHeader) {
uint32_t magicval = (uint32_t)(pHeader[0]) +
(uint32_t)(pHeader[1]) * 256 +
(uint32_t)(pHeader[2]) * 65536 +
(uint32_t)(pHeader[3]) * 16777216;
if(magicval != MAGIC) {
return false;
}
int xdim = pHeader[ASTC_HEADER_MAGIC];
int ydim = pHeader[ASTC_HEADER_MAGIC + 1];
int zdim = pHeader[ASTC_HEADER_MAGIC + 2];
if ((xdim < 3 || xdim > 6 || ydim < 3 || ydim > 6 || zdim < 3 || zdim > 6) &&
(xdim < 4 || xdim == 7 || xdim == 9 || xdim == 11 || xdim > 12 ||
ydim < 4 || ydim == 7 || ydim == 9 || ydim == 11 || ydim > 12 || zdim != 1))
{
return false;
}
return true;
}
int astcGetWidth(const astc_byte* pHeader) {
int xsize = pHeader[ASTC_HEADER_SIZE_X_BEGIN] + (pHeader[ASTC_HEADER_SIZE_X_BEGIN + 1] * 256) + (pHeader[ASTC_HEADER_SIZE_X_BEGIN + 2] * 65536);
return xsize;
}
int astcGetHeight(const astc_byte* pHeader) {
int ysize = pHeader[ASTC_HEADER_SIZE_Y_BEGIN] + (pHeader[ASTC_HEADER_SIZE_Y_BEGIN + 1] * 256) + (pHeader[ASTC_HEADER_SIZE_Y_BEGIN + 2] * 65536);
return ysize;
}

View File

@ -0,0 +1,53 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 <stdint.h>
#ifndef __ASTC_H__
#define __ASTC_H__
typedef unsigned char astc_byte;
typedef unsigned int astc_uint32;
// Size of a ASTC header
#define ASTC_HEADER_SIZE 16
#define ASTC_HEADER_MAGIC 4
// Check if a ASTC header is correctly formatted
bool astcIsValid(const astc_byte* pHeader);
// Read the image width from a ASTC header
int astcGetWidth(const astc_byte* pHeader);
// Read the image height from a ASTC header
int astcGetHeight(const astc_byte* pHeader);
#endif

View File

@ -32,7 +32,7 @@ NS_CC_BEGIN
CC_DLL const char* cocos2dVersion()
{
return "2.4.10-rc.1";
return "2.4.12";
}
NS_CC_END

View File

@ -96,6 +96,10 @@ THE SOFTWARE.
#include "platform/mac/CCGL-mac.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#if (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "platform/openharmony/CCGL-openharmony.h"
#endif
NS_CC_BEGIN
CC_DLL const char* cocos2dVersion();

View File

@ -30,6 +30,7 @@ THE SOFTWARE.
#include <memory>
#include <vector>
#include <functional>
#include <thread>
#include "base/ccMacros.h"

View File

@ -174,11 +174,11 @@ static bool configureCURL(HttpClient* client, HttpRequest* request, CURL* handle
if (code != CURLE_OK) {
return false;
}
code = curl_easy_setopt(handle, CURLOPT_TIMEOUT, request->getTimeout());
code = curl_easy_setopt(handle, CURLOPT_TIMEOUT, static_cast<long>(request->getTimeout()));
if (code != CURLE_OK) {
return false;
}
code = curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, request->getTimeout());
code = curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, static_cast<long>(request->getTimeout()));
if (code != CURLE_OK) {
return false;
}

View File

@ -263,7 +263,7 @@ static std::mutex __instanceMutex;
static struct lws_context* __wsContext = nullptr;
static WsThreadHelper* __wsHelper = nullptr;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
static std::string getFileNameForPath(const std::string& filePath)
{
std::string fileName = filePath;
@ -852,7 +852,7 @@ void WebSocketImpl::close()
}
void WebSocketImpl::closeAsync(int code, const std::string &reason)
{
{
if (_wsInstance)
{
lws_close_reason(_wsInstance, (lws_close_status)code, (unsigned char*)const_cast<char*>(reason.c_str()), reason.length());
@ -917,7 +917,7 @@ struct lws_vhost* WebSocketImpl::createVhost(struct lws_protocols* protocols, in
{
if (isCAFileExist)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
// if ca file is in the apk, try to extract it to writable path
std::string writablePath = fileUtils->getWritablePath();
std::string caFileName = getFileNameForPath(_caFilePath);

View File

@ -55,6 +55,13 @@ public:
ANDROIDOS, /**< Android, because ANDROID is a macro, so use ANDROIDOS instead */
IPHONE, /**< iPhone */
IPAD, /**< iPad */
BLACKBERRY, /**< BLACKBERRY> */
NACL, /**according to CCSys.js below*/
EMSCRIPTEN,
TIZEN,
WINRT,
WP8,
OpenHarmony /**< OpenHarmony > */
};
enum class LanguageType

View File

@ -111,6 +111,8 @@ THE SOFTWARE.
#include "platform/winrt/CCGL.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#include "platform/linux/CCGL-linux.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "platform/openharmony/CCGL-openharmony.h"
#endif
/// @endcond

View File

@ -81,6 +81,8 @@ extern "C"
#include "base/etc2.h"
}
#include "base/astc.h"
#if CC_USE_WEBP
#include "webp/decode.h"
#endif // CC_USE_WEBP
@ -95,6 +97,8 @@ extern "C"
#include "base/ZipUtils.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/CCFileUtils-android.h"
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "platform/openharmony/FileUtils-openharmony.h"
#endif
#include <map>
@ -141,7 +145,24 @@ namespace
#ifdef GL_COMPRESSED_RGBA8_ETC2_EAC
PixelFormatInfoMapValue(Image::PixelFormat::ETC2_RGBA, Image::PixelFormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, true)),
#endif
#ifdef GL_COMPRESSED_RGBA_ASTC_4x4_KHR
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_4x4, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_5x4, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 6, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_5x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 5, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_6x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_6x6, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 5, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_8x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 3, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_8x6, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 3, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_8x8, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 3, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x6, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x8, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x10, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 1, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_12x10, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 1, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_12x12, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 1, true, true)),
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
PixelFormatInfoMapValue(Image::PixelFormat::S3TC_DXT1, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
#endif
@ -596,6 +617,9 @@ bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
case Format::ETC2:
ret = initWithETC2Data(unpackedData, unpackedLen);
break;
case Format::ASTC:
ret = initWithASTCData(unpackedData, unpackedLen);
break;
case Format::S3TC:
ret = initWithS3TCData(unpackedData, unpackedLen);
break;
@ -649,7 +673,6 @@ bool Image::isEtc2(const unsigned char * data, ssize_t dataLen)
return etc2_pkm_is_valid((etc2_byte*)data) ? true : false;
}
bool Image::isS3TC(const unsigned char * data, ssize_t /*dataLen*/)
{
S3TCTexHeader *header = (S3TCTexHeader *)data;
@ -661,6 +684,11 @@ bool Image::isS3TC(const unsigned char * data, ssize_t /*dataLen*/)
return true;
}
bool Image::isASTC(const unsigned char * data, ssize_t dataLen)
{
return astcIsValid(const_cast<astc_byte *>(data));
}
bool Image::isJpg(const unsigned char * data, ssize_t dataLen)
{
if (dataLen <= 4)
@ -744,6 +772,10 @@ Image::Format Image::detectFormat(const unsigned char * data, ssize_t dataLen)
{
return Format::ETC2;
}
else if (isASTC(data, dataLen))
{
return Format::ASTC;
}
else if (isS3TC(data, dataLen))
{
return Format::S3TC;
@ -774,6 +806,35 @@ const Image::PixelFormatInfo& Image::getPixelFormatInfo() const
return getPixelFormatInfoMap().at(_renderFormat);
}
Image::PixelFormat Image::getASTCFormat(const unsigned char *pHeader) const
{
int xdim = pHeader[ASTC_HEADER_MAGIC];
int ydim = pHeader[ASTC_HEADER_MAGIC + 1];
if (xdim == 4) return Image::PixelFormat::ASTC_RGBA_4x4;
if (xdim == 5) {
if (ydim == 4) return Image::PixelFormat::ASTC_RGBA_5x4;
return Image::PixelFormat::ASTC_RGBA_5x5;
}
if (xdim == 6) {
if (ydim == 5) return Image::PixelFormat::ASTC_RGBA_6x5;
return Image::PixelFormat::ASTC_RGBA_6x6;
}
if (xdim == 8) {
if (ydim == 5) return Image::PixelFormat::ASTC_RGBA_8x5;
if (ydim == 6) return Image::PixelFormat::ASTC_RGBA_8x6;
return Image::PixelFormat::ASTC_RGBA_8x8;
}
if (xdim == 10) {
if (ydim == 5) return Image::PixelFormat::ASTC_RGBA_10x5;
if (ydim == 6) return Image::PixelFormat::ASTC_RGBA_10x6;
if (ydim == 8) return Image::PixelFormat::ASTC_RGBA_10x8;
return Image::PixelFormat::ASTC_RGBA_10x10;
}
if (ydim == 10) return Image::PixelFormat::ASTC_RGBA_12x10;
return Image::PixelFormat::ASTC_RGBA_12x12;
}
namespace
{
/*
@ -894,6 +955,7 @@ bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen)
jpeg_start_decompress( &cinfo );
/* init image info */
_isCompressed = false;
_width = cinfo.output_width;
_height = cinfo.output_height;
_hasPremultipliedAlpha = false;
@ -974,6 +1036,7 @@ bool Image::initWithPngData(const unsigned char * data, ssize_t dataLen)
// read png file info
png_read_info(png_ptr, info_ptr);
_isCompressed = false;
_width = png_get_image_width(png_ptr, info_ptr);
_height = png_get_image_height(png_ptr, info_ptr);
png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
@ -1366,11 +1429,17 @@ bool Image::initWithPVRv2Data(const unsigned char * data, ssize_t dataLen)
//Get size of mipmap
_width = width = CC_SWAP_INT32_LITTLE_TO_HOST(header->width);
_height = height = CC_SWAP_INT32_LITTLE_TO_HOST(header->height);
_isCompressed = true;
//Get ptr to where data starts..
dataLength = CC_SWAP_INT32_LITTLE_TO_HOST(header->dataLength);
assert(Configuration::getInstance()->supportsPVRTC());
if (Configuration::getInstance()->supportsPVRTC() == false)
{
CCLOG("initWithPVRv2Data: ERROR: Unsupported PVR Compress texture on this device");
return false;
}
//Move by size of header
_dataLen = dataLen - sizeof(PVRv2TexHeader);
@ -1496,12 +1565,18 @@ bool Image::initWithPVRv3Data(const unsigned char * data, ssize_t dataLen)
// sizing
int width = CC_SWAP_INT32_LITTLE_TO_HOST(header->width);
int height = CC_SWAP_INT32_LITTLE_TO_HOST(header->height);
_isCompressed = true;
_width = width;
_height = height;
int dataOffset = 0, dataSize = 0;
int blockSize = 0, widthBlocks = 0, heightBlocks = 0;
assert(Configuration::getInstance()->supportsPVRTC());
if (Configuration::getInstance()->supportsPVRTC() == false)
{
CCLOG("initWithPVRv3Data: ERROR: Unsupported PVR Compress texture on this device");
return false;
}
_dataLen = dataLen - (sizeof(PVRv3TexHeader) + header->metadataLength);
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
@ -1585,6 +1660,7 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
_width = etc1_pkm_get_width(header);
_height = etc1_pkm_get_height(header);
_isCompressed = true;
if (0 == _width || 0 == _height)
{
@ -1592,6 +1668,11 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
}
assert(Configuration::getInstance()->supportsETC());
if (Configuration::getInstance()->supportsETC() == false)
{
CCLOG("initWithETCData: ERROR: Unsupported ETC Compress texture on this device");
return false;
}
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
#ifdef GL_ETC1_RGB8_OES
@ -1617,6 +1698,7 @@ bool Image::initWithETC2Data(const unsigned char * data, ssize_t dataLen)
_width = etc2_pkm_get_width(header);
_height = etc2_pkm_get_height(header);
_isCompressed = true;
if (0 == _width || 0 == _height)
{
@ -1624,6 +1706,11 @@ bool Image::initWithETC2Data(const unsigned char * data, ssize_t dataLen)
}
assert(Configuration::getInstance()->supportsETC2());
if (Configuration::getInstance()->supportsETC2() == false)
{
CCLOG("initWithETC2Data: ERROR: Unsupported ETC2 Compress texture on this device");
return false;
}
etc2_uint32 format = etc2_pkm_get_format(header);
if (format == ETC2_RGB_NO_MIPMAPS)
@ -1718,6 +1805,45 @@ bool Image::initWithTGAData(tImageTGA* tgaData)
return ret;
}
bool Image::initWithASTCData(const unsigned char *data, ssize_t dataLen)
{
const auto *header = static_cast<const astc_byte *>(data);
//check the data
if (!astcIsValid(header))
{
return false;
}
_width = astcGetWidth(header);
_height = astcGetHeight(header);
_isCompressed = true;
if (0 == _width || 0 == _height)
{
return false;
}
assert(Configuration::getInstance()->supportsASTC());
if (Configuration::getInstance()->supportsASTC() == false)
{
CCLOG("initWithASTCData: ERROR: Unsupported ASTC Compress texture on this device");
return false;
}
_renderFormat = getASTCFormat(header);
_dataLen = dataLen - ASTC_HEADER_SIZE;
_data = static_cast<unsigned char *>(malloc(_dataLen * sizeof(unsigned char)));
if (_data == nullptr)
{
CCLOG("initWithASTCData: ERROR : Image _data is null!");
return false;
}
memcpy(_data, static_cast<const unsigned char *>(data) + ASTC_HEADER_SIZE, _dataLen);
return true;
}
static uint32_t makeFourCC(char ch0, char ch1, char ch2, char ch3)
{
const uint32_t fourCC = ((uint32_t)(char)(ch0) | ((uint32_t)(char)(ch1) << 8) | ((uint32_t)(char)(ch2) << 16) | ((uint32_t)(char)(ch3) << 24 ));
@ -1748,6 +1874,11 @@ bool Image::initWithS3TCData(const unsigned char * data, ssize_t dataLen)
int height = _height;
assert(Configuration::getInstance()->supportsS3TC());
if (Configuration::getInstance()->supportsS3TC() == false)
{
CCLOG("initWithS3TCData: ERROR: Unsupported S3TC Compress texture on this device");
return false;
}
_dataLen = dataLen - sizeof(S3TCTexHeader);
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
@ -1826,6 +1957,7 @@ bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
_renderFormat = config.input.has_alpha?Image::PixelFormat::RGBA8888:Image::PixelFormat::RGB888;
_width = config.input.width;
_height = config.input.height;
_isCompressed = false;
//we ask webp to give data with premultiplied alpha
_hasPremultipliedAlpha = (config.input.has_alpha != 0);
@ -1866,6 +1998,7 @@ bool Image::initWithRawData(const unsigned char * data, ssize_t dataLen, int wid
_width = width;
_hasPremultipliedAlpha = preMulti;
_renderFormat = Image::PixelFormat::RGBA8888;
_isCompressed = false;
// only RGBA8888 supported
int bytesPerComponent = 4;

View File

@ -84,6 +84,8 @@ public:
ETC,
//! ETC2
ETC2,
//! ASTC
ASTC,
//! S3TC
S3TC,
//! ATITC
@ -135,6 +137,34 @@ public:
ETC2_RGB,
//! ETC-compressed texture: GL_COMPRESSED_RGBA8_ETC2
ETC2_RGBA,
//! ASTC-compressed texture: ASTC_4x4
ASTC_RGBA_4x4,
//! ASTC-compressed texture: ASTC_5x4
ASTC_RGBA_5x4,
//! ASTC-compressed texture: ASTC_5x5
ASTC_RGBA_5x5,
//! ASTC-compressed texture: ASTC_6x5
ASTC_RGBA_6x5,
//! ASTC-compressed texture: ASTC_6x6
ASTC_RGBA_6x6,
//! ASTC-compressed texture: ASTC_8x5
ASTC_RGBA_8x5,
//! ASTC-compressed texture: ASTC_8x6
ASTC_RGBA_8x6,
//! ASTC-compressed texture: ASTC_8x8
ASTC_RGBA_8x8,
//! ASTC-compressed texture: ASTC_10x5
ASTC_RGBA_10x5,
//! ASTC-compressed texture: ASTC_10x6
ASTC_RGBA_10x6,
//! ASTC-compressed texture: ASTC_10x8
ASTC_RGBA_10x8,
//! ASTC-compressed texture: ASTC_10x10
ASTC_RGBA_10x10,
//! ASTC-compressed texture: ASTC_12x10
ASTC_RGBA_12x10,
//! ASTC-compressed texture: ASTC_12x12
ASTC_RGBA_12x12,
//! S3TC-compressed texture: S3TC_Dxt1
S3TC_DXT1,
//! S3TC-compressed texture: S3TC_Dxt3
@ -244,6 +274,7 @@ protected:
bool initWithPVRv3Data(const unsigned char * data, ssize_t dataLen);
bool initWithETCData(const unsigned char * data, ssize_t dataLen);
bool initWithETC2Data(const unsigned char * data, ssize_t dataLen);
bool initWithASTCData(const unsigned char * data, ssize_t dataLen);
bool initWithS3TCData(const unsigned char * data, ssize_t dataLen);
typedef struct sImageTGA tImageTGA;
@ -275,6 +306,7 @@ protected:
// false if we can't auto detect the image is premultiplied or not.
bool _hasPremultipliedAlpha;
std::string _filePath;
bool _isCompressed = false;
protected:
// noncopyable
@ -299,7 +331,10 @@ protected:
bool isPvr(const unsigned char * data, ssize_t dataLen);
bool isEtc(const unsigned char * data, ssize_t dataLen);
bool isEtc2(const unsigned char * data, ssize_t dataLen);
bool isASTC(const unsigned char * data, ssize_t detaLen);
bool isS3TC(const unsigned char * data,ssize_t dataLen);
PixelFormat getASTCFormat(const unsigned char * pHeader) const;
};
// end of platform group

View File

@ -53,6 +53,7 @@ THE SOFTWARE.
#define CC_PLATFORM_TIZEN 11
#define CC_PLATFORM_QT5 12
#define CC_PLATFORM_WINRT 13
#define CC_PLATFORM_OPENHARMONY 14
// Determine target platform by compile environment macro.
#define CC_TARGET_PLATFORM CC_PLATFORM_UNKNOWN
@ -135,6 +136,12 @@ THE SOFTWARE.
#define CC_TARGET_PLATFORM CC_PLATFORM_WINRT
#endif
//OPENHARMONY
#if defined(OPENHARMONY)
#undef CC_TARGET_PLATFORM
#define CC_TARGET_PLATFORM CC_PLATFORM_OPENHARMONY
#endif
//////////////////////////////////////////////////////////////////////////
// post configure
//////////////////////////////////////////////////////////////////////////
@ -150,5 +157,15 @@ THE SOFTWARE.
#endif
#endif // CC_PLATFORM_WIN32
#if (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#ifdef __cplusplus
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
#else
#define __BEGIN_DECLS
#define __END_DECLS
#endif
#endif // CC_PLATFORM_OPENHARMONY
/// @endcond
#endif // __BASE_CC_PLATFORM_CONFIG_H__

View File

@ -42,6 +42,8 @@ THE SOFTWARE.
#include "platform/winrt/CCPlatformDefine-winrt.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#include "platform/linux/CCPlatformDefine-linux.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "platform/openharmony/CCPlatformDefine-openharmony.h"
#endif
/// @endcond

View File

@ -42,11 +42,12 @@ public class Cocos2dxAccelerometer implements SensorEventListener {
// Fields
// ===========================================================
private final Context mContext;
private final SensorManager mSensorManager;
private final Sensor mAcceleration;
private final Sensor mAccelerationIncludingGravity;
private final Sensor mGyroscope;
private SensorManager mSensorManager;
private Sensor mAcceleration;
private Sensor mAccelerationIncludingGravity;
private Sensor mGyroscope;
private int mSamplingPeriodUs = SensorManager.SENSOR_DELAY_GAME;
private boolean mEnableSensor = false;
class Acceleration {
public float x = 0.0f;
@ -74,24 +75,39 @@ public class Cocos2dxAccelerometer implements SensorEventListener {
public Cocos2dxAccelerometer(final Context context) {
mContext = context;
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccelerationIncludingGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
// ===========================================================
// Getter & Setter
// ===========================================================
public void enable() {
mSensorManager.registerListener(this, mAcceleration, mSamplingPeriodUs);
mSensorManager.registerListener(this, mAccelerationIncludingGravity, mSamplingPeriodUs);
mSensorManager.registerListener(this, mGyroscope, mSamplingPeriodUs);
if (mEnableSensor) {
if (null == mSensorManager) {
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccelerationIncludingGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
mSensorManager.registerListener(this, mAcceleration, mSamplingPeriodUs);
mSensorManager.registerListener(this, mAccelerationIncludingGravity, mSamplingPeriodUs);
mSensorManager.registerListener(this, mGyroscope, mSamplingPeriodUs);
}
}
public void enableAccelerometer(boolean enabled) {
mEnableSensor = enabled;
if (enabled) {
enable();
} else {
disable();
}
}
public void disable() {
this.mSensorManager.unregisterListener(this);
if (mEnableSensor && null != mSensorManager) {
this.mSensorManager.unregisterListener(this);
}
}
public void setInterval(float interval) {

View File

@ -28,6 +28,7 @@ package org.cocos2dx.lib;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
@ -296,7 +297,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
e.printStackTrace();
}
mCocos2dxOrientationHelper = new Cocos2dxOrientationHelper(this);
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
mCocos2dxOrientationHelper = new Cocos2dxOrientationHelper(this);
}
}
public void setKeepScreenOn(boolean value) {
@ -390,7 +393,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
Cocos2dxAudioFocusManager.registerAudioFocusListener(this);
Utils.hideVirtualButton();
resumeIfHasFocus();
mCocos2dxOrientationHelper.onResume();
if (null != mCocos2dxOrientationHelper) {
mCocos2dxOrientationHelper.onResume();
}
}
@Override
@ -419,7 +424,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this);
Cocos2dxHelper.onPause();
mGLSurfaceView.onPause();
mCocos2dxOrientationHelper.onPause();
if (null != mCocos2dxOrientationHelper) {
mCocos2dxOrientationHelper.onPause();
}
}
@Override

View File

@ -82,7 +82,6 @@ public class Cocos2dxHelper {
private static AssetManager sAssetManager;
private static Cocos2dxAccelerometer sCocos2dxAccelerometer;
private static boolean sAccelerometerEnabled;
private static boolean sCompassEnabled;
private static boolean sActivityVisible;
private static String sPackageName;
@ -314,9 +313,9 @@ public class Cocos2dxHelper {
public static String getCurrentLanguageCode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return LocaleList.getDefault().get(0).getLanguage();
return LocaleList.getDefault().get(0).toString();
} else {
return Locale.getDefault().getLanguage();
return Locale.getDefault().toString();
}
}
@ -329,8 +328,7 @@ public class Cocos2dxHelper {
}
public static void enableAccelerometer() {
Cocos2dxHelper.sAccelerometerEnabled = true;
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
Cocos2dxHelper.sCocos2dxAccelerometer.enableAccelerometer(true);
}
public static void setAccelerometerInterval(float interval) {
@ -338,8 +336,7 @@ public class Cocos2dxHelper {
}
public static void disableAccelerometer() {
Cocos2dxHelper.sAccelerometerEnabled = false;
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
Cocos2dxHelper.sCocos2dxAccelerometer.enableAccelerometer(false);
}
public static void setKeepScreenOn(boolean value) {
@ -437,16 +434,12 @@ public class Cocos2dxHelper {
public static void onResume() {
sActivityVisible = true;
if (Cocos2dxHelper.sAccelerometerEnabled) {
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
}
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
}
public static void onPause() {
sActivityVisible = false;
if (Cocos2dxHelper.sAccelerometerEnabled) {
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
}
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
}
public static void onEnterBackground() {

View File

@ -1,4 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.cocos2dx.lib">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>

View File

@ -3,7 +3,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
buildToolsVersion PROP_BUILD_TOOLS_VERSION
namespace "org.cocos2dx.lib"
defaultConfig {
minSdkVersion PROP_MIN_SDK_VERSION
targetSdkVersion PROP_TARGET_SDK_VERSION

View File

@ -265,7 +265,8 @@ void Device::vibrate(float duration)
}
float Device::getBatteryLevel()
{
{
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
return [UIDevice currentDevice].batteryLevel;
}

View File

@ -46,4 +46,33 @@ THE SOFTWARE.
//#define GL_MAX_SAMPLES_APPLE GL_MAX_SAMPLES
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
#endif // CC_PLATFORM_IOS

View File

@ -0,0 +1,86 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "AppDelegate.h"
#include "cocos2d.h"
#include "cocos/scripting/js-bindings/manual/jsb_module_register.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/event/EventDispatcher.h"
#include "cocos/scripting/js-bindings/manual/jsb_classtype.hpp"
USING_NS_CC;
AppDelegate::AppDelegate(int width, int height) : Application("Cocos Game", width, height)
{
}
AppDelegate::~AppDelegate()
{
}
bool AppDelegate::applicationDidFinishLaunching()
{
se::ScriptEngine *se = se::ScriptEngine::getInstance();
jsb_set_xxtea_key("");
jsb_init_file_operation_delegate();
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
// Enable debugger here
jsb_enable_debugger("0.0.0.0", 6086, false);
#endif
se->setExceptionCallback([](const char *location, const char *message, const char *stack) {
// Send exception information to server like Tencent Bugly.
cocos2d::log("\nUncaught Exception:\n - location : %s\n - msg : %s\n - detail : \n %s\n", location, message, stack);
});
jsb_register_all_modules();
se->start();
se::AutoHandleScope hs;
// jsb_run_script("jsb-adapter/jsb-builtin.js");
// jsb_run_script("main.js");
se->addAfterCleanupHook([]() {
JSBClassType::destroy();
});
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::onPause()
{
}
// this function will be called when the app is active again
void AppDelegate::onResume()
{
}

View File

@ -0,0 +1,55 @@
/****************************************************************************
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/CCApplication.h"
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by Director.
*/
class AppDelegate : public cocos2d::Application
{
public:
AppDelegate(int width, int height);
virtual ~AppDelegate();
/**
@brief Implement Director and Scene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching() override;
/**
@brief The function be called when the application is paused
*/
virtual void onPause() override;
/**
@brief The function be called when the application is resumed
*/
virtual void onResume() override;
};

View File

@ -0,0 +1,143 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "platform/CCDevice.h"
#include "platform/openharmony/napi/NapiHelper.h"
NS_CC_BEGIN
int Device::getDPI() {
float value;
NapiHelper::napiCallFunction("getDPI", &value);
return value;
}
int Device::getDevicePixelRatio() {
// float value;
// NapiHelper::napiCallFunction("getPixelRation", &value);
// return value;
// TODO(qgh):openharmony does support this interface, but returning a value of 1.5 will cause the entire page to zoom in.
return 1;
}
void Device::setKeepScreenOn(bool value) {
CC_UNUSED_PARAM(value);
}
cocos2d::Vec4 Device::getSafeAreaEdge() {
return cocos2d::Vec4();
}
Device::Rotation Device::getDeviceRotation() {
int32_t value = 0;
NapiHelper::napiCallFunction("getDeviceOrientation", &value);
if(value == 0) {
return cocos2d::Device::Rotation::_0;
} else if(value == 1) {
// TODO(qgh): The openharmony platform is rotated clockwise.
return cocos2d::Device::Rotation::_270;
} else if(value == 2) {
return cocos2d::Device::Rotation::_180;
} else if(value == 3) {
// TODO(qgh): The openharmony platform is rotated clockwise.
return cocos2d::Device::Rotation::_90;
}
CC_ASSERT(false);
return cocos2d::Device::Rotation::_0;
}
Device::NetworkType Device::getNetworkType() {
int32_t value;
NapiHelper::napiCallFunction("getNetworkType", &value);
if(value == 0) {
return cocos2d::Device::NetworkType::WWAN;
} else if(value == 1 or value == 3) {
return cocos2d::Device::NetworkType::LAN;
} else {
return cocos2d::Device::NetworkType::NONE;
}
}
float Device::getBatteryLevel() {
int32_t value;
NapiHelper::napiCallFunction("getBatteryLevel", &value);
return value;
}
const Device::MotionValue& Device::getDeviceMotionValue() {
std::vector<float> v;
NapiHelper::napiCallFunction<std::vector<float> >("getDeviceMotionValue", &v);
static MotionValue motionValue;
if (!v.empty()) {
motionValue.accelerationIncludingGravityX = v[0];
motionValue.accelerationIncludingGravityY = v[1];
motionValue.accelerationIncludingGravityZ = v[2];
motionValue.accelerationX = v[3];
motionValue.accelerationY = v[4];
motionValue.accelerationZ = v[5];
motionValue.rotationRateAlpha = v[6];
motionValue.rotationRateBeta = v[7];
motionValue.rotationRateGamma = v[8];
} else {
memset(&motionValue, 0, sizeof(motionValue));
}
return motionValue;
}
std::string Device::getDeviceModel() {
std::string str;
NapiHelper::napiCallFunction<std::string>("getDeviceModel", &str);
return str;
}
void Device::setAccelerometerEnabled(bool isEnabled) {
// if (isEnabled)
// {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "enableAccelerometer");
// }
// else
// {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "disableAccelerometer");
// }
}
void Device::setAccelerometerInterval(float interval) {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "setAccelerometerInterval", interval);
}
void Device::vibrate(float duration) {
int32_t value = 0;
NapiHelper::napiCallFunctionByFloatArgs("vibrate", duration, &value);
}
NS_CC_END
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY

View File

@ -0,0 +1,80 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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.
****************************************************************************/
#ifndef __CCGL_H__
#define __CCGL_H__
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#define glClearDepth glClearDepthf
#define glDeleteVertexArrays glDeleteVertexArraysOES
#define glGenVertexArrays glGenVertexArraysOES
#define glBindVertexArray glBindVertexArrayOES
#define glMapBuffer glMapBufferOES
#define glUnmapBuffer glUnmapBufferOES
#define glTexImage3D glTexImage3DOES
#define glCompressedTexImage3D glCompressedTexImage3DOES
#define glCompressedTexSubImage3D glCompressedTexSubImage3DOES
#define glTexSubImage3D glTexSubImage3DOES
#define glDepthRange glDepthRangef
#define glSubImage3D glSubImage3DOES
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
#define GL_WRITE_ONLY GL_WRITE_ONLY_OES
// GL_GLEXT_PROTOTYPES isn't defined in glplatform.h on android ndk r7
// we manually define it here
#include <GLES2/gl2platform.h>
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES 1
#endif
// normal process
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
// gl2.h doesn't define GLchar on Android
typedef char GLchar;
// android defines GL_BGRA_EXT but not GL_BRGA
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
//declare here while define in EGLView_android.cpp
extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOESEXT;
extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOESEXT;
extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOESEXT;
#define glGenVertexArraysOES glGenVertexArraysOESEXT
#define glBindVertexArrayOES glBindVertexArrayOESEXT
#define glDeleteVertexArraysOES glDeleteVertexArraysOESEXT
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#endif // __CCGL_H__

View File

@ -0,0 +1,66 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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.
****************************************************************************/
#ifndef __CCPLATFORMDEFINE_H__
#define __CCPLATFORMDEFINE_H__
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <sys/types.h>
#include <hilog/log.h>
#define CC_DLL
#define CC_NO_MESSAGE_PSEUDOASSERT(cond) \
if (!(cond)) { \
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", \
"assert file:%{public}s function:%{public}s line:%{public}d", \
__FILE__, __FUNCTION__, __LINE__); \
}
#define CC_MESSAGE_PSEUDOASSERT(cond, msg) \
if (!(cond)) { \
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", \
"assert file:%{public}s function:%{public}s line:%{public}d, %{public}s", \
__FILE__, __FUNCTION__, __LINE__, msg); \
}
#define CC_ASSERT(cond) CC_NO_MESSAGE_PSEUDOASSERT(cond)
#define CC_UNUSED_PARAM(unusedparam) (void)unusedparam
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#endif /* __CCPLATFORMDEFINE_H__*/

View File

@ -0,0 +1,233 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "cocos/platform/openharmony/FileUtils-openharmony.h"
#include <hilog/log.h>
#include <sys/stat.h>
#include <cstdio>
#include <regex>
#include <string>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <assert.h>
#include "base/CCLog.h"
#include "scripting/js-bindings/jswrapper/napi/HelperMacros.h"
#define ASSETS_FOLDER_WRITEABLE_PATH "/data/accounts/account_0/applications/ohos.example.xcomponent1/ohos.example.xcomponent1/writeable_path"
#include "rawfile/raw_file_manager.h"
namespace cocos2d {
NativeResourceManager* FileUtilsOpenHarmony::_nativeResourceManager = nullptr;
FileUtils *createFileUtils() {
return new (std::nothrow) FileUtilsOpenHarmony();
}
FileUtilsOpenHarmony::FileUtilsOpenHarmony() {
// init();
}
std::string FileUtilsOpenHarmony::_ohWritablePath;
bool FileUtilsOpenHarmony::initResourceManager(napi_env env, napi_value param) {
_nativeResourceManager = OH_ResourceManager_InitNativeResourceManager(env, param);
return true;
}
FileUtils* FileUtils::getInstance()
{
if (s_sharedFileUtils == nullptr)
{
s_sharedFileUtils = new (std::nothrow) FileUtilsOpenHarmony();
if (!s_sharedFileUtils->init())
{
delete s_sharedFileUtils;
s_sharedFileUtils = nullptr;
cocos2d::log("ERROR: Could not init CCFileUtilsOpenHarmony");
}
}
return s_sharedFileUtils;
}
FileUtils::Status FileUtilsOpenHarmony::getContents(const std::string &filename, ResizableBuffer *buffer) {
if (filename.empty()) {
return FileUtils::Status::NotExists;
}
std::string fullPath = fullPathForFilename(filename);
if (fullPath.empty()) {
return FileUtils::Status::NotExists;
}
if (fullPath[0] == '/') {
return FileUtils::getContents(fullPath, buffer);
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return FileUtils::Status::NotInitialized;
}
RawFile *rawFile = OH_ResourceManager_OpenRawFile(_nativeResourceManager, fullPath.c_str());
if (nullptr == rawFile) {
return FileUtils::Status::OpenFailed;
}
auto size = OH_ResourceManager_GetRawFileSize(rawFile);
buffer->resize(size);
assert(buffer->buffer());
int readsize = OH_ResourceManager_ReadRawFile(rawFile, buffer->buffer(), size);
// TODO(unknown): read error
if (readsize < size) {
if (readsize >= 0) {
buffer->resize(readsize);
}
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::ReadFailed;
}
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::OK;
}
FileUtilsOpenHarmony::~FileUtilsOpenHarmony() {
if(_nativeResourceManager)
OH_ResourceManager_ReleaseNativeResourceManager(_nativeResourceManager);
}
bool FileUtilsOpenHarmony::init() {
_defaultResRootPath = "";
return FileUtils::init();
}
bool FileUtilsOpenHarmony::isAbsolutePath(const std::string &strPath) const {
return !strPath.empty() && (strPath[0] == '/');
}
std::string FileUtilsOpenHarmony::getWritablePath() const {
std::string dir("");
if (_ohWritablePath.length() > 0)
{
dir.append(_ohWritablePath).append("/");
}
return dir;
}
bool FileUtilsOpenHarmony::isFileExistInternal(const std::string &strFilePath) const {
if (strFilePath.empty()) {
return false;
}
std::string strPath = strFilePath;
if (!isAbsolutePath(strPath)) { // Not absolute path, add the default root path at the beginning.
strPath.insert(0, _defaultResRootPath);
} else {
FILE *fp = fopen(strFilePath.c_str(), "r");
if (fp)
{
fclose(fp);
return true;
}
return false;
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return false;
}
RawFile* rawFile = OH_ResourceManager_OpenRawFile(_nativeResourceManager, strPath.c_str());
if(rawFile) {
OH_ResourceManager_CloseRawFile(rawFile);
return true;
}
return false;
}
FileUtils::Status FileUtilsOpenHarmony::getRawFileDescriptor(const std::string &filename,RawFileDescriptor& descriptor) {
if (filename.empty()) {
return FileUtils::Status::NotExists;
}
std::string fullPath = fullPathForFilename(filename);
if (fullPath.empty()) {
return FileUtils::Status::NotExists;
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return FileUtils::Status::NotInitialized;
}
RawFile *rawFile = OH_ResourceManager_OpenRawFile(_nativeResourceManager, fullPath.c_str());
if (nullptr == rawFile) {
return FileUtils::Status::OpenFailed;
}
bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
if (!result) {
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::OpenFailed;
}
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::OK;
}
bool FileUtilsOpenHarmony::isDirectoryExistInternal(const std::string &dirPath) const {
if (dirPath.empty()) return false;
std::string dirPathMf = dirPath[dirPath.length() - 1] == '/' ? dirPath.substr(0, dirPath.length() - 1) : dirPath;
if (dirPathMf[0] == '/') {
struct stat st;
return stat(dirPathMf.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
}
if (dirPathMf.find(_defaultResRootPath) == 0) {
dirPathMf = dirPathMf.substr(_defaultResRootPath.length(), dirPathMf.length());
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return false;
}
RawDir* rawDir = OH_ResourceManager_OpenRawDir(_nativeResourceManager, dirPathMf.c_str());
if(rawDir) {
OH_ResourceManager_CloseRawDir(rawDir);
return true;
}
return false;
}
} // namespace cc

View File

@ -0,0 +1,66 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
//clang-format off
#include <cstdint>
//clang-format on
#include <rawfile/raw_dir.h>
#include <rawfile/raw_file.h>
#include <rawfile/raw_file_manager.h>
#include "cocos/platform/CCFileUtils.h"
#include <napi/native_api.h>
class NativeResourceManager;
namespace cocos2d {
class CC_DLL FileUtilsOpenHarmony : public FileUtils {
public:
FileUtilsOpenHarmony();
virtual ~FileUtilsOpenHarmony() override;
static bool initResourceManager(napi_env env, napi_value info);
bool init() override;
bool isAbsolutePath(const std::string &strPath) const override;
FileUtils::Status getRawFileDescriptor(const std::string &filename,RawFileDescriptor& descriptor);
virtual std::string getWritablePath() const override;
virtual FileUtils::Status getContents(const std::string &filename, ResizableBuffer *buffer) override;
static std::string _ohWritablePath;
private:
virtual bool isFileExistInternal(const std::string &strFilePath) const override;
virtual bool isDirectoryExistInternal(const std::string &dirPath) const override;
friend class FileUtils;
static NativeResourceManager* _nativeResourceManager;
};
} // namespace cc

View File

@ -0,0 +1,291 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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/openharmony/OpenHarmonyPlatform.h"
#include "platform/CCPlatformDefine.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <napi/native_api.h>
#include "cocos2d.h"
#include "cocos/scripting/js-bindings/manual/jsb_module_register.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/event/EventDispatcher.h"
#include "cocos/scripting/js-bindings/manual/jsb_classtype.hpp"
#include "base/CCScheduler.h"
#include "cocos/scripting/js-bindings/event/EventDispatcher.h"
#include <sstream>
#include <chrono>
namespace {
void sendMsgToWorker(const cocos2d::MessageType& type, void* component, void* window) {
cocos2d::OpenHarmonyPlatform* platform = cocos2d::OpenHarmonyPlatform::getInstance();
cocos2d::WorkerMessageData data{type, static_cast<void*>(component), window};
platform->enqueue(data);
}
void onSurfaceCreatedCB(OH_NativeXComponent* component, void* window) {
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_SURFACE_CREATED, component, window);
}
void dispatchTouchEventCB(OH_NativeXComponent* component, void* window) {
OH_NativeXComponent_TouchEvent touchEvent;
int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
return;
}
cocos2d::TouchEvent* ev = new cocos2d::TouchEvent;
if (touchEvent.type == OH_NATIVEXCOMPONENT_DOWN) {
ev->type = cocos2d::TouchEvent::Type::BEGAN;
} else if (touchEvent.type == OH_NATIVEXCOMPONENT_MOVE) {
ev->type = cocos2d::TouchEvent::Type::MOVED;
} else if (touchEvent.type == OH_NATIVEXCOMPONENT_UP) {
ev->type = cocos2d::TouchEvent::Type::ENDED;
} else if (touchEvent.type == OH_NATIVEXCOMPONENT_CANCEL) {
ev->type = cocos2d::TouchEvent::Type::CANCELLED;
}
for(int i = 0; i < touchEvent.numPoints; ++i) {
cocos2d::TouchInfo touchInfo;
touchInfo.index = touchEvent.touchPoints[i].id;
touchInfo.x = touchEvent.touchPoints[i].x;
touchInfo.y = touchEvent.touchPoints[i].y;
if (touchEvent.id == touchInfo.index) {
ev->touches.push_back(touchInfo);
}
}
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_TOUCH_EVENT, reinterpret_cast<void*>(ev), window);
}
void onSurfaceChangedCB(OH_NativeXComponent* component, void* window) {
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_SURFACE_CHANGED, component, window);
}
void onSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) {
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_SURFACE_DESTROY, component, window);
}
bool setCanvasCallback(se::Object* global) {
cocos2d::OpenHarmonyPlatform* platform = cocos2d::OpenHarmonyPlatform::getInstance();
uint32_t innerWidth = (uint32_t)platform->width_;
uint32_t innerHeight = (uint32_t)platform->height_;
global->setProperty("innerWidth", se::Value(innerWidth));
global->setProperty("innerHeight", se::Value(innerHeight));
LOGD("exit setCanvasCallback setCanvasCallback");
return true;
}
} // namespace
namespace cocos2d {
OpenHarmonyPlatform::OpenHarmonyPlatform() {
_callback.OnSurfaceCreated = onSurfaceCreatedCB;
_callback.OnSurfaceChanged = onSurfaceChangedCB;
_callback.OnSurfaceDestroyed = onSurfaceDestroyedCB;
_callback.DispatchTouchEvent = dispatchTouchEventCB;
}
int32_t OpenHarmonyPlatform::init() {
return 0;
}
OpenHarmonyPlatform* OpenHarmonyPlatform::getInstance() {
static OpenHarmonyPlatform platform;
return &platform;
}
int32_t OpenHarmonyPlatform::run(int argc, const char** argv) {
LOGD("begin openharmonyplatform run");
int width = static_cast<int>(width_);
int height = static_cast<int>(height_);
g_app = new AppDelegate(width, height);
g_app->applicationDidFinishLaunching();
EventDispatcher::init();
g_started = true;
LOGD("end openharmonyplatform run");
return 0;
}
void OpenHarmonyPlatform::setNativeXComponent(OH_NativeXComponent* component) {
_component = component;
OH_NativeXComponent_RegisterCallback(_component, &_callback);
}
void OpenHarmonyPlatform::enqueue(const WorkerMessageData& msg) {
_messageQueue.enqueue(msg);
triggerMessageSignal();
}
void OpenHarmonyPlatform::triggerMessageSignal() {
if(_workerLoop != nullptr) {
// It is possible that when the message is sent, the worker thread has not yet started.
uv_async_send(&_messageSignal);
}
}
bool OpenHarmonyPlatform::dequeue(WorkerMessageData* msg) {
return _messageQueue.dequeue(msg);
}
// static
void OpenHarmonyPlatform::onMessageCallback(const uv_async_t* /* req */) {
void* window = nullptr;
WorkerMessageData msgData;
OpenHarmonyPlatform* platform = OpenHarmonyPlatform::getInstance();
while (true) {
//loop until all msg dispatch
if (!platform->dequeue(reinterpret_cast<WorkerMessageData*>(&msgData))) {
// Queue has no data
break;
}
if ((msgData.type >= MessageType::WM_XCOMPONENT_SURFACE_CREATED) && (msgData.type <= MessageType::WM_XCOMPONENT_SURFACE_DESTROY)) {
if (msgData.type == MessageType::WM_XCOMPONENT_TOUCH_EVENT) {
TouchEvent* ev = reinterpret_cast<TouchEvent*>(msgData.data);
EventDispatcher::dispatchTouchEvent(*ev);
delete ev;
ev = nullptr;
} else if (msgData.type == MessageType::WM_XCOMPONENT_SURFACE_CREATED) {
OH_NativeXComponent* nativexcomponet = reinterpret_cast<OH_NativeXComponent*>(msgData.data);
CC_ASSERT(nativexcomponet != nullptr);
platform->onSurfaceCreated(nativexcomponet, msgData.window);
} else if (msgData.type == MessageType::WM_XCOMPONENT_SURFACE_CHANGED) {
OH_NativeXComponent* nativexcomponet = reinterpret_cast<OH_NativeXComponent*>(msgData.data);
CC_ASSERT(nativexcomponet != nullptr);
platform->onSurfaceChanged(nativexcomponet, msgData.window);
} else if (msgData.type == MessageType::WM_XCOMPONENT_SURFACE_DESTROY) {
OH_NativeXComponent* nativexcomponet = reinterpret_cast<OH_NativeXComponent*>(msgData.data);
CC_ASSERT(nativexcomponet != nullptr);
platform->onSurfaceDestroyed(nativexcomponet, msgData.window);
} else {
CC_ASSERT(false);
}
continue;
}
if (msgData.type == MessageType::WM_APP_SHOW) {
platform->onShowNative();
} else if (msgData.type == MessageType::WM_APP_HIDE) {
platform->onHideNative();
} else if (msgData.type == MessageType::WM_APP_DESTROY) {
platform->onDestroyNative();
}
}
}
void OpenHarmonyPlatform::onCreateNative(napi_env env, uv_loop_t* loop) {
LOGD("OpenHarmonyPlatform::onCreateNative");
}
void OpenHarmonyPlatform::onShowNative() {
LOGD("OpenHarmonyPlatform::onShowNative");
EventDispatcher::dispatchOnResumeEvent();
}
void OpenHarmonyPlatform::onHideNative() {
LOGD("OpenHarmonyPlatform::onHideNative");
EventDispatcher::dispatchOnPauseEvent();
}
void OpenHarmonyPlatform::onDestroyNative() {
LOGD("OpenHarmonyPlatform::onDestroyNative");
}
void OpenHarmonyPlatform::timerCb(uv_timer_t* handle) {
if(OpenHarmonyPlatform::getInstance()->eglCore_ != nullptr){
OpenHarmonyPlatform::getInstance()->tick();
OpenHarmonyPlatform::getInstance()->eglCore_->Update();
}
}
void OpenHarmonyPlatform::workerInit(napi_env env, uv_loop_t* loop) {
_workerLoop = loop;
if (_workerLoop) {
uv_async_init(_workerLoop, &_messageSignal, reinterpret_cast<uv_async_cb>(OpenHarmonyPlatform::onMessageCallback));
if (!_messageQueue.empty()) {
triggerMessageSignal(); // trigger the signal to handle the pending message
}
}
}
void OpenHarmonyPlatform::requestVSync() {
// OH_NativeVSync_RequestFrame(OpenHarmonyPlatform::getInstance()->_nativeVSync, OnVSync, nullptr);
if (_workerLoop) {
// Todo: Starting the timer in this way is inaccurate and will be fixed later.
uv_timer_init(_workerLoop, &_timerHandle);
// The tick function needs to be called as quickly as possible because it is controlling the frame rate inside the engine.
uv_timer_start(&_timerHandle, &OpenHarmonyPlatform::timerCb, 0, 1);
}
}
int32_t OpenHarmonyPlatform::loop() {
return 0;
}
void OpenHarmonyPlatform::onSurfaceCreated(OH_NativeXComponent* component, void* window) {
eglCore_ = new EGLCore();
int32_t ret=OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
eglCore_->GLContextInit(window, width_, height_);
se::ScriptEngine *scriptEngine = se::ScriptEngine::getInstance();
scriptEngine->addRegisterCallback(setCanvasCallback);
if(g_app!=nullptr){
OpenHarmonyPlatform* platform = OpenHarmonyPlatform::getInstance();
g_app->updateViewSize(static_cast<float>(platform->width_), static_cast<float>(platform->height_));
}
LOGD("egl init finished.");
}
}
void OpenHarmonyPlatform::onSurfaceChanged(OH_NativeXComponent* component, void* window) {
int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
// nativeOnSizeChanged is firstly called before Application initiating.
if (g_app != nullptr) {
g_app->updateViewSize(width_, height_);
}
}
void OpenHarmonyPlatform::onSurfaceDestroyed(OH_NativeXComponent* component, void* window) {
}
void OpenHarmonyPlatform::tick() {
static std::chrono::steady_clock::time_point prevTime;
static std::chrono::steady_clock::time_point now;
static float dt = 0.f;
static float dtSum = 0.f;
static uint32_t jsbInvocationTotalCount = 0;
static uint32_t jsbInvocationTotalFrames = 0;
std::shared_ptr<Scheduler> scheduler = g_app->getScheduler();
scheduler->update(dt);
EventDispatcher::dispatchTickEvent(dt);
PoolManager::getInstance()->getCurrentPool()->clear();
now = std::chrono::steady_clock::now();
dt = std::chrono::duration_cast<std::chrono::microseconds>(now - prevTime).count() / 1000000.f;
prevTime = std::chrono::steady_clock::now();
}
}; // namespace cc

View File

@ -0,0 +1,96 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
// #include "platform/UniversalPlatform.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <uv.h>
#include <string>
#include <unordered_map>
#include <napi/native_api.h>
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "platform/openharmony/WorkerMessageQueue.h"
#include "scripting/js-bindings/event/EventDispatcher.h"
#include "platform/openharmony/render/egl_core.h"
#include "platform/openharmony/AppDelegate.h"
namespace cocos2d {
#define NANOSECONDS_PER_SECOND 1000000000
#define NANOSECONDS_60FPS 16666667L
class OpenHarmonyPlatform {
public:
OpenHarmonyPlatform();
int32_t init();
static OpenHarmonyPlatform* getInstance();
void onCreateNative(napi_env env, uv_loop_t* loop);
void onShowNative();
void onHideNative();
void onDestroyNative();
void workerInit(napi_env env, uv_loop_t* loop);
void setNativeXComponent(OH_NativeXComponent* component);
int32_t run(int argc, const char** argv);
void resume();
void pause();
int32_t loop();
void requestVSync();
void enqueue(const WorkerMessageData& data);
bool dequeue(WorkerMessageData* data);
void triggerMessageSignal();
public:
// Callback, called by ACE XComponent
void onSurfaceCreated(OH_NativeXComponent* component, void* window);
void onSurfaceChanged(OH_NativeXComponent* component, void* window);
void onSurfaceDestroyed(OH_NativeXComponent* component, void* window);
void dispatchTouchEvent(OH_NativeXComponent* component, void* window);
static void onMessageCallback(const uv_async_t* req);
static void timerCb(uv_timer_t* handle);
void tick();
OH_NativeXComponent* _component{nullptr};
OH_NativeXComponent_Callback _callback;
uv_timer_t _timerHandle;
uv_loop_t* _workerLoop{nullptr};
uv_async_t _messageSignal{};
WorkerMessageQueue _messageQueue;
EGLCore* eglCore_{nullptr};
uint64_t width_;
uint64_t height_;
Application* g_app = nullptr;
//game started
bool g_started = false;
};
} // namespace cc

View File

@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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/openharmony/WorkerMessageQueue.h"
namespace cocos2d {
void WorkerMessageQueue::enqueue(const WorkerMessageData& data) {
std::lock_guard<std::mutex> lck(_mutex);
_queue.push(data);
}
bool WorkerMessageQueue::dequeue(WorkerMessageData *data) {
std::lock_guard<std::mutex> lck(_mutex);
if (empty()) {
return false;
}
*data = _queue.front();
_queue.pop();
return true;
}
bool WorkerMessageQueue::empty() const {
return _queue.empty();
}
} // namespace cocos2d

View File

@ -0,0 +1,67 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <queue>
#include <thread>
#include <mutex>
namespace cocos2d {
enum class MessageType {
WM_XCOMPONENT_SURFACE_CREATED = 0,
WM_XCOMPONENT_TOUCH_EVENT,
WM_XCOMPONENT_SURFACE_CHANGED,
WM_XCOMPONENT_SURFACE_DESTROY,
WM_APP_SHOW,
WM_APP_HIDE,
WM_APP_DESTROY,
WM_VSYNC,
};
struct WorkerMessageData {
MessageType type;
void* data;
void* window;
};
class WorkerMessageQueue final {
public:
void enqueue(const WorkerMessageData& data);
bool dequeue(WorkerMessageData *data);
bool empty() const;
size_t size() const {
return _queue.size();
}
private:
std::mutex _mutex;
std::queue<WorkerMessageData> _queue;
};
} // namespace cc

View File

@ -0,0 +1,280 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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/CCApplication.h"
#include "platform/openharmony/napi/NapiHelper.h"
#include "base/CCScheduler.h"
#include "base/CCConfiguration.h"
#include "audio/include/AudioEngine.h"
#include "scripting/js-bindings/event/EventDispatcher.h"
#include "platform/openharmony/OpenHarmonyPlatform.h"
PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOESEXT = 0;
PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOESEXT = 0;
PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOESEXT = 0;
NS_CC_BEGIN
void Application::updateViewSize(int width, int height)
{
if(width <= 0 || height <= 0)
{
return;
}
_viewSize.x = width;
_viewSize.y = height;
// handle resize event
Application::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {
EventDispatcher::dispatchResizeEvent(width, height);
});
}
Application* Application::_instance = nullptr;
std::shared_ptr<Scheduler> Application::_scheduler = nullptr;
Application::Application(const std::string& name, int width, int height)
{
Application::_instance = this;
Configuration::getInstance();
_scheduler = std::make_shared<Scheduler>();
_renderTexture = new RenderTexture(width, height);
updateViewSize(width, height);
}
Application::~Application()
{
#if USE_AUDIO
AudioEngine::end();
#endif
EventDispatcher::destroy();
se::ScriptEngine::destroyInstance();
delete _renderTexture;
_renderTexture = nullptr;
Application::_instance = nullptr;
}
void Application::start()
{
if(!applicationDidFinishLaunching())
return;
}
void Application::restart()
{
// restartJSVM();
}
void Application::end()
{
int32_t value;
NapiHelper::napiCallFunction("terminateProcess", &value);
}
void Application::setMultitouch(bool /*value*/)
{
}
bool Application::applicationDidFinishLaunching()
{
return true;
}
void Application::onPause()
{
}
void Application::onResume()
{
}
void Application::setPreferredFramesPerSecond(int fps)
{
_fps = fps;
// setPreferredFramesPerSecondJNI(_fps);
}
bool Application::isDisplayStats() {
se::AutoHandleScope hs;
se::Value ret;
char commandBuf[100] = "cc.debug.isDisplayStats();";
se::ScriptEngine::getInstance()->evalString(commandBuf, 100, &ret);
return ret.toBoolean();
}
void Application::setDisplayStats(bool isShow) {
se::AutoHandleScope hs;
char commandBuf[100] = {0};
sprintf(commandBuf, "cc.debug.setDisplayStats(%s);", isShow ? "true" : "false");
se::ScriptEngine::getInstance()->evalString(commandBuf);
}
std::string Application::getCurrentLanguageCode() const {
std::string str;
NapiHelper::napiCallFunction<std::string>("getSystemLanguage", &str);
std::string::size_type pos = str.find('-');
if(pos != std::string::npos) {
str = str.substr(0, pos);
}
return str;
}
Application::LanguageType Application::getCurrentLanguage() const
{
std::string languageName = getCurrentLanguageCode(); // NOLINT
const char* pLanguageName = languageName.c_str();
LanguageType ret = LanguageType::ENGLISH;
if (0 == strcmp("zh", pLanguageName))
{
ret = LanguageType::CHINESE;
}
else if (0 == strcmp("en", pLanguageName))
{
ret = LanguageType::ENGLISH;
}
else if (0 == strcmp("fr", pLanguageName))
{
ret = LanguageType::FRENCH;
}
else if (0 == strcmp("it", pLanguageName))
{
ret = LanguageType::ITALIAN;
}
else if (0 == strcmp("de", pLanguageName))
{
ret = LanguageType::GERMAN;
}
else if (0 == strcmp("es", pLanguageName))
{
ret = LanguageType::SPANISH;
}
else if (0 == strcmp("ru", pLanguageName))
{
ret = LanguageType::RUSSIAN;
}
else if (0 == strcmp("nl", pLanguageName))
{
ret = LanguageType::DUTCH;
}
else if (0 == strcmp("ko", pLanguageName))
{
ret = LanguageType::KOREAN;
}
else if (0 == strcmp("ja", pLanguageName))
{
ret = LanguageType::JAPANESE;
}
else if (0 == strcmp("hu", pLanguageName))
{
ret = LanguageType::HUNGARIAN;
}
else if (0 == strcmp("pt", pLanguageName))
{
ret = LanguageType::PORTUGUESE;
}
else if (0 == strcmp("ar", pLanguageName))
{
ret = LanguageType::ARABIC;
}
else if (0 == strcmp("nb", pLanguageName))
{
ret = LanguageType::NORWEGIAN;
}
else if (0 == strcmp("pl", pLanguageName))
{
ret = LanguageType::POLISH;
}
else if (0 == strcmp("tr", pLanguageName))
{
ret = LanguageType::TURKISH;
}
else if (0 == strcmp("uk", pLanguageName))
{
ret = LanguageType::UKRAINIAN;
}
else if (0 == strcmp("ro", pLanguageName))
{
ret = LanguageType::ROMANIAN;
}
else if (0 == strcmp("bg", pLanguageName))
{
ret = LanguageType::BULGARIAN;
}
return ret;
}
Application::Platform Application::getPlatform() const
{
return Platform::OpenHarmony;
}
float Application::getScreenScale() const
{
return 1.f;
}
GLint Application::getMainFBO() const
{
return _mainFBO;
}
void Application::onCreateView(PixelFormat& /*pixelformat*/, DepthFormat& /*depthFormat*/, int& /*multisamplingCount*/)
{
}
bool Application::openURL(const std::string &url)
{
return false;
}
void Application::copyTextToClipboard(const std::string &text)
{
// copyTextToClipboardJNI(text);
}
std::string Application::getSystemVersion()
{
std::string str;
NapiHelper::napiCallFunction<std::string>("getOSFullName", &str);
return str;
}
const cocos2d::Vec2& Application::getViewSize() const
{
return _viewSize;
}
NS_CC_END

View File

@ -0,0 +1,718 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 <array>
#include <regex>
#include <memory>
#include "base/csscolorparser.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_platform.h"
#include "math/CCMath.h"
#include "base/CCData.h"
#include "platform/CCCanvasRenderingContext2D.h"
//#include "platform/openharmony/OpenHarmonyPlatform.h"
#include <native_drawing/drawing_text_typography.h>
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_font_collection.h>
#include <native_drawing/drawing_types.h>
#include <native_drawing/drawing_path.h>
#include <native_drawing/drawing_bitmap.h>
#include <native_drawing/drawing_text_declaration.h>
#include <native_drawing/drawing_brush.h>
using namespace cocos2d;
enum class TextAlign {
LEFT,
CENTER,
RIGHT
};
enum class TextBaseline {
TOP,
MIDDLE,
BOTTOM,
ALPHABETIC
};
class ScopedTypography {
public:
ScopedTypography(OH_Drawing_Typography* typography) :_typegraphy(typography) {}
~ScopedTypography() {
if(_typegraphy) {
OH_Drawing_DestroyTypography(_typegraphy);
}
}
OH_Drawing_Typography* get() {
return _typegraphy;
}
private:
OH_Drawing_Typography* _typegraphy{nullptr};
};
class CanvasRenderingContext2DImpl {
public:
using Point = std::array<float, 2>;
using Vec2 = std::array<float, 2>;
using Size = std::array<float, 2>;
using Color4F = std::array<float, 4>;
CanvasRenderingContext2DImpl() {
_typographyStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextDirection(_typographyStyle, TEXT_DIRECTION_LTR);
OH_Drawing_SetTypographyTextAlign(_typographyStyle, TEXT_ALIGN_LEFT);
_fontCollection = OH_Drawing_CreateFontCollection();
_typographyCreate = OH_Drawing_CreateTypographyHandler(_typographyStyle, _fontCollection);
_textStyle = OH_Drawing_CreateTextStyle();
}
~CanvasRenderingContext2DImpl() {
if(_typographyStyle) {
OH_Drawing_DestroyTypographyStyle(_typographyStyle);
_typographyStyle = nullptr;
}
if(_fontCollection) {
OH_Drawing_DestroyFontCollection(_fontCollection);
}
if(_typographyCreate) {
OH_Drawing_DestroyTypographyHandler(_typographyCreate);
_typographyCreate = nullptr;
}
if(_textStyle) {
OH_Drawing_DestroyTextStyle(_textStyle);
_textStyle = nullptr;
}
if(_canvas) {
OH_Drawing_CanvasDestroy(_canvas);
_canvas = nullptr;
}
if(_bitmap) {
OH_Drawing_BitmapDestroy(_bitmap);
_bitmap = nullptr;
}
}
void recreateBuffer(float w, float h) {
_bufferWidth = w;
_bufferHeight = h;
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
if (_canvas) {
OH_Drawing_CanvasDestroy(_canvas);
_canvas = nullptr;
}
if (_bitmap) {
OH_Drawing_BitmapDestroy(_bitmap);
_bitmap = nullptr;
}
_bufferSize = static_cast<int>(_bufferWidth * _bufferHeight * 4);
auto *data = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * _bufferSize));
memset(data, 0x00, _bufferSize);
_imageData.fastSet(data, _bufferSize);
_bitmap = OH_Drawing_BitmapCreate();
OH_Drawing_BitmapBuild(_bitmap, _bufferWidth, _bufferHeight, &_format);
_canvas = OH_Drawing_CanvasCreate();
OH_Drawing_CanvasBind(_canvas, _bitmap);
}
void beginPath() {
}
void closePath() {
}
void moveTo(float x, float y) {
// MoveToEx(_DC, static_cast<int>(x), static_cast<int>(-(y - _bufferHeight - _fontSize)), nullptr);
_x = x;
_y = y;
}
void lineTo(float x, float y) {
}
void stroke() {
}
void saveContext() {
}
void restoreContext() {
}
void clearRect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
if (_imageData.isNull()) {
return;
}
recreateBuffer(w, h);
}
void fillRect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
uint8_t r = static_cast<uint8_t>(_fillStyle[0]);
uint8_t g = static_cast<uint8_t>(_fillStyle[1]);
uint8_t b = static_cast<uint8_t>(_fillStyle[2]);
uint8_t a = static_cast<uint8_t>(_fillStyle[3]);
OH_Drawing_Path* path = OH_Drawing_PathCreate();
OH_Drawing_PathMoveTo(path, x, y);
OH_Drawing_PathLineTo(path, x + w, y);
OH_Drawing_PathLineTo(path, x + w, y + h);
OH_Drawing_PathLineTo(path, x, y + h);
OH_Drawing_PathLineTo(path, x, y);
OH_Drawing_PathClose(path);
OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(a, r, g, b));
OH_Drawing_CanvasAttachBrush(_canvas, brush);
OH_Drawing_CanvasDrawPath(_canvas, path);
}
void fillText(const std::string &text, float x, float y, float /*maxWidth*/) {
if (text.empty() || _bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
Size textSize = {0, 0};
Point offsetPoint = convertDrawPoint(Point{x, y}, text);
drawText(text, offsetPoint[0], offsetPoint[1]);
}
void strokeText(const std::string &text, float /*x*/, float /*y*/, float /*maxWidth*/) const {
}
Size measureText(const std::string &text) {
auto typography = createTypography(text);
return std::array<float, 2>{static_cast<float>(OH_Drawing_TypographyGetMaxIntrinsicWidth(typography->get())),
static_cast<float>(OH_Drawing_TypographyGetHeight(typography->get()))};
}
void updateFont(const std::string &fontName,
float fontSize,
bool bold,
bool italic,
bool oblique,
bool /* smallCaps */) {
_fontName = fontName;
_fontSize = static_cast<int>(fontSize);
std::string fontPath;
if (!_fontName.empty()) {
const char* fontFamilies[1];
fontFamilies[0] = fontName.c_str();
OH_Drawing_SetTextStyleFontFamilies(_textStyle, 1, fontFamilies);
OH_Drawing_SetTextStyleLocale(_textStyle, "en");
}
if (_fontSize)
OH_Drawing_SetTextStyleFontSize(_textStyle, _fontSize);
if (bold)
OH_Drawing_SetTextStyleFontWeight(_textStyle, FONT_WEIGHT_700);
else
OH_Drawing_SetTextStyleFontWeight(_textStyle, FONT_WEIGHT_400);
if(italic)
OH_Drawing_SetTextStyleFontStyle(_textStyle, FONT_STYLE_ITALIC);
else
OH_Drawing_SetTextStyleFontStyle(_textStyle, FONT_STYLE_NORMAL);
}
void setTextAlign(TextAlign align) {
_textAlign = align;
}
void setTextBaseline(TextBaseline baseline) {
_textBaseLine = baseline;
}
void setFillStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
_fillStyle = {static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)};
OH_Drawing_SetTextStyleColor(_textStyle, OH_Drawing_ColorSetArgb(a, r, g, b));
}
void setStrokeStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
_strokeStyle = {static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)};
}
void setLineWidth(float lineWidth) {
_lineWidth = lineWidth;
}
const Data &getDataRef() const {
return _imageData;
}
void removeCustomFont() {
}
// x, y offset value
int drawText(const std::string &text, float x, float y) {
auto typography = createTypography(text);
OH_Drawing_TypographyPaint(typography->get(), _canvas, (double)x, (double)y);
void* bitmapAddr = OH_Drawing_BitmapGetPixels(_bitmap);
memcpy(_imageData.getBytes(), bitmapAddr, _bufferSize);
return 0;
}
Size sizeWithText(const wchar_t *pszText, int nLen) {
return std::array<float, 2>{0.0F, 0.0F};
}
void prepareBitmap(int nWidth, int nHeight) {
}
void deleteBitmap() {
}
void fillTextureData() {
}
std::array<float, 2> convertDrawPoint(Point point, const std::string &text) {
auto typography = createTypography(text);
Size textSize {static_cast<float>(OH_Drawing_TypographyGetMaxIntrinsicWidth(typography->get())),
static_cast<float>(OH_Drawing_TypographyGetHeight(typography->get()))};
if (_textAlign == TextAlign::CENTER) {
point[0] -= textSize[0] / 2.0f;
} else if (_textAlign == TextAlign::RIGHT) {
point[0] -= textSize[0];
}
double alphabeticBaseLine = OH_Drawing_TypographyGetAlphabeticBaseline(typography->get());
if (_textBaseLine == TextBaseline::TOP) {
//point[1] += -alphabeticBaseLine;
} else if (_textBaseLine == TextBaseline::MIDDLE) {
point[1] += -textSize[1] / 2.0f;
} else if (_textBaseLine == TextBaseline::BOTTOM) {
point[1] += -textSize[1];
} else if (_textBaseLine == TextBaseline::ALPHABETIC) {
//GetTextMetrics(_DC, &_tm);
//point[1] -= _tm.tmAscent;
point[1] -= alphabeticBaseLine;
}
return point;
}
std::unique_ptr<ScopedTypography> createTypography(const std::string &text) {
OH_Drawing_TypographyHandlerPushTextStyle(_typographyCreate, _textStyle);
OH_Drawing_TypographyHandlerAddText(_typographyCreate, text.c_str());
OH_Drawing_TypographyHandlerPopTextStyle(_typographyCreate);
OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(_typographyCreate);
OH_Drawing_TypographyLayout(typography, _bufferWidth);
return std::make_unique<ScopedTypography>(typography);
}
void fill() {
}
void setLineCap(const std::string &lineCap) {
}
void setLineJoin(const std::string &lineJoin) {
}
void fillImageData(const Data & /* imageData */,
float /* imageWidth */,
float /* imageHeight */,
float /* offsetX */,
float /* offsetY */) {
}
void strokeText(const std::string & /* text */,
float /* x */,
float /* y */,
float /* maxWidth */) {
}
void rect(float /* x */,
float /* y */,
float /* w */,
float /* h */) {
}
void updateData() {
}
private:
int32_t _x{0};
int32_t _y{0};
int32_t _lineCap{0};
int32_t _lineJoin{0};
OH_Drawing_Bitmap* _bitmap{nullptr};
OH_Drawing_BitmapFormat _format {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
OH_Drawing_Canvas* _canvas{nullptr};
OH_Drawing_TypographyStyle* _typographyStyle{nullptr};
OH_Drawing_TypographyCreate* _typographyCreate{nullptr};
OH_Drawing_FontCollection* _fontCollection{nullptr};
OH_Drawing_TextStyle* _textStyle{nullptr};
Data _imageData;
std::string _curFontPath;
int _savedDC{0};
float _lineWidth{0.0F};
float _bufferWidth{0.0F};
float _bufferHeight{0.0F};
int32_t _bufferSize{0};
std::string _fontName;
int _fontSize{0};
Size _textSize;
TextAlign _textAlign{TextAlign::CENTER};
TextBaseline _textBaseLine{TextBaseline::TOP};
Color4F _fillStyle{0};
Color4F _strokeStyle{0};
};
NS_CC_BEGIN
CanvasGradient::CanvasGradient()
{
// SE_LOGD("CanvasGradient constructor: %p\n", this);
}
CanvasGradient::~CanvasGradient()
{
// SE_LOGD("CanvasGradient destructor: %p\n", this);
}
void CanvasGradient::addColorStop(float offset, const std::string& color)
{
// SE_LOGD("CanvasGradient::addColorStop: %p\n", this);
}
// CanvasRenderingContext2D
CanvasRenderingContext2D::CanvasRenderingContext2D(float width, float height)
: __width(width)
, __height(height)
{
// SE_LOGD("CanvasRenderingContext2D constructor: %p, width: %f, height: %f\n", this, width, height);
_impl = new CanvasRenderingContext2DImpl();
recreateBufferIfNeeded();
}
CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
// SE_LOGD("CanvasRenderingContext2D destructor: %p\n", this);
delete _impl;
}
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
{
// SE_LOGD("CanvasRenderingContext2D::clearRect: %p, %f, %f, %f, %f\n", this, x, y, width, height);
recreateBufferIfNeeded();
_impl->clearRect(x, y, width, height);
}
void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
{
recreateBufferIfNeeded();
_impl->fillRect(x, y, width, height);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::fillText(const std::string& text, float x, float y, float maxWidth)
{
// SE_LOGD("CanvasRenderingContext2D::fillText: %s, %f, %f, %f\n", text.c_str(), x, y, maxWidth);
if (text.empty())
return;
recreateBufferIfNeeded();
_impl->fillText(text, x, y, maxWidth);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::strokeText(const std::string& text, float x, float y, float maxWidth)
{
// SE_LOGD("CanvasRenderingContext2D::strokeText: %s, %f, %f, %f\n", text.c_str(), x, y, maxWidth);
if (text.empty())
return;
recreateBufferIfNeeded();
_impl->strokeText(text, x, y, maxWidth);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
cocos2d::Size CanvasRenderingContext2D::measureText(const std::string& text)
{
// SE_LOGD("CanvasRenderingContext2D::measureText: %s\n", text.c_str());
auto s = _impl->measureText(text);
s[0] = ceil(s[0] * 100) / 100;
s[1] = ceil(s[1] * 100) / 100;
return cocos2d::Size(s[0], s[1]);
}
CanvasGradient* CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
{
return nullptr;
}
void CanvasRenderingContext2D::save()
{
_impl->saveContext();
}
void CanvasRenderingContext2D::beginPath()
{
_impl->beginPath();
}
void CanvasRenderingContext2D::closePath()
{
_impl->closePath();
}
void CanvasRenderingContext2D::moveTo(float x, float y)
{
_impl->moveTo(x, y);
}
void CanvasRenderingContext2D::lineTo(float x, float y)
{
_impl->lineTo(x, y);
}
void CanvasRenderingContext2D::stroke()
{
_impl->stroke();
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::restore()
{
_impl->restoreContext();
}
void CanvasRenderingContext2D::setCanvasBufferUpdatedCallback(const CanvasBufferUpdatedCallback& cb)
{
_canvasBufferUpdatedCB = cb;
}
void CanvasRenderingContext2D::setPremultiply(bool multiply)
{
_premultiply = multiply;
}
void CanvasRenderingContext2D::set__width(float width)
{
// SE_LOGD("CanvasRenderingContext2D::set__width: %f\n", width);
__width = width;
_isBufferSizeDirty = true;
recreateBufferIfNeeded();
}
void CanvasRenderingContext2D::set__height(float height)
{
// SE_LOGD("CanvasRenderingContext2D::set__height: %f\n", height);
__height = height;
_isBufferSizeDirty = true;
recreateBufferIfNeeded();
}
void CanvasRenderingContext2D::set_lineWidth(float lineWidth)
{
_lineWidth = lineWidth;
_impl->setLineWidth(lineWidth);
}
void CanvasRenderingContext2D::set_lineCap(const std::string& lineCap)
{
if(lineCap.empty()) return ;
_impl->setLineCap(lineCap);
}
void CanvasRenderingContext2D::set_lineJoin(const std::string& lineJoin)
{
if(lineJoin.empty()) return ;
_impl->setLineJoin(lineJoin);
}
void CanvasRenderingContext2D::fill()
{
_impl->fill();
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::rect(float x, float y, float width, float height)
{
// SE_LOGD("CanvasRenderingContext2D::rect: %p, %f, %f, %f, %f\n", this, x, y, width, height);
recreateBufferIfNeeded();
_impl->rect(x, y, width, height);
}
/*
* support format e.g.: "oblique bold small-caps 18px Arial"
* "italic bold small-caps 25px Arial"
* "italic 25px Arial"
* */
void CanvasRenderingContext2D::set_font(const std::string& font)
{
if (_font != font) {
_font = font;
std::string fontName = "sans-serif";
std::string fontSizeStr = "30";
std::regex re(R"(\s*((\d+)([\.]\d+)?)px\s+([^\r\n]*))");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(_font.cbegin(), _font.cend(), results, re)) {
fontSizeStr = results[2].str();
// support get font name from `60px American` or `60px "American abc-abc_abc"`
// support get font name contain space,example `times new roman`
// if regex rule that does not conform to the rules,such as Chinese,it defaults to sans-serif
std::match_results<std::string::const_iterator> fontResults;
std::regex fontRe(R"(([\w\s-]+|"[\w\s-]+"$))");
std::string tmp(results[4].str());
if (std::regex_match(tmp, fontResults, fontRe)) {
fontName = results[4].str();
}
}
double fontSize = atof(fontSizeStr.c_str());
bool isBold = font.find("bold", 0) != std::string::npos || font.find("Bold", 0) != std::string::npos;
bool isItalic = font.find("italic", 0) != std::string::npos || font.find("Italic", 0) != std::string::npos;
bool isSmallCaps = font.find("small-caps", 0) != std::string::npos || font.find("Small-Caps") != std::string::npos;
bool isOblique = font.find("oblique", 0) != std::string::npos || font.find("Oblique", 0) != std::string::npos;
//font-style: italic, oblique, normal
//font-weight: normal, bold
//font-variant: normal, small-caps
_impl->updateFont(fontName, fontSize, isBold, isItalic, isOblique, isSmallCaps);
}
}
void CanvasRenderingContext2D::set_textAlign(const std::string& textAlign)
{
// SE_LOGD("CanvasRenderingContext2D::set_textAlign: %s\n", textAlign.c_str());
if (textAlign == "left") {
_impl->setTextAlign(TextAlign::LEFT);
} else if (textAlign == "center" || textAlign == "middle") {
_impl->setTextAlign(TextAlign::CENTER);
} else if (textAlign == "right") {
_impl->setTextAlign(TextAlign::RIGHT);
} else {
CC_ASSERT(false);
}
}
void CanvasRenderingContext2D::set_textBaseline(const std::string& textBaseline)
{
// SE_LOGD("CanvasRenderingContext2D::set_textBaseline: %s\n", textBaseline.c_str());
if (textBaseline == "top") {
_impl->setTextBaseline(TextBaseline::TOP);
} else if (textBaseline == "middle") {
_impl->setTextBaseline(TextBaseline::MIDDLE);
} else if (textBaseline == "bottom") //REFINE:, how to deal with alphabetic, currently we handle it as bottom mode.
{
_impl->setTextBaseline(TextBaseline::BOTTOM);
} else if (textBaseline == "alphabetic") {
_impl->setTextBaseline(TextBaseline::ALPHABETIC);
} else {
CC_ASSERT(false);
}
}
void CanvasRenderingContext2D::set_fillStyle(const std::string& fillStyle)
{
CSSColorParser::Color color = CSSColorParser::parse(fillStyle);
_impl->setFillStyle(color.r, color.g, color.b, static_cast<uint8_t>(color.a * 255));
// SE_LOGD("CanvasRenderingContext2D::set_fillStyle: %s, (%d, %d, %d, %f)\n", fillStyle.c_str(), color.r, color.g, color.b, color.a);
}
void CanvasRenderingContext2D::set_strokeStyle(const std::string& strokeStyle)
{
CSSColorParser::Color color = CSSColorParser::parse(strokeStyle);
_impl->setStrokeStyle(color.r, color.g, color.b, static_cast<uint8_t>(color.a * 255));
}
void CanvasRenderingContext2D::set_globalCompositeOperation(const std::string& globalCompositeOperation)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::_fillImageData(const Data& imageData, float imageWidth, float imageHeight, float offsetX, float offsetY)
{
_impl->fillImageData(imageData, imageWidth, imageHeight, offsetX, offsetY);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
// transform
//REFINE:
void CanvasRenderingContext2D::translate(float x, float y)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::scale(float x, float y)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::rotate(float angle)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::transform(float a, float b, float c, float d, float e, float f)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::setTransform(float a, float b, float c, float d, float e, float f)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::recreateBufferIfNeeded()
{
if (_isBufferSizeDirty) {
_isBufferSizeDirty = false;
// SE_LOGD("Recreate buffer %p, w: %f, h:%f\n", this, __width, __height);
_impl->recreateBuffer(__width, __height);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
}
NS_CC_END

View File

@ -0,0 +1,389 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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/openharmony/napi/NapiHelper.h"
#include "platform/openharmony/OpenHarmonyPlatform.h"
#include "scripting/js-bindings/jswrapper/napi/HelperMacros.h"
#include "cocos/platform/openharmony/FileUtils-openharmony.h"
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "ui/edit-box/EditBox-openharmony.h"
#include "ui/webview/WebViewImpl-openharmony.h"
#include "platform/openharmony/WorkerMessageQueue.h"
#define KEYCODE_BACK_OH 6
namespace cocos2d {
const int32_t kMaxStringLen = 512;
// Must be the same as the value called by js
enum ContextType {
APP_LIFECYCLE = 0,
JS_PAGE_LIFECYCLE,
XCOMPONENT_CONTEXT,
XCOMPONENT_REGISTER_LIFECYCLE_CALLBACK,
NATIVE_RENDER_API,
WORKER_INIT,
ENGINE_UTILS,
EDITBOX_UTILS,
WEBVIEW_UTILS,
DISPLAY_UTILS,
UV_ASYNC_SEND,
};
NapiHelper::PostMessage2UIThreadCb NapiHelper::_postMsg2UIThreadCb;
NapiHelper::PostSyncMessage2UIThreadCb NapiHelper::_postSyncMsg2UIThreadCb;
static bool js_set_PostMessage2UIThreadCallback(se::State& s) {
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
do {
if (args[0].isObject() && args[0].toObject()->isFunction()) {
//se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
//jsThis.toObject()->attachObject(jsFunc.toObject());
auto * thisObj = s.thisObject();
NapiHelper::_postMsg2UIThreadCb = [=](const std::string larg0, const se::Value& larg1) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(2);
ok &= std_string_to_seval(larg0, &args[0]);
CC_ASSERT(ok);
args[1] = larg1;
//ok &= nativevalue_to_se(larg1, args[1], nullptr /*ctx*/);
se::Value rval;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, &rval);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
};
}
} while(false);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_set_PostMessage2UIThreadCallback);
static bool js_set_PostSyncMessage2UIThreadCallback(se::State& s) {
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
do {
if (args[0].isObject() && args[0].toObject()->isFunction()) {
//se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
//jsThis.toObject()->attachObject(jsFunc.toObject());
auto * thisObj = s.thisObject();
NapiHelper::_postSyncMsg2UIThreadCb = [=](const std::string larg0, const se::Value& larg1, se::Value* res) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(2);
ok &= std_string_to_seval(larg0, &args[0]);
CC_ASSERT(ok);
args[1] = larg1;
//ok &= nativevalue_to_se(larg1, args[1], nullptr /*ctx*/);
//se::Value rval;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, res);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
};
}
} while(false);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_set_PostSyncMessage2UIThreadCallback);
// NAPI Interface
napi_value NapiHelper::getContext(napi_env env, napi_callback_info info) {
napi_status status;
napi_value exports;
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
if (argc != 1) {
napi_throw_type_error(env, NULL, "Wrong number of arguments");
return nullptr;
}
napi_valuetype valuetype;
status = napi_typeof(env, args[0], &valuetype);
if (status != napi_ok) {
return nullptr;
}
if (valuetype != napi_number) {
napi_throw_type_error(env, NULL, "Wrong arguments");
return nullptr;
}
int64_t value;
NAPI_CALL(env, napi_get_value_int64(env, args[0], &value));
NAPI_CALL(env, napi_create_object(env, &exports));
switch (value) {
case APP_LIFECYCLE: {
// Register app lifecycle
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("onCreate", NapiHelper::napiOnCreate),
DECLARE_NAPI_FUNCTION("onShow", NapiHelper::napiOnShow),
DECLARE_NAPI_FUNCTION("onHide", NapiHelper::napiOnHide),
DECLARE_NAPI_FUNCTION("onDestroy", NapiHelper::napiOnDestroy),
DECLARE_NAPI_FUNCTION("onBackPress", NapiHelper::napiOnBackPress),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}
break;
case JS_PAGE_LIFECYCLE: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("onPageShow", NapiHelper::napiOnPageShow),
DECLARE_NAPI_FUNCTION("onPageHide", NapiHelper::napiOnPageHide),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
case XCOMPONENT_REGISTER_LIFECYCLE_CALLBACK: {
} break;
case NATIVE_RENDER_API: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("nativeEngineInit", NapiHelper::napiNativeEngineInit),
DECLARE_NAPI_FUNCTION("nativeEngineStart", NapiHelper::napiNativeEngineStart),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
case WORKER_INIT: {
se::ScriptEngine::setEnv(env);
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("workerInit", NapiHelper::napiWorkerInit),
DECLARE_NAPI_FUNCTION("setPostMessageFunction", _SE(js_set_PostMessage2UIThreadCallback)),
DECLARE_NAPI_FUNCTION("setPostSyncMessageFunction", _SE(js_set_PostSyncMessage2UIThreadCallback)),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
case ENGINE_UTILS: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("resourceManagerInit", NapiHelper::napiResourceManagerInit),
DECLARE_NAPI_FUNCTION("writablePathInit", NapiHelper::napiWritablePathInit),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}break;
case EDITBOX_UTILS: {
std::vector<napi_property_descriptor> desc;
OpenHarmonyEditBox::GetInterfaces(desc);
NAPI_CALL(env, napi_define_properties(env, exports, desc.size(), desc.data()));
}break;
case WEBVIEW_UTILS: {
std::vector<napi_property_descriptor> desc;
OpenHarmonyWebView::GetInterfaces(desc);
NAPI_CALL(env, napi_define_properties(env, exports, desc.size(), desc.data()));
} break;
case DISPLAY_UTILS: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("onDisplayChange", NapiHelper::napiOnDisplayChange),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}
case UV_ASYNC_SEND: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("send", NapiHelper::napiASend),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
default:
LOGE("unknown type");
}
return exports;
}
// NAPI Interface
bool NapiHelper::exportFunctions(napi_env env, napi_value exports) {
napi_status status;
// Application/SDK etc. Init
// XComponent Init:
napi_value exportInstance = nullptr;
OH_NativeXComponent* nativeXComponent = nullptr;
int32_t ret;
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
status = napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
if (status != napi_ok) {
return false;
}
status = napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
if (status != napi_ok) {
LOGE("napi_unwrap error %{public}d", status);
return false;
}
ret = OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
return false;
}
OpenHarmonyPlatform::getInstance()->setNativeXComponent(nativeXComponent);
return true;
}
napi_value NapiHelper::napiOnCreate(napi_env env, napi_callback_info info) {
// uv_loop_t* loop = nullptr;
// NAPI_CALL(env, napi_get_uv_event_loop(env, &loop));
// OpenHarmonyPlatform::getInstance()->onCreateNative(env, loop);
LOGD("NapiHelper::napiOnCreate");
return nullptr;
}
napi_value NapiHelper::napiOnShow(napi_env env, napi_callback_info info) {
cocos2d::WorkerMessageData data{cocos2d::MessageType::WM_APP_SHOW, nullptr, nullptr};
OpenHarmonyPlatform::getInstance()->enqueue(data);
Application* app = OpenHarmonyPlatform::getInstance()->g_app;
if (app) {
app->onResume();
}
LOGD("NapiHelper::napiOnShow");
return nullptr;
}
napi_value NapiHelper::napiOnHide(napi_env env, napi_callback_info info) {
cocos2d::WorkerMessageData data{cocos2d::MessageType::WM_APP_HIDE, nullptr, nullptr};
OpenHarmonyPlatform::getInstance()->enqueue(data);
Application* app = OpenHarmonyPlatform::getInstance()->g_app;
if (app) {
app->onPause();
}
LOGD("NapiHelper::napiOnHide");
return nullptr;
}
napi_value NapiHelper::napiOnBackPress(napi_env env, napi_callback_info info) {
KeyboardEvent event;
event.key = KEYCODE_BACK_OH;
event.action = KeyboardEvent::Action::RELEASE;
EventDispatcher::dispatchKeyboardEvent(event);
return nullptr;
}
napi_value NapiHelper::napiOnDestroy(napi_env env, napi_callback_info info) {
cocos2d::WorkerMessageData data{cocos2d::MessageType::WM_APP_DESTROY, nullptr, nullptr};
OpenHarmonyPlatform::getInstance()->enqueue(data);
LOGD("NapiHelper::napiOnDestroy");
return nullptr;
}
napi_value NapiHelper::napiOnPageShow(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiOnPageShow");
return nullptr;
}
napi_value NapiHelper::napiOnPageHide(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiOnPageHide");
return nullptr;
}
napi_value NapiHelper::napiNativeEngineInit(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiNativeEngineInit");
se::ScriptEngine::setEnv(env);
OpenHarmonyPlatform::getInstance()->run(0, nullptr);
return nullptr;
}
napi_value NapiHelper::napiNativeEngineStart(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiNativeEngineStart");
OpenHarmonyPlatform::getInstance()->requestVSync();
return nullptr;
}
napi_value NapiHelper::napiWorkerInit(napi_env env, napi_callback_info info) {
uv_loop_t* loop = nullptr;
NAPI_CALL(env, napi_get_uv_event_loop(env, &loop));
OpenHarmonyPlatform::getInstance()->workerInit(env, loop);
return nullptr;
}
napi_value NapiHelper::napiOnDisplayChange(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
CC_ASSERT(argc > 0);
int32_t value;
NAPI_CALL(env, napi_get_value_int32(env, args[0], &value));
cocos2d::Device::Rotation rotation = cocos2d::Device::Rotation::_0;
if(value == 0) {
rotation = cocos2d::Device::Rotation::_0;
} else if(value == 1) {
// TODO(qgh): The openharmony platform is rotated clockwise.
rotation = cocos2d::Device::Rotation::_270;
} else if(value == 2) {
rotation = cocos2d::Device::Rotation::_180;
} else if(value == 3) {
// TODO(qgh): The openharmony platform is rotated clockwise.
rotation = cocos2d::Device::Rotation::_90;
}
EventDispatcher::dispatchOrientationChangeEvent((int)rotation);
return nullptr;
}
napi_value NapiHelper::napiResourceManagerInit(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
FileUtilsOpenHarmony::initResourceManager(env, args[0]);
return nullptr;
}
napi_value NapiHelper::napiWritablePathInit(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
napi_status status;
char buffer[kMaxStringLen];
size_t result = 0;
NODE_API_CALL(status, env, napi_get_value_string_utf8(env, args[0], buffer, kMaxStringLen, &result));
FileUtilsOpenHarmony::_ohWritablePath = std::string(buffer);
return nullptr;
}
napi_value NapiHelper::napiASend(napi_env env, napi_callback_info info) {
OpenHarmonyPlatform::getInstance()->triggerMessageSignal();
return nullptr;
}
}

View File

@ -0,0 +1,174 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <napi/native_api.h>
#include <uv.h>
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
namespace cocos2d {
class NapiHelper {
public:
static napi_value getContext(napi_env env, napi_callback_info info);
// APP Lifecycle
static napi_value napiOnCreate(napi_env env, napi_callback_info info);
static napi_value napiOnShow(napi_env env, napi_callback_info info);
static napi_value napiOnHide(napi_env env, napi_callback_info info);
static napi_value napiOnDestroy(napi_env env, napi_callback_info info);
static napi_value napiOnBackPress(napi_env env, napi_callback_info info);
// JS Page : Lifecycle
static napi_value napiOnPageShow(napi_env env, napi_callback_info info);
static napi_value napiOnPageHide(napi_env env, napi_callback_info info);
// Worker Func
static napi_value napiWorkerInit(napi_env env, napi_callback_info info);
static napi_value napiASend(napi_env env, napi_callback_info info);
static napi_value napiNativeEngineInit(napi_env env, napi_callback_info info);
static napi_value napiNativeEngineStart(napi_env env, napi_callback_info info);
static napi_value napiWritablePathInit(napi_env env, napi_callback_info info);
static napi_value napiResourceManagerInit(napi_env env, napi_callback_info info);
static napi_value napiOnDisplayChange(napi_env env, napi_callback_info info);
template <class ReturnType>
static napi_value napiCallFunction(const std::string& functionName, ReturnType* value) {
if (!se::ScriptEngine::getInstance()->isValid()) {
return nullptr;
}
se::Value tickVal;
se::AutoHandleScope scope;
if (tickVal.isUndefined()) {
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty(functionName, &tickVal);
}
se::Value rval;
se::ValueArray tickArgsValArr(1);
if (!tickVal.isUndefined()) {
tickVal.toObject()->call(tickArgsValArr, nullptr, &rval);
}
if(rval.isNullOrUndefined()) {
return nullptr;
}
bool ok = true;
ok &= seval_to_native_base_type(rval, value);
SE_PRECONDITION2(ok, nullptr, "Error processing arguments");
return nullptr;
}
static napi_value napiCallFunctionByStrArgs(const std::string& functionName, const std::string& args1, int32_t* value) {
if (!se::ScriptEngine::getInstance()->isValid()) {
return nullptr;
}
se::Value tickVal;
se::AutoHandleScope scope;
if (tickVal.isUndefined()) {
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty(functionName, &tickVal);
}
se::Value rval;
se::ValueArray tickArgsValArr;
tickArgsValArr.push_back(se::Value(args1));
if (!tickVal.isUndefined()) {
tickVal.toObject()->call(tickArgsValArr, nullptr, &rval);
}
if(rval.isNullOrUndefined()) {
return nullptr;
}
bool ok = true;
ok &= seval_to_native_base_type(rval, value);
SE_PRECONDITION2(ok, nullptr, "Error processing arguments");
return nullptr;
}
static napi_value napiCallFunctionByFloatArgs(const std::string& functionName, float& sec, int32_t* value) {
if (!se::ScriptEngine::getInstance()->isValid()) {
return nullptr;
}
se::Value tickVal;
se::AutoHandleScope scope;
if (tickVal.isUndefined()) {
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty(functionName, &tickVal);
}
se::Value rval;
se::ValueArray tickArgsValArr;
tickArgsValArr.push_back(se::Value(sec));
if (!tickVal.isUndefined()) {
tickVal.toObject()->call(tickArgsValArr, nullptr, &rval);
}
if(rval.isNullOrUndefined()) {
return nullptr;
}
bool ok = true;
ok &= seval_to_native_base_type(rval, value);
SE_PRECONDITION2(ok, nullptr, "Error processing arguments");
return nullptr;
}
static napi_value napiSetPostMessageFunction(napi_env env, napi_callback_info info);
// Napi export
static bool exportFunctions(napi_env env, napi_value exports);
static void postStringMessageToUIThread(const std::string& type, std::string param) {
if (!_postMsg2UIThreadCb) {
return;
}
CC_UNUSED bool ok = true;
se::Value value;
ok &= std_string_to_seval(param, &value);
_postMsg2UIThreadCb(type, value);
}
static void postIntMessageToUIThread(const std::string& type, int param) {
if (!_postMsg2UIThreadCb) {
return;
}
CC_UNUSED bool ok = true;
se::Value value;
ok &= native_int_to_se(param, value, nullptr /*ctx*/);
_postMsg2UIThreadCb(type, value);
}
static void postUnorderedMapMessageToUIThread(const std::string& type, std::unordered_map<std::string, cocos2d::Value> param) {
if (!_postMsg2UIThreadCb) {
return;
}
CC_UNUSED bool ok = true;
se::Value value;
ok &= native_unorderedmap_to_se(param, value, nullptr /*ctx*/);
_postMsg2UIThreadCb(type, value);
}
public:
using PostMessage2UIThreadCb = std::function<void(const std::string&, const se::Value&)>;
static PostMessage2UIThreadCb _postMsg2UIThreadCb;
using PostSyncMessage2UIThreadCb = std::function<void(const std::string&, const se::Value&, se::Value*)>;
static PostSyncMessage2UIThreadCb _postSyncMsg2UIThreadCb;
};
}

View File

@ -0,0 +1,63 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 <ace/xcomponent/native_interface_xcomponent.h>
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "platform/openharmony/napi/NapiHelper.h"
const char kLibname[] = "cocos";
/*
* function for module exports
*/
static napi_value init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("getContext", cocos2d::NapiHelper::getContext),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
bool ret = cocos2d::NapiHelper::exportFunctions(env, exports);
if (!ret) {
LOGE("Init failed");
}
return exports;
}
/*
* Napi Module define
*/
static napi_module cocos2dModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = init, // called by ACE XComponent
.nm_modname = kLibname,
.nm_priv = ((void*)0),
.reserved = {0},
};
/*
* Module register function
*/
extern "C" __attribute__((constructor)) void RegisterModule(void) {
napi_module_register(&cocos2dModule);
}

View File

@ -0,0 +1,113 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "egl_core.h"
#include "platform/openharmony/napi/NapiHelper.h"
EGLConfig getConfig(int version, EGLDisplay eglDisplay) {
int attribList[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_STENCIL_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_NONE
};
EGLConfig configs = NULL;
int configsNum;
if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &configsNum)) {
LOGE("eglChooseConfig ERROR");
return NULL;
}
return configs;
}
void EGLCore::GLContextInit(void* window, int w, int h)
{
LOGD("EGLCore::GLContextInit window = %{public}p, w = %{public}d, h = %{public}d.", window, w, h);
width_ = w;
height_ = h;
mEglWindow = (EGLNativeWindowType)(window);
// 1. create sharedcontext
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (mEGLDisplay == EGL_NO_DISPLAY) {
LOGE("EGLCore::unable to get EGL display.");
return;
}
EGLint eglMajVers, eglMinVers;
if (!eglInitialize(mEGLDisplay, &eglMajVers, &eglMinVers)) {
mEGLDisplay = EGL_NO_DISPLAY;
LOGE("EGLCore::unable to initialize display");
return;
}
mEGLConfig = getConfig(3, mEGLDisplay);
if (mEGLConfig == nullptr) {
LOGE("EGLCore::GLContextInit config ERROR");
return;
}
// 2. Create EGL Surface from Native Window
if (mEglWindow) {
mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mEglWindow, nullptr);
if (mEGLSurface == nullptr) {
LOGE("EGLCore::eglCreateContext eglSurface is null");
return;
}
}
// 3. Create EGLContext from
int attrib3_list[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig, mSharedEGLContext, attrib3_list);
if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
LOGE("EGLCore::eglMakeCurrent error = %{public}d", eglGetError());
}
}
void EGLCore::Update()
{
eglSwapBuffers(mEGLDisplay, mEGLSurface);
}
bool EGLCore::checkGlError(const char* op)
{
LOGE("EGL ERROR CODE = %{public}x", eglGetError());
GLint error;
for (error = glGetError(); error; error = glGetError()) {
LOGE("ERROR: %{public}s, ERROR CODE = %{public}x", op, error);
return true;
}
return false;
}

View File

@ -0,0 +1,53 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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.
****************************************************************************/
#ifndef _GL_CORE_
#define _GL_CORE_
#include "platform/openharmony/CCGL-openharmony.h"
#include <string>
class EGLCore {
public:
EGLCore() {};
void GLContextInit(void* window, int w, int h);
void Update();
public:
int width_;
int height_;
private:
bool checkGlError(const char* op);
EGLNativeWindowType mEglWindow;
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLConfig mEGLConfig = nullptr;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLContext mSharedEGLContext = EGL_NO_CONTEXT;
EGLSurface mEGLSurface = nullptr;
};
#endif // _GL_CORE_

View File

@ -30,6 +30,10 @@
#include <android/log.h>
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include <hilog/log.h>
#endif
#ifndef RENDERER_BEGIN
#define RENDERER_BEGIN namespace cocos2d { namespace renderer {
#endif // RENDERER_BEGIN
@ -53,6 +57,8 @@
#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#define RENDERER_LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#define RENDERER_LOGV(fmt, ...) ((void) OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "HMG_LOG", " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#else
#define RENDERER_LOGV(fmt, ...) printf("V/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#endif // (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
@ -65,6 +71,11 @@
#define RENDERER_LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define RENDERER_LOGW(fmt, ...) __android_log_print(ANDROID_LOG_WARN, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define RENDERER_LOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, RENDERER_LOG_TAG, " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#define RENDERER_LOGD(fmt, ...) OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "HMG_LOG", " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define RENDERER_LOGI(fmt, ...) OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "HMG_LOG", " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define RENDERER_LOGW(fmt, ...) OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, "HMG_LOG", " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define RENDERER_LOGE(fmt, ...) OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#else
#define RENDERER_LOGD(fmt, ...) printf("D/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define RENDERER_LOGI(fmt, ...) printf("I/" RENDERER_LOG_TAG " (" RENDERER_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)

View File

@ -613,7 +613,7 @@ void DeviceGraphics::initCaps()
GL_CHECK(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &_caps.maxTextureUnits));
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS ||CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
// IDEA: how to get these infomations
_caps.maxColorAttatchments = 1;
_caps.maxDrawBuffers = 1;
@ -760,13 +760,12 @@ void DeviceGraphics::commitBlendStates()
ENUM_CLASS_TO_GLENUM(_nextState->blendSrcAlpha),
ENUM_CLASS_TO_GLENUM(_nextState->blendDstAlpha)));
}
}
if (_currentState->blendEq != _nextState->blendEq ||
if (_currentState->blendEq != _nextState->blendEq ||
_currentState->blendAlphaEq != _nextState->blendAlphaEq)
{
GL_CHECK(glBlendEquationSeparate(ENUM_CLASS_TO_GLENUM(_nextState->blendEq),
ENUM_CLASS_TO_GLENUM(_nextState->blendAlphaEq)));
{
GL_CHECK(glBlendEquationSeparate(ENUM_CLASS_TO_GLENUM(_nextState->blendEq),
ENUM_CLASS_TO_GLENUM(_nextState->blendAlphaEq)));
}
}
else
{

View File

@ -1,5 +1,5 @@
#include "scripting/js-bindings/auto/jsb_cocos2dx_audioengine_auto.hpp"
#if (USE_AUDIO > 0) && (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 (USE_AUDIO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "audio/include/AudioEngine.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "base/ccConfig.h"
#if (USE_AUDIO > 0) && (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 (USE_AUDIO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"

View File

@ -1,5 +1,5 @@
#include "scripting/js-bindings/auto/jsb_cocos2dx_network_auto.hpp"
#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_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "network/CCDownloader.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "base/ccConfig.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_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"

View File

@ -1,5 +1,5 @@
#include "scripting/js-bindings/auto/jsb_gfx_auto.hpp"
#if (USE_GFX_RENDERER > 0) && (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 (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "renderer/gfx/GFX.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "base/ccConfig.h"
#if (USE_GFX_RENDERER > 0) && (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 (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"

View File

@ -1,5 +1,5 @@
#include "scripting/js-bindings/auto/jsb_renderer_auto.hpp"
#if (USE_GFX_RENDERER > 0) && (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 (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "renderer/renderer/Renderer.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "base/ccConfig.h"
#if (USE_GFX_RENDERER > 0) && (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 (USE_GFX_RENDERER > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"

View File

@ -1,5 +1,5 @@
#include "scripting/js-bindings/auto/jsb_video_auto.hpp"
#if (USE_VIDEO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#if (USE_VIDEO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "ui/videoplayer/VideoPlayer.h"
@ -519,4 +519,4 @@ bool register_all_video(se::Object* obj)
return true;
}
#endif //#if (USE_VIDEO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#endif //#if (USE_VIDEO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)

View File

@ -1,6 +1,6 @@
#pragma once
#include "base/ccConfig.h"
#if (USE_VIDEO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#if (USE_VIDEO > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"

View File

@ -1,5 +1,5 @@
#include "scripting/js-bindings/auto/jsb_webview_auto.hpp"
#if (USE_WEB_VIEW > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#if (USE_WEB_VIEW > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY) && !defined(CC_TARGET_OS_TVOS)
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
#include "scripting/js-bindings/manual/jsb_global.h"
#include "ui/webview/WebView.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "base/ccConfig.h"
#if (USE_WEB_VIEW > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#if (USE_WEB_VIEW > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY) && !defined(CC_TARGET_OS_TVOS)
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"

View File

@ -42,3 +42,7 @@
#include "chakracore/Object.hpp"
#endif
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_NAPI
#include "napi/Object.h"
#endif

View File

@ -42,6 +42,10 @@
#include "chakracore/SeApi.h"
#endif
#if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_NAPI
#include "napi/SeApi.h"
#endif
#include "Value.hpp"
#include "Object.hpp"
#include "State.hpp"

View File

@ -26,6 +26,13 @@
#include "Object.hpp"
namespace se {
#ifndef LIKELY
#ifdef __GNUC__
#define LIKELY(expr) __builtin_expect(!!(expr), 1)
#else
#define LIKELY(expr) expr
#endif
#endif
ValueArray EmptyValueArray;
@ -358,6 +365,21 @@ namespace se {
_u._number = v;
}
void Value::setDouble(double v) {
reset(Type::Number);
_u._number = v;
}
void Value::setInt64(int64_t v) {
reset(Type::BigInt);
_u._bigint = v;
}
void Value::setUint64(uint64_t v) {
reset(Type::BigInt);
_u._bigint = static_cast<int64_t>(v);
}
void Value::setString(const char* v)
{
if (v != nullptr)
@ -457,6 +479,11 @@ namespace se {
return static_cast<uint32_t>(toNumber());
}
uint64_t Value::toUint64() const
{
return static_cast<uint64_t>(toNumber());
}
long Value::toLong() const
{
return static_cast<long>(toNumber());
@ -485,6 +512,23 @@ namespace se {
return _u._number;
}
double Value::toDouble() const {
assert(_type == Type::Number || _type == Type::Boolean || _type == Type::BigInt || _type == Type::String);
if (LIKELY(_type == Type::Number)) {
return _u._number;
}
if (_type == Type::BigInt) {
// CC_LOG_WARNING("convert int64 to double");
return static_cast<double>(_u._bigint);
}
if (_type == Type::String) {
return std::stod(*_u._string);
}
return _u._boolean ? 1.0 : 0.0;
}
bool Value::toBoolean() const
{
assert(_type == Type::Boolean);

View File

@ -47,7 +47,8 @@ namespace se {
Number,
Boolean,
String,
Object
Object, // NOLINT(readability-identifier-naming)
BigInt
};
static Value Null;
@ -238,6 +239,24 @@ namespace se {
*/
void setNumber(double v);
/**
* @brief Sets se::Value to a double value.
* @param[in] v The double value to be set.
*/
void setDouble(double v);
/**
* @brief Sets se::Value to a int64_t value.
* @param[in] v The int64_t value to be set.
*/
void setInt64(int64_t v);
/**
* @brief Sets se::Value to a unsigned int64_t
* @param[in] v The unsigned int64_t value to be set.
*/
void setUint64(uint64_t v);
/**
* @brief Sets se::Value to an UTF8 null-terminated string value.
* @param[in] v The UTF8 null-terminated string value to be set.
@ -300,6 +319,8 @@ namespace se {
*/
uint32_t toUint32() const;
uint64_t toUint64() const;
/**
* @brief Converts se::Value to long.
* @return long integer.
@ -324,6 +345,12 @@ namespace se {
*/
double toNumber() const;
/**
* @brief Converts se::Value to double number.
* @return double number.
*/
double toDouble() const;
/**
* @brief Converts se::Value to boolean.
* @return boolean.
@ -362,6 +389,12 @@ namespace se {
*/
inline bool isNumber() const { return _type == Type::Number; }
/**
* @brief Tests whether se::Value stores a Bigint.
* @return true if se::Value stores a uint64_t or a int64_t, otherwise false.
*/
inline bool isBigInt() const { return _type == Type::BigInt; }
/**
* @brief Tests whether se::Value stores a string.
* @return true if se::Value stores a string, otherwise false.
@ -407,6 +440,7 @@ namespace se {
double _number;
std::string* _string;
Object* _object;
int64_t _bigint;
} _u;
Type _type;

View File

@ -29,6 +29,7 @@
#define SCRIPT_ENGINE_V8 2
#define SCRIPT_ENGINE_JSC 3
//#define SCRIPT_ENGINE_CHAKRACORE 4
#define SCRIPT_ENGINE_NAPI 5
#define SCRIPT_ENGINE_V8_ON_MAC 1 // default using v8 on macOS, set 0 to disable
@ -49,14 +50,14 @@
#define SCRIPT_ENGINE_TYPE SCRIPT_ENGINE_JSC
#endif
#endif
#elif defined(OPENHARMONY)
#define SCRIPT_ENGINE_TYPE SCRIPT_ENGINE_NAPI
//TODO how to make simulator build with v8 too? Because in release mode, it will build
// which means it will build armv7, but v8 doesn't support armv7.
#else
#define SCRIPT_ENGINE_TYPE SCRIPT_ENGINE_V8
#endif
#ifndef USE_V8_DEBUGGER
#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
#define USE_V8_DEBUGGER 1
@ -102,6 +103,12 @@ void seLogE(const char * format, ...);
#define SE_LOGD(fmt, ...) seLogD("D/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#define SE_LOGE(fmt, ...) seLogE("E/" LOG_TAG " (" QUOTEME(__LINE__) "): " fmt "", ##__VA_ARGS__)
#elif defined(OPENHARMONY)
#include <hilog/log.h>
#define SE_LOGD(...) OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__)
#define SE_LOGE(...) OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__)
#else
#define SE_LOGD(...) do { fprintf(stdout, __VA_ARGS__); fflush(stdout); } while (false)

View File

@ -0,0 +1,238 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "Class.h"
#include <string>
#include "CommonHeader.h"
#include "ScriptEngine.h"
#include "Utils.h"
namespace se {
napi_value *Class::_exports = nullptr;
std::vector<Class *> __allClasses;
Class::Class() {
__allClasses.push_back(this);
};
Class::~Class() {
}
/* static */
Class *Class::create(const std::string &clsName, se::Object *parent, Object *parentProto, napi_callback ctor) {
Class *cls = new Class();
if (cls != nullptr && !cls->init(clsName, parent, parentProto, ctor)) {
delete cls;
cls = nullptr;
}
return cls;
}
Class* Class::create(const std::initializer_list<const char *> &classPath, se::Object *parent, Object *parentProto, napi_callback ctor) {
se::AutoHandleScope scope;
se::Object *currentParent = parent;
se::Value tmp;
for (auto i = 0; i < classPath.size() - 1; i++) {
bool ok = currentParent->getProperty(*(classPath.begin() + i), &tmp);
assert(ok); // class or namespace in path is not defined
currentParent = tmp.toObject();
}
return create(*(classPath.end() - 1), currentParent, parentProto, ctor);
}
bool Class::init(const std::string &clsName, Object *parent, Object *parentProto, napi_callback ctor) {
_name = clsName;
_parent = parent;
if (_parent != nullptr)
_parent->incRef();
_parentProto = parentProto;
if (_parentProto != nullptr)
_parentProto->incRef();
if (ctor) {
_ctorFunc = ctor;
}
return true;
}
napi_value Class::_defaultCtor(napi_env env, napi_callback_info info) {
LOGE("check default ctor called");
return nullptr;
}
void Class::defineProperty(const char* name, napi_callback g, napi_callback s) {
_properties.push_back({name, nullptr, nullptr, g, s, 0, napi_default_jsproperty, 0});
}
void Class::defineProperty(const std::initializer_list<const char *> &names, napi_callback g, napi_callback s) {
for (const auto *name : names) {
defineProperty(name, g, s);
}
}
void Class::defineStaticProperty(const char* name, napi_callback g, napi_callback s) {
if(g != nullptr && s != nullptr)
_properties.push_back({name, nullptr, nullptr, g, s, 0, napi_static, 0});
}
void Class::defineFunction(const char* name, napi_callback func) {
// When Napi defines a function, it needs to add the enum attribute, otherwise JS cannot traverse the function
_properties.push_back({name, nullptr, func, nullptr, nullptr, nullptr, napi_default_jsproperty, nullptr});
}
void Class::defineStaticFunction(const char* name, napi_callback func) {
_properties.push_back({name, nullptr, func, nullptr, nullptr, 0, napi_property_attributes((int)napi_static|(int)napi_writable), 0});
}
void Class::defineFinalizeFunction(napi_finalize func) {
assert(func != nullptr);
_finalizeFunc = func;
}
napi_finalize Class::_getFinalizeFunction() const {
return _finalizeFunc;
}
bool Class::install() {
napi_value cons;
napi_status status;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_define_class(ScriptEngine::getEnv(), _name.c_str(), -1, _ctorFunc, nullptr, _properties.size(), _properties.data(), &cons));
if (_parentProto) {
inherit(ScriptEngine::getEnv(), cons, _parentProto->_getJSObject());
}
NODE_API_CALL(status, ScriptEngine::getEnv(),
napi_create_reference(ScriptEngine::getEnv(), cons, 1, &_constructor));
NODE_API_CALL(status, ScriptEngine::getEnv(),
napi_set_named_property(ScriptEngine::getEnv(), _parent->_getJSObject(), _name.c_str(), cons));
napi_value proto;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_named_property(ScriptEngine::getEnv(), cons, "prototype", &proto));
if (status == napi_ok) {
_proto = Object::_createJSObject(ScriptEngine::getEnv(), proto, nullptr);
_proto->root();
}
return true;
}
napi_status Class::inherit(napi_env env, napi_value subclass, napi_value superProto) {
napi_value global, objectClass, setProto;
napi_value argv[2];
napi_value callbackResult = nullptr;
napi_get_global(env, &global);
napi_status status = napi_get_named_property(env, global, "Object", &objectClass);
if (status != napi_ok) {
return napi_ok;
}
status = napi_get_named_property(env, objectClass, "setPrototypeOf", &setProto);
if (status != napi_ok) {
return napi_ok;
}
status = napi_get_named_property(env, subclass, "prototype", &argv[0]);
if (status != napi_ok) {
return napi_ok;
}
argv[1] = superProto;
status = napi_call_function(env, objectClass, setProto, 2, argv, &callbackResult);
if (status != napi_ok) {
return napi_ok;
}
return napi_ok;
}
napi_value Class::_createJSObjectWithClass(Class *cls) {
napi_value obj = nullptr;
napi_status status;
assert(cls);
napi_value clsCtor = cls->_getCtorFunc();
if (!clsCtor) {
LOGE("get ctor func err");
return nullptr;
}
se::ScriptEngine::getInstance()->_setNeedCallConstructor(false);
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_new_instance( ScriptEngine::getEnv(), clsCtor, 0, nullptr, &obj));
se::ScriptEngine::getInstance()->_setNeedCallConstructor(true);
return obj;
}
Object *Class::getProto() const {
//not impl
return _proto;
}
napi_ref Class::_getCtorRef() const {
return _constructor;
}
napi_value Class::_getCtorFunc() const {
assert(_constructor);
napi_value result = nullptr;
napi_status status;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_reference_value(ScriptEngine::getEnv(), _constructor, &result));
return result;
}
void Class::_setCtor(Object *obj) {
assert(!_ctor.has_value());
_ctor = obj;
if (obj != nullptr) {
obj->root();
obj->incRef();
}
}
void Class::destroy() {
SAFE_DEC_REF(_parent);
SAFE_DEC_REF(_proto);
SAFE_DEC_REF(_parentProto);
if (_ctor.has_value()) {
if (_ctor.value() != nullptr) {
_ctor.value()->unroot();
_ctor.value()->decRef();
}
_ctor.reset();
}
}
void Class::cleanup() {
for (auto cls : __allClasses) {
cls->destroy();
}
se::ScriptEngine::getInstance()->addAfterCleanupHook([]() {
for (auto cls : __allClasses) {
delete cls;
}
__allClasses.clear();
});
}
}; // namespace se

View File

@ -0,0 +1,81 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <string>
#include <optional>
#include "CommonHeader.h"
#include "Object.h"
namespace se {
class Class {
public:
static Class *create(const std::string &clsName, se::Object *parent, Object *parentProto, napi_callback ctor = nullptr);
static Class *create(const std::initializer_list<const char *> &classPath, se::Object *parent, Object *parentProto, napi_callback ctor = nullptr);
void defineFunction(const char* name, napi_callback func);
void defineProperty(const char* name, napi_callback g, napi_callback s);
void defineProperty(const std::initializer_list<const char *> &names, napi_callback g, napi_callback s);
void defineStaticFunction(const char* name, napi_callback func);
void defineStaticProperty(const char* name, napi_callback g, napi_callback s);
static napi_value _createJSObjectWithClass(Class *cls);
void defineFinalizeFunction(napi_finalize func);
napi_finalize _getFinalizeFunction() const;
Object * getProto() const;
bool install();
napi_status inherit(napi_env env, napi_value subclass, napi_value superclass);
napi_ref _getCtorRef() const;
napi_value _getCtorFunc() const;
const char * getName() const { return _name.c_str(); }
static void setExports(napi_value *expPtr) { _exports = expPtr; }
static void cleanup();
// Private API used in wrapper
void _setCtor(Object *obj); // NOLINT(readability-identifier-naming)
inline const std::optional<Object *> &_getCtor() const { return _ctor; } // NOLINT(readability-identifier-naming)
private:
Class();
~Class();
bool init(const std::string &clsName, Object *parent, Object *parentProto, napi_callback ctor = nullptr);
void destroy();
static napi_value _defaultCtor(napi_env env, napi_callback_info info);
private:
std::optional<Object *> _ctor;
static napi_value * _exports;
std::string _name;
Object * _parent = nullptr;
Object * _proto = nullptr;
Object * _parentProto = nullptr;
napi_callback _ctorFunc = Class::_defaultCtor;
napi_ref _constructor = nullptr;
std::vector<napi_property_descriptor> _properties;
napi_finalize _finalizeFunc = nullptr;
};
}; // namespace se

View File

@ -0,0 +1,74 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <napi/native_api.h>
#include "native_common.h"
// Empty value so that macros here are able to return NULL or void
#define NODE_API_RETVAL_NOTHING // Intentionally blank #define
// Returns NULL on failed assertion.
// This is meant to be used inside napi_callback methods.
#define NODE_API_ASSERT(env, assertion, message) \
NODE_API_ASSERT_BASE(env, assertion, message, NULL)
// Returns empty on failed assertion.
// This is meant to be used inside functions with void return type.
#define NODE_API_ASSERT_RETURN_VOID(env, assertion, message) \
NODE_API_ASSERT_BASE(env, assertion, message, NODE_API_RETVAL_NOTHING)
#define NODE_API_CALL_BASE(env, the_call, ret_val) \
do { \
if ((the_call) != napi_ok) { \
assert(false); \
} \
} while (0)
// Returns nullptr if the_call doesn't return napi_ok.
#define NODE_API_CALL(status, env, the_call) \
status = the_call; \
if (status != napi_ok) \
LOGI("error:%d", status); \
NODE_API_CALL_BASE(env, status, nullptr)
// Returns empty if the_call doesn't return napi_ok.
#define NODE_API_CALL_RETURN_VOID(env, the_call) \
NODE_API_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING)
#define DECLARE_NODE_API_PROPERTY(name, func) \
{ (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr }
#define DECLARE_NODE_API_GETTER(name, func) \
{ (name), nullptr, nullptr, (func), nullptr, nullptr, napi_default, nullptr }
void add_returned_status(napi_env env,
const char* key,
napi_value object,
char* expected_message,
napi_status expected_status,
napi_status actual_status);
void add_last_status(napi_env env, const char* key, napi_value return_value);

View File

@ -0,0 +1,145 @@
/****************************************************************************
Copyright (c) 2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
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 "HelperMacros.h"
#include "../State.hpp"
#include "Class.h"
#include "Object.h"
#include "ScriptEngine.h"
#include "Utils.h"
SE_HOT napi_value jsbFunctionWrapper(napi_env env, napi_callback_info info, se_function_ptr func, const char *funcName) {
napi_status status;
bool ret = false;
napi_value _this;
se::ValueArray seArgs;
seArgs.reserve(15);
size_t argc = 15;
napi_value args[15];
NODE_API_CALL(status, env, napi_get_cb_info(env, info, &argc, args, &_this, NULL));
void* nativeThisObject = nullptr;
status = napi_unwrap(env, _this, &nativeThisObject);
se::internal::jsToSeArgs(argc, args, &seArgs);
se::State state(nativeThisObject, seArgs);
ret = func(state);
if (!ret) {
SE_LOGE("[ERROR] Failed to invoke %s, location: %s:%d\n", funcName, __FILE__, __LINE__);
return nullptr;
}
napi_value retVal;
if (se::internal::setReturnValue(state.rval(), retVal))
return retVal;
return nullptr;
}
SE_HOT void jsbFinalizeWrapper(void *thisObject, se_function_ptr func, const char *funcName) {
se::State state(reinterpret_cast<se::Object *>(thisObject));
bool ret = func(state);
if (!ret) {
SE_LOGE("[ERROR] Failed to invoke %s, location: %s:%d\n", funcName, __FILE__, __LINE__);
}
}
SE_HOT napi_value jsbConstructorWrapper(napi_env env, napi_callback_info info, se_function_ptr func, se_finalize_ptr finalizeCb, se::Class *cls, const char *funcName) {
napi_status status;
bool ret = false;
napi_value _this;
se::ValueArray seArgs;
seArgs.reserve(10);
size_t argc = 10;
napi_value args[10];
NODE_API_CALL(status, env, napi_get_cb_info(env, info, &argc, args, &_this, NULL));
if (!se::ScriptEngine::getInstance()->_needCallConstructor()) {
return _this;
}
se::internal::jsToSeArgs(argc, args, &seArgs);
se::Object *thisObject = se::Object::_createJSObject(env, _this, cls);
thisObject->_setFinalizeCallback(finalizeCb);
se::State state(thisObject, seArgs);
ret = func(state);
if (!ret) {
SE_LOGE("[ERROR] Failed to invoke %s, location: %s:%d\n", funcName, __FILE__, __LINE__);
}
se::Value property;
bool foundCtor = false;
if (!cls->_getCtor().has_value()) {
foundCtor = thisObject->getProperty("_ctor", &property, true);
if (foundCtor) {
cls->_setCtor(property.toObject());
} else {
cls->_setCtor(nullptr);
}
} else {
auto *ctorObj = cls->_getCtor().value();
if (ctorObj != nullptr) {
property.setObject(ctorObj);
foundCtor = true;
}
}
if (foundCtor) {
property.toObject()->call(seArgs, thisObject);
}
return _this;
}
SE_HOT napi_value jsbGetterWrapper(napi_env env, napi_callback_info info, se_function_ptr func, const char *funcName) {
napi_value _this;
napi_status status;
NODE_API_CALL(status, env,
napi_get_cb_info(env, info, nullptr, nullptr, &_this, nullptr));
void* obj = nullptr;
status = napi_unwrap(env, _this, &obj);
se::State state(obj);
bool ret = func(state);
if (!ret) {
SE_LOGE("[ERROR] Failed to invoke %s, location: %s:%d\n", funcName, __FILE__, __LINE__);
return nullptr;
}
napi_value retVal;
se::internal::setReturnValue(state.rval(), retVal);
return retVal;
}
SE_HOT napi_value jsbSetterWrapper(napi_env env, napi_callback_info info, se_function_ptr func, const char *funcName) {
napi_status status;
size_t argc = 1;
napi_value args[1];
napi_value _this;
se::Value data;
NODE_API_CALL(status, env, napi_get_cb_info(env, info, &argc, args, &_this, nullptr));
se::internal::jsToSeValue(args[0], &data);
se::ValueArray args2;
args2.reserve(10);
args2.push_back(std::move(data));
void* nativeThisObject = nullptr;
status = napi_unwrap(env, _this, &nativeThisObject);
se::State state(nativeThisObject, args2);
bool ret = func(state);
if (!ret) {
SE_LOGE("[ERROR] Failed to invoke %s, location: %s:%d\n", funcName, __FILE__, __LINE__);
}
return nullptr;
}

View File

@ -0,0 +1,153 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "CommonHeader.h"
#if !defined(_WIN)
#include <hilog/log.h>
#ifndef LOGI
#define LOGI(...) ((void) OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#define LOGW(...) ((void) OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#define LOGE(...) ((void) OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#define LOGD(...) ((void) OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "HMG_LOG", __VA_ARGS__))
#endif
#else
#define LOGI
#define LOGW
#define LOGE
#endif
namespace se {
class Class;
class Object;
class State;
} // namespace se
using se_function_ptr = bool (*)(se::State &state);
using se_finalize_ptr = void (*)(napi_env env, void *nativeObject, void *hint);
napi_value jsbFunctionWrapper(napi_env, napi_callback_info,
se_function_ptr,
const char *);
void jsbFinalizeWrapper(void *thisObject,
se_function_ptr,
const char *);
napi_value jsbConstructorWrapper(napi_env, napi_callback_info,
se_function_ptr,
se_finalize_ptr finalizeCb,
se::Class *,
const char *);
napi_value jsbGetterWrapper(napi_env, napi_callback_info,
se_function_ptr,
const char *);
napi_value jsbSetterWrapper(napi_env, napi_callback_info,
se_function_ptr,
const char *);
#ifdef __GNUC__
#define SE_UNUSED __attribute__((unused))
#define SE_HOT __attribute__((hot))
#else
#define SE_UNUSED
#define SE_HOT
#endif
template <typename T, typename STATE>
constexpr inline T *SE_THIS_OBJECT(STATE &s) { // NOLINT(readability-identifier-naming)
return reinterpret_cast<T *>(s.nativeThisObject());
}
#define SAFE_INC_REF(obj) \
if (obj != nullptr) obj->incRef()
#define SAFE_DEC_REF(obj) \
if ((obj) != nullptr) { \
(obj)->decRef(); \
(obj) = nullptr; \
}
#define _SE(name) name##Registry // NOLINT(readability-identifier-naming, bugprone-reserved-identifier)
#define SE_QUOTEME_(x) #x // NOLINT(readability-identifier-naming)
#define SE_QUOTEME(x) SE_QUOTEME_(x)
#define SE_REPORT_ERROR(fmt, ...) SE_LOGE("[ERROR] (" __FILE__ ", " SE_QUOTEME(__LINE__) "): " fmt "\n", ##__VA_ARGS__)
#define SE_BIND_PROP_GET_IMPL(funcName, postFix) \
napi_value funcName##postFix##Registry(napi_env env, napi_callback_info info) { \
return jsbGetterWrapper(env, info, funcName, #funcName); \
}
#define SE_BIND_PROP_GET(funcName) SE_BIND_PROP_GET_IMPL(funcName, )
#define SE_BIND_FUNC_AS_PROP_GET(funcName) SE_BIND_PROP_GET_IMPL(funcName, _asGetter)
#define SE_BIND_PROP_SET_IMPL(funcName, postFix) \
napi_value funcName##postFix##Registry(napi_env env, napi_callback_info info) { \
return jsbSetterWrapper(env, info, funcName, #funcName); \
}
#define SE_BIND_PROP_SET(funcName) SE_BIND_PROP_SET_IMPL(funcName, )
#define SE_BIND_FUNC_AS_PROP_SET(funcName) SE_BIND_PROP_SET_IMPL(funcName, _asSetter)
#define SE_DECLARE_FUNC(funcName) \
napi_value funcName##Registry(napi_env env, napi_callback_info info)
#define SE_BIND_FUNC(funcName) \
napi_value funcName##Registry( \
napi_env env, napi_callback_info info) { \
return jsbFunctionWrapper(env, info, funcName, #funcName); \
}
#define SE_BIND_FUNC_FAST(funcName) \
napi_value funcName##Registry(napi_env env, napi_callback_info info) { \
napi_status status; \
napi_value _this; \
size_t argc = 10; \
napi_value args[10]; \
void* nativeThisObject = nullptr; \
NODE_API_CALL(status, env, napi_get_cb_info(env, info, &argc, args, &_this, NULL)); \
status = napi_unwrap(env, _this, &nativeThisObject); \
auto *nativeObject = nativeThisObject != nullptr ? nativeThisObject->getPrivateData() : nullptr; \
funcName(nativeObject); \
return nullptr; \
}
#define SE_BIND_CTOR(funcName, cls, finalizeCb) \
napi_value funcName##Registry( \
napi_env env, napi_callback_info info) { \
return jsbConstructorWrapper(env, info, funcName, _SE(finalizeCb), cls, #funcName); \
}
#define SE_BIND_SUB_CLS_CTOR SE_BIND_CTOR
#define SE_DECLARE_FINALIZE_FUNC(funcName) \
void funcName##Registry( \
napi_env env, void *nativeObject, void * /*finalize_hint*/);
#define SE_BIND_FINALIZE_FUNC(funcName) \
void funcName##Registry( \
napi_env env, void *nativeObject, void *hint /*finalize_hint*/) { \
if (nativeObject == nullptr) { \
return; \
} \
jsbFinalizeWrapper(nativeObject, funcName, #funcName); \
}

View File

@ -0,0 +1,738 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "Object.h"
#include <memory>
#include <unordered_map>
#include "../MappingUtils.hpp"
#include "Class.h"
#include "ScriptEngine.h"
#include "Utils.h"
#define MAX_STRING_LEN 512
namespace se {
std::unique_ptr<std::unordered_map<Object*, void*>> __objectMap; // Currently, the value `void*` is always nullptr
Object::Object() {}
Object::~Object() {
if (__objectMap) {
__objectMap->erase(this);
}
}
Object* Object::createObjectWithClass(Class* cls) {
napi_value jsobj = Class::_createJSObjectWithClass(cls);
Object* obj = Object::_createJSObject(ScriptEngine::getEnv(), jsobj, cls);
return obj;
}
bool Object::setProperty(const char* name, const Value& data) {
napi_status status;
napi_value jsVal;
internal::seToJsValue(data, &jsVal);
NODE_API_CALL(status, _env, napi_set_named_property(_env, _objRef.getValue(_env), name, jsVal));
return status == napi_ok;
}
bool Object::getProperty(const char* name, Value* d) {
napi_status status;
napi_value jsVal;
Value data;
NODE_API_CALL(status, _env, napi_get_named_property(_env, _objRef.getValue(_env), name, &jsVal));
if (status == napi_ok) {
internal::jsToSeValue(jsVal, &data);
*d = data;
if (data.isUndefined()) {
return false;
}
return true;
}
return false;
}
bool Object::deleteProperty(const char *name) {
napi_status status;
napi_value key;
NODE_API_CALL(status, _env, napi_get_named_property(_env, _objRef.getValue(_env), name, &key));
if (status != napi_ok) {
return false;
}
bool ret = false;
NODE_API_CALL(status, _env, napi_delete_property(_env, _objRef.getValue(_env), key, &ret));
return ret;
}
bool Object::isArray() const {
napi_status status;
bool ret = false;
NODE_API_CALL(status, _env, napi_is_array(_env, _objRef.getValue(_env), &ret));
return ret;
}
bool Object::getArrayLength(uint32_t* length) const {
napi_status status;
uint32_t len = 0;
NODE_API_CALL(status, _env, napi_get_array_length(_env, _objRef.getValue(_env), &len));
if (length) {
*length = len;
}
return true;
}
bool Object::getArrayElement(uint32_t index, Value* data) const {
napi_status status;
napi_value val;
NODE_API_CALL(status, _env, napi_get_element(_env, _objRef.getValue(_env), index, &val));
internal::jsToSeValue(val, data);
return true;
}
bool Object::setArrayElement(uint32_t index, const Value& data) {
napi_status status;
napi_value val;
internal::seToJsValue(data, &val);
NODE_API_CALL(status, _env, napi_set_element(_env, _objRef.getValue(_env), index, val));
return true;
}
bool Object::isTypedArray() const {
napi_status status;
bool ret = false;
NODE_API_CALL(status, _env, napi_is_typedarray(_env, _objRef.getValue(_env), &ret));
return ret;
}
bool Object::isProxy() const {
//return const_cast<Object *>(this)->_obj.handle(__isolate)->IsProxy();
// todo:
return false;
}
Object::TypedArrayType Object::getTypedArrayType() const {
napi_status status;
napi_typedarray_type type;
napi_value inputBuffer;
size_t byteOffset;
size_t length;
NODE_API_CALL(status, _env, napi_get_typedarray_info(_env, _objRef.getValue(_env), &type, &length, NULL, &inputBuffer, &byteOffset));
TypedArrayType ret = TypedArrayType::NONE;
switch (type) {
case napi_int8_array:
ret = TypedArrayType::INT8;
break;
case napi_uint8_array:
ret = TypedArrayType::UINT8;
break;
case napi_uint8_clamped_array:
ret = TypedArrayType::UINT8_CLAMPED;
break;
case napi_int16_array:
ret = TypedArrayType::INT16;
break;
case napi_uint16_array:
ret = TypedArrayType::UINT16;
break;
case napi_int32_array:
ret = TypedArrayType::INT32;
break;
case napi_uint32_array:
ret = TypedArrayType::UINT32;
break;
case napi_float32_array:
ret = TypedArrayType::FLOAT32;
break;
case napi_float64_array:
ret = TypedArrayType::FLOAT64;
break;
default:
break;
}
return ret;
}
bool Object::getTypedArrayData(uint8_t** ptr, size_t* length) const {
napi_status status;
napi_typedarray_type type;
napi_value inputBuffer;
size_t byteOffset;
size_t byteLength;
void* data = nullptr;
NODE_API_CALL(status, _env, napi_get_typedarray_info(_env, _objRef.getValue(_env), &type, &byteLength, &data, &inputBuffer, &byteOffset));
*ptr = (uint8_t*)(data);
if (length) {
*length = byteLength;
}
return true;
}
bool Object::isArrayBuffer() const {
bool ret = false;
napi_status status;
NODE_API_CALL(status, _env, napi_is_arraybuffer(_env, _objRef.getValue(_env), &ret));
return ret;
}
bool Object::getArrayBufferData(uint8_t** ptr, size_t* length) const {
napi_status status;
size_t len = 0;
NODE_API_CALL(status, _env, napi_get_arraybuffer_info(_env, _objRef.getValue(_env), reinterpret_cast<void**>(ptr), &len));
if (length) {
*length = len;
}
return true;
}
Object* Object::createTypedArray(Object::TypedArrayType type, const void* data, size_t byteLength) {
napi_status status;
if (type == TypedArrayType::NONE) {
SE_LOGE("Don't pass se::Object::TypedArrayType::NONE to createTypedArray API!");
return nullptr;
}
if (type == TypedArrayType::UINT8_CLAMPED) {
SE_LOGE("Doesn't support to create Uint8ClampedArray with Object::createTypedArray API!");
return nullptr;
}
napi_typedarray_type napiType;
napi_value outputBuffer;
void* outputPtr = nullptr;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_arraybuffer(ScriptEngine::getEnv(), byteLength, &outputPtr, &outputBuffer));
if (outputPtr && data && byteLength > 0) {
memcpy(outputPtr, data, byteLength);
}
size_t sizeOfEle = 0;
switch (type) {
case TypedArrayType::INT8:
napiType = napi_int8_array;
sizeOfEle = 1;
break;
case TypedArrayType::UINT8:
napiType = napi_uint8_array;
sizeOfEle = 1;
break;
case TypedArrayType::INT16:
napiType = napi_int16_array;
sizeOfEle = 2;
break;
case TypedArrayType::UINT16:
napiType = napi_uint16_array;
sizeOfEle = 2;
break;
case TypedArrayType::INT32:
napiType = napi_int32_array;
sizeOfEle = 4;
break;
case TypedArrayType::UINT32:
napiType = napi_uint32_array;
sizeOfEle = 4;
break;
case TypedArrayType::FLOAT32:
napiType = napi_float32_array;
sizeOfEle = 4;
break;
case TypedArrayType::FLOAT64:
napiType = napi_float64_array;
sizeOfEle = 8;
break;
default:
assert(false); // Should never go here.
break;
}
size_t eleCounts = byteLength / sizeOfEle;
napi_value outputArray;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_typedarray(ScriptEngine::getEnv(), napiType, eleCounts, outputBuffer, 0, &outputArray));
Object* obj = Object::_createJSObject(ScriptEngine::getEnv(), outputArray, nullptr);
return obj;
}
Object* Object::createTypedArrayWithBuffer(TypedArrayType type, const Object *obj) {
return Object::createTypedArrayWithBuffer(type, obj, 0);
}
Object* Object::createTypedArrayWithBuffer(TypedArrayType type, const Object *obj, size_t offset) {
size_t byteLength{0};
uint8_t *skip{nullptr};
if (obj->getArrayBufferData(&skip, &byteLength)) {
return Object::createTypedArrayWithBuffer(type, obj, offset, byteLength - offset);
}
assert(false);
return nullptr;
}
Object* Object::createTypedArrayWithBuffer(TypedArrayType type, const Object *obj, size_t offset, size_t byteLength) {
if (type == TypedArrayType::NONE) {
SE_LOGE("Don't pass se::Object::TypedArrayType::NONE to createTypedArray API!");
return nullptr;
}
if (type == TypedArrayType::UINT8_CLAMPED) {
SE_LOGE("Doesn't support to create Uint8ClampedArray with Object::createTypedArray API!");
return nullptr;
}
assert(obj->isArrayBuffer());
napi_status status;
napi_value outputBuffer = obj->_getJSObject();
napi_typedarray_type napiType;
size_t sizeOfEle = 0;
switch (type) {
case TypedArrayType::INT8:
napiType = napi_int8_array;
sizeOfEle = 1;
break;
case TypedArrayType::UINT8:
napiType = napi_uint8_array;
sizeOfEle = 1;
break;
case TypedArrayType::INT16:
napiType = napi_int8_array;
sizeOfEle = 2;
case TypedArrayType::UINT16:
napiType = napi_uint8_array;
sizeOfEle = 2;
break;
case TypedArrayType::INT32:
napiType = napi_int32_array;
sizeOfEle = 4;
case TypedArrayType::UINT32:
napiType = napi_uint32_array;
sizeOfEle = 4;
case TypedArrayType::FLOAT32:
napiType = napi_float32_array;
sizeOfEle = 4;
break;
case TypedArrayType::FLOAT64:
napiType = napi_float64_array;
sizeOfEle = 8;
break;
default:
assert(false); // Should never go here.
break;
}
size_t eleCounts = byteLength / sizeOfEle;
napi_value outputArray;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_typedarray(ScriptEngine::getEnv(), napiType, eleCounts, outputBuffer, offset, &outputArray));
return Object::_createJSObject(ScriptEngine::getEnv(), outputArray, nullptr);
}
Object* Object::createExternalArrayBufferObject(void *contents, size_t byteLength, BufferContentsFreeFunc freeFunc, void *freeUserData) {
napi_status status;
napi_value result;
if (freeFunc) {
struct ExternalArrayBufferCallbackParams* param = new (struct ExternalArrayBufferCallbackParams);
param->func = freeFunc;
param->contents = contents;
param->byteLength = byteLength;
param->userData = freeUserData;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_external_arraybuffer(
ScriptEngine::getEnv(), contents, byteLength, [](napi_env env, void* finalize_data, void* finalize_hint) {
if (finalize_hint) {
struct ExternalArrayBufferCallbackParams* param = reinterpret_cast<struct ExternalArrayBufferCallbackParams *>(finalize_hint);
param->func(param->contents, param->byteLength, param->userData);
delete param;
}
},
reinterpret_cast<void*>(param), &result));
} else {
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_external_arraybuffer(
ScriptEngine::getEnv(), contents, byteLength, nullptr,
freeUserData, &result));
}
Object* obj = Object::_createJSObject(ScriptEngine::getEnv(), result, nullptr);
return obj;
}
bool Object::isFunction() const {
napi_valuetype valuetype0;
napi_status status;
NODE_API_CALL(status, _env, napi_typeof(_env, _objRef.getValue(_env), &valuetype0));
return (valuetype0 == napi_function);
}
bool Object::defineFunction(const char* funcName, napi_callback func) {
napi_value fn;
napi_status status;
NODE_API_CALL(status, _env, napi_create_function(_env, funcName, NAPI_AUTO_LENGTH, func, NULL, &fn));
NODE_API_CALL(status, _env, napi_set_named_property(_env, _objRef.getValue(_env), funcName, fn));
return true;
}
bool Object::defineProperty(const char* name, napi_callback getter, napi_callback setter) {
napi_status status;
napi_property_descriptor properties[] = {{name, nullptr, nullptr, getter, setter, 0, napi_default, 0}};
status = napi_define_properties(_env, _objRef.getValue(_env), sizeof(properties) / sizeof(napi_property_descriptor), properties);
if (status == napi_ok) {
return true;
}
return false;
}
Object* Object::_createJSObject(napi_env env, napi_value js_object, Class* cls) { // NOLINT(readability-identifier-naming)
Object* ret = new Object();
if (!ret->init(env, js_object, cls)) {
delete ret;
ret = nullptr;
}
return ret;
}
Object* Object::createPlainObject() {
napi_value result;
napi_status status;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_object(ScriptEngine::getEnv(), &result));
Object* obj = _createJSObject(ScriptEngine::getEnv(), result, nullptr);
return obj;
}
Object* Object::createArrayObject(size_t length) {
napi_value result;
napi_status status;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_array_with_length(ScriptEngine::getEnv(), length, &result));
Object* obj = _createJSObject(ScriptEngine::getEnv(), result, nullptr);
return obj;
}
Object* Object::createArrayBufferObject(const void* data, size_t byteLength) {
napi_value result;
napi_status status;
void* retData;
Object* obj = nullptr;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_arraybuffer(ScriptEngine::getEnv(), byteLength, &retData, &result));
if (status == napi_ok) {
if (data) {
memcpy(retData, data, byteLength);
}
obj = _createJSObject(ScriptEngine::getEnv(), result, nullptr);
}
return obj;
}
bool Object::getAllKeys(std::vector<std::string>* allKeys) const {
napi_status status;
napi_value names;
NODE_API_CALL(status, _env, napi_get_property_names(_env, _objRef.getValue(_env), &names));
if (status != napi_ok) {
return false;
}
uint32_t name_len = 0;
NODE_API_CALL(status, _env, napi_get_array_length(_env, names, &name_len));
for (uint32_t i = 0; i < name_len; i++) {
napi_value val;
NODE_API_CALL(status, _env, napi_get_element(_env, names, i, &val));
if (status == napi_ok) {
char buffer[MAX_STRING_LEN];
size_t result = 0;
NODE_API_CALL(status, _env, napi_get_value_string_utf8(_env, val, buffer, MAX_STRING_LEN, &result));
if (result > 0) {
allKeys->push_back(buffer);
}
}
}
return true;
}
bool Object::init(napi_env env, napi_value js_object, Class* cls) {
assert(env);
_cls = cls;
_env = env;
_objRef.initWeakref(env, js_object);
if (__objectMap) {
assert(__objectMap->find(this) == __objectMap->end());
__objectMap->emplace(this, nullptr);
}
napi_status status;
return true;
}
bool Object::call(const ValueArray& args, Object* thisObject, Value* rval) {
size_t argc = 0;
std::vector<napi_value> argv;
argv.reserve(10);
argc = args.size();
internal::seToJsArgs(_env, args, &argv);
napi_value return_val;
napi_status status;
assert(isFunction());
napi_value thisObj = thisObject ? thisObject->_getJSObject() : nullptr;
status =
napi_call_function(_env, thisObj, _getJSObject(), argc, argv.data(), &return_val);
if (rval) {
internal::jsToSeValue(return_val, rval);
}
return true;
}
void Object::_setFinalizeCallback(napi_finalize finalizeCb) {
assert(finalizeCb != nullptr);
_finalizeCb = finalizeCb;
}
void Object::setPrivateData(void* data){
assert(_privateData == nullptr);
assert(NativePtrToObjectMap::find(data) == NativePtrToObjectMap::end());
napi_status status;
NativePtrToObjectMap::emplace(data, this);
_privateData = data;
//issue https://github.com/nodejs/node/issues/23999
auto tmpThis = _objRef.getValue(_env);
//_objRef.deleteRef();
napi_ref result = nullptr;
NODE_API_CALL(status, _env,
napi_wrap(_env, tmpThis, data, weakCallback,
(void*)this /* finalize_hint */, &result));
//_objRef.setWeakref(_env, result);
setProperty("__native_ptr__", se::Value(static_cast<long>(reinterpret_cast<uintptr_t>(data))));
}
void* Object::getPrivateData() const{
napi_status status;
void* data;
auto tmpThis = _objRef.getValue(_env);
status = napi_unwrap(_env, tmpThis, &data);
const_cast<Object*>(this)->_privateData = data;
return _privateData;
}
bool Object::attachObject(Object* obj) {
assert(obj);
Object* global = ScriptEngine::getInstance()->getGlobalObject();
Value jsbVal;
if (!global->getProperty("jsb", &jsbVal)) {
return false;
}
Object* jsbObj = jsbVal.toObject();
Value func;
if (!jsbObj->getProperty("registerNativeRef", &func)) {
return false;
}
ValueArray args;
args.push_back(Value(this));
args.push_back(Value(obj));
func.toObject()->call(args, global);
return true;
}
bool Object::detachObject(Object* obj) {
assert(obj);
Object* global = ScriptEngine::getInstance()->getGlobalObject();
Value jsbVal;
if (!global->getProperty("jsb", &jsbVal)) {
return false;
}
Object* jsbObj = jsbVal.toObject();
Value func;
if (!jsbObj->getProperty("unregisterNativeRef", &func)) {
return false;
}
ValueArray args;
args.push_back(Value(this));
args.push_back(Value(obj));
func.toObject()->call(args, global);
return true;
}
std::string Object::toString() const {
std::string ret;
napi_status status;
if (isFunction() || isArray() || isTypedArray()) {
napi_value result;
NODE_API_CALL(status, _env, napi_coerce_to_string(_env, _objRef.getValue(_env), &result));
char buffer[MAX_STRING_LEN];
size_t result_t = 0;
NODE_API_CALL(status, _env, napi_get_value_string_utf8(_env, result, buffer, MAX_STRING_LEN, &result_t));
ret = buffer;
} else if (isArrayBuffer()) {
ret = "[object ArrayBuffer]";
} else {
ret = "[object Object]";
}
return ret;
}
void Object::root() {
napi_status status;
if (_rootCount == 0) {
uint32_t result = 0;
_objRef.incRef(_env);
//NODE_API_CALL(status, _env, napi_reference_ref(_env, _wrapper, &result));
}
++_rootCount;
}
void Object::unroot() {
napi_status status;
if (_rootCount > 0) {
--_rootCount;
if (_rootCount == 0) {
_objRef.decRef(_env);
}
}
}
bool Object::isRooted() const {
return _rootCount > 0;
}
Class* Object::_getClass() const {
return _cls;
}
Object* Object::getObjectWithPtr(void* ptr) {
Object* obj = nullptr;
auto iter = NativePtrToObjectMap::find(ptr);
if (iter != NativePtrToObjectMap::end()) {
obj = iter->second;
obj->incRef();
}
return obj;
}
napi_value Object::_getJSObject() const {
return _objRef.getValue(_env);
}
void Object::weakCallback(napi_env env, void* nativeObject, void* finalizeHint /*finalize_hint*/) {
if (finalizeHint) {
if (nativeObject == nullptr) {
return;
}
void *rawPtr = reinterpret_cast<Object*>(finalizeHint)->_privateData;
Object* seObj = reinterpret_cast<Object*>(finalizeHint);
if (seObj->_onCleaingPrivateData) { //called by cleanPrivateData, not release seObj;
return;
}
if (seObj->_clearMappingInFinalizer && rawPtr != nullptr) {
auto iter = NativePtrToObjectMap::find(rawPtr);
if (iter != NativePtrToObjectMap::end()) {
NativePtrToObjectMap::erase(iter);
} else {
SE_LOGE("not find ptr in NativePtrToObjectMap");
}
}
// TODO: remove test code before releasing.
const char* clsName = seObj->_getClass()->getName();
SE_LOGE("weakCallback class name:%s, ptr:%p", clsName, rawPtr);
if (seObj->_finalizeCb != nullptr) {
seObj->_finalizeCb(env, finalizeHint, finalizeHint);
} else {
assert(seObj->_getClass() != nullptr);
if (seObj->_getClass()->_getFinalizeFunction() != nullptr) {
seObj->_getClass()->_getFinalizeFunction()(env, finalizeHint, finalizeHint);
}
}
seObj->decRef();
}
}
void Object::setup() {
__objectMap = std::make_unique<std::unordered_map<Object*, void*>>();
}
void Object::cleanup() {
void* nativeObj = nullptr;
Object* obj = nullptr;
Class* cls = nullptr;
const auto& nativePtrToObjectMap = NativePtrToObjectMap::instance();
for (const auto& e : nativePtrToObjectMap) {
nativeObj = e.first;
obj = e.second;
if (obj->_finalizeCb != nullptr) {
obj->_finalizeCb(ScriptEngine::getEnv(), nativeObj, nullptr);
} else {
if (obj->_getClass() != nullptr) {
if (obj->_getClass()->_getFinalizeFunction() != nullptr) {
obj->_getClass()->_getFinalizeFunction()(ScriptEngine::getEnv(), nativeObj, nullptr);
}
}
}
obj->decRef();
}
NativePtrToObjectMap::clear();
if (__objectMap) {
for (const auto& e : *__objectMap) {
obj = e.first;
cls = obj->_getClass();
obj->_rootCount = 0;
}
}
__objectMap.reset();
}
Object* Object::createJSONObject(const std::string& jsonStr) {
//not impl
return nullptr;
}
void Object::clearPrivateData(bool clearMapping) {
if (_privateData != nullptr) {
napi_status status;
void* result = nullptr;
auto tmpThis = _objRef.getValue(_env);
_onCleaingPrivateData = true;
if (clearMapping) {
NativePtrToObjectMap::erase(_privateData);
}
NODE_API_CALL(status, _env, napi_remove_wrap(_env, tmpThis, &result));
_privateData = nullptr;
_onCleaingPrivateData = false;
}
}
Object* Object::createUTF8String(const std::string& str) {
napi_status status;
napi_value result;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_string_utf8(ScriptEngine::getEnv(),str.c_str(),NAPI_AUTO_LENGTH,&result));
Object* obj = _createJSObject(ScriptEngine::getEnv(), result, nullptr);
return obj;
}
} // namespace se

View File

@ -0,0 +1,431 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <cassert>
#include "../RefCounter.hpp"
#include "../Value.hpp"
#include "../config.hpp"
#include "CommonHeader.h"
#include "HelperMacros.h"
namespace se {
class Class;
namespace internal {
struct PrivateData;
}
class ObjectRef {
private:
napi_ref _ref = nullptr;
int _refCounts = 0;
napi_env _env = nullptr;
napi_value _obj = nullptr;
public:
~ObjectRef() {
deleteRef();
}
napi_value getValue(napi_env env) const {
napi_value result;
napi_status status;
NODE_API_CALL(status, env, napi_get_reference_value(env, _ref, &result));
assert(status == napi_ok);
assert(result != nullptr);
return result;
}
void initWeakref(napi_env env, napi_value obj) {
assert(_ref == nullptr);
_obj = obj;
_env = env;
napi_create_reference(env, obj, 0, &_ref);
}
void setWeakref(napi_env env, napi_ref ref) {
assert(_ref == nullptr);
_ref = ref;
}
void initStrongRef(napi_env env, napi_value obj) {
assert(_ref == nullptr);
_refCounts = 1;
_obj = obj;
napi_create_reference(env, obj, _refCounts, &_ref);
_env = env;
}
void incRef(napi_env env) {
assert(_refCounts == 0);
if (_refCounts == 0) {
uint32_t result = 0;
_refCounts = 1;
napi_reference_ref(env, _ref, &result);
}
}
void decRef(napi_env env) {
assert(_refCounts == 1);
uint32_t result = 0;
if (_refCounts > 0) {
_refCounts--;
if (_refCounts == 0) {
napi_reference_unref(env, _ref, &result);
}
}
}
void deleteRef() {
_refCounts = 0;
if (!_ref) {
return;
}
napi_delete_reference(_env, _ref);
_ref = nullptr;
}
};
class Object;
class Object : public RefCounter {
public:
enum class TypedArrayType {
NONE,
INT8,
INT16,
INT32,
UINT8,
UINT8_CLAMPED,
UINT16,
UINT32,
FLOAT32,
FLOAT64
};
using BufferContentsFreeFunc = void (*)(void *contents, size_t byteLength, void *userData);
struct ExternalArrayBufferCallbackParams {
BufferContentsFreeFunc func{nullptr};
void *contents{nullptr};
size_t byteLength{0};
void *userData{0};
};
Object();
~Object();
/**
* @brief Sets a property to an object.
* @param[in] name A utf-8 string containing the property's name.
* @param[in] value A value to be used as the property's value.
* @return true if the property is set successfully, otherwise false.
*/
bool setProperty(const char *name, const Value &data);
inline bool setProperty(const std::string &name, const Value &value) {
return setProperty(name.c_str(), value);
}
/**
* @brief Gets a property from an object.
* @param[in] name A utf-8 string containing the property's name.
* @param[out] value The property's value if object has the property, otherwise the undefined value.
* @return true if object has the property, otherwise false.
*/
bool getProperty(const char *name, Value *data);
inline bool getProperty(const char *name, Value *data, bool cachePropertyName) {
return getProperty(name, data);
}
inline bool getProperty(const std::string &name, Value *value) {
return getProperty(name.c_str(), value);
}
/**
* @brief Delete a property of an object.
* @param[in] name A utf-8 string containing the property's name.
* @return true if the property is deleted successfully, otherwise false.
*/
bool deleteProperty(const char *name);
/**
* @brief Gets an object's private data.
* @return A void* that is the object's private data, if the object has private data, otherwise nullptr.
*/
void* getPrivateData() const;
/**
* @brief Sets a pointer to private data on an object.
* @param[in] data A void* to set as the object's private data.
* @note This method will associate private data with se::Object by std::unordered_map::emplace.
* It's used for search a se::Object via a void* private data.
*/
void setPrivateData(void* data);
/**
* @brief Clears private data of an object.
* @param clearMapping Whether to clear the mapping of native object & se::Object.
*/
void clearPrivateData(bool clearMapping = true);
/**
* @brief Sets whether to clear the mapping of native object & se::Object in finalizer
*/
void setClearMappingInFinalizer(bool v) { _clearMappingInFinalizer = v; }
/**
* @brief Tests whether an object is an array.
* @return true if object is an array, otherwise false.
*/
bool isArray() const;
/**
* @brief Gets array length of an array object.
* @param[out] length The array length to be stored. It's set to 0 if there is an error.
* @return true if succeed, otherwise false.
*/
bool getArrayLength(uint32_t *length) const;
/**
* @brief Gets an element from an array object by numeric index.
* @param[in] index An integer value for index.
* @param[out] data The se::Value to be stored for the element in certain index.
* @return true if succeed, otherwise false.
*/
bool getArrayElement(uint32_t index, Value *data) const;
/**
* @brief Sets an element to an array object by numeric index.
* @param[in] index An integer value for index.
* @param[in] data The se::Value to be set to array with certain index.
* @return true if succeed, otherwise false.
*/
bool setArrayElement(uint32_t index, const Value &data);
/** @brief Tests whether an object is a typed array.
* @return true if object is a typed array, otherwise false.
*/
bool isTypedArray() const;
/** @brief Tests whether an object is a proxy object.
* @return true if object is a proxy object, otherwise false.
*/
bool isProxy() const;
/**
* @brief Gets the type of a typed array object.
* @return The type of a typed array object.
*/
TypedArrayType getTypedArrayType() const;
/**
* @brief Gets backing store of a typed array object.
* @param[out] ptr A temporary pointer to the backing store of a JavaScript Typed Array object.
* @param[out] length The byte length of a JavaScript Typed Array object.
* @return true if succeed, otherwise false.
*/
bool getTypedArrayData(uint8_t **ptr, size_t *length) const;
/**
* @brief Tests whether an object is an array buffer object.
* @return true if object is an array buffer object, otherwise false.
*/
bool isArrayBuffer() const;
/**
* @brief Gets buffer data of an array buffer object.
* @param[out] ptr A pointer to the data buffer that serves as the backing store for a JavaScript Typed Array object.
* @param[out] length The number of bytes in a JavaScript data object.
* @return true if succeed, otherwise false.
*/
bool getArrayBufferData(uint8_t **ptr, size_t *length) const;
/**
* @brief Creates a JavaScript Typed Array Object with specified format from an existing pointer,
if provide a null pointer,then will create a empty JavaScript Typed Array Object.
* @param[in] type The format of typed array.
* @param[in] data A pointer to the byte buffer to be used as the backing store of the Typed Array object.
* @param[in] byteLength The number of bytes pointed to by the parameter bytes.
* @return A JavaScript Typed Array Object whose backing store is the same as the one pointed data, or nullptr if there is an error.
* @note The return value (non-null) has to be released manually.
*/
static Object *createTypedArray(TypedArrayType type, const void *data, size_t byteLength);
static Object *createTypedArrayWithBuffer(TypedArrayType type, const Object *obj);
static Object *createTypedArrayWithBuffer(TypedArrayType type, const Object *obj, size_t offset);
static Object *createTypedArrayWithBuffer(TypedArrayType type, const Object *obj, size_t offset, size_t byteLength);
static Object *createExternalArrayBufferObject(void *contents, size_t byteLength, BufferContentsFreeFunc freeFunc, void *freeUserData = nullptr);
/**
* @brief Tests whether an object can be called as a function.
* @return true if object can be called as a function, otherwise false.
*/
bool isFunction() const;
/**
* @brief Defines a function with a native callback for an object.
* @param[in] funcName A utf-8 string containing the function name.
* @param[in] func The native callback triggered by JavaScript code.
* @return true if succeed, otherwise false.
*/
bool defineFunction(const char *funcName, napi_callback func);
/**
* @brief Defines a property with native accessor callbacks for an object.
* @param[in] name A utf-8 string containing the property's name.
* @param[in] getter The native callback for getter.
* @param[in] setter The native callback for setter.
* @return true if succeed, otherwise false.
*/
bool defineProperty(const char *name, napi_callback getter, napi_callback setter);
bool attachObject(Object *obj);
/**
* @brief Detaches an object from current object.
* @param[in] obj The object to be detached.
* @return true if succeed, otherwise false.
* @note The attached object will not be released if current object is not garbage collected.
*/
bool detachObject(Object *obj);
/**
* @brief Calls an object as a function.
* @param[in] args A se::Value array of arguments to pass to the function. Pass se::EmptyValueArray if argumentCount is 0.
* @param[in] thisObject The object to use as "this," or NULL to use the global object as "this."
* @param[out] rval The se::Value that results from calling object as a function, passing nullptr if return value is ignored.
* @return true if object is a function and there isn't any errors, otherwise false.
*/
bool call(const ValueArray &args, Object *thisObject, Value *rval = nullptr);
/**
* @brief Creates a JavaScript Native Binding Object from an existing se::Class instance.
* @param[in] cls The se::Class instance which stores native callback informations.
* @return A JavaScript Native Binding Object, or nullptr if there is an error.
* @note The return value (non-null) has to be released manually.
*/
static Object *createObjectWithClass(Class *cls);
static Object *_createJSObject(napi_env env, napi_value js_object, Class *cls);
/**
* @brief Creates a JavaScript Object like `{} or new Object()`.
* @return A JavaScript Object, or nullptr if there is an error.
* @note The return value (non-null) has to be released manually.
*/
static Object *createPlainObject();
/**
* @brief Creates a JavaScript Array Object like `[] or new Array()`.
* @param[in] length The initical length of array.
* @return A JavaScript Array Object, or nullptr if there is an error.
* @note The return value (non-null) has to be released manually.
*/
static Object *createArrayObject(size_t length);
/**
* @brief Creates a JavaScript Array Buffer object from an existing pointer.
* @param[in] bytes A pointer to the byte buffer to be used as the backing store of the Typed Array object.
* @param[in] byteLength The number of bytes pointed to by the parameter bytes.
* @return A Array Buffer Object whose backing store is the same as the one pointed to data, or nullptr if there is an error.
* @note The return value (non-null) has to be released manually.
*/
static Object *createArrayBufferObject(const void *data, size_t byteLength);
/**
* Gets the Proxy Target object
* @param proxy The JavaScript Proxy object.
* @return The target JavaScript object of the parameter.
*/
static Object *createProxyTarget(se::Object *proxy);
/**
* @brief Roots an object from garbage collection.
* @note Use this method when you want to store an object in a global or on the heap, where the garbage collector will not be able to discover your reference to it.
* An object may be rooted multiple times and must be unrooted an equal number of times before becoming eligible for garbage collection.
*/
void root();
/**
* @brief Unroots an object from garbage collection.
* @note An object may be rooted multiple times and must be unrooted an equal number of times before becoming eligible for garbage collection.
*/
void unroot();
/**
* @brief Tests whether an object is rooted.
* @return true if it has been already rooted, otherwise false.
*/
bool isRooted() const;
/**
* @brief Creates a JavaScript Object from a JSON formatted string.
* @param[in] jsonStr The utf-8 string containing the JSON string to be parsed.
* @return A JavaScript Object containing the parsed value, or nullptr if the input is invalid.
* @note The return value (non-null) has to be released manually.
*/
static Object *createJSONObject(const std::string &jsonStr);
/**
* @brief Gets all property names of an object.
* @param[out] allKeys A string vector to store all property names.
* @return true if succeed, otherwise false.
*/
bool getAllKeys(std::vector<std::string> *allKeys) const;
/**
* @brief Gets a se::Object from an existing native object pointer.
* @param[in] ptr The native object pointer associated with the se::Object
* @return A JavaScript Native Binding Object, or nullptr if there is an error.
* @note The return value (non-null) has to be released manually.
*/
static Object *getObjectWithPtr(void *ptr);
Class * _getClass() const; // NOLINT(readability-identifier-naming)
napi_value _getJSObject() const;
void _setFinalizeCallback(napi_finalize finalizeCb); // NOLINT(readability-identifier-naming)
/**
* @brief Returns the string for describing current object.
* @return The string for describing current object.
*/
std::string toString() const;
bool init(napi_env env, napi_value js_object, Class *cls);
static Object *createUTF8String(const std::string& str);
private:
// Object();
// virtual ~Object();
static void weakCallback(napi_env env, void *nativeObject, void * /*finalize_hint*/);
static void setup();
static void cleanup();
private:
ObjectRef _objRef;
napi_finalize _finalizeCb = nullptr;
bool _clearMappingInFinalizer = true;
void* _privateData = nullptr;
napi_env _env = nullptr;
Class * _cls = nullptr;
uint32_t _rootCount = 0;
bool _onCleaingPrivateData = false;
internal::PrivateData* _internalData;
friend class ScriptEngine;
};
}; // namespace se

View File

@ -0,0 +1,315 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "ScriptEngine.h"
#include <sstream>
#include "../MappingUtils.hpp"
#include "Class.h"
#include "Utils.h"
#include "CommonHeader.h"
#include <napi/native_api.h>
namespace se {
AutoHandleScope::AutoHandleScope() {
napi_open_handle_scope(ScriptEngine::getEnv(), &_handleScope);
}
AutoHandleScope::~AutoHandleScope() {
napi_close_handle_scope(ScriptEngine::getEnv(), _handleScope);
}
ScriptEngine *gSriptEngineInstance = nullptr;
ScriptEngine::ScriptEngine() {};
ScriptEngine::~ScriptEngine() = default;
void ScriptEngine::setFileOperationDelegate(const FileOperationDelegate &delegate) {
_fileOperationDelegate = delegate;
}
const ScriptEngine::FileOperationDelegate &ScriptEngine::getFileOperationDelegate() const {
return _fileOperationDelegate;
}
ScriptEngine *ScriptEngine::getInstance() {
if (gSriptEngineInstance == nullptr) {
gSriptEngineInstance = new ScriptEngine();
}
return gSriptEngineInstance;
}
void ScriptEngine::destroyInstance() {
if (gSriptEngineInstance) {
gSriptEngineInstance->cleanup();
delete gSriptEngineInstance;
gSriptEngineInstance = nullptr;
}
}
bool ScriptEngine::runScript(const std::string &path, Value *ret /* = nullptr */) {
assert(!path.empty());
napi_status status;
napi_value result = nullptr;
LOGD("napi runScript path=%{public}s.",path.c_str());
//NODE_API_CALL(status, ScriptEngine::getEnv(), napi_run_script_path(ScriptEngine::getEnv(), path.c_str(), &result));
if (ret && result) {
internal::jsToSeValue(result, ret);
}
return false;
}
bool ScriptEngine::evalString(const char *scriptStr, ssize_t length, Value *ret, const char *fileName) {
napi_status status;
napi_value script;
napi_value result;
length = length < 0 ? NAPI_AUTO_LENGTH : length;
status = napi_create_string_utf8(ScriptEngine::getEnv(), scriptStr, length, &script);
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_run_script(ScriptEngine::getEnv(), script, &result));
return true;
}
bool ScriptEngine::init() {
napi_status status;
napi_value result;
for (const auto &hook : _beforeInitHookArray) {
hook();
}
Object::setup();
NativePtrToObjectMap::init();
NonRefNativePtrCreatedByCtorMap::init();
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_global(ScriptEngine::getEnv(), &result));
_globalObj = Object::_createJSObject(ScriptEngine::getEnv(), result, nullptr);
_globalObj->root();
_globalObj->setProperty("window", Value(_globalObj));
_globalObj->setProperty("scriptEngineType", se::Value("napi"));
_isValid = true;
for (const auto &hook : _afterInitHookArray) {
hook();
}
_afterInitHookArray.clear();
return _isValid;
}
Object *ScriptEngine::getGlobalObject() const {
return _globalObj;
}
bool ScriptEngine::start() {
bool ok = true;
if (!init()) {
return false;
}
_startTime = std::chrono::steady_clock::now();
for (auto cb : _permRegisterCallbackArray) {
ok = cb(_globalObj);
assert(ok);
if (!ok) {
break;
}
}
for (auto cb : _registerCallbackArray) {
ok = cb(_globalObj);
assert(ok);
if (!ok) {
break;
}
}
// After ScriptEngine is started, _registerCallbackArray isn't needed. Therefore, clear it here.
_registerCallbackArray.clear();
return ok;
}
void ScriptEngine::cleanup() {
if (!_isValid) {
return;
}
SE_LOGD("ScriptEngine::cleanup begin ...\n");
_isInCleanup = true;
for (const auto &hook : _beforeCleanupHookArray) {
hook();
}
_beforeCleanupHookArray.clear();
SAFE_DEC_REF(_globalObj);
Object::cleanup();
Class::cleanup();
garbageCollect();
_globalObj = nullptr;
_isValid = false;
_registerCallbackArray.clear();
for (const auto &hook : _afterCleanupHookArray) {
hook();
}
_afterCleanupHookArray.clear();
_isInCleanup = false;
NativePtrToObjectMap::destroy();
SE_LOGD("ScriptEngine::cleanup end ...\n");
}
void ScriptEngine::addBeforeCleanupHook(const std::function<void()> &hook) {
_beforeCleanupHookArray.push_back(hook);
return;
}
void ScriptEngine::addBeforeInitHook(const std::function<void()> &hook) {
_beforeInitHookArray.push_back(hook);
}
void ScriptEngine::addAfterCleanupHook(const std::function<void()> &hook) {
_afterCleanupHookArray.push_back(hook);
return;
}
void ScriptEngine::addRegisterCallback(RegisterCallback cb) {
assert(std::find(_registerCallbackArray.begin(), _registerCallbackArray.end(), cb) == _registerCallbackArray.end());
_registerCallbackArray.push_back(cb);
}
napi_env ScriptEngine::getEnv() {
return getInstance()->_env;
}
void ScriptEngine::setEnv(napi_env env) {
getInstance()->_env = env;
}
// void ScriptEngine::addPermanentRegisterCallback(RegisterCallback cb) {
// if (std::find(_permRegisterCallbackArray.begin(), _permRegisterCallbackArray.end(), cb) == _permRegisterCallbackArray.end()) {
// _permRegisterCallbackArray.push_back(cb);
// }
// }
void ScriptEngine::setExceptionCallback(const ExceptionCallback &cb) {
//not impl
return;
}
const std::chrono::steady_clock::time_point &ScriptEngine::getStartTime() const {
return _startTime;
}
bool ScriptEngine::isValid() const {
return _isValid;
}
void ScriptEngine::enableDebugger(const std::string &serverAddr, uint32_t port, bool isWait) {
//not impl
return;
}
bool ScriptEngine::saveByteCodeToFile(const std::string &path, const std::string &pathBc) {
//not impl
return true;
}
void ScriptEngine::clearException() {
//not impl
return;
}
void ScriptEngine::garbageCollect() {
//not impl
return;
}
bool ScriptEngine::isGarbageCollecting() const {
return _isGarbageCollecting;
}
void ScriptEngine::_setGarbageCollecting(bool isGarbageCollecting) { //NOLINT(readability-identifier-naming)
_isGarbageCollecting = isGarbageCollecting;
}
void ScriptEngine::setJSExceptionCallback(const ExceptionCallback &cb) {
//not impl
return;
}
void ScriptEngine::addAfterInitHook(const std::function<void()> &hook) {
_afterInitHookArray.push_back(hook);
return;
}
std::string ScriptEngine::getCurrentStackTrace() {
//not impl
return "";
}
void ScriptEngine::_setNeedCallConstructor(bool need) {
_isneedCallConstructor = need;
}
bool ScriptEngine::_needCallConstructor() {
return _isneedCallConstructor;
}
bool ScriptEngine::callFunction(Object *targetObj, const char *funcName, uint32_t argc, Value *args, Value *rval) {
Value objFunc;
if (!targetObj->getProperty(funcName, &objFunc)) {
return false;
}
ValueArray argv;
for (size_t i = 0; i < argc; ++i) {
argv.push_back(args[i]);
}
objFunc.toObject()->call(argv, targetObj, rval);
return true;
}
void ScriptEngine::handlePromiseExceptions() {
//not impl
assert(true);
return;
}
void ScriptEngine::mainLoopUpdate() {
// empty implementation
}
void ScriptEngine::throwException(const std::string &errorMessage) {
napi_status status;
NODE_API_CALL_RETURN_VOID(getEnv(), napi_throw_error(getEnv(), nullptr, errorMessage.c_str()));
}
}; // namespace se

View File

@ -0,0 +1,307 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <functional>
#include <thread>
#include "../Value.hpp"
#include "../config.hpp"
#include "CommonHeader.h"
using HandleScope = napi_handle_scope;
namespace se {
class AutoHandleScope {
public:
// This interface needs to be implemented in NAPI, similar to V8.
// Ref:https://nodejs.org/docs/latest-v17.x/api/n-api.html#object-lifetime-management
AutoHandleScope();
~AutoHandleScope();
private:
HandleScope _handleScope;
};
// using RegisterCallback = bool (*)(Object *);
using ExceptionCallback = std::function<void(const char *, const char *, const char *)>; // location, message, stack
class ScriptEngine {
public:
/**
* Delegate class for file operation
*/
class FileOperationDelegate {
public:
FileOperationDelegate()
: onGetDataFromFile(nullptr),
onGetStringFromFile(nullptr),
onCheckFileExist(nullptr),
onGetFullPath(nullptr) {}
/**
* @brief Tests whether delegate is valid.
*/
bool isValid() const {
return onGetDataFromFile != nullptr && onGetStringFromFile != nullptr && onCheckFileExist != nullptr && onGetFullPath != nullptr;
}
// path, buffer, buffer size
std::function<void(const std::string &, const std::function<void(const uint8_t *, size_t)> &)> onGetDataFromFile;
// path, return file string content.
std::function<std::string(const std::string &)> onGetStringFromFile;
// path
std::function<bool(const std::string &)> onCheckFileExist;
// path, return full path
std::function<std::string(const std::string &)> onGetFullPath;
};
ScriptEngine();
~ScriptEngine();
/**
* @brief Sets the delegate for file operation.
* @param delegate[in] The delegate instance for file operation.
*/
void setFileOperationDelegate(const FileOperationDelegate &delegate);
/**
* @brief Compile script file into v8::ScriptCompiler::CachedData and save to file.
* @param[in] path The path of script file.
* @param[in] pathBc The location where bytecode file should be written to. The path should be ends with ".bc", which indicates a bytecode file.
* @return true if succeed, otherwise false.
*/
bool saveByteCodeToFile(const std::string &path, const std::string &pathBc);
/**
* @brief Gets the delegate for file operation.
* @return The delegate for file operation
*/
const FileOperationDelegate &getFileOperationDelegate() const;
static ScriptEngine *getInstance();
/**
* @brief Destroys the instance of script engine.
*/
static void destroyInstance();
/**
* @brief Clears all exceptions.
*/
void clearException();
/**
* @brief Sets the callback function while an exception is fired in JS.
* @param[in] cb The callback function to notify that an exception is fired.
*/
void setJSExceptionCallback(const ExceptionCallback &cb);
/**
* @brief Sets the callback function while an exception is fired.
* @param[in] cb The callback function to notify that an exception is fired.
*/
void setExceptionCallback(const ExceptionCallback &cb);
/**
* @brief Grab a snapshot of the current JavaScript execution stack.
* @return current stack trace string
*/
std::string getCurrentStackTrace();
/**
* @brief Executes a utf-8 string buffer which contains JavaScript code.
* @param[in] script A utf-8 string buffer, if it isn't null-terminated, parameter `length` should be assigned and > 0.
* @param[in] length The length of parameter `scriptStr`, it will be set to string length internally if passing < 0 and parameter `scriptStr` is null-terminated.
* @param[in] ret The se::Value that results from evaluating script. Passing nullptr if you don't care about the result.
* @param[in] fileName A string containing a URL for the script's source file. This is used by debuggers and when reporting exceptions. Pass NULL if you do not care to include source file information.
* @return true if succeed, otherwise false.
*/
bool evalString(const char *script, ssize_t length = -1, Value *ret = nullptr, const char *fileName = nullptr);
/**
* @brief Adds a callback for registering a native binding module, which will not be removed by ScriptEngine::cleanup.
* @param[in] cb A callback for registering a native binding module.
* @note This method just add a callback to a vector, callbacks is invoked in `start` method.
*/
// void addPermanentRegisterCallback(RegisterCallback cb);
/**
* @brief Starts the script engine.
* @return true if succeed, otherwise false.
* @note This method will invoke all callbacks of native binding modules by the order of registration.
*/
bool start();
/**
* @brief Initializes script engine.
* @return true if succeed, otherwise false.
* @note This method will create JavaScript context and global object.
*/
bool init();
/**
* @brief Adds a hook function before initializing script engine.
* @param[in] hook A hook function to be invoked before initializing script engine.
* @note Multiple hook functions could be added, they will be invoked by the order of adding.
*/
void addBeforeInitHook(const std::function<void()> &hook);
/**
* @brief Adds a hook function after initializing script engine.
* @param[in] hook A hook function to be invoked before initializing script engine.
* @note Multiple hook functions could be added, they will be invoked by the order of adding.
*/
void addAfterInitHook(const std::function<void()> &hook);
/**
* @brief Cleanups script engine.
* @note This method will removes all objects in JavaScript VM even whose are rooted, then shutdown JavaScript VMf.
*/
void cleanup();
/**
* @brief Adds a hook function before cleanuping script engine.
* @param[in] hook A hook function to be invoked before cleanuping script engine.
* @note Multiple hook functions could be added, they will be invoked by the order of adding.
*/
void addBeforeCleanupHook(const std::function<void()> &hook);
/**
* @brief Adds a hook function after cleanuping script engine.
* @param[in] hook A hook function to be invoked after cleanuping script engine.
* @note Multiple hook functions could be added, they will be invoked by the order of adding.
*/
void addAfterCleanupHook(const std::function<void()> &hook);
/**
* @brief Gets the global object of JavaScript VM.
* @return The se::Object stores the global JavaScript object.
*/
Object *getGlobalObject() const;
typedef bool (*RegisterCallback)(Object*);
static napi_env getEnv();
static void setEnv(napi_env env);
/**
* @brief Adds a callback for registering a native binding module.
* @param[in] cb A callback for registering a native binding module.
* @note This method just add a callback to a vector, callbacks is invoked in `start` method.
*/
void addRegisterCallback(RegisterCallback cb);
const std::chrono::steady_clock::time_point &getStartTime() const;
/**
* @brief Tests whether script engine is doing garbage collection.
* @return true if it's in garbage collection, otherwise false.
*/
bool isGarbageCollecting() const;
/**
* @brief Performs a JavaScript garbage collection.
*/
void garbageCollect();
/**
* @brief Tests whether script engine is being cleaned up.
* @return true if it's in cleaning up, otherwise false.
*/
bool isInCleanup() const { return _isInCleanup; }
/**
* @brief Executes a file which contains JavaScript code.
* @param[in] path Script file path.
* @param[in] ret The se::Value that results from evaluating script. Passing nullptr if you don't care about the result.
* @return true if succeed, otherwise false.
*/
bool runScript(const std::string &path, Value *ret = nullptr);
/**
* @brief Tests whether script engine is valid.
* @return true if it's valid, otherwise false.
*/
bool isValid() const;
/**
* @brief Enables JavaScript debugger
* @param[in] serverAddr The address of debugger server.
* @param[in] isWait Whether wait debugger attach when loading.
*/
void enableDebugger(const std::string &serverAddr, uint32_t port, bool isWait = false);
/**
* @brief Tests whether JavaScript debugger is enabled
* @return true if JavaScript debugger is enabled, otherwise false.
*/
bool isDebuggerEnabled() const;
/**
* @brief Main loop update trigger, it's need to invoked in main thread every frame.
*/
void mainLoopUpdate();
bool runByteCodeFile(const std::string &pathBc, Value *ret /* = nullptr */);
/**
* @brief Throw JS exception
*/
void throwException(const std::string &errorMessage);
/**
* @brief for napi_new_instance, skip constructor.
*/
void _setNeedCallConstructor(bool need);
/**
* @brief for napi_new_instance, skip constructor.
*/
bool _needCallConstructor();
/**
* @brief Fast version of call script function, faster than Object::call
*/
bool callFunction(Object *targetObj, const char *funcName, uint32_t argc, Value *args, Value *rval = nullptr);
void _setGarbageCollecting(bool isGarbageCollecting); // NOLINT(readability-identifier-naming)
void handlePromiseExceptions();
private:
FileOperationDelegate _fileOperationDelegate;
std::vector<RegisterCallback> _registerCallbackArray;
std::vector<RegisterCallback> _permRegisterCallbackArray;
std::vector<std::function<void()>> _beforeInitHookArray;
std::vector<std::function<void()>> _afterInitHookArray;
std::vector<std::function<void()>> _beforeCleanupHookArray;
std::vector<std::function<void()>> _afterCleanupHookArray;
Object * _globalObj = nullptr;
napi_env _env = nullptr;
bool _isValid{false};
bool _isGarbageCollecting{false};
bool _isInCleanup{false};
bool _isErrorHandleWorking{false};
bool _isneedCallConstructor{true};
std::chrono::steady_clock::time_point _startTime;
};
}; // namespace se

View File

@ -0,0 +1,32 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "Class.h"
#include "HelperMacros.h"
#include "Object.h"
#include "ScriptEngine.h"
#include "Utils.h"

View File

@ -0,0 +1,195 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
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 "Utils.h"
#include "CommonHeader.h"
#include "ScriptEngine.h"
#include "Class.h"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#define MAX_STRING_LENS 1024
namespace se {
namespace internal {
void jsToSeValue(const target_value& value, Value* v) {
assert(v != nullptr);
napi_status status;
napi_valuetype valType;
int64_t iRet = 0;
double dRet = 0.0;
bool bRet = false;
bool lossless = false;
size_t len = 0;
void* privateObjPtr = nullptr;
void* nativePtr = nullptr;
void* privateData = nullptr;
Object* obj = nullptr;
if (!value) {
valType = napi_valuetype::napi_undefined;
}else {
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_typeof(ScriptEngine::getEnv(), value, &valType));
}
switch (valType) {
case napi_valuetype::napi_undefined:
v->setUndefined();
break;
case napi_valuetype::napi_null:
v->setNull();
break;
case napi_valuetype::napi_number:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_value_double(ScriptEngine::getEnv(), value, &dRet));
if (status == napi_ok) {
v->setDouble(dRet);
} else {
v->setUndefined();
}
break;
case napi_valuetype::napi_bigint:
//NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_value_bigint_int64(ScriptEngine::getEnv(), value, &iRet, &lossless));
if (lossless) {
v->setInt64(iRet);
} else {
v->setUndefined();
}
break;
case napi_valuetype::napi_string:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_value_string_utf8(ScriptEngine::getEnv(), value, nullptr, 0, &len));
if (status == napi_ok) {
std::string valueStr;
len += 1;
valueStr.resize(len);
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_value_string_utf8(ScriptEngine::getEnv(), value, const_cast<char*>(valueStr.data()), valueStr.size(), &len));
if (valueStr.length() != len) {
valueStr.resize(len);
}
v->setString(valueStr);
} else {
v->setUndefined();
}
break;
case napi_valuetype::napi_boolean:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_value_bool(ScriptEngine::getEnv(), value, &bRet));
if (status == napi_ok) {
v->setBoolean(bRet);
} else {
v->setUndefined();
}
break;
case napi_valuetype::napi_object:
case napi_valuetype::napi_function:
status = napi_unwrap(ScriptEngine::getEnv(), value, &privateData);
if (privateData) {
obj = Object::getObjectWithPtr(privateData);
}
if (obj == nullptr) {
obj = Object::_createJSObject(ScriptEngine::getEnv(), value, nullptr);
}
if (obj) {
v->setObject(obj, true);
obj->decRef();
} else {
v->setUndefined();
}
break;
default:
break;
}
}
void jsToSeArgs(size_t argc, target_value* argv, ValueArray* outArr) {
assert(outArr != nullptr);
for (int i = 0; i < argc; i++) {
Value v;
jsToSeValue(argv[i], &v);
outArr->push_back(v);
}
}
bool seToJsValue(const Value& v, target_value* outJsVal) {
assert(outJsVal != nullptr);
bool ret = false;
napi_status status = napi_ok;
switch (v.getType()) {
case Value::Type::Number:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_double(ScriptEngine::getEnv(), v.toDouble(), outJsVal));
ret = (status == napi_ok);
break;
case Value::Type::String: {
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_string_utf8(ScriptEngine::getEnv(), v.toString().c_str(), v.toString().length(), outJsVal));
ret = (status == napi_ok);
} break;
case Value::Type::Boolean:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_boolean(ScriptEngine::getEnv(), v.toBoolean(), outJsVal));
ret = (status == napi_ok);
break;
case Value::Type::Object:
*outJsVal = v.toObject()->_getJSObject();
ret = (outJsVal != nullptr);
break;
case Value::Type::Null:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_null(ScriptEngine::getEnv(), outJsVal));
ret = (status == napi_ok);
break;
case Value::Type::Undefined:
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_get_undefined(ScriptEngine::getEnv(), outJsVal));
ret = (status == napi_ok);
break;
case Value::Type::BigInt:
//NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_bigint_int64(ScriptEngine::getEnv(), v.toInt64(), outJsVal));
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_double(ScriptEngine::getEnv(), v.toDouble(), outJsVal));
ret = (status == napi_ok);
break;
default:
assert(false);
break;
}
//LOGI("type :%d", v.getType());
return ret;
}
void seToJsArgs(napi_env env, const ValueArray& args, std::vector<target_value>* outArr) {
assert(outArr != nullptr);
for (const auto& data : args) {
napi_value jsval;
seToJsValue(data, &jsval);
outArr->push_back(jsval);
}
}
bool setReturnValue(const Value& data, target_value& argv) {
if (data.getType() == Value::Type::BigInt) {
// TODO: fix 'TypeError: Cannot mix BigInt and other types, use explicit conversions' for spine & dragonbones
napi_status status;
NODE_API_CALL(status, ScriptEngine::getEnv(), napi_create_double(ScriptEngine::getEnv(), data.toDouble(), &argv));
return true;
}
return seToJsValue(data, &argv);
}
} // namespace internal
}; // namespace se

View File

@ -0,0 +1,46 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "../config.hpp"
#include "Object.h"
namespace se {
namespace internal {
using target_value = napi_value;
struct PrivateData {
void * data;
Object *seObj;
};
bool setReturnValue(const Value &data, target_value &argv);
void jsToSeValue(const target_value &value, Value *v);
void jsToSeArgs(size_t argc, target_value *argv, ValueArray *outArr);
bool seToJsValue(const Value &v, target_value *jsval);
void seToJsArgs(napi_env env, const ValueArray &args, std::vector<target_value> *outArr);
} // namespace internal
} // namespace se

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