From 4e4e506c7452449fdd4afe070c6b1f54b7dedb75 Mon Sep 17 00:00:00 2001 From: Yuriy Levchenko Date: Fri, 29 Aug 2025 00:23:14 +0300 Subject: [PATCH 001/169] Implement Metal buffer uploads and image locking --- cmake/Depends_Xcode_iOS/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- cmake/Xcode_iOS/CMakeLists.txt | 4 +- cmake/Xcode_iOS_Simulator/CMakeLists.txt | 4 +- cmake/macro_template.cmake | 2 + src/Environment/CMakeLists.txt | 4 + src/Environment/Metal/CMakeLists.txt | 11 + .../MetalRenderImageExtensionInterface.h | 14 + src/Environment/Metal/MetalRenderIncluder.h | 8 + .../MetalRenderSystemExtensionInterface.h | 14 + src/Interface/RenderEnumInterface.h | 1 + .../AstralaxPlugin/AstralaxService.cpp | 4 + src/Systems/MetalRenderSystem/CMakeLists.txt | 33 + .../MetalRenderFragmentShader.h | 32 + .../MetalRenderFragmentShader.mm | 33 + .../MetalRenderSystem/MetalRenderImage.h | 57 ++ .../MetalRenderSystem/MetalRenderImage.mm | 163 +++++ .../MetalRenderImageLocked.h | 38 ++ .../MetalRenderImageLocked.mm | 41 ++ .../MetalRenderIndexBuffer.h | 53 ++ .../MetalRenderIndexBuffer.mm | 118 ++++ .../MetalRenderMaterialStageCache.h | 21 + .../MetalRenderMaterialStageCache.mm | 13 + .../MetalRenderSystem/MetalRenderProgram.h | 37 + .../MetalRenderSystem/MetalRenderProgram.mm | 52 ++ .../MetalRenderProgramVariable.h | 49 ++ .../MetalRenderProgramVariable.mm | 73 ++ .../MetalRenderSystem/MetalRenderSystem.h | 176 +++++ .../MetalRenderSystem/MetalRenderSystem.mm | 638 ++++++++++++++++++ .../MetalRenderTargetTexture.h | 55 ++ .../MetalRenderTargetTexture.mm | 116 ++++ .../MetalRenderSystem/MetalRenderTypes.h | 10 + .../MetalRenderVertexAttribute.h | 49 ++ .../MetalRenderVertexAttribute.mm | 50 ++ .../MetalRenderVertexBuffer.h | 53 ++ .../MetalRenderVertexBuffer.mm | 118 ++++ .../MetalRenderVertexShader.h | 32 + .../MetalRenderVertexShader.mm | 33 + 38 files changed, 2207 insertions(+), 6 deletions(-) create mode 100644 src/Environment/Metal/CMakeLists.txt create mode 100644 src/Environment/Metal/MetalRenderImageExtensionInterface.h create mode 100644 src/Environment/Metal/MetalRenderIncluder.h create mode 100644 src/Environment/Metal/MetalRenderSystemExtensionInterface.h create mode 100644 src/Systems/MetalRenderSystem/CMakeLists.txt create mode 100644 src/Systems/MetalRenderSystem/MetalRenderFragmentShader.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderFragmentShader.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderImage.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderImage.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderImageLocked.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderImageLocked.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderProgram.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderProgram.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderProgramVariable.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderProgramVariable.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderSystem.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderSystem.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderTargetTexture.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderTargetTexture.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderTypes.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm create mode 100644 src/Systems/MetalRenderSystem/MetalRenderVertexShader.h create mode 100644 src/Systems/MetalRenderSystem/MetalRenderVertexShader.mm diff --git a/cmake/Depends_Xcode_iOS/CMakeLists.txt b/cmake/Depends_Xcode_iOS/CMakeLists.txt index d70cab3b07..409ac0cb38 100644 --- a/cmake/Depends_Xcode_iOS/CMakeLists.txt +++ b/cmake/Depends_Xcode_iOS/CMakeLists.txt @@ -12,7 +12,7 @@ INCLUDE(${MENGINE_REPOSITORY}/cmake/macro_template.cmake) INCLUDE(${MENGINE_REPOSITORY}/cmake/xcode_ios_template.cmake) INCLUDE(${MENGINE_REPOSITORY}/cmake/dependencies_template.cmake) -SET_MENGINE_ENVIRONMENT(IOS OPENGL SDL XCODE) +SET_MENGINE_ENVIRONMENT(IOS METAL SDL XCODE) SET_MENGINE_DEPENDENCIES_OUTPUT_DIRECTORY() diff --git a/cmake/Depends_Xcode_iOS_Simulator/CMakeLists.txt b/cmake/Depends_Xcode_iOS_Simulator/CMakeLists.txt index 571b472137..93e8a30cd5 100644 --- a/cmake/Depends_Xcode_iOS_Simulator/CMakeLists.txt +++ b/cmake/Depends_Xcode_iOS_Simulator/CMakeLists.txt @@ -12,7 +12,7 @@ INCLUDE(${MENGINE_REPOSITORY}/cmake/macro_template.cmake) INCLUDE(${MENGINE_REPOSITORY}/cmake/xcode_ios_simulator_template.cmake) INCLUDE(${MENGINE_REPOSITORY}/cmake/dependencies_template.cmake) -SET_MENGINE_ENVIRONMENT(IOS_SIMULATOR OPENGL SDL2 XCODE) +SET_MENGINE_ENVIRONMENT(IOS_SIMULATOR METAL SDL2 XCODE) SET_MENGINE_DEPENDENCIES_OUTPUT_DIRECTORY() diff --git a/cmake/Xcode_iOS/CMakeLists.txt b/cmake/Xcode_iOS/CMakeLists.txt index 85af251af1..ba25c3f84e 100644 --- a/cmake/Xcode_iOS/CMakeLists.txt +++ b/cmake/Xcode_iOS/CMakeLists.txt @@ -18,7 +18,7 @@ INCLUDE(${MENGINE_REPOSITORY}/cmake/mengine_template.cmake) set(CMAKE_COMPILE_WARNING_AS_ERROR ON) -SET_MENGINE_ENVIRONMENT(IOS OPENGL SDL2 XCODE) +SET_MENGINE_ENVIRONMENT(IOS METAL SDL2 XCODE) ADD_MENGINE_FRAMEWORK() @@ -40,7 +40,7 @@ ADD_SYSTEM(MENGINE_SYSTEM_THREAD POSIXThreadSystem "MENGINE_SYSTEM_THREAD") ADD_SYSTEM(MENGINE_SYSTEM_TIME POSIXTimeSystem "MENGINE_SYSTEM_TIME") ADD_SYSTEM(MENGINE_SYSTEM_CRYPTOGRAPHY AppleCryptographySystem "MENGINE_SYSTEM_CRYPTOGRAPHY") ADD_SYSTEM(MENGINE_SYSTEM_HTTP AppleHttpSystem "MENGINE_SYSTEM_HTTP") -ADD_SYSTEM(MENGINE_SYSTEM_RENDER OpenGLRenderSystem "MENGINE_SYSTEM_RENDER") +ADD_SYSTEM(MENGINE_SYSTEM_RENDER MetalRenderSystem "MENGINE_SYSTEM_RENDER") # plugins ADD_PLUGIN(MENGINE_PLUGIN_MENGINE ON OFF "MENGINE_PLUGIN_MENGINE") diff --git a/cmake/Xcode_iOS_Simulator/CMakeLists.txt b/cmake/Xcode_iOS_Simulator/CMakeLists.txt index 5ba141f9eb..eba47c876d 100644 --- a/cmake/Xcode_iOS_Simulator/CMakeLists.txt +++ b/cmake/Xcode_iOS_Simulator/CMakeLists.txt @@ -18,7 +18,7 @@ INCLUDE(${MENGINE_REPOSITORY}/cmake/mengine_template.cmake) set(CMAKE_COMPILE_WARNING_AS_ERROR ON) -SET_MENGINE_ENVIRONMENT(IOS_SIMULATOR OPENGL SDL2 XCODE) +SET_MENGINE_ENVIRONMENT(IOS_SIMULATOR METAL SDL2 XCODE) ADD_MENGINE_FRAMEWORK() @@ -38,7 +38,7 @@ ADD_SYSTEM(MENGINE_SYSTEM_UNICODE NativeUnicodeSystem "MENGINE_SYSTEM_UNICODE") ADD_SYSTEM(MENGINE_SYSTEM_THREAD SDL2ThreadSystem "MENGINE_SYSTEM_THREAD") ADD_SYSTEM(MENGINE_SYSTEM_TIME POSIXTimeSystem "MENGINE_SYSTEM_TIME") ADD_SYSTEM(MENGINE_SYSTEM_CRYPTOGRAPHY AppleCryptographySystem "MENGINE_SYSTEM_CRYPTOGRAPHY") -ADD_SYSTEM(MENGINE_SYSTEM_RENDER OpenGLRenderSystem "MENGINE_SYSTEM_RENDER") +ADD_SYSTEM(MENGINE_SYSTEM_RENDER MetalRenderSystem "MENGINE_SYSTEM_RENDER") # plugins ADD_PLUGIN(MENGINE_PLUGIN_MENGINE ON OFF "MENGINE_PLUGIN_MENGINE") diff --git a/cmake/macro_template.cmake b/cmake/macro_template.cmake index 5e0a888517..84c357789a 100644 --- a/cmake/macro_template.cmake +++ b/cmake/macro_template.cmake @@ -57,6 +57,7 @@ MACRO(SET_MENGINE_ENVIRONMENT MENGINE_TARGET MENGINE_RENDER MENGINE_PLATFORM MEN SET(MENGINE_RENDER_OPENGL OFF CACHE BOOL "MENGINE_RENDER_OPENGL" FORCE) SET(MENGINE_RENDER_DIRECTX9 OFF CACHE BOOL "MENGINE_RENDER_DIRECTX9" FORCE) SET(MENGINE_RENDER_DIRECTX11 OFF CACHE BOOL "MENGINE_RENDER_DIRECTX11" FORCE) + SET(MENGINE_RENDER_METAL OFF CACHE BOOL "MENGINE_RENDER_METAL" FORCE) SET(MENGINE_PLATFORM_SDL2 OFF CACHE BOOL "MENGINE_PLATFORM_SDL2" FORCE) SET(MENGINE_PLATFORM_WIN32 OFF CACHE BOOL "MENGINE_PLATFORM_WIN32" FORCE) @@ -178,6 +179,7 @@ MACRO(SET_MENGINE_ENVIRONMENT MENGINE_TARGET MENGINE_RENDER MENGINE_PLATFORM MEN MESSAGE("MENGINE_RENDER_OPENGL: ${MENGINE_RENDER_OPENGL}") MESSAGE("MENGINE_RENDER_DIRECTX9: ${MENGINE_RENDER_DIRECTX9}") MESSAGE("MENGINE_RENDER_DIRECTX11: ${MENGINE_RENDER_DIRECTX11}") + MESSAGE("MENGINE_RENDER_METAL: ${MENGINE_RENDER_METAL}") MESSAGE("*********************************************") MESSAGE("MENGINE_PLATFORM_SDL2: ${MENGINE_PLATFORM_SDL2}") MESSAGE("MENGINE_PLATFORM_WIN32: ${MENGINE_PLATFORM_WIN32}") diff --git a/src/Environment/CMakeLists.txt b/src/Environment/CMakeLists.txt index 62bd455bfe..7741ac73bc 100644 --- a/src/Environment/CMakeLists.txt +++ b/src/Environment/CMakeLists.txt @@ -16,6 +16,10 @@ if(MENGINE_RENDER_OPENGL) ADD_SUBDIRECTORY(OpenGL) endif() +if(MENGINE_RENDER_METAL) + ADD_SUBDIRECTORY(Metal) +endif() + if(MENGINE_PLATFORM_SDL2) ADD_SUBDIRECTORY(SDL2) endif() diff --git a/src/Environment/Metal/CMakeLists.txt b/src/Environment/Metal/CMakeLists.txt new file mode 100644 index 0000000000..84e48b1a95 --- /dev/null +++ b/src/Environment/Metal/CMakeLists.txt @@ -0,0 +1,11 @@ +MENGINE_PROJECT(Metal) + +ADD_FILTER( + src + MetalRenderIncluder.h + MetalRenderSystemExtensionInterface.h + MetalRenderImageExtensionInterface.h +) + +ADD_MENGINE_INTERFACE(Environment) + diff --git a/src/Environment/Metal/MetalRenderImageExtensionInterface.h b/src/Environment/Metal/MetalRenderImageExtensionInterface.h new file mode 100644 index 0000000000..723d811b14 --- /dev/null +++ b/src/Environment/Metal/MetalRenderImageExtensionInterface.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Interface/UnknownInterface.h" + +namespace Mengine +{ + class MetalRenderImageExtensionInterface + : public UnknownInterface + { + public: + // Empty interface reserved for Metal image extensions. + }; +} + diff --git a/src/Environment/Metal/MetalRenderIncluder.h b/src/Environment/Metal/MetalRenderIncluder.h new file mode 100644 index 0000000000..9eb3c897ed --- /dev/null +++ b/src/Environment/Metal/MetalRenderIncluder.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Config/Config.h" + +// This header is a placeholder for Metal specific includes. +// It is intentionally left minimal to avoid platform specific +// dependencies during cross-platform builds. + diff --git a/src/Environment/Metal/MetalRenderSystemExtensionInterface.h b/src/Environment/Metal/MetalRenderSystemExtensionInterface.h new file mode 100644 index 0000000000..ab21653fa3 --- /dev/null +++ b/src/Environment/Metal/MetalRenderSystemExtensionInterface.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Interface/UnknownInterface.h" + +namespace Mengine +{ + class MetalRenderSystemExtensionInterface + : public UnknownInterface + { + public: + // Empty interface reserved for Metal specific extensions. + }; +} + diff --git a/src/Interface/RenderEnumInterface.h b/src/Interface/RenderEnumInterface.h index 792a8d9722..df7403fdbc 100644 --- a/src/Interface/RenderEnumInterface.h +++ b/src/Interface/RenderEnumInterface.h @@ -15,6 +15,7 @@ namespace Mengine RP_DX11, RP_OPENGL, RP_OPENGLES, + RP_METAL, RP_UNKNOWN }; ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/AstralaxPlugin/AstralaxService.cpp b/src/Plugins/AstralaxPlugin/AstralaxService.cpp index 7dbbf2928d..5ccf1e94ae 100644 --- a/src/Plugins/AstralaxPlugin/AstralaxService.cpp +++ b/src/Plugins/AstralaxPlugin/AstralaxService.cpp @@ -1521,6 +1521,10 @@ namespace Mengine { this->createFragmentShaderGLESSource_( ss, m ); }break; + case RP_METAL: + { + this->createFragmentShaderGLESSource_( ss, m ); + }break; default: { LOGGER_ERROR( "not supported render platform [%u]" diff --git a/src/Systems/MetalRenderSystem/CMakeLists.txt b/src/Systems/MetalRenderSystem/CMakeLists.txt new file mode 100644 index 0000000000..43c67ff217 --- /dev/null +++ b/src/Systems/MetalRenderSystem/CMakeLists.txt @@ -0,0 +1,33 @@ +MENGINE_PROJECT(MetalRenderSystem) + +ADD_FILTER( + src + MetalRenderSystem.h + MetalRenderSystem.mm + MetalRenderTypes.h + MetalRenderVertexBuffer.h + MetalRenderVertexBuffer.mm + MetalRenderIndexBuffer.h + MetalRenderIndexBuffer.mm + MetalRenderVertexAttribute.h + MetalRenderVertexAttribute.mm + MetalRenderFragmentShader.h + MetalRenderFragmentShader.mm + MetalRenderVertexShader.h + MetalRenderVertexShader.mm + MetalRenderProgram.h + MetalRenderProgram.mm + MetalRenderProgramVariable.h + MetalRenderProgramVariable.mm + MetalRenderImage.h + MetalRenderImage.mm + MetalRenderImageLocked.h + MetalRenderImageLocked.mm + MetalRenderTargetTexture.h + MetalRenderTargetTexture.mm + MetalRenderMaterialStageCache.h + MetalRenderMaterialStageCache.mm +) + +ADD_MENGINE_LIBRARY(Systems) + diff --git a/src/Systems/MetalRenderSystem/MetalRenderFragmentShader.h b/src/Systems/MetalRenderSystem/MetalRenderFragmentShader.h new file mode 100644 index 0000000000..84583b2751 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderFragmentShader.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Interface/RenderFragmentShaderInterface.h" +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class MetalRenderFragmentShader + : public RenderFragmentShaderInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderFragmentShader ); + + public: + MetalRenderFragmentShader(); + ~MetalRenderFragmentShader() override; + + public: + bool initialize( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile ); + void finalize(); + + public: + const ConstString & getName() const override; + + protected: + ConstString m_name; + MemoryInterfacePtr m_memory; + }; + + typedef IntrusivePtr MetalRenderFragmentShaderPtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderFragmentShader.mm b/src/Systems/MetalRenderSystem/MetalRenderFragmentShader.mm new file mode 100644 index 0000000000..cbd669eab8 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderFragmentShader.mm @@ -0,0 +1,33 @@ +#include "MetalRenderFragmentShader.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderFragmentShader::MetalRenderFragmentShader() + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderFragmentShader::~MetalRenderFragmentShader() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderFragmentShader::initialize( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile ) + { + MENGINE_UNUSED( _compile ); + + m_name = _name; + m_memory = _memory; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderFragmentShader::finalize() + { + m_memory = nullptr; + } + ////////////////////////////////////////////////////////////////////////// + const ConstString & MetalRenderFragmentShader::getName() const + { + return m_name; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderImage.h b/src/Systems/MetalRenderSystem/MetalRenderImage.h new file mode 100644 index 0000000000..fcda1f8c34 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderImage.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Interface/RenderImageInterface.h" +#include "Kernel/Factorable.h" +#include "MetalRenderTypes.h" + +#include "Kernel/Rect.h" + +namespace Mengine +{ + class MetalRenderImage + : public RenderImageInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderImage ); + + public: + MetalRenderImage( MetalDeviceId _device ); + ~MetalRenderImage() override; + bool initialize( uint32_t _mipmaps, uint32_t _width, uint32_t _height, EPixelFormat _format, bool _upscalePow2 ); + bool initializeFromTexture( id _texture, uint32_t _width, uint32_t _height, EPixelFormat _format ); + void finalize() override; + + public: + void setRenderImageProvider( const RenderImageProviderInterfacePtr & _renderImageProvider ) override; + const RenderImageProviderInterfacePtr & getRenderImageProvider() const override; + + uint32_t getHWMipmaps() const override; + uint32_t getHWWidth() const override; + uint32_t getHWHeight() const override; + EPixelFormat getHWPixelFormat() const override; + float getHWWidthInv() const override; + float getHWHeightInv() const override; + bool getUpscalePow2() const override; + + RenderImageLockedInterfacePtr lock( uint32_t _level, const Rect & _rect, bool _readOnly ) override; + bool unlock( const RenderImageLockedInterfacePtr & _lock, uint32_t _level, bool _successful ) override; + + public: + id getTexture() const; + + protected: + RenderImageProviderInterfacePtr m_renderImageProvider; + MetalDeviceId m_device; + id m_texture; + uint32_t m_mipmaps; + uint32_t m_width; + uint32_t m_height; + float m_hwWidthInv; + float m_hwHeightInv; + EPixelFormat m_format; + bool m_upscalePow2; + }; + + typedef IntrusivePtr MetalRenderImagePtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderImage.mm b/src/Systems/MetalRenderSystem/MetalRenderImage.mm new file mode 100644 index 0000000000..ce237e7c8e --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderImage.mm @@ -0,0 +1,163 @@ +#include "MetalRenderImage.h" +#include "MetalRenderImageLocked.h" + +#include "Kernel/PixelFormatHelper.h" +#include "Kernel/FactorableUnique.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderImage::MetalRenderImage( MetalDeviceId _device ) + : m_renderImageProvider( nullptr ) + , m_device( _device ) + , m_texture( nil ) + , m_mipmaps( 0 ) + , m_width( 0 ) + , m_height( 0 ) + , m_hwWidthInv( 0.f ) + , m_hwHeightInv( 0.f ) + , m_format( PF_UNKNOWN ) + , m_upscalePow2( false ) + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderImage::~MetalRenderImage() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderImage::initialize( uint32_t _mipmaps, uint32_t _width, uint32_t _height, EPixelFormat _format, bool _upscalePow2 ) + { + m_mipmaps = _mipmaps; + m_width = _width; + m_height = _height; + m_format = _format; + m_upscalePow2 = _upscalePow2; + m_hwWidthInv = 1.f / (float)_width; + m_hwHeightInv = 1.f / (float)_height; + + MTLPixelFormat pixelFormat = MTLPixelFormatRGBA8Unorm; + + MTLTextureDescriptor * descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat width:_width height:_height mipmapped:(_mipmaps > 1 ? YES : NO)]; + descriptor.usage = MTLTextureUsageShaderRead; + + m_texture = [m_device newTextureWithDescriptor:descriptor]; + + return m_texture != nil; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderImage::initializeFromTexture( id _texture, uint32_t _width, uint32_t _height, EPixelFormat _format ) + { + m_texture = _texture; + m_mipmaps = 1; + m_width = _width; + m_height = _height; + m_format = _format; + m_upscalePow2 = false; + m_hwWidthInv = 1.f / (float)_width; + m_hwHeightInv = 1.f / (float)_height; + + return m_texture != nil; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderImage::finalize() + { + m_renderImageProvider = nullptr; + m_texture = nil; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderImage::setRenderImageProvider( const RenderImageProviderInterfacePtr & _renderImageProvider ) + { + m_renderImageProvider = _renderImageProvider; + } + ////////////////////////////////////////////////////////////////////////// + const RenderImageProviderInterfacePtr & MetalRenderImage::getRenderImageProvider() const + { + return m_renderImageProvider; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderImage::getHWMipmaps() const + { + return m_mipmaps; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderImage::getHWWidth() const + { + return m_width; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderImage::getHWHeight() const + { + return m_height; + } + ////////////////////////////////////////////////////////////////////////// + EPixelFormat MetalRenderImage::getHWPixelFormat() const + { + return m_format; + } + ////////////////////////////////////////////////////////////////////////// + float MetalRenderImage::getHWWidthInv() const + { + return m_hwWidthInv; + } + ////////////////////////////////////////////////////////////////////////// + float MetalRenderImage::getHWHeightInv() const + { + return m_hwHeightInv; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderImage::getUpscalePow2() const + { + return m_upscalePow2; + } + ////////////////////////////////////////////////////////////////////////// + RenderImageLockedInterfacePtr MetalRenderImage::lock( uint32_t _level, const Rect & _rect, bool _readOnly ) + { + MENGINE_UNUSED( _readOnly ); + + uint32_t rectWidth = _rect.getWidth(); + uint32_t rectHeight = _rect.getHeight(); + + uint32_t miplevelWidth = rectWidth >> _level; + uint32_t miplevelHeight = rectHeight >> _level; + + size_t size = Helper::getTextureMemorySize( miplevelWidth, miplevelHeight, m_format ); + size_t pitch = size / miplevelHeight; + + MetalRenderImageLockedPtr locked = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ASSERTION_MEMORY_PANIC( locked, "invalid create image locked" ); + + locked->initialize( size, pitch, _rect ); + + return locked; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderImage::unlock( const RenderImageLockedInterfacePtr & _lock, uint32_t _level, bool _successful ) + { + if( _successful == false ) + { + return true; + } + + if( m_texture == nil ) + { + return false; + } + + MetalRenderImageLocked * locked = _lock.getT(); + + const Rect & lockedRect = locked->getLockedRect(); + + size_t pitch; + void * buffer = locked->getBuffer( &pitch ); + + MTLRegion region = MTLRegionMake2D( lockedRect.left, lockedRect.top, lockedRect.getWidth(), lockedRect.getHeight() ); + [m_texture replaceRegion:region mipmapLevel:_level withBytes:buffer bytesPerRow:pitch]; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + id MetalRenderImage::getTexture() const + { + return m_texture; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderImageLocked.h b/src/Systems/MetalRenderSystem/MetalRenderImageLocked.h new file mode 100644 index 0000000000..dc5366acc1 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderImageLocked.h @@ -0,0 +1,38 @@ +#pragma once + +#include "Interface/RenderImageLockedInterface.h" +#include "Interface/MemoryInterface.h" + +#include "Kernel/Rect.h" +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class MetalRenderImageLocked + : public RenderImageLockedInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderImageLocked ); + + public: + MetalRenderImageLocked(); + ~MetalRenderImageLocked() override; + + public: + void initialize( size_t _size, size_t _pitch, const Rect & _rect ); + + public: + const Rect & getLockedRect() const; + + protected: + Pointer getBuffer( size_t * const _pitch ) const override; + + protected: + MemoryInterfacePtr m_lockedMemory; + Rect m_lockedRect; + size_t m_lockedPitch; + }; + + typedef IntrusivePtr MetalRenderImageLockedPtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderImageLocked.mm b/src/Systems/MetalRenderSystem/MetalRenderImageLocked.mm new file mode 100644 index 0000000000..15db31017b --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderImageLocked.mm @@ -0,0 +1,41 @@ +#include "MetalRenderImageLocked.h" + +#include "Interface/MemoryServiceInterface.h" + +#include "Kernel/AssertionMemoryPanic.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderImageLocked::MetalRenderImageLocked() + : m_lockedPitch( 0 ) + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderImageLocked::~MetalRenderImageLocked() = default; + ////////////////////////////////////////////////////////////////////////// + void MetalRenderImageLocked::initialize( size_t _size, size_t _pitch, const Rect & _rect ) + { + MemoryBufferInterfacePtr memory = MEMORY_SERVICE()->createMemoryBuffer( MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid create memory" ); + + memory->newBuffer( _size ); + + m_lockedMemory = memory; + m_lockedRect = _rect; + m_lockedPitch = _pitch; + } + ////////////////////////////////////////////////////////////////////////// + const Rect & MetalRenderImageLocked::getLockedRect() const + { + return m_lockedRect; + } + ////////////////////////////////////////////////////////////////////////// + Pointer MetalRenderImageLocked::getBuffer( size_t * const _pitch ) const + { + *_pitch = m_lockedPitch; + return m_lockedMemory->getBuffer(); + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h new file mode 100644 index 0000000000..ca53879645 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h @@ -0,0 +1,53 @@ +#pragma once + +#include "MetalRenderTypes.h" +#include "Interface/RenderIndexBufferInterface.h" +#include "Kernel/Factorable.h" +#include "Interface/MemoryInterface.h" + +namespace Mengine +{ + class MetalRenderIndexBuffer + : public RenderIndexBufferInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderIndexBuffer ); + + public: + MetalRenderIndexBuffer( MetalDeviceId _device ); + ~MetalRenderIndexBuffer() override; + + public: + bool initialize( uint32_t _indexSize, EBufferType _bufferType ) override; + void finalize() override; + + protected: + uint32_t getIndexCount() const override; + uint32_t getIndexSize() const override; + + protected: + bool resize( uint32_t _count ) override; + + protected: + MemoryInterfacePtr lock( uint32_t _offset, uint32_t _count ) override; + bool unlock() override; + + public: + MetalBufferId getBuffer() const; + + protected: + bool draw( const void * _buffer, uint32_t _offset, uint32_t _count ) override; + + protected: + MetalDeviceId m_device; + MetalBufferId m_buffer; + EBufferType m_bufferType; + uint32_t m_indexSize; + uint32_t m_indexCount; + uint32_t m_lockOffset; + MemoryBufferInterfacePtr m_memory; + }; + + typedef IntrusivePtr MetalRenderIndexBufferPtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm new file mode 100644 index 0000000000..7294f2b116 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm @@ -0,0 +1,118 @@ +#include "MetalRenderIndexBuffer.h" + +#include "Interface/MemoryServiceInterface.h" +#include "Kernel/Logger.h" +#include "Kernel/AssertionMemoryPanic.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderIndexBuffer::MetalRenderIndexBuffer( MetalDeviceId _device ) + : m_device( _device ) + , m_buffer( nil ) + , m_bufferType( BT_STATIC ) + , m_indexSize( 0 ) + , m_indexCount( 0 ) + , m_lockOffset( 0 ) + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderIndexBuffer::~MetalRenderIndexBuffer() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderIndexBuffer::initialize( uint32_t _indexSize, EBufferType _bufferType ) + { + m_indexSize = _indexSize; + m_bufferType = _bufferType; + + MemoryBufferInterfacePtr memory = MEMORY_SERVICE()->createMemoryBuffer( MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid create memory" ); + + m_memory = memory; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderIndexBuffer::finalize() + { + m_memory = nullptr; + m_buffer = nil; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderIndexBuffer::getIndexCount() const + { + return m_indexCount; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderIndexBuffer::getIndexSize() const + { + return m_indexSize; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderIndexBuffer::resize( uint32_t _count ) + { + if( m_indexCount >= _count ) + { + return true; + } + + m_indexCount = _count; + + m_buffer = [m_device newBufferWithLength:m_indexCount * m_indexSize options:MTLResourceStorageModeShared]; + + return m_buffer != nil; + } + ////////////////////////////////////////////////////////////////////////// + MemoryInterfacePtr MetalRenderIndexBuffer::lock( uint32_t _offset, uint32_t _count ) + { + if( _offset + _count > m_indexCount ) + { + LOGGER_ASSERTION( "offset %u count %u more max size %u", _offset, _count, m_indexCount ); + + return nullptr; + } + + m_lockOffset = _offset; + + m_memory->newBuffer( _count * m_indexSize ); + + return m_memory; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderIndexBuffer::unlock() + { + if( m_buffer != nil ) + { + memcpy( ((uint8_t *)[m_buffer contents]) + m_lockOffset * m_indexSize, m_memory->getBuffer(), m_memory->getSize() ); + } + + m_memory->clearBuffer(); + + return true; + } + ////////////////////////////////////////////////////////////////////////// + MetalBufferId MetalRenderIndexBuffer::getBuffer() const + { + return m_buffer; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderIndexBuffer::draw( const void * _buffer, uint32_t _offset, uint32_t _count ) + { + if( _offset + _count > m_indexCount ) + { + LOGGER_ASSERTION( "offset %u count %u more max size %u", _offset, _count, m_indexCount ); + + return false; + } + + if( m_buffer == nil ) + { + return false; + } + + memcpy( ((uint8_t *)[m_buffer contents]) + _offset * m_indexSize, _buffer, _count * m_indexSize ); + + return true; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h new file mode 100644 index 0000000000..8ac7076fa3 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Interface/RenderMaterialStageCacheInterface.h" +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class MetalRenderMaterialStageCache + : public RenderMaterialStageCacheInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderMaterialStageCache ); + + public: + MetalRenderMaterialStageCache(); + ~MetalRenderMaterialStageCache() override; + }; + + typedef IntrusivePtr MetalRenderMaterialStageCachePtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm new file mode 100644 index 0000000000..05e446be8d --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm @@ -0,0 +1,13 @@ +#include "MetalRenderMaterialStageCache.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderMaterialStageCache::MetalRenderMaterialStageCache() + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderMaterialStageCache::~MetalRenderMaterialStageCache() = default; + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderProgram.h b/src/Systems/MetalRenderSystem/MetalRenderProgram.h new file mode 100644 index 0000000000..5c347a7cb5 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderProgram.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Interface/RenderProgramInterface.h" +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class MetalRenderProgram + : public RenderProgramInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderProgram ); + + public: + MetalRenderProgram(); + ~MetalRenderProgram() override; + + public: + bool initialize( const ConstString & _name, const RenderVertexShaderInterfacePtr & _vertex, const RenderFragmentShaderInterfacePtr & _fragment, const RenderVertexAttributeInterfacePtr & _attribute, uint32_t _samplerCount ); + void finalize(); + + public: + const ConstString & getName() const override; + const RenderVertexAttributeInterfacePtr & getVertexAttribute() const override; + const RenderVertexShaderInterfacePtr & getVertexShader() const override; + const RenderFragmentShaderInterfacePtr & getFragmentShader() const override; + + protected: + ConstString m_name; + RenderVertexShaderInterfacePtr m_vertexShader; + RenderFragmentShaderInterfacePtr m_fragmentShader; + RenderVertexAttributeInterfacePtr m_vertexAttribute; + }; + + typedef IntrusivePtr MetalRenderProgramPtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderProgram.mm b/src/Systems/MetalRenderSystem/MetalRenderProgram.mm new file mode 100644 index 0000000000..2c1deb087f --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderProgram.mm @@ -0,0 +1,52 @@ +#include "MetalRenderProgram.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderProgram::MetalRenderProgram() + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderProgram::~MetalRenderProgram() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderProgram::initialize( const ConstString & _name, const RenderVertexShaderInterfacePtr & _vertex, const RenderFragmentShaderInterfacePtr & _fragment, const RenderVertexAttributeInterfacePtr & _attribute, uint32_t _samplerCount ) + { + MENGINE_UNUSED( _samplerCount ); + + m_name = _name; + m_vertexShader = _vertex; + m_fragmentShader = _fragment; + m_vertexAttribute = _attribute; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderProgram::finalize() + { + m_vertexShader = nullptr; + m_fragmentShader = nullptr; + m_vertexAttribute = nullptr; + } + ////////////////////////////////////////////////////////////////////////// + const ConstString & MetalRenderProgram::getName() const + { + return m_name; + } + ////////////////////////////////////////////////////////////////////////// + const RenderVertexAttributeInterfacePtr & MetalRenderProgram::getVertexAttribute() const + { + return m_vertexAttribute; + } + ////////////////////////////////////////////////////////////////////////// + const RenderVertexShaderInterfacePtr & MetalRenderProgram::getVertexShader() const + { + return m_vertexShader; + } + ////////////////////////////////////////////////////////////////////////// + const RenderFragmentShaderInterfacePtr & MetalRenderProgram::getFragmentShader() const + { + return m_fragmentShader; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderProgramVariable.h b/src/Systems/MetalRenderSystem/MetalRenderProgramVariable.h new file mode 100644 index 0000000000..e7bf5d793c --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderProgramVariable.h @@ -0,0 +1,49 @@ +#pragma once + +#include "Interface/RenderProgramVariableInterface.h" +#include "Kernel/Factorable.h" +#include "Kernel/Vector.h" + +namespace Mengine +{ + class MetalRenderProgramVariable + : public RenderProgramVariableInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderProgramVariable ); + + public: + MetalRenderProgramVariable(); + ~MetalRenderProgramVariable() override; + + public: + bool initialize( uint32_t _vertexCount, uint32_t _pixelCount ); + void finalize(); + + public: + void setVertexVariables( const Char * _uniform, uint32_t _index, const float * _values, uint32_t _size, uint32_t _count ) override; + void setPixelVariables( const Char * _uniform, uint32_t _index, const float * _values, uint32_t _size, uint32_t _count ) override; + void updatePixelVariables( uint32_t _index, const float * _values, uint32_t _size, uint32_t _count ) override; + + public: + struct ProgramVariableDesc + { + Char uniform[32 + 1] = {'\0'}; + uint32_t offset; + uint32_t size; + uint32_t count; + }; + + protected: + typedef Vector VectorDataFloats; + VectorDataFloats m_dataFloats; + VectorDataFloats m_pixelFloats; + + typedef Vector VectorVariables; + VectorVariables m_vertexVariables; + VectorVariables m_pixelVariables; + }; + + typedef IntrusivePtr MetalRenderProgramVariablePtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderProgramVariable.mm b/src/Systems/MetalRenderSystem/MetalRenderProgramVariable.mm new file mode 100644 index 0000000000..a8cba76474 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderProgramVariable.mm @@ -0,0 +1,73 @@ +#include "MetalRenderProgramVariable.h" + +#include "Config/StdString.h" +#include "Config/StdAlgorithm.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + namespace Detail + { + template + static void makeVariableData( MetalRenderProgramVariable::ProgramVariableDesc & _variable, Vector & _container, const Char * _uniform, const T * _values, uint32_t _size, uint32_t _count ) + { + StdString::strcpy_safe( _variable.uniform, _uniform, 32 ); + + _variable.offset = (uint32_t)_container.size(); + _variable.size = _size; + _variable.count = _count; + + _container.insert( _container.end(), _values, _values + _size * _count ); + } + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderProgramVariable::MetalRenderProgramVariable() + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderProgramVariable::~MetalRenderProgramVariable() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderProgramVariable::initialize( uint32_t _vertexCount, uint32_t _pixelCount ) + { + m_vertexVariables.resize( _vertexCount ); + m_pixelVariables.resize( _pixelCount ); + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderProgramVariable::finalize() + { + m_dataFloats.clear(); + m_pixelFloats.clear(); + + m_vertexVariables.clear(); + m_pixelVariables.clear(); + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderProgramVariable::setVertexVariables( const Char * _uniform, uint32_t _index, const float * _values, uint32_t _size, uint32_t _count ) + { + ProgramVariableDesc v; + Detail::makeVariableData( v, m_dataFloats, _uniform, _values, _size, _count ); + + m_vertexVariables[_index] = v; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderProgramVariable::setPixelVariables( const Char * _uniform, uint32_t _index, const float * _values, uint32_t _size, uint32_t _count ) + { + ProgramVariableDesc v; + Detail::makeVariableData( v, m_pixelFloats, _uniform, _values, _size, _count ); + + m_pixelVariables[_index] = v; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderProgramVariable::updatePixelVariables( uint32_t _index, const float * _values, uint32_t _size, uint32_t _count ) + { + ProgramVariableDesc & v = m_pixelVariables[_index]; + + float * dest = m_pixelFloats.data() + v.offset; + + StdAlgorithm::copy( _values, _values + _size * _count, dest ); + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.h b/src/Systems/MetalRenderSystem/MetalRenderSystem.h new file mode 100644 index 0000000000..6786fc1704 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.h @@ -0,0 +1,176 @@ +#pragma once + +#include "Interface/RenderSystemInterface.h" +#include "Kernel/ServiceBase.h" + +#import +#import + +namespace Mengine +{ + class MetalRenderSystem + : public ServiceBase + { + DECLARE_UNKNOWABLE(); + + public: + MetalRenderSystem(); + ~MetalRenderSystem() override; + + public: + bool _initializeService() override; + void _finalizeService() override; + + public: + ERenderPlatform getRenderPlatformType() const override; + const ConstString & getRenderPlatformName() const override; + + public: + bool createRenderWindow( const RenderWindowDesc * _windowDesc ) override; + void destroyRenderWindow() override; + + public: + void setProjectionMatrix( const mt::mat4f & _projection ) override; + void setViewMatrix( const mt::mat4f & _view ) override; + void setTextureMatrix( uint32_t _stage, const mt::mat4f & _texture ) override; + void setWorldMatrix( const mt::mat4f & _world ) override; + + public: + RenderVertexBufferInterfacePtr createVertexBuffer( uint32_t _vertexSize, EBufferType _bufferType, const DocumentInterfacePtr & _doc ) override; + bool setVertexBuffer( const RenderVertexBufferInterfacePtr & _vertexBuffer ) override; + + RenderIndexBufferInterfacePtr createIndexBuffer( uint32_t _indexSize, EBufferType _bufferType, const DocumentInterfacePtr & _doc ) override; + bool setIndexBuffer( const RenderIndexBufferInterfacePtr & _indexBuffer ) override; + + public: + RenderVertexAttributeInterfacePtr createVertexAttribute( const ConstString & _name, uint32_t _elementSize, const DocumentInterfacePtr & _doc ) override; + RenderFragmentShaderInterfacePtr createFragmentShader( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile, const DocumentInterfacePtr & _doc ) override; + RenderVertexShaderInterfacePtr createVertexShader( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile, const DocumentInterfacePtr & _doc ) override; + + RenderProgramInterfacePtr createProgram( const ConstString & _name, const RenderVertexShaderInterfacePtr & _vertex, const RenderFragmentShaderInterfacePtr & _fragment, const RenderVertexAttributeInterfacePtr & _vertexAttribute, uint32_t _samplerCount, const DocumentInterfacePtr & _doc ) override; + void setProgram( const RenderProgramInterfacePtr & _program ) override; + void updateProgram( const RenderProgramInterfacePtr & _program ) override; + RenderProgramVariableInterfacePtr createProgramVariable( uint32_t _vertexCount, uint32_t _pixelCount, const DocumentInterfacePtr & _doc ) override; + bool setProgramVariable( const RenderProgramInterfacePtr & _program, const RenderProgramVariableInterfacePtr & _variable ) override; + + public: + void drawIndexedPrimitive( const RenderMaterialStageCacheInterfacePtr & _stageCache, const RenderIndexedPrimitiveDesc & _desc ) override; + + public: + void setTexture( const RenderProgramInterfacePtr & _program, uint32_t _stage, const RenderImageInterfacePtr & _texture ) override; + void setTextureAddressing( uint32_t _stage, ETextureAddressMode _modeU, ETextureAddressMode _modeV, uint32_t _border ) override; + void setTextureFactor( uint32_t _color ) override; + void setBlendFactor( EBlendFactor _src, EBlendFactor _dst, EBlendOp _op, EBlendFactor _separateSrc, EBlendFactor _separateDst, EBlendOp _separateOp, bool _separate ) override; + void setCullMode( ECullMode _mode ) override; + void setDepthBufferTestEnable( bool _depthTest ) override; + void setDepthBufferWriteEnable( bool _depthWrite ) override; + void setDepthBufferCmpFunc( ECompareFunction _depthFunction ) override; + void setFillMode( EFillMode _mode ) override; + void setColorBufferWriteEnable( bool _r, bool _g, bool _b, bool _a ) override; + void setAlphaBlendEnable( bool _alphaBlend ) override; + + void setTextureStageFilter( uint32_t _stage, ETextureFilter _minification, ETextureFilter _mipmap, ETextureFilter _magnification ) override; + + public: + RenderImageInterfacePtr createImage( uint32_t _mipmaps, uint32_t _width, uint32_t _height, EPixelFormat _format, const DocumentInterfacePtr & _doc ) override; + + RenderTargetInterfacePtr createRenderTargetTexture( uint32_t _width, uint32_t _height, EPixelFormat _format, const DocumentInterfacePtr & _doc ) override; + RenderTargetInterfacePtr createRenderTargetOffscreen( uint32_t _width, uint32_t _height, EPixelFormat _format, const DocumentInterfacePtr & _doc ) override; + + RenderImageInterfacePtr createRenderImageTarget( const RenderTargetInterfacePtr & _renderTarget, const DocumentInterfacePtr & _doc ) override; + + public: + RenderMaterialStageCacheInterfacePtr createRenderMaterialStageCache( const RenderMaterialStage * _stage, const DocumentInterfacePtr & _doc ) override; + + public: + bool beginScene() override; + void endScene() override; + void swapBuffers() override; + void clearFrameBuffer( uint32_t _frameBufferTypes, const Color & _color, double _depth, int32_t _stencil ) override; + + void setScissor( const Viewport & _viewport ) override; + void removeScissor() override; + + void setViewport( const Viewport & _viewport ) override; + + void changeWindowMode( const Resolution & _resolution, bool _fullscreen ) override; + + void onWindowMovedOrResized() override; + void onWindowClose() override; + + void onDeviceLostPrepare() override; + bool onDeviceLostRestore() override; + + void onWindowChangeFullscreenPrepare( bool _fullscreen ) override; + bool onWindowChangeFullscreen( bool _fullscreen ) override; + + void setVSync( bool _vSync ) override; + + public: + uint32_t getMaxCombinedTextureImageUnits() const override; + + public: + uint32_t getAvailableTextureMemory() const override; + + protected: + ConstString m_renderSystemName; + + static constexpr uint32_t METAL_MAX_TEXTURE_STAGES = 4; + + mt::mat4f m_projectionMatrix; + mt::mat4f m_viewMatrix; + mt::mat4f m_worldMatrix; + mt::mat4f m_textureMatrix[METAL_MAX_TEXTURE_STAGES]; + + Viewport m_scissor; + bool m_scissorEnabled; + Viewport m_viewport; + + RenderVertexBufferInterfacePtr m_currentVertexBuffer; + RenderIndexBufferInterfacePtr m_currentIndexBuffer; + RenderProgramInterfacePtr m_currentProgram; + RenderProgramVariableInterfacePtr m_currentProgramVariable; + + RenderImageInterfacePtr m_textures[METAL_MAX_TEXTURE_STAGES]; + + struct TextureStageState + { + ETextureAddressMode addressU; + ETextureAddressMode addressV; + uint32_t addressBorder; + ETextureFilter minification; + ETextureFilter mipmap; + ETextureFilter magnification; + }; + + TextureStageState m_textureStages[METAL_MAX_TEXTURE_STAGES]; + + uint32_t m_textureFactor; + + EBlendFactor m_blendSrc; + EBlendFactor m_blendDst; + EBlendOp m_blendOp; + EBlendFactor m_blendSrcAlpha; + EBlendFactor m_blendDstAlpha; + EBlendOp m_blendOpAlpha; + bool m_separateBlend; + bool m_alphaBlend; + + ECullMode m_cullMode; + bool m_depthTest; + bool m_depthWrite; + ECompareFunction m_depthFunction; + EFillMode m_fillMode; + bool m_colorWriteR; + bool m_colorWriteG; + bool m_colorWriteB; + bool m_colorWriteA; + bool m_vsync; + + id m_device; + id m_commandQueue; + CAMetalLayer * m_metalLayer; + id m_commandBuffer; + }; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm new file mode 100644 index 0000000000..c41130e1a4 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm @@ -0,0 +1,638 @@ +#include "MetalRenderSystem.h" + +#include "MetalRenderTypes.h" +#include "MetalRenderVertexBuffer.h" +#include "MetalRenderIndexBuffer.h" +#include "MetalRenderVertexAttribute.h" +#include "MetalRenderFragmentShader.h" +#include "MetalRenderVertexShader.h" +#include "MetalRenderProgram.h" +#include "MetalRenderProgramVariable.h" +#include "MetalRenderImage.h" +#include "MetalRenderTargetTexture.h" +#include "MetalRenderMaterialStageCache.h" + +#include "Kernel/ConstStringHelper.h" +#include "Kernel/Logger.h" +#include "Kernel/FactorableUnique.h" +#include "Kernel/AssertionMemoryPanic.h" +#include "Kernel/Vector.h" +#include "Interface/MemoryServiceInterface.h" +#include "math/uv4.h" + +namespace Mengine +{ + SERVICE_FACTORY( MetalRenderSystem, Mengine::MetalRenderSystem ); + ////////////////////////////////////////////////////////////////////////// + MetalRenderSystem::MetalRenderSystem() + { + m_renderSystemName = STRINGIZE_STRING_LOCAL( "Metal" ); + + m_projectionMatrix = mt::mat4f::identity(); + m_viewMatrix = mt::mat4f::identity(); + m_worldMatrix = mt::mat4f::identity(); + + for( uint32_t i = 0; i != METAL_MAX_TEXTURE_STAGES; ++i ) + { + m_textureMatrix[i] = mt::mat4f::identity(); + } + + m_scissorEnabled = false; + m_viewport = Viewport( mt::vec2f::identity(), mt::vec2f::identity() ); + m_scissor = m_viewport; + + m_currentVertexBuffer = nullptr; + m_currentIndexBuffer = nullptr; + m_currentProgram = nullptr; + m_currentProgramVariable = nullptr; + + for( uint32_t i = 0; i != METAL_MAX_TEXTURE_STAGES; ++i ) + { + m_textures[i] = nullptr; + TextureStageState & stage = m_textureStages[i]; + stage.addressU = TAM_CLAMP; + stage.addressV = TAM_CLAMP; + stage.addressBorder = 0; + stage.minification = TF_POINT; + stage.mipmap = TF_NONE; + stage.magnification = TF_POINT; + } + + m_textureFactor = 0; + + m_blendSrc = BF_ONE; + m_blendDst = BF_ZERO; + m_blendOp = BOP_ADD; + m_blendSrcAlpha = BF_ONE; + m_blendDstAlpha = BF_ZERO; + m_blendOpAlpha = BOP_ADD; + m_separateBlend = false; + m_alphaBlend = false; + + m_cullMode = CM_NONE; + m_depthTest = false; + m_depthWrite = false; + m_depthFunction = CF_LESS_EQUAL; + m_fillMode = FM_SOLID; + m_colorWriteR = true; + m_colorWriteG = true; + m_colorWriteB = true; + m_colorWriteA = true; + m_vsync = false; + + m_device = nil; + m_commandQueue = nil; + m_metalLayer = nil; + m_commandBuffer = nil; + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderSystem::~MetalRenderSystem() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::_initializeService() + { + m_device = MTLCreateSystemDefaultDevice(); + + if( m_device == nil ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to create device" ); + + return false; + } + + m_commandQueue = [m_device newCommandQueue]; + + if( m_commandQueue == nil ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to create command queue" ); + + return false; + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::_finalizeService() + { + m_commandBuffer = nil; + m_metalLayer = nil; + m_commandQueue = nil; + m_device = nil; + } + ////////////////////////////////////////////////////////////////////////// + ERenderPlatform MetalRenderSystem::getRenderPlatformType() const + { + return RP_METAL; + } + ////////////////////////////////////////////////////////////////////////// + const ConstString & MetalRenderSystem::getRenderPlatformName() const + { + return m_renderSystemName; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::createRenderWindow( const RenderWindowDesc * _windowDesc ) + { + m_metalLayer = [CAMetalLayer layer]; + [m_metalLayer setDevice:m_device]; + + if( _windowDesc != nullptr ) + { + m_metalLayer.drawableSize = CGSizeMake( _windowDesc->resolution.getWidth(), _windowDesc->resolution.getHeight() ); + m_vsync = _windowDesc->waitForVSync; + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::destroyRenderWindow() + { + m_metalLayer = nil; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setProjectionMatrix( const mt::mat4f & _projection ) + { + m_projectionMatrix = _projection; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setViewMatrix( const mt::mat4f & _view ) + { + m_viewMatrix = _view; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setTextureMatrix( uint32_t _stage, const mt::mat4f & _texture ) + { + if( _stage < METAL_MAX_TEXTURE_STAGES ) + { + m_textureMatrix[_stage] = _texture; + } + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setWorldMatrix( const mt::mat4f & _world ) + { + m_worldMatrix = _world; + } + ////////////////////////////////////////////////////////////////////////// + RenderVertexBufferInterfacePtr MetalRenderSystem::createVertexBuffer( uint32_t _vertexSize, EBufferType _bufferType, const DocumentInterfacePtr & _doc ) + { + MetalRenderVertexBufferPtr buffer = Helper::makeFactorableUnique( _doc, m_device ); + + MENGINE_ASSERTION_MEMORY_PANIC( buffer, "invalid create vertex buffer" ); + + if( buffer->initialize( _vertexSize, _bufferType ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize vertex buffer" ); + + return nullptr; + } + + return buffer; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::setVertexBuffer( const RenderVertexBufferInterfacePtr & _vertexBuffer ) + { + m_currentVertexBuffer = _vertexBuffer; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + RenderIndexBufferInterfacePtr MetalRenderSystem::createIndexBuffer( uint32_t _indexSize, EBufferType _bufferType, const DocumentInterfacePtr & _doc ) + { + MetalRenderIndexBufferPtr buffer = Helper::makeFactorableUnique( _doc, m_device ); + + MENGINE_ASSERTION_MEMORY_PANIC( buffer, "invalid create index buffer" ); + + if( buffer->initialize( _indexSize, _bufferType ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize index buffer" ); + + return nullptr; + } + + return buffer; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::setIndexBuffer( const RenderIndexBufferInterfacePtr & _indexBuffer ) + { + m_currentIndexBuffer = _indexBuffer; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + RenderVertexAttributeInterfacePtr MetalRenderSystem::createVertexAttribute( const ConstString & _name, uint32_t _elementSize, const DocumentInterfacePtr & _doc ) + { + MetalRenderVertexAttributePtr attribute = Helper::makeFactorableUnique( _doc ); + + MENGINE_ASSERTION_MEMORY_PANIC( attribute, "invalid create vertex attribute '%s'", _name.c_str() ); + + if( attribute->initialize( _name, _elementSize ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize vertex attribute '%s'", _name.c_str() ); + + return nullptr; + } + + return attribute; + } + ////////////////////////////////////////////////////////////////////////// + RenderFragmentShaderInterfacePtr MetalRenderSystem::createFragmentShader( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile, const DocumentInterfacePtr & _doc ) + { + MetalRenderFragmentShaderPtr shader = Helper::makeFactorableUnique( _doc ); + + MENGINE_ASSERTION_MEMORY_PANIC( shader, "invalid create fragment shader '%s'", _name.c_str() ); + + if( shader->initialize( _name, _memory, _compile ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize fragment shader '%s'", _name.c_str() ); + + return nullptr; + } + + return shader; + } + ////////////////////////////////////////////////////////////////////////// + RenderVertexShaderInterfacePtr MetalRenderSystem::createVertexShader( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile, const DocumentInterfacePtr & _doc ) + { + MetalRenderVertexShaderPtr shader = Helper::makeFactorableUnique( _doc ); + + MENGINE_ASSERTION_MEMORY_PANIC( shader, "invalid create vertex shader '%s'", _name.c_str() ); + + if( shader->initialize( _name, _memory, _compile ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize vertex shader '%s'", _name.c_str() ); + + return nullptr; + } + + return shader; + } + ////////////////////////////////////////////////////////////////////////// + RenderProgramInterfacePtr MetalRenderSystem::createProgram( const ConstString & _name, const RenderVertexShaderInterfacePtr & _vertex, const RenderFragmentShaderInterfacePtr & _fragment, const RenderVertexAttributeInterfacePtr & _vertexAttribute, uint32_t _samplerCount, const DocumentInterfacePtr & _doc ) + { + MetalRenderProgramPtr program = Helper::makeFactorableUnique( _doc ); + + MENGINE_ASSERTION_MEMORY_PANIC( program, "invalid create program '%s'", _name.c_str() ); + + if( program->initialize( _name, _vertex, _fragment, _vertexAttribute, _samplerCount ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize program '%s'", _name.c_str() ); + + return nullptr; + } + + return program; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setProgram( const RenderProgramInterfacePtr & _program ) + { + m_currentProgram = _program; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::updateProgram( const RenderProgramInterfacePtr & _program ) + { + m_currentProgram = _program; + } + ////////////////////////////////////////////////////////////////////////// + RenderProgramVariableInterfacePtr MetalRenderSystem::createProgramVariable( uint32_t _vertexCount, uint32_t _pixelCount, const DocumentInterfacePtr & _doc ) + { + MetalRenderProgramVariablePtr variable = Helper::makeFactorableUnique( _doc ); + + MENGINE_ASSERTION_MEMORY_PANIC( variable, "invalid create program variable" ); + + if( variable->initialize( _vertexCount, _pixelCount ) == false ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to initialize program variable" ); + + return nullptr; + } + + return variable; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::setProgramVariable( const RenderProgramInterfacePtr & _program, const RenderProgramVariableInterfacePtr & _variable ) + { + if( m_currentProgram != _program ) + { + m_currentProgram = _program; + } + + m_currentProgramVariable = _variable; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::drawIndexedPrimitive( const RenderMaterialStageCacheInterfacePtr & _stageCache, const RenderIndexedPrimitiveDesc & _desc ) + { + MENGINE_UNUSED( _stageCache ); + + if( m_commandBuffer == nil || m_metalLayer == nil ) + { + return; + } + + MetalRenderVertexBuffer * vb = m_currentVertexBuffer.getT(); + MetalRenderIndexBuffer * ib = m_currentIndexBuffer.getT(); + + id drawable = [m_metalLayer nextDrawable]; + + if( drawable == nil ) + { + return; + } + + MTLRenderPassDescriptor * pass = [MTLRenderPassDescriptor renderPassDescriptor]; + pass.colorAttachments[0].texture = drawable.texture; + pass.colorAttachments[0].loadAction = MTLLoadActionLoad; + pass.colorAttachments[0].storeAction = MTLStoreActionStore; + + id encoder = [m_commandBuffer renderCommandEncoderWithDescriptor:pass]; + + if( vb != nullptr ) + { + [encoder setVertexBuffer:vb->getBuffer() offset:0 atIndex:0]; + } + + if( ib != nullptr ) + { + MTLIndexType indexType = (m_currentIndexBuffer->getIndexSize() == 2) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32; + [encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:_desc.indexCount indexType:indexType indexBuffer:ib->getBuffer() indexBufferOffset:_desc.startIndex * m_currentIndexBuffer->getIndexSize()]; + } + + [encoder endEncoding]; + + [m_commandBuffer presentDrawable:drawable]; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setTexture( const RenderProgramInterfacePtr & _program, uint32_t _stage, const RenderImageInterfacePtr & _texture ) + { + if( m_currentProgram != _program ) + { + m_currentProgram = _program; + } + + if( _stage >= METAL_MAX_TEXTURE_STAGES ) + { + return; + } + + m_textures[_stage] = _texture; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setTextureAddressing( uint32_t _stage, ETextureAddressMode _modeU, ETextureAddressMode _modeV, uint32_t _border ) + { + if( _stage >= METAL_MAX_TEXTURE_STAGES ) + { + return; + } + + m_textureStages[_stage].addressU = _modeU; + m_textureStages[_stage].addressV = _modeV; + m_textureStages[_stage].addressBorder = _border; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setTextureFactor( uint32_t _color ) + { + m_textureFactor = _color; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setBlendFactor( EBlendFactor _src, EBlendFactor _dst, EBlendOp _op, EBlendFactor _separateSrc, EBlendFactor _separateDst, EBlendOp _separateOp, bool _separate ) + { + m_blendSrc = _src; + m_blendDst = _dst; + m_blendOp = _op; + m_blendSrcAlpha = _separateSrc; + m_blendDstAlpha = _separateDst; + m_blendOpAlpha = _separateOp; + m_separateBlend = _separate; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setCullMode( ECullMode _mode ) + { + m_cullMode = _mode; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setDepthBufferTestEnable( bool _depthTest ) + { + m_depthTest = _depthTest; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setDepthBufferWriteEnable( bool _depthWrite ) + { + m_depthWrite = _depthWrite; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setDepthBufferCmpFunc( ECompareFunction _depthFunction ) + { + m_depthFunction = _depthFunction; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setFillMode( EFillMode _mode ) + { + m_fillMode = _mode; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setColorBufferWriteEnable( bool _r, bool _g, bool _b, bool _a ) + { + m_colorWriteR = _r; + m_colorWriteG = _g; + m_colorWriteB = _b; + m_colorWriteA = _a; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setAlphaBlendEnable( bool _alphaBlend ) + { + m_alphaBlend = _alphaBlend; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setTextureStageFilter( uint32_t _stage, ETextureFilter _minification, ETextureFilter _mipmap, ETextureFilter _magnification ) + { + if( _stage >= METAL_MAX_TEXTURE_STAGES ) + { + return; + } + + m_textureStages[_stage].minification = _minification; + m_textureStages[_stage].mipmap = _mipmap; + m_textureStages[_stage].magnification = _magnification; + } + ////////////////////////////////////////////////////////////////////////// + RenderImageInterfacePtr MetalRenderSystem::createImage( uint32_t _mipmaps, uint32_t _width, uint32_t _height, EPixelFormat _format, const DocumentInterfacePtr & _doc ) + { + MetalRenderImagePtr image = Helper::makeFactorableUnique( _doc, m_device ); + + MENGINE_ASSERTION_MEMORY_PANIC( image, "invalid create metal image" ); + + if( image->initialize( _mipmaps, _width, _height, _format ) == false ) + { + return nullptr; + } + + return image; + } + ////////////////////////////////////////////////////////////////////////// + RenderTargetInterfacePtr MetalRenderSystem::createRenderTargetTexture( uint32_t _width, uint32_t _height, EPixelFormat _format, const DocumentInterfacePtr & _doc ) + { + MetalRenderTargetTexturePtr target = Helper::makeFactorableUnique( _doc, m_device ); + + MENGINE_ASSERTION_MEMORY_PANIC( target, "invalid create metal render target" ); + + if( target->initialize( _width, _height, _format ) == false ) + { + return nullptr; + } + + return target; + } + ////////////////////////////////////////////////////////////////////////// + RenderTargetInterfacePtr MetalRenderSystem::createRenderTargetOffscreen( uint32_t _width, uint32_t _height, EPixelFormat _format, const DocumentInterfacePtr & _doc ) + { + return this->createRenderTargetTexture( _width, _height, _format, _doc ); + } + ////////////////////////////////////////////////////////////////////////// + RenderImageInterfacePtr MetalRenderSystem::createRenderImageTarget( const RenderTargetInterfacePtr & _renderTarget, const DocumentInterfacePtr & _doc ) + { + MetalRenderTargetTexture * target = _renderTarget.getT(); + + MetalRenderImagePtr image = Helper::makeFactorableUnique( _doc, target->getDevice() ); + + if( image->initializeFromTexture( target->getTexture(), target->getHWWidth(), target->getHWHeight(), target->getHWPixelFormat() ) == false ) + { + return nullptr; + } + + return image; + } + ////////////////////////////////////////////////////////////////////////// + RenderMaterialStageCacheInterfacePtr MetalRenderSystem::createRenderMaterialStageCache( const RenderMaterialStage * _stage, const DocumentInterfacePtr & _doc ) + { + MENGINE_UNUSED( _stage ); + + MetalRenderMaterialStageCachePtr cache = Helper::makeFactorableUnique( _doc ); + MENGINE_ASSERTION_MEMORY_PANIC( cache, "invalid create material stage cache" ); + return cache; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::beginScene() + { + m_commandBuffer = [m_commandQueue commandBuffer]; + + return m_commandBuffer != nil; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::endScene() + { + if( m_commandBuffer != nil ) + { + [m_commandBuffer commit]; + m_commandBuffer = nil; + } + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::swapBuffers() + { + // presentation handled during drawIndexedPrimitive + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::clearFrameBuffer( uint32_t _frameBufferTypes, const Color & _color, double _depth, int32_t _stencil ) + { + MENGINE_UNUSED( _depth ); + MENGINE_UNUSED( _stencil ); + + if( ( _frameBufferTypes & FBT_COLOR ) == 0 ) + { + return; + } + + if( m_commandBuffer == nil || m_metalLayer == nil ) + { + return; + } + + id drawable = [m_metalLayer nextDrawable]; + + if( drawable == nil ) + { + return; + } + + MTLRenderPassDescriptor * pass = [MTLRenderPassDescriptor renderPassDescriptor]; + pass.colorAttachments[0].texture = drawable.texture; + pass.colorAttachments[0].loadAction = MTLLoadActionClear; + pass.colorAttachments[0].storeAction = MTLStoreActionStore; + pass.colorAttachments[0].clearColor = MTLClearColorMake( _color.getR(), _color.getG(), _color.getB(), _color.getA() ); + + id encoder = [m_commandBuffer renderCommandEncoderWithDescriptor:pass]; + [encoder endEncoding]; + + [m_commandBuffer presentDrawable:drawable]; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setScissor( const Viewport & _viewport ) + { + m_scissor = _viewport; + m_scissorEnabled = true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::removeScissor() + { + m_scissorEnabled = false; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setViewport( const Viewport & _viewport ) + { + m_viewport = _viewport; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::changeWindowMode( const Resolution & _resolution, bool _fullscreen ) + { + MENGINE_UNUSED( _resolution ); + MENGINE_UNUSED( _fullscreen ); + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::onWindowMovedOrResized() + { + //Empty + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::onWindowClose() + { + //Empty + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::onDeviceLostPrepare() + { + //Empty + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::onDeviceLostRestore() + { + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::onWindowChangeFullscreenPrepare( bool _fullscreen ) + { + MENGINE_UNUSED( _fullscreen ); + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderSystem::onWindowChangeFullscreen( bool _fullscreen ) + { + MENGINE_UNUSED( _fullscreen ); + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setVSync( bool _vSync ) + { + m_vsync = _vSync; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderSystem::getMaxCombinedTextureImageUnits() const + { + return METAL_MAX_TEXTURE_STAGES; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderSystem::getAvailableTextureMemory() const + { + return 0U; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderTargetTexture.h b/src/Systems/MetalRenderSystem/MetalRenderTargetTexture.h new file mode 100644 index 0000000000..ed2d077464 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderTargetTexture.h @@ -0,0 +1,55 @@ +#pragma once + +#include "Interface/RenderTargetInterface.h" +#include "Kernel/Factorable.h" +#include "math/uv4.h" +#include "MetalRenderTypes.h" + +namespace Mengine +{ + class MetalRenderTargetTexture + : public RenderTargetInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderTargetTexture ); + + public: + MetalRenderTargetTexture( MetalDeviceId _device ); + ~MetalRenderTargetTexture() override; + bool initialize( uint32_t _width, uint32_t _height, EPixelFormat _format ); + void finalize(); + + public: + uint32_t getHWMipmaps() const override; + uint32_t getHWWidth() const override; + uint32_t getHWHeight() const override; + EPixelFormat getHWPixelFormat() const override; + float getHWWidthInv() const override; + float getHWHeightInv() const override; + bool getUpscalePow2() const override; + + bool begin() const override; + void end() const override; + + const mt::uv4f & getUV() const override; + + bool getData( void * const _buffer, size_t _pitch ) const override; + + public: + id getTexture() const; + MetalDeviceId getDevice() const; + + protected: + MetalDeviceId m_device; + id m_texture; + uint32_t m_width; + uint32_t m_height; + float m_hwWidthInv; + float m_hwHeightInv; + EPixelFormat m_format; + mt::uv4f m_uv; + }; + + typedef IntrusivePtr MetalRenderTargetTexturePtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderTargetTexture.mm b/src/Systems/MetalRenderSystem/MetalRenderTargetTexture.mm new file mode 100644 index 0000000000..c538acb87d --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderTargetTexture.mm @@ -0,0 +1,116 @@ +#include "MetalRenderTargetTexture.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderTargetTexture::MetalRenderTargetTexture( MetalDeviceId _device ) + : m_device( _device ) + , m_texture( nil ) + , m_width( 0 ) + , m_height( 0 ) + , m_hwWidthInv( 0.f ) + , m_hwHeightInv( 0.f ) + , m_format( PF_UNKNOWN ) + , m_uv( mt::uv4f::identity() ) + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderTargetTexture::~MetalRenderTargetTexture() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderTargetTexture::initialize( uint32_t _width, uint32_t _height, EPixelFormat _format ) + { + m_width = _width; + m_height = _height; + m_format = _format; + m_hwWidthInv = 1.f / (float)_width; + m_hwHeightInv = 1.f / (float)_height; + + MTLPixelFormat pixelFormat = MTLPixelFormatRGBA8Unorm; + + MTLTextureDescriptor * descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat width:_width height:_height mipmapped:NO]; + descriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; + + m_texture = [m_device newTextureWithDescriptor:descriptor]; + + return m_texture != nil; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderTargetTexture::finalize() + { + m_texture = nil; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderTargetTexture::getHWMipmaps() const + { + return 1; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderTargetTexture::getHWWidth() const + { + return m_width; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderTargetTexture::getHWHeight() const + { + return m_height; + } + ////////////////////////////////////////////////////////////////////////// + EPixelFormat MetalRenderTargetTexture::getHWPixelFormat() const + { + return m_format; + } + ////////////////////////////////////////////////////////////////////////// + float MetalRenderTargetTexture::getHWWidthInv() const + { + return m_hwWidthInv; + } + ////////////////////////////////////////////////////////////////////////// + float MetalRenderTargetTexture::getHWHeightInv() const + { + return m_hwHeightInv; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderTargetTexture::getUpscalePow2() const + { + return false; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderTargetTexture::begin() const + { + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderTargetTexture::end() const + { + } + ////////////////////////////////////////////////////////////////////////// + const mt::uv4f & MetalRenderTargetTexture::getUV() const + { + return m_uv; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderTargetTexture::getData( void * const _buffer, size_t _pitch ) const + { + if( m_texture == nil ) + { + return false; + } + + MTLRegion region = MTLRegionMake2D( 0, 0, m_width, m_height ); + [m_texture getBytes:_buffer bytesPerRow:_pitch fromRegion:region mipmapLevel:0]; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + id MetalRenderTargetTexture::getTexture() const + { + return m_texture; + } + ////////////////////////////////////////////////////////////////////////// + MetalDeviceId MetalRenderTargetTexture::getDevice() const + { + return m_device; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderTypes.h b/src/Systems/MetalRenderSystem/MetalRenderTypes.h new file mode 100644 index 0000000000..2f6c942a22 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderTypes.h @@ -0,0 +1,10 @@ +#pragma once + +#import + +namespace Mengine +{ + using MetalDeviceId = id; + using MetalBufferId = id; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.h b/src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.h new file mode 100644 index 0000000000..bd4a3c1e9c --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.h @@ -0,0 +1,49 @@ +#pragma once + +#include "Interface/RenderVertexAttributeInterface.h" +#include "Kernel/Factorable.h" +#include "Kernel/Vector.h" + +namespace Mengine +{ + class MetalRenderVertexAttribute + : public RenderVertexAttributeInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderVertexAttribute ); + + public: + MetalRenderVertexAttribute(); + ~MetalRenderVertexAttribute() override; + + public: + bool initialize( const ConstString & _name, uint32_t _elementSize ); + void finalize(); + + public: + const ConstString & getName() const override; + uint32_t getElementSize() const override; + + public: + void addAttribute( const ConstString & _uniform, uint32_t _index, uint32_t _size, EVertexAttributeType _type, bool _normalized, uint32_t _stride, uint32_t _offset ) override; + + protected: + struct Attribute + { + ConstString uniform; + uint32_t index; + uint32_t size; + EVertexAttributeType type; + bool normalized; + uint32_t stride; + uint32_t offset; + }; + + ConstString m_name; + uint32_t m_elementSize; + Vector m_attributes; + }; + + typedef IntrusivePtr MetalRenderVertexAttributePtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.mm b/src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.mm new file mode 100644 index 0000000000..664e64bec6 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexAttribute.mm @@ -0,0 +1,50 @@ +#include "MetalRenderVertexAttribute.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderVertexAttribute::MetalRenderVertexAttribute() + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderVertexAttribute::~MetalRenderVertexAttribute() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderVertexAttribute::initialize( const ConstString & _name, uint32_t _elementSize ) + { + m_name = _name; + m_elementSize = _elementSize; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderVertexAttribute::finalize() + { + //Empty + } + ////////////////////////////////////////////////////////////////////////// + const ConstString & MetalRenderVertexAttribute::getName() const + { + return m_name; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderVertexAttribute::getElementSize() const + { + return m_elementSize; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderVertexAttribute::addAttribute( const ConstString & _uniform, uint32_t _index, uint32_t _size, EVertexAttributeType _type, bool _normalized, uint32_t _stride, uint32_t _offset ) + { + Attribute desc; + desc.uniform = _uniform; + desc.index = _index; + desc.size = _size; + desc.type = _type; + desc.normalized = _normalized; + desc.stride = _stride; + desc.offset = _offset; + + m_attributes.emplace_back( desc ); + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h new file mode 100644 index 0000000000..b1afe42b3c --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h @@ -0,0 +1,53 @@ +#pragma once + +#include "MetalRenderTypes.h" +#include "Interface/RenderVertexBufferInterface.h" +#include "Kernel/Factorable.h" +#include "Interface/MemoryInterface.h" + +namespace Mengine +{ + class MetalRenderVertexBuffer + : public RenderVertexBufferInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderVertexBuffer ); + + public: + MetalRenderVertexBuffer( MetalDeviceId _device ); + ~MetalRenderVertexBuffer() override; + + public: + bool initialize( uint32_t _vertexSize, EBufferType _bufferType ) override; + void finalize() override; + + protected: + uint32_t getVertexCount() const override; + uint32_t getVertexSize() const override; + + protected: + bool resize( uint32_t _count ) override; + + protected: + MemoryInterfacePtr lock( uint32_t _offset, uint32_t _count ) override; + bool unlock() override; + + public: + MetalBufferId getBuffer() const; + + protected: + bool draw( const void * _buffer, uint32_t _offset, uint32_t _count ) override; + + protected: + MetalDeviceId m_device; + MetalBufferId m_buffer; + EBufferType m_bufferType; + uint32_t m_vertexSize; + uint32_t m_vertexCount; + uint32_t m_lockOffset; + MemoryBufferInterfacePtr m_memory; + }; + + typedef IntrusivePtr MetalRenderVertexBufferPtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm new file mode 100644 index 0000000000..98301c58e4 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm @@ -0,0 +1,118 @@ +#include "MetalRenderVertexBuffer.h" + +#include "Interface/MemoryServiceInterface.h" +#include "Kernel/Logger.h" +#include "Kernel/AssertionMemoryPanic.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderVertexBuffer::MetalRenderVertexBuffer( MetalDeviceId _device ) + : m_device( _device ) + , m_buffer( nil ) + , m_bufferType( BT_STATIC ) + , m_vertexSize( 0 ) + , m_vertexCount( 0 ) + , m_lockOffset( 0 ) + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderVertexBuffer::~MetalRenderVertexBuffer() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderVertexBuffer::initialize( uint32_t _vertexSize, EBufferType _bufferType ) + { + m_vertexSize = _vertexSize; + m_bufferType = _bufferType; + + MemoryBufferInterfacePtr memory = MEMORY_SERVICE()->createMemoryBuffer( MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid create memory" ); + + m_memory = memory; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderVertexBuffer::finalize() + { + m_memory = nullptr; + m_buffer = nil; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderVertexBuffer::getVertexCount() const + { + return m_vertexCount; + } + ////////////////////////////////////////////////////////////////////////// + uint32_t MetalRenderVertexBuffer::getVertexSize() const + { + return m_vertexSize; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderVertexBuffer::resize( uint32_t _count ) + { + if( m_vertexCount >= _count ) + { + return true; + } + + m_vertexCount = _count; + + m_buffer = [m_device newBufferWithLength:m_vertexCount * m_vertexSize options:MTLResourceStorageModeShared]; + + return m_buffer != nil; + } + ////////////////////////////////////////////////////////////////////////// + MemoryInterfacePtr MetalRenderVertexBuffer::lock( uint32_t _offset, uint32_t _count ) + { + if( _offset + _count > m_vertexCount ) + { + LOGGER_ASSERTION( "offset %u count %u more max size %u", _offset, _count, m_vertexCount ); + + return nullptr; + } + + m_lockOffset = _offset; + + m_memory->newBuffer( _count * m_vertexSize ); + + return m_memory; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderVertexBuffer::unlock() + { + if( m_buffer != nil ) + { + memcpy( ((uint8_t *)[m_buffer contents]) + m_lockOffset * m_vertexSize, m_memory->getBuffer(), m_memory->getSize() ); + } + + m_memory->clearBuffer(); + + return true; + } + ////////////////////////////////////////////////////////////////////////// + MetalBufferId MetalRenderVertexBuffer::getBuffer() const + { + return m_buffer; + } + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderVertexBuffer::draw( const void * _buffer, uint32_t _offset, uint32_t _count ) + { + if( _offset + _count > m_vertexCount ) + { + LOGGER_ASSERTION( "offset %u count %u more max size %u", _offset, _count, m_vertexCount ); + + return false; + } + + if( m_buffer == nil ) + { + return false; + } + + memcpy( ((uint8_t *)[m_buffer contents]) + _offset * m_vertexSize, _buffer, _count * m_vertexSize ); + + return true; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h new file mode 100644 index 0000000000..2d01a9227f --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Interface/RenderVertexShaderInterface.h" +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class MetalRenderVertexShader + : public RenderVertexShaderInterface + , public Factorable + { + DECLARE_FACTORABLE( MetalRenderVertexShader ); + + public: + MetalRenderVertexShader(); + ~MetalRenderVertexShader() override; + + public: + bool initialize( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile ); + void finalize(); + + public: + const ConstString & getName() const override; + + protected: + ConstString m_name; + MemoryInterfacePtr m_memory; + }; + + typedef IntrusivePtr MetalRenderVertexShaderPtr; +} + diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexShader.mm b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.mm new file mode 100644 index 0000000000..5a2d91b7e8 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.mm @@ -0,0 +1,33 @@ +#include "MetalRenderVertexShader.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + MetalRenderVertexShader::MetalRenderVertexShader() + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderVertexShader::~MetalRenderVertexShader() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderVertexShader::initialize( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile ) + { + MENGINE_UNUSED( _compile ); + + m_name = _name; + m_memory = _memory; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void MetalRenderVertexShader::finalize() + { + m_memory = nullptr; + } + ////////////////////////////////////////////////////////////////////////// + const ConstString & MetalRenderVertexShader::getName() const + { + return m_name; + } + ////////////////////////////////////////////////////////////////////////// +} + From 3f36de2af672000cbb26096d0505373eadb27c70 Mon Sep 17 00:00:00 2001 From: Yuriy Levchenko Date: Fri, 29 Aug 2025 00:32:12 +0300 Subject: [PATCH 002/169] Store Metal index buffer type --- src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h | 2 ++ src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm | 7 +++++++ src/Systems/MetalRenderSystem/MetalRenderSystem.mm | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h index ca53879645..9e44a20573 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h @@ -34,6 +34,7 @@ namespace Mengine public: MetalBufferId getBuffer() const; + MTLIndexType getIndexType() const; protected: bool draw( const void * _buffer, uint32_t _offset, uint32_t _count ) override; @@ -43,6 +44,7 @@ namespace Mengine MetalBufferId m_buffer; EBufferType m_bufferType; uint32_t m_indexSize; + MTLIndexType m_indexType; uint32_t m_indexCount; uint32_t m_lockOffset; MemoryBufferInterfacePtr m_memory; diff --git a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm index 7294f2b116..85390a59bf 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm @@ -12,6 +12,7 @@ , m_buffer( nil ) , m_bufferType( BT_STATIC ) , m_indexSize( 0 ) + , m_indexType( MTLIndexTypeUInt16 ) , m_indexCount( 0 ) , m_lockOffset( 0 ) { @@ -23,6 +24,7 @@ { m_indexSize = _indexSize; m_bufferType = _bufferType; + m_indexType = (_indexSize == 2) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32; MemoryBufferInterfacePtr memory = MEMORY_SERVICE()->createMemoryBuffer( MENGINE_DOCUMENT_FACTORABLE ); MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid create memory" ); @@ -95,6 +97,11 @@ return m_buffer; } ////////////////////////////////////////////////////////////////////////// + MTLIndexType MetalRenderIndexBuffer::getIndexType() const + { + return m_indexType; + } + ////////////////////////////////////////////////////////////////////////// bool MetalRenderIndexBuffer::draw( const void * _buffer, uint32_t _offset, uint32_t _count ) { if( _offset + _count > m_indexCount ) diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm index c41130e1a4..16cd5e8a99 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm @@ -352,7 +352,7 @@ if( ib != nullptr ) { - MTLIndexType indexType = (m_currentIndexBuffer->getIndexSize() == 2) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32; + MTLIndexType indexType = ib->getIndexType(); [encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:_desc.indexCount indexType:indexType indexBuffer:ib->getBuffer() indexBufferOffset:_desc.startIndex * m_currentIndexBuffer->getIndexSize()]; } From 952430f3dfa690f3f1ef773b37efa450440dba8d Mon Sep 17 00:00:00 2001 From: Yuriy Levchenko Date: Fri, 29 Aug 2025 00:59:34 +0300 Subject: [PATCH 003/169] Offset vertex buffer by base vertex --- src/Systems/MetalRenderSystem/MetalRenderSystem.mm | 3 ++- src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm index 16cd5e8a99..7619df8922 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm @@ -347,7 +347,8 @@ if( vb != nullptr ) { - [encoder setVertexBuffer:vb->getBuffer() offset:0 atIndex:0]; + uint32_t vertexOffset = _desc.baseVertexIndex * vb->getVertexSize(); + [encoder setVertexBuffer:vb->getBuffer() offset:vertexOffset atIndex:0]; } if( ib != nullptr ) diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h index b1afe42b3c..5e237344fe 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.h @@ -21,7 +21,7 @@ namespace Mengine bool initialize( uint32_t _vertexSize, EBufferType _bufferType ) override; void finalize() override; - protected: + public: uint32_t getVertexCount() const override; uint32_t getVertexSize() const override; From 15f566e18e495dbf936bbb812e34641b2c8da695 Mon Sep 17 00:00:00 2001 From: Yuriy Levchenko Date: Fri, 29 Aug 2025 01:08:34 +0300 Subject: [PATCH 004/169] Refactor Metal renderer to cache method results --- .../MetalRenderSystem/MetalRenderImage.mm | 5 ++- .../MetalRenderIndexBuffer.mm | 9 +++-- .../MetalRenderSystem/MetalRenderSystem.mm | 36 +++++++++++++++---- .../MetalRenderVertexBuffer.mm | 9 +++-- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/Systems/MetalRenderSystem/MetalRenderImage.mm b/src/Systems/MetalRenderSystem/MetalRenderImage.mm index ce237e7c8e..b5c3619b18 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderImage.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderImage.mm @@ -148,7 +148,10 @@ size_t pitch; void * buffer = locked->getBuffer( &pitch ); - MTLRegion region = MTLRegionMake2D( lockedRect.left, lockedRect.top, lockedRect.getWidth(), lockedRect.getHeight() ); + uint32_t lockedWidth = lockedRect.getWidth(); + uint32_t lockedHeight = lockedRect.getHeight(); + + MTLRegion region = MTLRegionMake2D( lockedRect.left, lockedRect.top, lockedWidth, lockedHeight ); [m_texture replaceRegion:region mipmapLevel:_level withBytes:buffer bytesPerRow:pitch]; return true; diff --git a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm index 85390a59bf..6004ca41f8 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm @@ -84,7 +84,11 @@ { if( m_buffer != nil ) { - memcpy( ((uint8_t *)[m_buffer contents]) + m_lockOffset * m_indexSize, m_memory->getBuffer(), m_memory->getSize() ); + void * memoryBuffer = m_memory->getBuffer(); + size_t memorySize = m_memory->getSize(); + void * bufferContents = [m_buffer contents]; + + memcpy( ((uint8_t *)bufferContents) + m_lockOffset * m_indexSize, memoryBuffer, memorySize ); } m_memory->clearBuffer(); @@ -116,7 +120,8 @@ return false; } - memcpy( ((uint8_t *)[m_buffer contents]) + _offset * m_indexSize, _buffer, _count * m_indexSize ); + void * bufferContents = [m_buffer contents]; + memcpy( ((uint8_t *)bufferContents) + _offset * m_indexSize, _buffer, _count * m_indexSize ); return true; } diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm index 7619df8922..e593e7e387 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm @@ -136,7 +136,10 @@ if( _windowDesc != nullptr ) { - m_metalLayer.drawableSize = CGSizeMake( _windowDesc->resolution.getWidth(), _windowDesc->resolution.getHeight() ); + CGFloat drawableWidth = (CGFloat)_windowDesc->resolution.getWidth(); + CGFloat drawableHeight = (CGFloat)_windowDesc->resolution.getHeight(); + + m_metalLayer.drawableSize = CGSizeMake( drawableWidth, drawableHeight ); m_vsync = _windowDesc->waitForVSync; } @@ -347,14 +350,22 @@ if( vb != nullptr ) { - uint32_t vertexOffset = _desc.baseVertexIndex * vb->getVertexSize(); - [encoder setVertexBuffer:vb->getBuffer() offset:vertexOffset atIndex:0]; + uint32_t vertexSize = vb->getVertexSize(); + uint32_t vertexOffset = _desc.baseVertexIndex * vertexSize; + + MetalBufferId bufferId = vb->getBuffer(); + [encoder setVertexBuffer:bufferId offset:vertexOffset atIndex:0]; } if( ib != nullptr ) { MTLIndexType indexType = ib->getIndexType(); - [encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:_desc.indexCount indexType:indexType indexBuffer:ib->getBuffer() indexBufferOffset:_desc.startIndex * m_currentIndexBuffer->getIndexSize()]; + MetalBufferId indexBuffer = ib->getBuffer(); + + uint32_t indexSize = m_currentIndexBuffer->getIndexSize(); + uint32_t bufferOffset = _desc.startIndex * indexSize; + + [encoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle indexCount:_desc.indexCount indexType:indexType indexBuffer:indexBuffer indexBufferOffset:bufferOffset]; } [encoder endEncoding]; @@ -492,9 +503,15 @@ { MetalRenderTargetTexture * target = _renderTarget.getT(); - MetalRenderImagePtr image = Helper::makeFactorableUnique( _doc, target->getDevice() ); + MetalDeviceId device = target->getDevice(); + MetalRenderImagePtr image = Helper::makeFactorableUnique( _doc, device ); + + MetalTextureId texture = target->getTexture(); + uint32_t hwWidth = target->getHWWidth(); + uint32_t hwHeight = target->getHWHeight(); + EPixelFormat hwPixelFormat = target->getHWPixelFormat(); - if( image->initializeFromTexture( target->getTexture(), target->getHWWidth(), target->getHWHeight(), target->getHWPixelFormat() ) == false ) + if( image->initializeFromTexture( texture, hwWidth, hwHeight, hwPixelFormat ) == false ) { return nullptr; } @@ -558,7 +575,12 @@ pass.colorAttachments[0].texture = drawable.texture; pass.colorAttachments[0].loadAction = MTLLoadActionClear; pass.colorAttachments[0].storeAction = MTLStoreActionStore; - pass.colorAttachments[0].clearColor = MTLClearColorMake( _color.getR(), _color.getG(), _color.getB(), _color.getA() ); + double clearR = _color.getR(); + double clearG = _color.getG(); + double clearB = _color.getB(); + double clearA = _color.getA(); + + pass.colorAttachments[0].clearColor = MTLClearColorMake( clearR, clearG, clearB, clearA ); id encoder = [m_commandBuffer renderCommandEncoderWithDescriptor:pass]; [encoder endEncoding]; diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm index 98301c58e4..1ede3162d4 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm @@ -82,7 +82,11 @@ { if( m_buffer != nil ) { - memcpy( ((uint8_t *)[m_buffer contents]) + m_lockOffset * m_vertexSize, m_memory->getBuffer(), m_memory->getSize() ); + void * memoryBuffer = m_memory->getBuffer(); + size_t memorySize = m_memory->getSize(); + void * bufferContents = [m_buffer contents]; + + memcpy( ((uint8_t *)bufferContents) + m_lockOffset * m_vertexSize, memoryBuffer, memorySize ); } m_memory->clearBuffer(); @@ -109,7 +113,8 @@ return false; } - memcpy( ((uint8_t *)[m_buffer contents]) + _offset * m_vertexSize, _buffer, _count * m_vertexSize ); + void * bufferContents = [m_buffer contents]; + memcpy( ((uint8_t *)bufferContents) + _offset * m_vertexSize, _buffer, _count * m_vertexSize ); return true; } From 064b535233e9527c89e1604840ffe5a3d4e88d50 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 28 Aug 2025 21:00:48 +0300 Subject: [PATCH 005/169] wip android signing --- gradle/app.gradle | 82 +++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/gradle/app.gradle b/gradle/app.gradle index 0bb2603b73..97730b90d3 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -124,44 +124,6 @@ android { } } - signingConfigs { - if (project.hasProperty("ANDROID_APP_DEBUG_STORE_FILE") == true) { - debug { - println "ANDROID_APP_DEBUG_STORE_FILE: $ANDROID_APP_DEBUG_STORE_FILE" - println "ANDROID_APP_DEBUG_KEY_ALIAS: $ANDROID_APP_DEBUG_KEY_ALIAS" - - def f = new File(ANDROID_APP_DEBUG_STORE_FILE) - - if (f.exists() == false) { - throw new GradleException("ANDROID_APP_DEBUG_STORE_FILE not found folder: $ANDROID_APP_DEBUG_STORE_FILE") - } - - storeFile file(ANDROID_APP_DEBUG_STORE_FILE) - storePassword ANDROID_APP_DEBUG_STORE_PASSWORD - keyAlias ANDROID_APP_DEBUG_KEY_ALIAS - keyPassword ANDROID_APP_DEBUG_KEY_PASSWORD - } - } - - if (project.hasProperty("ANDROID_APP_RELEASE_STORE_FILE") == true) { - release { - println "ANDROID_APP_RELEASE_STORE_FILE: $ANDROID_APP_RELEASE_STORE_FILE" - println "ANDROID_APP_RELEASE_KEY_ALIAS: $ANDROID_APP_RELEASE_KEY_ALIAS" - - def f = new File(ANDROID_APP_RELEASE_STORE_FILE) - - if (f.exists() == false) { - throw new GradleException("ANDROID_APP_RELEASE_STORE_FILE not found folder: $ANDROID_APP_RELEASE_STORE_FILE") - } - - storeFile file(ANDROID_APP_RELEASE_STORE_FILE) - storePassword ANDROID_APP_RELEASE_STORE_PASSWORD - keyAlias ANDROID_APP_RELEASE_KEY_ALIAS - keyPassword ANDROID_APP_RELEASE_KEY_PASSWORD - } - } - } - defaultConfig { if (project.hasProperty("ANDROID_APP_ID") == true) { applicationId ANDROID_APP_ID @@ -199,15 +161,51 @@ android { println "versionName: $versionName" } + signingConfigs { + if (project.hasProperty("ANDROID_APP_DEBUG_STORE_FILE") == true) { + debug { + println "ANDROID_APP_DEBUG_STORE_FILE: $ANDROID_APP_DEBUG_STORE_FILE" + + def f = new File(ANDROID_APP_DEBUG_STORE_FILE) + + if (f.exists() == false) { + throw new GradleException("ANDROID_APP_DEBUG_STORE_FILE not found folder: $ANDROID_APP_DEBUG_STORE_FILE") + } + + storeFile file(ANDROID_APP_DEBUG_STORE_FILE) + storePassword ANDROID_APP_DEBUG_STORE_PASSWORD + keyAlias ANDROID_APP_DEBUG_KEY_ALIAS + keyPassword ANDROID_APP_DEBUG_KEY_PASSWORD + } + } + + if (project.hasProperty("ANDROID_APP_RELEASE_STORE_FILE") == true) { + release { + println "ANDROID_APP_RELEASE_STORE_FILE: $ANDROID_APP_RELEASE_STORE_FILE" + + def f = new File(ANDROID_APP_RELEASE_STORE_FILE) + + if (f.exists() == false) { + throw new GradleException("ANDROID_APP_RELEASE_STORE_FILE not found folder: $ANDROID_APP_RELEASE_STORE_FILE") + } + + storeFile file(ANDROID_APP_RELEASE_STORE_FILE) + storePassword ANDROID_APP_RELEASE_STORE_PASSWORD + keyAlias ANDROID_APP_RELEASE_KEY_ALIAS + keyPassword ANDROID_APP_RELEASE_KEY_PASSWORD + } + } + } + buildTypes { - debug { - if (project.hasProperty("ANDROID_APP_DEBUG_STORE_FILE") == true) { + if (project.hasProperty("ANDROID_APP_DEBUG_STORE_FILE") == true) { + debug { signingConfig signingConfigs.debug } } - release { - if (project.hasProperty("ANDROID_APP_RELEASE_STORE_FILE") == true) { + if (project.hasProperty("ANDROID_APP_RELEASE_STORE_FILE") == true) { + release { signingConfig signingConfigs.release } } From 1369585bc7e352183f8c98b379d4655ff951382d Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 30 Aug 2025 16:14:18 +0300 Subject: [PATCH 006/169] improve android Sentry logs add android ANDROID_APP_*****_STORE_TYPE update android com.android.tools.build:gradle 8.12.2 --- gradle/androidx.gradle | 2 +- gradle/app.gradle | 10 +++ gradle/build.gradle | 2 +- .../org/Mengine/Base/MengineAnalytics.java | 8 +++ .../java/org/Mengine/Base/MengineLog.java | 2 +- .../java/org/Mengine/Base/MengineUtils.java | 7 ++- .../Plugin/Sentry/MengineSentryPlugin.java | 63 ++++++++++++++++++- 7 files changed, 86 insertions(+), 8 deletions(-) diff --git a/gradle/androidx.gradle b/gradle/androidx.gradle index ca0a3e84b2..c8971359ca 100644 --- a/gradle/androidx.gradle +++ b/gradle/androidx.gradle @@ -5,7 +5,7 @@ def ANDROID_APP_IMPLEMENTATION_ANDROIDX_PREFERENCE = Utils.getStringProperty("AN def ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT", "1.7.1") def ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW", "1.4.0") def ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS", "1.0.0") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS", "2.9.2") +def ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS", "2.9.3") dependencies { implementation "androidx.core:core:$ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE" diff --git a/gradle/app.gradle b/gradle/app.gradle index 97730b90d3..647252f15e 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -165,6 +165,10 @@ android { if (project.hasProperty("ANDROID_APP_DEBUG_STORE_FILE") == true) { debug { println "ANDROID_APP_DEBUG_STORE_FILE: $ANDROID_APP_DEBUG_STORE_FILE" + println "ANDROID_APP_DEBUG_STORE_TYPE: $ANDROID_APP_DEBUG_STORE_TYPE" + println "ANDROID_APP_DEBUG_STORE_PASSWORD: $ANDROID_APP_DEBUG_STORE_PASSWORD" + println "ANDROID_APP_DEBUG_KEY_ALIAS: $ANDROID_APP_DEBUG_KEY_ALIAS" + println "ANDROID_APP_DEBUG_KEY_PASSWORD: $ANDROID_APP_DEBUG_KEY_PASSWORD" def f = new File(ANDROID_APP_DEBUG_STORE_FILE) @@ -173,6 +177,7 @@ android { } storeFile file(ANDROID_APP_DEBUG_STORE_FILE) + storeType ANDROID_APP_DEBUG_STORE_TYPE storePassword ANDROID_APP_DEBUG_STORE_PASSWORD keyAlias ANDROID_APP_DEBUG_KEY_ALIAS keyPassword ANDROID_APP_DEBUG_KEY_PASSWORD @@ -182,6 +187,10 @@ android { if (project.hasProperty("ANDROID_APP_RELEASE_STORE_FILE") == true) { release { println "ANDROID_APP_RELEASE_STORE_FILE: $ANDROID_APP_RELEASE_STORE_FILE" + println "ANDROID_APP_RELEASE_STORE_TYPE: $ANDROID_APP_RELEASE_STORE_TYPE" + println "ANDROID_APP_RELEASE_STORE_PASSWORD: $ANDROID_APP_RELEASE_STORE_PASSWORD" + println "ANDROID_APP_RELEASE_KEY_ALIAS: $ANDROID_APP_RELEASE_KEY_ALIAS" + println "ANDROID_APP_RELEASE_KEY_PASSWORD: $ANDROID_APP_RELEASE_KEY_PASSWORD" def f = new File(ANDROID_APP_RELEASE_STORE_FILE) @@ -190,6 +199,7 @@ android { } storeFile file(ANDROID_APP_RELEASE_STORE_FILE) + storeType ANDROID_APP_RELEASE_STORE_TYPE storePassword ANDROID_APP_RELEASE_STORE_PASSWORD keyAlias ANDROID_APP_RELEASE_KEY_ALIAS keyPassword ANDROID_APP_RELEASE_KEY_PASSWORD diff --git a/gradle/build.gradle b/gradle/build.gradle index 29badb43c9..79a10fb4b0 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -13,7 +13,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.12.1' + classpath 'com.android.tools.build:gradle:8.12.2' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0' diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java index ff7eef3b6f..5d917db984 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java @@ -84,6 +84,14 @@ static public void addContextGetterParameterDouble(@Size(min = 1L,max = 40L) Str MengineAnalytics.m_getter.put(key, value); } + static public Map collapseContextParameters() { + Map parameters = new HashMap<>(MengineAnalytics.m_bases); + + MengineAnalytics.collapseGetter(parameters); + + return parameters; + } + static private void collapseGetter(Map parameters) { for (Map.Entry entry : MengineAnalytics.m_getter.entrySet()) { String key = entry.getKey(); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java index a20d19a336..355e96055e 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java @@ -42,7 +42,7 @@ public static void logNativeLevel(int level, @NonNull MengineTag category, @NonN Log.wtf(category.toString(), "\uD83D\uDFE5 " + msg); break; case LM_MESSAGE_RELEASE: - Log.w(category.toString(), msg); + Log.w(category.toString(), "\uD83D\uDCDD " + msg); break; case LM_ERROR: Log.e(category.toString(), "\uD83D\uDD34 " + msg); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java index 49dcc4b79d..3b006355fd 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java @@ -954,9 +954,12 @@ public static int getDeviceScreenSize(Context context) { } public static boolean isDeviceTablet(Context context) { - int screenLayoutSize = MengineUtils.getDeviceScreenSize(context); + Resources resources = context.getResources(); + Configuration configuration = resources.getConfiguration(); + + int smallestWidthDp = configuration.smallestScreenWidthDp; - if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_LARGE || screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_XLARGE) { + if (smallestWidthDp >= 600) { return true; } diff --git a/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java b/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java index 682ad5f17a..2116c1878d 100644 --- a/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java +++ b/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java @@ -6,11 +6,16 @@ import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import org.Mengine.Base.MengineAnalytics; import org.Mengine.Base.MengineApplication; import org.Mengine.Base.MengineListenerApplication; import org.Mengine.Base.MengineListenerEngine; +import org.Mengine.Base.MengineListenerLogger; import org.Mengine.Base.MengineListenerTransparencyConsent; import org.Mengine.Base.MengineListenerUser; +import org.Mengine.Base.MengineLog; +import org.Mengine.Base.MengineParamLoggerException; +import org.Mengine.Base.MengineParamLoggerMessage; import org.Mengine.Base.MengineService; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineParamTransparencyConsent; @@ -18,11 +23,16 @@ import java.util.Map; +import io.sentry.JsonSerializable; import io.sentry.Sentry; +import io.sentry.SentryAttribute; +import io.sentry.SentryAttributes; +import io.sentry.SentryLogLevel; import io.sentry.android.core.SentryAndroid; +import io.sentry.logger.SentryLogParameters; import io.sentry.protocol.User; -public class MengineSentryPlugin extends MengineService implements MengineListenerApplication, MengineListenerEngine, MengineListenerTransparencyConsent, MengineListenerUser { +public class MengineSentryPlugin extends MengineService implements MengineListenerApplication, MengineListenerEngine, MengineListenerTransparencyConsent, MengineListenerLogger, MengineListenerUser { public static final String SERVICE_NAME = "Sentry"; public static final boolean SERVICE_EMBEDDING = true; @@ -162,6 +172,55 @@ public void onAppState(@NonNull MengineApplication application, String name, Obj this.setCustomKey("." + name, value); } + static private SentryLogLevel getSentryLogLevel(@NonNull MengineParamLoggerMessage message) { + switch (message.MESSAGE_LEVEL) { + case MengineLog.LM_DEBUG: + return SentryLogLevel.DEBUG; + case MengineLog.LM_INFO: + return SentryLogLevel.INFO; + case MengineLog.LM_MESSAGE: + case MengineLog.LM_MESSAGE_RELEASE: + return SentryLogLevel.INFO; + case MengineLog.LM_WARNING: + return SentryLogLevel.WARN; + case MengineLog.LM_FATAL: + return SentryLogLevel.FATAL; + } + + return SentryLogLevel.TRACE; + } + + @Override + public void onMengineLog(@NonNull MengineApplication application, @NonNull MengineParamLoggerMessage message) { + if (BuildConfig.DEBUG == false) { + if (message.MESSAGE_LEVEL != MengineLog.LM_WARNING && message.MESSAGE_LEVEL != MengineLog.LM_ERROR && message.MESSAGE_LEVEL != MengineLog.LM_FATAL) { + return; + } + } + + SentryLogLevel level = MengineSentryPlugin.getSentryLogLevel(message); + + SentryAttributes attributes = SentryAttributes.of(null); + attributes.add(SentryAttribute.stringAttribute("log.category", message.MESSAGE_CATEGORY.toString())); + attributes.add(SentryAttribute.stringAttribute("log.thread", message.MESSAGE_THREAD)); + + if (message.MESSAGE_FILE != null) { + attributes.add(SentryAttribute.stringAttribute("log.file", message.MESSAGE_FILE)); + attributes.add(SentryAttribute.integerAttribute("log.line", message.MESSAGE_LINE)); + } + + if (message.MESSAGE_FUNCTION != null) { + attributes.add(SentryAttribute.stringAttribute("log.function", message.MESSAGE_FUNCTION)); + } + + Sentry.logger().log(level, SentryLogParameters.create(attributes), message.MESSAGE_DATA); + } + + @Override + public void onMengineException(@NonNull MengineApplication application, @NonNull MengineParamLoggerException exception) { + this.recordException(exception.EXCEPTION_THROWABLE); + } + public void setCustomKey(String key, Object value) { if (value == null) { Sentry.setExtra(key, "null"); @@ -175,8 +234,6 @@ public void recordException(Throwable throwable) { , throwable.getMessage() ); - throwable.printStackTrace(System.err); - Sentry.captureException(throwable); } From b1fc62a80e9d085543286fd65fec22f25f7bfb3e Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 31 Aug 2025 12:55:12 +0300 Subject: [PATCH 007/169] fix compile --- src/Kernel/CryptographyHelper.h | 1 + src/Plugins/AppleAppLovinPlugin/CMakeLists.txt | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Kernel/CryptographyHelper.h b/src/Kernel/CryptographyHelper.h index 744aea4a10..83dff6052e 100644 --- a/src/Kernel/CryptographyHelper.h +++ b/src/Kernel/CryptographyHelper.h @@ -2,6 +2,7 @@ #include "Config/Char.h" #include "Config/StdInt.h" +#include "Config/StdDef.h" namespace Mengine { diff --git a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt index 59b6d4f2ff..badc59e2c0 100644 --- a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt @@ -98,14 +98,14 @@ macro(ADD_APPLOVIN_MEDIATION MEDIATION POD VERSION) endif() endmacro() -ADD_APPLOVIN_MEDIATION(ADMOB "AppLovinMediationGoogleAdapter" "12.8.0.0") +ADD_APPLOVIN_MEDIATION(ADMOB "AppLovinMediationGoogleAdapter" "12.9.0.0") ADD_APPLOVIN_MEDIATION(AMAZON "AppLovinMediationAmazonAdMarketplaceAdapter" "5.2.0.0") ADD_APPLOVIN_MEDIATION(BIDMACHINE "AppLovinMediationBidMachineAdapter" "3.3.0.0.0") ADD_APPLOVIN_MEDIATION(BIGO "AppLovinMediationBigoAdsAdapter" "4.7.0.2") ADD_APPLOVIN_MEDIATION(CHARTBOOST "AppLovinMediationChartboostAdapter" "9.9.0.0") ADD_APPLOVIN_MEDIATION(CSJ "AppLovinMediationCSJAdapter" "6.7.1.6.0") ADD_APPLOVIN_MEDIATION(DTEXCHANGE "AppLovinMediationFyberAdapter" "8.3.6.0") #DT Exchange -ADD_APPLOVIN_MEDIATION(GOOGLEADMANAGER "AppLovinMediationGoogleAdManagerAdapter" "12.8.0.0") +ADD_APPLOVIN_MEDIATION(GOOGLEADMANAGER "AppLovinMediationGoogleAdManagerAdapter" "12.9.0.0") ADD_APPLOVIN_MEDIATION(HYPRMX "AppLovinMediationHyprMXAdapter" "6.4.2.0.0") ADD_APPLOVIN_MEDIATION(INMOBI "AppLovinMediationInMobiAdapter" "10.8.3.1") ADD_APPLOVIN_MEDIATION(IRONSOURCE "AppLovinMediationIronSourceAdapter" "8.8.0.0.0") @@ -121,7 +121,7 @@ ADD_APPLOVIN_MEDIATION(PANGLE "AppLovinMediationByteDanceAdapter" "7.1.1.1.0") # ADD_APPLOVIN_MEDIATION(PUBMATIC "AppLovinMediationPubMaticAdapter" "4.5.2.0") ADD_APPLOVIN_MEDIATION(SMAATO "AppLovinMediationSmaatoAdapter" "22.9.3.1") ADD_APPLOVIN_MEDIATION(TENCENT "AppLovinMediationTencentGDTAdapter" "4.15.21.1") -ADD_APPLOVIN_MEDIATION(UNITYADS "AppLovinMediationUnityAdsAdapter" "4.15.1.1") +ADD_APPLOVIN_MEDIATION(UNITYADS "AppLovinMediationUnityAdsAdapter" "4.16.0.0") ADD_APPLOVIN_MEDIATION(VERVE "AppLovinMediationVerveAdapter" "3.6.0.0") ADD_APPLOVIN_MEDIATION(MYTARGET "AppLovinMediationMyTargetAdapter" "5.31.0.0") #VK ADD_APPLOVIN_MEDIATION(YANDEX "AppLovinMediationYandexAdapter" "7.12.3.0") From bad8ed27b7acef35282188ef61f7299774a2dc0e Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 31 Aug 2025 18:46:22 +0300 Subject: [PATCH 008/169] fix build --- src/Systems/POSIXThreadSystem/POSIXThreadIdentity.cpp | 9 +++++---- src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Systems/POSIXThreadSystem/POSIXThreadIdentity.cpp b/src/Systems/POSIXThreadSystem/POSIXThreadIdentity.cpp index 125275f5e1..c493f095e1 100644 --- a/src/Systems/POSIXThreadSystem/POSIXThreadIdentity.cpp +++ b/src/Systems/POSIXThreadSystem/POSIXThreadIdentity.cpp @@ -149,17 +149,18 @@ namespace Mengine if( PLATFORM_SYSTEM() ->beginThread( (ThreadId)m_threadId ) == false ) { - LOGGER_ERROR( "invalid begin thread: %" MENGINE_PRIu64 " name: %s" - , (ThreadId)m_threadId + LOGGER_ERROR( "invalid begin thread identity name: %s id: %" MENGINE_PRIu64 " priority: %d" , m_description.nameA + , (ThreadId)m_threadId + , m_priority ); return; } - LOGGER_INFO( "thread", "create thread name: %s id: %ld priority: %d" + LOGGER_INFO( "thread", "begin thread name: %s id: %" MENGINE_PRIu64 " priority: %d" , m_description.nameA - , m_threadId + , (ThreadId)m_threadId , m_priority ); diff --git a/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp b/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp index 2df8889d86..1196d32ad3 100644 --- a/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp +++ b/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp @@ -143,17 +143,18 @@ namespace Mengine if( PLATFORM_SYSTEM() ->beginThread( (ThreadId)m_threadId ) == false ) { - LOGGER_ERROR( "invalid begin thread: %" MENGINE_PRIu64 " name: %s" - , (ThreadId)m_threadId + LOGGER_ERROR( "invalid begin thread processor name: %s id: %" MENGINE_PRIu64 " priority: %d" , m_description.nameA + , (ThreadId)m_threadId + , m_priority ); return; } - LOGGER_INFO( "thread", "create thread name: %s id: %ld priority: %d" + LOGGER_INFO( "thread", "begin thread processor name: %s id: %" MENGINE_PRIu64 " priority: %d" , m_description.nameA - , m_threadId + , (ThreadId)m_threadId , m_priority ); From 46b318c505902feef1306680cdf09bbdec197d67 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 1 Sep 2025 23:13:07 +0300 Subject: [PATCH 009/169] update android com.amplitude:analytics-android 1.22.2 update android com.devtodev:android-analytics 2.5.1 update android com.google.firebase:firebase-bom 34.2.0 --- cmake/mengine_template.cmake | 4 ---- gradle/build.gradle | 2 +- gradle/plugins/Amplitude/build.gradle | 2 +- gradle/plugins/AppLovin/Core/build.gradle | 8 ++++---- gradle/plugins/DevToDev/build.gradle | 2 +- gradle/plugins/Firebase/build.gradle | 2 +- gradle/plugins/FirebaseCrashlytics/build.gradle | 4 ++-- gradle/plugins/FirebasePerformanceMonitoring/build.gradle | 2 +- src/Bootstrapper/Bootstrapper.cpp | 5 +++++ 9 files changed, 16 insertions(+), 15 deletions(-) diff --git a/cmake/mengine_template.cmake b/cmake/mengine_template.cmake index b8078a820a..468c6e412d 100644 --- a/cmake/mengine_template.cmake +++ b/cmake/mengine_template.cmake @@ -111,10 +111,6 @@ if(MENGINE_DEPLOY_PATH) endif() endif() -if(MENGINE_SECURE_VALUE) - MESSAGE("MENGINE_SECURE_VALUE: ${MENGINE_SECURE_VALUE}") -endif() - MESSAGE("CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") MESSAGE("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") MESSAGE("CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") diff --git a/gradle/build.gradle b/gradle/build.gradle index 79a10fb4b0..ab4cf4e17c 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -34,7 +34,7 @@ buildscript { } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPLOVIN") == true && project.hasProperty("MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY") == true) { - classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:5.9.7' + classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:5.9.8' } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_DATADOG") == true) { diff --git a/gradle/plugins/Amplitude/build.gradle b/gradle/plugins/Amplitude/build.gradle index 136fb407fa..2c67f1f112 100644 --- a/gradle/plugins/Amplitude/build.gradle +++ b/gradle/plugins/Amplitude/build.gradle @@ -8,5 +8,5 @@ android { dependencies { implementation 'com.squareup.okhttp3:okhttp:5.1.0' - implementation 'com.amplitude:analytics-android:1.21.5' + implementation 'com.amplitude:analytics-android:1.22.2' } \ No newline at end of file diff --git a/gradle/plugins/AppLovin/Core/build.gradle b/gradle/plugins/AppLovin/Core/build.gradle index acc66ac622..f7b20a0eeb 100644 --- a/gradle/plugins/AppLovin/Core/build.gradle +++ b/gradle/plugins/AppLovin/Core/build.gradle @@ -158,11 +158,11 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE == true) { - implementation 'com.applovin.mediation:mobilefuse-adapter:1.9.2.1' + implementation 'com.applovin.mediation:mobilefuse-adapter:1.9.3.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO == true) { - implementation 'com.applovin.mediation:moloco-adapter:3.12.1.0' + implementation 'com.applovin.mediation:moloco-adapter:4.0.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY == true) { @@ -170,7 +170,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE == true) { - implementation 'com.applovin.mediation:bytedance-adapter:7.5.0.2.0' + implementation 'com.applovin.mediation:bytedance-adapter:7.5.0.3.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC == true) { @@ -178,7 +178,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO == true) { - implementation 'com.applovin.mediation:smaato-adapter:22.7.2.1' + implementation 'com.applovin.mediation:smaato-adapter:22.7.2.3' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS == true) { diff --git a/gradle/plugins/DevToDev/build.gradle b/gradle/plugins/DevToDev/build.gradle index fc17b13b7c..6aec55c727 100644 --- a/gradle/plugins/DevToDev/build.gradle +++ b/gradle/plugins/DevToDev/build.gradle @@ -11,7 +11,7 @@ android { dependencies { implementation 'com.devtodev:android-google:1.0.1' - implementation 'com.devtodev:android-analytics:2.5.0' + implementation 'com.devtodev:android-analytics:2.5.1' } android { diff --git a/gradle/plugins/Firebase/build.gradle b/gradle/plugins/Firebase/build.gradle index db1e6f1c2a..c79215f913 100644 --- a/gradle/plugins/Firebase/build.gradle +++ b/gradle/plugins/Firebase/build.gradle @@ -5,7 +5,7 @@ android { } dependencies { - api enforcedPlatform('com.google.firebase:firebase-bom:34.1.0') + api enforcedPlatform('com.google.firebase:firebase-bom:34.2.0') implementation 'com.google.firebase:firebase-common:22.0.0' } diff --git a/gradle/plugins/FirebaseCrashlytics/build.gradle b/gradle/plugins/FirebaseCrashlytics/build.gradle index a070a35cb8..fcd09785d2 100644 --- a/gradle/plugins/FirebaseCrashlytics/build.gradle +++ b/gradle/plugins/FirebaseCrashlytics/build.gradle @@ -10,8 +10,8 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-crashlytics:20.0.0' - implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.0' + implementation 'com.google.firebase:firebase-crashlytics:20.0.1' + implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.1' } android { diff --git a/gradle/plugins/FirebasePerformanceMonitoring/build.gradle b/gradle/plugins/FirebasePerformanceMonitoring/build.gradle index 277a80def3..fae2f23018 100644 --- a/gradle/plugins/FirebasePerformanceMonitoring/build.gradle +++ b/gradle/plugins/FirebasePerformanceMonitoring/build.gradle @@ -8,5 +8,5 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-perf:22.0.0' + implementation 'com.google.firebase:firebase-perf:22.0.1' } \ No newline at end of file diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index 9361fb306f..2cddb45c32 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -51,6 +51,7 @@ #include "Config/Path.h" #include "Configuration/Configurations.h" +#include "Configuration/SecureValue.h" ////////////////////////////////////////////////////////////////////////// #ifndef MENGINE_BOOTSTRAPPER_LOAD_CONFIG @@ -1052,6 +1053,10 @@ namespace Mengine PLATFORM_SERVICE() ->initializeFileService(); +#if defined(MENGINE_DEBUG) + LOGGER_MESSAGE( "secure: %s", MENGINE_SECURE_VALUE ); +#endif + LOGGER_INFO( "bootstrapper", "debug mode '%s'", Helper::isDebugMode() == true ? "ON" : "OFF" ); LOGGER_INFO( "bootstrapper", "development mode '%s'", Helper::isDevelopmentMode() == true ? "ON" : "OFF" ); LOGGER_INFO( "bootstrapper", "build publish '%s'", Helper::isBuildPublish() == true ? "ON" : "OFF" ); From 9590a985dd19b6229ade8089445c84631d9bde64 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 3 Sep 2025 21:29:28 +0300 Subject: [PATCH 010/169] fix rewarded no ads update android com.applovin:applovin-sdk 13.4.0 --- .../org/Mengine/Base/MengineAdService.java | 18 -------- gradle/plugins/AppLovin/Core/build.gradle | 2 +- .../Plugin/DataDog/MengineDataDogPlugin.java | 12 ++++- .../Win32Platform/Win32PlatformService.cpp | 45 ++++++++++--------- .../Win32Platform/Win32PlatformService.h | 4 +- .../AppleAdvertisementApplicationDelegate.mm | 6 --- 6 files changed, 35 insertions(+), 52 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java index f02b7437ed..8c2098813d 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java @@ -521,12 +521,6 @@ public boolean canOfferRewarded(String placement) { return false; } - boolean noAds = this.getNoAds(); - - if (noAds == true) { - return false; - } - MengineApplication application = MengineApplication.INSTANCE; if (adPoint.canOfferAd(application) == false) { @@ -554,12 +548,6 @@ public boolean canYouShowRewarded(String placement) { return false; } - boolean noAds = this.getNoAds(); - - if (noAds == true) { - return false; - } - MengineApplication application = MengineApplication.INSTANCE; if (adPoint.canYouShowAd(application) == false) { @@ -587,12 +575,6 @@ public boolean showRewarded(String placement) { return false; } - boolean noAds = this.getNoAds(); - - if (noAds == true) { - return false; - } - if (m_adProvider.showRewarded(placement) == false) { return false; } diff --git a/gradle/plugins/AppLovin/Core/build.gradle b/gradle/plugins/AppLovin/Core/build.gradle index f7b20a0eeb..43f50cbd48 100644 --- a/gradle/plugins/AppLovin/Core/build.gradle +++ b/gradle/plugins/AppLovin/Core/build.gradle @@ -89,7 +89,7 @@ dependencies { implementation project(':plugins:AdMob') } - implementation api('com.applovin:applovin-sdk:13.3.1') + implementation api('com.applovin:applovin-sdk:13.4.0') if (MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW == true) { implementation 'com.google.android.ump:user-messaging-platform:3.2.0' diff --git a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java index be0a8b4e04..bc90fffaaf 100644 --- a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java +++ b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java @@ -138,7 +138,7 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine String installId = application.getInstallId(); String userId = application.getUserId(); - if (userId != null) { + if (userId != null && consent == TrackingConsent.GRANTED) { Datadog.setUserInfo(userId, null, null, Map.of("install_id", installId)); } @@ -201,6 +201,14 @@ public void onDestroy(@NonNull MengineActivity activity) { @Override public void onMengineChangeUserId(@NonNull MengineApplication application, String oldUserId, String newUserId) { + MengineParamTransparencyConsent consentParam = application.makeTransparencyConsentParam(); + + TrackingConsent consent = this.getTrackingConsent(consentParam); + + if (consent != TrackingConsent.GRANTED) { + return; + } + String installId = application.getInstallId(); Datadog.setUserInfo(newUserId, null, null, Map.of("install_id", installId)); @@ -208,7 +216,7 @@ public void onMengineChangeUserId(@NonNull MengineApplication application, Strin @Override public void onMengineRemoveUserData(@NonNull MengineApplication application) { - Datadog.setUserInfo(null, null, null, null); + Datadog.clearAllData(); } @Override diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index 0bf88fc8d8..055af0fa38 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -100,7 +100,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// Win32PlatformService::Win32PlatformService() : m_beginTime( 0 ) - , m_hInstance( NULL ) , m_hWnd( NULL ) , m_xDpi( ~0U ) , m_yDpi( ~0U ) @@ -141,9 +140,7 @@ namespace Mengine #if defined(MENGINE_SETLOCALE_ENABLE) ::setlocale( LC_ALL, MENGINE_SETLOCALE_VALUE ); -#endif - - m_hInstance = ::GetModuleHandle( NULL ); +#endif if( ::QueryPerformanceFrequency( &m_performanceFrequency ) == TRUE ) { @@ -394,21 +391,6 @@ namespace Mengine this->detachWindow(); - if( m_hInstance != NULL ) - { - LPCWSTR lpClassName = m_windowClassName.c_str(); - - if( ::UnregisterClass( lpClassName, m_hInstance ) == FALSE ) - { - LOGGER_ERROR( "invalid UnregisterClass [%ls] get error: %ls" - , m_windowClassName.c_str() - , Helper::Win32GetLastErrorMessageW() - ); - } - - m_hInstance = NULL; - } - MENGINE_ASSERTION_FACTORY_EMPTY( m_factoryDynamicLibraries ); m_factoryDynamicLibraries = nullptr; @@ -797,7 +779,9 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Win32PlatformService::setHWNDIcon( const WChar * _iconResource ) { - HICON hIcon = ::LoadIcon( m_hInstance, _iconResource ); + HINSTANCE hInstance = ::GetModuleHandle( NULL ); + + HICON hIcon = ::LoadIcon( hInstance, _iconResource ); if( hIcon == NULL ) { @@ -2165,6 +2149,8 @@ namespace Mengine return true; } + HINSTANCE hInstance = ::GetModuleHandle( NULL ); + WNDCLASSEX wc; ::ZeroMemory( &wc, sizeof( WNDCLASSEX ) ); wc.cbSize = sizeof( WNDCLASSEX ); @@ -2172,7 +2158,7 @@ namespace Mengine wc.lpfnWndProc = &Detail::wndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = m_hInstance; + wc.hInstance = hInstance; wc.hIcon = m_hIcon; wc.hCursor = ::LoadCursor( NULL, MAKEINTRESOURCEW( 32512 ) ); @@ -2207,7 +2193,10 @@ namespace Mengine HWND hWnd = ::CreateWindowEx( dwExStyle, m_windowClassName.c_str(), m_projectTitle.c_str() , dwStyle , rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top - , NULL, NULL, m_hInstance, (LPVOID)this ); + , NULL + , NULL + , hInstance + , (LPVOID)this ); if( hWnd == NULL ) { @@ -2368,6 +2357,18 @@ namespace Mengine m_hWnd = NULL; + LPCWSTR lpClassName = m_windowClassName.c_str(); + + HINSTANCE hInstance = ::GetModuleHandle( NULL ); + + if( ::UnregisterClass( lpClassName, hInstance ) == FALSE ) + { + LOGGER_ERROR( "invalid UnregisterClass [%ls] get error: %ls" + , m_windowClassName.c_str() + , Helper::Win32GetLastErrorMessageW() + ); + } + this->updateWndMessage_(); return true; diff --git a/src/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index cebc65272e..b639e6f39d 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.h +++ b/src/Platforms/Win32Platform/Win32PlatformService.h @@ -197,9 +197,7 @@ namespace Mengine protected: Timestamp m_beginTime; - StaticWString m_windowClassName; - - HINSTANCE m_hInstance; + StaticWString m_windowClassName; HWND m_hWnd; diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm index 23a20fe087..71f40936e3 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm @@ -246,12 +246,6 @@ - (BOOL)hasRewarded { return NO; } - BOOL noAds = [self getNoAds]; - - if (noAds == YES) { - return NO; - } - if ([self.m_provider hasRewarded] == NO) { return NO; } From 2dca6e48d7de22f221e4d3fda62d55e01895f077 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 3 Sep 2025 21:52:08 +0300 Subject: [PATCH 011/169] fix android disable --- .../java/org/Mengine/Base/MengineApplication.java | 2 +- .../main/java/org/Mengine/Base/MengineMain.java | 7 ++++++- .../main/java/org/Mengine/Base/MengineNative.java | 1 - .../src/main/java/org/Mengine/Base/MengineUI.java | 2 -- .../main/java/org/Mengine/Base/MengineUtils.java | 10 ---------- src/Environment/Android/AndroidEnv.cpp | 15 --------------- 6 files changed, 7 insertions(+), 30 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java index 37af581f64..2a11e45c43 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java @@ -1212,7 +1212,7 @@ public void nativeCall(@NonNull String plugin, String method, Object ... args) { MengineNative.AndroidKernelService_call(plugin, method, args); } - private void invalidInitialize(@NonNull MengineServiceInvalidInitializeException e, @NonNull Map attributes) { + public void invalidInitialize(@NonNull MengineServiceInvalidInitializeException e, @NonNull Map attributes) { MengineLog.logException(TAG, e, attributes); m_invalidInitialize = true; diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java index e0a687fd80..ebee6cea6d 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; +import java.util.Map; import java.util.concurrent.CountDownLatch; public class MengineMain implements Runnable { @@ -70,7 +71,11 @@ public void run() { } if (MengineNative.AndroidMain_main(m_nativeApplication) == false) { - MengineLog.logInfo(TAG, "main finish with failed" ); + if (MengineActivity.INSTANCE == null) { + MengineApplication.INSTANCE.invalidInitialize(new MengineServiceInvalidInitializeException("main finish with failed"), Map.of()); + } else { + MengineActivity.INSTANCE.finishWithAlertDialog("main finish with failed"); + } return; } diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java index 3c45f6a177..b94ff5c7a3 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java @@ -50,7 +50,6 @@ public class MengineNative { public static native void AndroidPlatform_trimMemory(int level); public static native void AndroidPlatform_changeLocale(String locale); - public static native void AndroidEnv_nativeDebugBreak(); public static native void AndroidEnv_setMengineAndroidClassLoaderJNI(ClassLoader cl); public static native void AndroidEnv_removeMengineAndroidClassLoaderJNI(); public static native boolean AndroidEnv_isMasterRelease(); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUI.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUI.java index a60b0b0527..5eb6b50d40 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUI.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUI.java @@ -368,8 +368,6 @@ public static void finishActivityWithAlertDialog(@NonNull MengineActivity activi MengineLog.logError(TAG, format, args); - MengineUtils.debugBreak(); - MengineUI.showOkAlertDialog(activity, () -> { activity.finishAndRemoveTask(); }, title, format, args); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java index 3b006355fd..a1ac2e0b00 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java @@ -970,14 +970,6 @@ public static boolean isDebuggerConnected() { return android.os.Debug.isDebuggerConnected(); } - public static void debugBreak() { - if (android.os.Debug.isDebuggerConnected() == false) { - return; - } - - MengineNative.AndroidEnv_nativeDebugBreak(); - } - public static boolean isAppInForeground(Context context) { ActivityManager activityManager = context.getSystemService(ActivityManager.class); @@ -1021,8 +1013,6 @@ public static void printCurrentStackTrace() { } public static void throwRuntimeException(String message, Throwable throwable) { - MengineUtils.debugBreak(); - throw new RuntimeException(message, throwable); } diff --git a/src/Environment/Android/AndroidEnv.cpp b/src/Environment/Android/AndroidEnv.cpp index 1cee862bff..4ef27d7c92 100644 --- a/src/Environment/Android/AndroidEnv.cpp +++ b/src/Environment/Android/AndroidEnv.cpp @@ -18,21 +18,6 @@ static jobject g_jobject_MengineClassLoader = nullptr; extern "C" { - ////////////////////////////////////////////////////////////////////////// - JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidEnv_1nativeDebugBreak )( JNIEnv *, jclass cls ) - { - Mengine::MengineJNIEnvThread * env = Mengine::Mengine_JNI_GetEnvThread(); - - jclass jclass_MengineUtils = Mengine::Mengine_JNI_LoadClass( env, "org/Mengine/Base/MengineUtils" ); - - jmethodID jmethodIdPrintCurrentStackTrace = Mengine::Mengine_JNI_GetStaticMethodID( env, jclass_MengineUtils, "printCurrentStackTrace", "()V" ); - - Mengine::Mengine_JNI_CallStaticVoidMethod( env, jclass_MengineUtils, jmethodIdPrintCurrentStackTrace ); - - Mengine::Mengine_JNI_DeleteLocalRef( env, jclass_MengineUtils ); - - ::raise( SIGTRAP ); - } ////////////////////////////////////////////////////////////////////////// JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidEnv_1setMengineAndroidClassLoaderJNI )( JNIEnv * env, jclass cls, jobject cl ) { From 282f0176c66147f94f33bc6307764ec731cc6dca Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 4 Sep 2025 00:02:33 +0300 Subject: [PATCH 012/169] rework Mengine_JNI_GetEnv --- .../java/org/Mengine/Base/MengineMain.java | 10 +- .../Android/AndroidActivityHelper.cpp | 30 +- .../Android/AndroidActivityHelper.h | 20 +- .../Android/AndroidApplicationHelper.cpp | 10 +- .../Android/AndroidApplicationHelper.h | 10 +- .../Android/AndroidAssetService.cpp | 4 +- src/Environment/Android/AndroidEnv.cpp | 605 +++++++----------- src/Environment/Android/AndroidEnv.h | 299 ++++----- .../Android/AndroidEnvironmentService.cpp | 8 +- .../Android/AndroidFragmentHelper.cpp | 10 +- .../Android/AndroidFragmentHelper.h | 10 +- src/Environment/Android/AndroidHelper.cpp | 118 ++-- src/Environment/Android/AndroidHelper.h | 104 +-- .../Android/AndroidKernelService.cpp | 26 +- .../Android/AndroidKernelService.h | 4 +- .../Android/AndroidKernelServiceInterface.h | 4 +- src/Environment/Android/AndroidLogger.cpp | 4 +- .../Android/AndroidPluginCallbackInterface.h | 2 +- .../Android/ConstStringHolderJString.cpp | 4 +- .../Android/ConstStringHolderJString.h | 4 +- .../AndroidAnalyticsEventProvider.cpp | 6 +- .../AndroidPlatformService.cpp | 34 +- .../AndroidPlatform/AndroidProxyLogger.cpp | 2 +- .../AndroidNativePythonCallback.cpp | 6 +- .../AndroidNativePythonCallback.h | 2 +- .../AndroidNativePythonHelper.cpp | 24 +- .../AndroidNativePythonHelper.h | 8 +- .../AndroidNativePythonService.cpp | 20 +- .../AndroidNativePythonService.h | 2 +- .../PythonAndroidPluginCallback.cpp | 2 +- .../PythonAndroidPluginCallback.h | 2 +- .../AndroidHttpSystem/AndroidHttpRequest.cpp | 2 +- .../AndroidHttpSystem/AndroidHttpRequest.h | 2 +- .../AndroidHttpRequestDeleteMessage.cpp | 2 +- .../AndroidHttpRequestDeleteMessage.h | 2 +- .../AndroidHttpRequestGetAsset.cpp | 2 +- .../AndroidHttpRequestGetAsset.h | 2 +- .../AndroidHttpRequestGetMessage.cpp | 2 +- .../AndroidHttpRequestGetMessage.h | 2 +- .../AndroidHttpRequestHeaderData.cpp | 2 +- .../AndroidHttpRequestHeaderData.h | 2 +- .../AndroidHttpRequestPing.cpp | 2 +- .../AndroidHttpRequestPing.h | 2 +- .../AndroidHttpRequestPostMessage.cpp | 2 +- .../AndroidHttpRequestPostMessage.h | 2 +- 45 files changed, 643 insertions(+), 779 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java index ebee6cea6d..6d4513ed3f 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java @@ -71,10 +71,14 @@ public void run() { } if (MengineNative.AndroidMain_main(m_nativeApplication) == false) { - if (MengineActivity.INSTANCE == null) { - MengineApplication.INSTANCE.invalidInitialize(new MengineServiceInvalidInitializeException("main finish with failed"), Map.of()); + if (m_thread.isInterrupted() == false) { + if (MengineActivity.INSTANCE == null) { + MengineApplication.INSTANCE.invalidInitialize(new MengineServiceInvalidInitializeException("main finish with failed"), Map.of()); + } else { + MengineActivity.INSTANCE.finishWithAlertDialog("main finish with failed"); + } } else { - MengineActivity.INSTANCE.finishWithAlertDialog("main finish with failed"); + MengineLog.logInfo(TAG, "main finish with failed"); } return; diff --git a/src/Environment/Android/AndroidActivityHelper.cpp b/src/Environment/Android/AndroidActivityHelper.cpp index 36b95f2126..3f7a7d585d 100644 --- a/src/Environment/Android/AndroidActivityHelper.cpp +++ b/src/Environment/Android/AndroidActivityHelper.cpp @@ -13,7 +13,7 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + void AndroidCallVoidActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -42,7 +42,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jobject_MengineActivity ); } ////////////////////////////////////////////////////////////////////////// - jobject AndroidCallObjectActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jobject AndroidCallObjectActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -73,7 +73,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jboolean AndroidCallBooleanActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jboolean AndroidCallBooleanActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -104,7 +104,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jint AndroidCallIntActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jint AndroidCallIntActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -135,7 +135,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jlong AndroidCallLongActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jlong AndroidCallLongActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -166,7 +166,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + void AndroidCallVoidActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -191,9 +191,11 @@ namespace Mengine MENGINE_VA_LIST_END( args ); Helper::AndroidEnvExceptionCheck( _jenv ); + + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); } ////////////////////////////////////////////////////////////////////////// - jobject AndroidCallObjectActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jobject AndroidCallObjectActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -219,10 +221,12 @@ namespace Mengine Helper::AndroidEnvExceptionCheck( _jenv ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return jresult; } ////////////////////////////////////////////////////////////////////////// - jboolean AndroidCallBooleanActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jboolean AndroidCallBooleanActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -248,10 +252,12 @@ namespace Mengine Helper::AndroidEnvExceptionCheck( _jenv ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return jresult; } ////////////////////////////////////////////////////////////////////////// - jint AndroidCallIntActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jint AndroidCallIntActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -277,10 +283,12 @@ namespace Mengine Helper::AndroidEnvExceptionCheck( _jenv ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return jresult; } ////////////////////////////////////////////////////////////////////////// - jlong AndroidCallLongActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jlong AndroidCallLongActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodActivity( _jenv, _name, _signature ); @@ -306,6 +314,8 @@ namespace Mengine Helper::AndroidEnvExceptionCheck( _jenv ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return jresult; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Environment/Android/AndroidActivityHelper.h b/src/Environment/Android/AndroidActivityHelper.h index 7d51cc76b1..e97cc2dc27 100644 --- a/src/Environment/Android/AndroidActivityHelper.h +++ b/src/Environment/Android/AndroidActivityHelper.h @@ -9,17 +9,17 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - MENGINE_NODISCARD jobject AndroidCallObjectActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jboolean AndroidCallBooleanActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jint AndroidCallIntActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jlong AndroidCallLongActivityMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); + void AndroidCallVoidActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + MENGINE_NODISCARD jobject AndroidCallObjectActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jboolean AndroidCallBooleanActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jint AndroidCallIntActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jlong AndroidCallLongActivityMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - MENGINE_NODISCARD jobject AndroidCallObjectActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jboolean AndroidCallBooleanActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jint AndroidCallIntActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jlong AndroidCallLongActivityStaticMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); + void AndroidCallVoidActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + MENGINE_NODISCARD jobject AndroidCallObjectActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jboolean AndroidCallBooleanActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jint AndroidCallIntActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jlong AndroidCallLongActivityStaticMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); ////////////////////////////////////////////////////////////////////////// } } diff --git a/src/Environment/Android/AndroidApplicationHelper.cpp b/src/Environment/Android/AndroidApplicationHelper.cpp index 7b5568f601..586eb63a8d 100644 --- a/src/Environment/Android/AndroidApplicationHelper.cpp +++ b/src/Environment/Android/AndroidApplicationHelper.cpp @@ -13,7 +13,7 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + void AndroidCallVoidApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodApplication( _jenv, _name, _signature ); @@ -42,7 +42,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jobject_MengineApplication ); } ////////////////////////////////////////////////////////////////////////// - jobject AndroidCallObjectApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jobject AndroidCallObjectApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodApplication( _jenv, _name, _signature ); @@ -73,7 +73,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jboolean AndroidCallBooleanApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jboolean AndroidCallBooleanApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodApplication( _jenv, _name, _signature ); @@ -104,7 +104,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jint AndroidCallIntApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jint AndroidCallIntApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodApplication( _jenv, _name, _signature ); @@ -135,7 +135,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jlong AndroidCallLongApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ) + jlong AndroidCallLongApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ) { jmethodID jmethodId = Mengine_JNI_GetMethodApplication( _jenv, _name, _signature ); diff --git a/src/Environment/Android/AndroidApplicationHelper.h b/src/Environment/Android/AndroidApplicationHelper.h index e4ba25f346..e7d9d8eadf 100644 --- a/src/Environment/Android/AndroidApplicationHelper.h +++ b/src/Environment/Android/AndroidApplicationHelper.h @@ -9,11 +9,11 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - MENGINE_NODISCARD jobject AndroidCallObjectApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jboolean AndroidCallBooleanApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jint AndroidCallIntApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); - jlong AndroidCallLongApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _signature, ... ); + void AndroidCallVoidApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + MENGINE_NODISCARD jobject AndroidCallObjectApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jboolean AndroidCallBooleanApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jint AndroidCallIntApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); + jlong AndroidCallLongApplicationMethod( JNIEnv * _jenv, const Char * _name, const Char * _signature, ... ); ////////////////////////////////////////////////////////////////////////// } } diff --git a/src/Environment/Android/AndroidAssetService.cpp b/src/Environment/Android/AndroidAssetService.cpp index 40ac4ab116..1d5fd6b4e7 100644 --- a/src/Environment/Android/AndroidAssetService.cpp +++ b/src/Environment/Android/AndroidAssetService.cpp @@ -24,7 +24,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidAssetService::_initializeService() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -58,7 +58,7 @@ namespace Mengine { if(m_jAssetManagerGlobalRef != nullptr ) { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Environment/Android/AndroidEnv.cpp b/src/Environment/Android/AndroidEnv.cpp index 4ef27d7c92..b65d39acf9 100644 --- a/src/Environment/Android/AndroidEnv.cpp +++ b/src/Environment/Android/AndroidEnv.cpp @@ -146,47 +146,12 @@ namespace Mengine g_androidEnvJavaVM->DetachCurrentThread(); } ////////////////////////////////////////////////////////////////////////// - static int Mengine_JNI_SetEnv( JNIEnv * _env, MengineJNIEnvThread ** _envThread ) + static int Mengine_JNI_SetEnv( JNIEnv * _env ) { MENGINE_ASSERTION_FATAL( g_androidEnvThreadKey != 0, "android ENV thread key not initialized" ); MENGINE_ASSERTION_FATAL( pthread_getspecific( g_androidEnvThreadKey ) == nullptr, "ENV thread key already set" ); - MengineJNIEnvThread * envThread = (MengineJNIEnvThread *)StdLib::malloc( sizeof(MengineJNIEnvThread) ); - - if( envThread == nullptr ) - { - __android_log_print( ANDROID_LOG_ERROR, "Mengine", "[ERROR] JNI_SetEnv failed to allocate memory for MengineJNIEnvThread" ); - - return JNI_FALSE; - } - - envThread->env = _env; - envThread->jclass_Boolean = _env->FindClass( "java/lang/Boolean" ); - envThread->jclass_Character = _env->FindClass( "java/lang/Character" ); - envThread->jclass_Integer = _env->FindClass( "java/lang/Integer" ); - envThread->jclass_Long = _env->FindClass( "java/lang/Long" ); - envThread->jclass_Float = _env->FindClass( "java/lang/Float" ); - envThread->jclass_Double = _env->FindClass( "java/lang/Double" ); - envThread->jclass_String = _env->FindClass( "java/lang/String" ); - envThread->jclass_Exception = _env->FindClass( "java/lang/Exception" ); - envThread->jclass_List = _env->FindClass( "java/util/List" ); - envThread->jclass_Map = _env->FindClass( "java/util/Map" ); - envThread->jclass_Set = _env->FindClass( "java/util/Set" ); - envThread->jclass_ArrayList = _env->FindClass( "java/util/ArrayList" ); - envThread->jclass_HashMap = _env->FindClass( "java/util/HashMap" ); - envThread->jclass_MapEntry = _env->FindClass( "java/util/Map$Entry" ); - envThread->jclass_Iterator = _env->FindClass( "java/util/Iterator" ); - envThread->jclass_Rect = _env->FindClass( "android/graphics/Rect" ); - envThread->jclass_JSONObject = _env->FindClass( "org/json/JSONObject" ); - envThread->jclass_JSONArray = _env->FindClass( "org/json/JSONArray" ); - envThread->jclass_Class = _env->FindClass( "java/lang/Class" ); - envThread->jclass_ClassLoader = _env->FindClass( "java/lang/ClassLoader" ); - - envThread->jclass_MengineCallback = Mengine_JNI_LoadClass( envThread, "org/Mengine/Base/MengineCallback" ); - envThread->jclass_MengineApplication = Mengine_JNI_LoadClass( envThread, "org/Mengine/Base/MengineApplication" ); - envThread->jclass_MengineActivity = Mengine_JNI_LoadClass( envThread, "org/Mengine/Base/MengineActivity" ); - - int status = ::pthread_setspecific( g_androidEnvThreadKey, (void *)envThread ); + int status = ::pthread_setspecific( g_androidEnvThreadKey, (void *)_env ); if( status != JNI_OK ) { @@ -197,11 +162,6 @@ namespace Mengine __android_log_print( ANDROID_LOG_INFO, "Mengine", "JNI_SetEnv set JNIEnv for current thread" ); - if( _envThread != nullptr ) - { - *_envThread = envThread; - } - return JNI_TRUE; } ////////////////////////////////////////////////////////////////////////// @@ -220,7 +180,7 @@ namespace Mengine __android_log_print( ANDROID_LOG_INFO, "Mengine", "JNI_SetEnv created pthread key for JNIEnv" ); - if( Mengine_JNI_SetEnv( _env, nullptr ) == JNI_FALSE ) + if( Mengine_JNI_SetEnv( _env ) == JNI_FALSE ) { return JNI_FALSE; } @@ -228,15 +188,15 @@ namespace Mengine return JNI_TRUE; } ////////////////////////////////////////////////////////////////////////// - MengineJNIEnvThread * Mengine_JNI_GetEnvThread() + JNIEnv * Mengine_JNI_GetEnv() { MENGINE_ASSERTION_FATAL( g_androidEnvThreadKey != 0, "android ENV thread key not initialized" ); - MengineJNIEnvThread * envThread = (MengineJNIEnvThread *)::pthread_getspecific(g_androidEnvThreadKey ); + JNIEnv * jenv = (JNIEnv *)::pthread_getspecific(g_androidEnvThreadKey ); - if( envThread != nullptr ) + if( jenv != nullptr ) { - return envThread; + return jenv; } if( g_androidEnvJavaVM == nullptr ) @@ -246,8 +206,8 @@ namespace Mengine return nullptr; } - JNIEnv * new_env; - jint status = g_androidEnvJavaVM->AttachCurrentThread( &new_env, nullptr ); + JNIEnv * new_jenv; + jint status = g_androidEnvJavaVM->AttachCurrentThread( &new_jenv, nullptr ); if( status != JNI_OK ) { @@ -256,8 +216,7 @@ namespace Mengine return nullptr; } - MengineJNIEnvThread * new_envThread; - if( Mengine_JNI_SetEnv( new_env, &new_envThread ) == JNI_FALSE ) + if( Mengine_JNI_SetEnv( new_jenv ) == JNI_FALSE ) { __android_log_print( ANDROID_LOG_ERROR, "Mengine", "[ERROR] JNI_GetEnv failed to set environment" ); @@ -266,7 +225,7 @@ namespace Mengine return nullptr; } - return new_envThread; + return new_jenv; } ////////////////////////////////////////////////////////////////////////// int Mengine_JNI_SetupThread() @@ -288,7 +247,7 @@ namespace Mengine return JNI_FALSE; } - if( Mengine_JNI_SetEnv( env, nullptr ) == JNI_FALSE ) + if( Mengine_JNI_SetEnv( env ) == JNI_FALSE ) { __android_log_print( ANDROID_LOG_ERROR, "Mengine", "[ERROR] JNI_SetupThread failed to set environment" ); @@ -302,355 +261,302 @@ namespace Mengine return JNI_TRUE; } ////////////////////////////////////////////////////////////////////////// - static JNIEnv * Mengine_JNI_GetEnv( MengineJNIEnvThread * _jenv ) + jboolean Mengine_JNI_IsInstanceOf( JNIEnv * _jenv, jobject _jobject, jclass _jclass ) { - JNIEnv * env = _jenv->env; - - return env; - } - ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_IsInstanceOf( MengineJNIEnvThread * _jenv, jobject _jobject, jclass _jclass ) - { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jboolean result = env->IsInstanceOf( _jobject, _jclass ); + jboolean result = _jenv->IsInstanceOf( _jobject, _jclass ); return result; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassBoolean( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassBoolean( JNIEnv * _jenv ) { - jclass jclass_Boolean = _jenv->jclass_Boolean; + jclass jclass_Boolean = _jenv->FindClass( "java/lang/Boolean" ); return jclass_Boolean; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassCharacter( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassCharacter( JNIEnv * _jenv ) { - jclass jclass_Character = _jenv->jclass_Character; + jclass jclass_Character = _jenv->FindClass( "java/lang/Character" ); return jclass_Character; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassInteger( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassInteger( JNIEnv * _jenv ) { - jclass jclass_Integer = _jenv->jclass_Integer; + jclass jclass_Integer = _jenv->FindClass( "java/lang/Integer" ); return jclass_Integer; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassLong( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassLong( JNIEnv * _jenv ) { - jclass jclass_Long = _jenv->jclass_Long; + jclass jclass_Long = _jenv->FindClass( "java/lang/Long" ); return jclass_Long; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassFloat( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassFloat( JNIEnv * _jenv ) { - jclass jclass_Float = _jenv->jclass_Float; + jclass jclass_Float = _jenv->FindClass( "java/lang/Float" ); return jclass_Float; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassDouble( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassDouble( JNIEnv * _jenv ) { - jclass jclass_Double = _jenv->jclass_Double; + jclass jclass_Double = _jenv->FindClass( "java/lang/Double" ); return jclass_Double; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassString( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassString( JNIEnv * _jenv ) { - jclass jclass_String = _jenv->jclass_String; + jclass jclass_String = _jenv->FindClass( "java/lang/String" ); return jclass_String; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassException( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassException( JNIEnv * _jenv ) { - jclass jclass_Exception = _jenv->jclass_Exception; + jclass jclass_Exception = _jenv->FindClass( "java/lang/Exception" ); return jclass_Exception; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassList( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassList( JNIEnv * _jenv ) { - jclass jclass_List = _jenv->jclass_List; + jclass jclass_List = _jenv->FindClass( "java/util/List" ); return jclass_List; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassMap( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassMap( JNIEnv * _jenv ) { - jclass jclass_Map = _jenv->jclass_Map; + jclass jclass_Map = _jenv->FindClass( "java/util/Map" ); return jclass_Map; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassSet( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassSet( JNIEnv * _jenv ) { - jclass jclass_Set = _jenv->jclass_Set; + jclass jclass_Set = _jenv->FindClass( "java/util/Set" ); return jclass_Set; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassArrayList( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassArrayList( JNIEnv * _jenv ) { - jclass jclass_ArrayList = _jenv->jclass_ArrayList; + jclass jclass_ArrayList = _jenv->FindClass( "java/util/ArrayList" ); return jclass_ArrayList; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassHashMap( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassHashMap( JNIEnv * _jenv ) { - jclass jclass_HashMap = _jenv->jclass_HashMap; + jclass jclass_HashMap = _jenv->FindClass( "java/util/HashMap" ); return jclass_HashMap; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassMapEntry( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassMapEntry( JNIEnv * _jenv ) { - jclass jclass_MapEntry = _jenv->jclass_MapEntry; + jclass jclass_MapEntry = _jenv->FindClass( "java/util/Map$Entry" ); return jclass_MapEntry; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassIterator( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassIterator( JNIEnv * _jenv ) { - jclass jclass_Iterator = _jenv->jclass_Iterator; + jclass jclass_Iterator = _jenv->FindClass( "java/util/Iterator" ); return jclass_Iterator; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassRect( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassRect( JNIEnv * _jenv ) { - jclass jclass_Rect = _jenv->jclass_Rect; + jclass jclass_Rect = _jenv->FindClass( "android/graphics/Rect" ); return jclass_Rect; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassJSONObject( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassJSONObject( JNIEnv * _jenv ) { - jclass jclass_JSONObject = _jenv->jclass_JSONObject; + jclass jclass_JSONObject = _jenv->FindClass( "org/json/JSONObject" ); return jclass_JSONObject; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassJSONArray( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassJSONArray( JNIEnv * _jenv ) { - jclass jclass_JSONArray = _jenv->jclass_JSONArray; + jclass jclass_JSONArray = _jenv->FindClass( "org/json/JSONArray" ); return jclass_JSONArray; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassClass( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassClass( JNIEnv * _jenv ) { - jclass jclass_Class = _jenv->jclass_Class; + jclass jclass_Class = _jenv->FindClass( "java/lang/Class" ); return jclass_Class; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassClassLoader( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassClassLoader( JNIEnv * _jenv ) { - jclass jclass_ClassLoader = _jenv->jclass_ClassLoader; + jclass jclass_ClassLoader = _jenv->FindClass( "java/lang/ClassLoader" ); return jclass_ClassLoader; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetObjectClass( MengineJNIEnvThread * _jenv, jobject _jobject ) + jclass Mengine_JNI_GetObjectClass( JNIEnv * _jenv, jobject _jobject ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jclass jclass_Object = env->GetObjectClass( _jobject ); + jclass jclass_Object = _jenv->GetObjectClass( _jobject ); return jclass_Object; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_DeleteLocalRef( MengineJNIEnvThread * _jenv, jobject _jobject ) + void Mengine_JNI_DeleteLocalRef( JNIEnv * _jenv, jobject _jobject ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->DeleteLocalRef( _jobject ); + _jenv->DeleteLocalRef( _jobject ); } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_NewGlobalRef( MengineJNIEnvThread * _jenv, jobject _jobject ) + jobject Mengine_JNI_NewGlobalRef( JNIEnv * _jenv, jobject _jobject ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobjectGlobal = env->NewGlobalRef( _jobject ); + jobject jobjectGlobal = _jenv->NewGlobalRef( _jobject ); return jobjectGlobal; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_DeleteGlobalRef( MengineJNIEnvThread * _jenv, jobject _jobject ) + void Mengine_JNI_DeleteGlobalRef( JNIEnv * _jenv, jobject _jobject ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->DeleteGlobalRef( _jobject ); + _jenv->DeleteGlobalRef( _jobject ); } ////////////////////////////////////////////////////////////////////////// - int Mengine_JNI_ExceptionCheck( MengineJNIEnvThread * _jenv ) + int Mengine_JNI_ExceptionCheck( JNIEnv * _jenv ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - int result = env->ExceptionCheck(); + int result = _jenv->ExceptionCheck(); return result; } ////////////////////////////////////////////////////////////////////////// - jthrowable Mengine_JNI_ExceptionOccurred( MengineJNIEnvThread * _jenv ) + jthrowable Mengine_JNI_ExceptionOccurred( JNIEnv * _jenv ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jthrowable jThrowable = env->ExceptionOccurred(); + jthrowable jThrowable = _jenv->ExceptionOccurred(); return jThrowable; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_ExceptionClear( MengineJNIEnvThread * _jenv ) + void Mengine_JNI_ExceptionClear( JNIEnv * _jenv ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->ExceptionClear(); + _jenv->ExceptionClear(); } ////////////////////////////////////////////////////////////////////////// - int Mengine_JNI_PushLocalFrame( MengineJNIEnvThread * _jenv, jint _capacity ) + int Mengine_JNI_PushLocalFrame( JNIEnv * _jenv, jint _capacity ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - int status = env->PushLocalFrame( _capacity ); + int status = _jenv->PushLocalFrame( _capacity ); return status; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_PopLocalFrame( MengineJNIEnvThread * _jenv, jobject _result ) + jobject Mengine_JNI_PopLocalFrame( JNIEnv * _jenv, jobject _result ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobjectResult = env->PopLocalFrame( _result ); + jobject jobjectResult = _jenv->PopLocalFrame( _result ); return jobjectResult; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_FindClass( MengineJNIEnvThread * _jenv, const Char * _name ) + jclass Mengine_JNI_FindClass( JNIEnv * _jenv, const Char * _name ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jclass jclass_FindClass = env->FindClass( _name ); + jclass jclass_FindClass = _jenv->FindClass( _name ); return jclass_FindClass; } ////////////////////////////////////////////////////////////////////////// - jmethodID Mengine_JNI_GetMethodID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) + jmethodID Mengine_JNI_GetMethodID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jmethodID jmethodID = env->GetMethodID( _jclass, _name, _signature ); + jmethodID jmethodID = _jenv->GetMethodID( _jclass, _name, _signature ); return jmethodID; } ////////////////////////////////////////////////////////////////////////// - jmethodID Mengine_JNI_GetStaticMethodID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) + jmethodID Mengine_JNI_GetStaticMethodID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jmethodID jmethodID = env->GetStaticMethodID( _jclass, _name, _signature ); + jmethodID jmethodID = _jenv->GetStaticMethodID( _jclass, _name, _signature ); return jmethodID; } ////////////////////////////////////////////////////////////////////////// - jfieldID Mengine_JNI_GetFieldID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) + jfieldID Mengine_JNI_GetFieldID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jfieldID jfieldID = env->GetFieldID( _jclass, _name, _signature ); + jfieldID jfieldID = _jenv->GetFieldID( _jclass, _name, _signature ); return jfieldID; } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_GetIntField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jint Mengine_JNI_GetIntField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jint jintField = env->GetIntField( _jobject, _fieldID ); + jint jintField = _jenv->GetIntField( _jobject, _fieldID ); return jintField; } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_GetBooleanField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jboolean Mengine_JNI_GetBooleanField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jboolean jbooleanField = env->GetBooleanField( _jobject, _fieldID ); + jboolean jbooleanField = _jenv->GetBooleanField( _jobject, _fieldID ); return jbooleanField; } ////////////////////////////////////////////////////////////////////////// - jchar Mengine_JNI_GetCharField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jchar Mengine_JNI_GetCharField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jchar jcharField = env->GetCharField( _jobject, _fieldID ); + jchar jcharField = _jenv->GetCharField( _jobject, _fieldID ); return jcharField; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_GetLongField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jlong Mengine_JNI_GetLongField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jlong jlongField = env->GetLongField( _jobject, _fieldID ); + jlong jlongField = _jenv->GetLongField( _jobject, _fieldID ); return jlongField; } ////////////////////////////////////////////////////////////////////////// - jfloat Mengine_JNI_GetFloatField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jfloat Mengine_JNI_GetFloatField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jfloat jfloatField = env->GetFloatField( _jobject, _fieldID ); + jfloat jfloatField = _jenv->GetFloatField( _jobject, _fieldID ); return jfloatField; } ////////////////////////////////////////////////////////////////////////// - jdouble Mengine_JNI_GetDoubleField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jdouble Mengine_JNI_GetDoubleField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jdouble jdoubleField = env->GetDoubleField( _jobject, _fieldID ); + jdouble jdoubleField = _jenv->GetDoubleField( _jobject, _fieldID ); return jdoubleField; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_GetObjectField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ) + jobject Mengine_JNI_GetObjectField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobjectField = env->GetObjectField( _jobject, _fieldID ); + jobject jobjectField = _jenv->GetObjectField( _jobject, _fieldID ); return jobjectField; } ////////////////////////////////////////////////////////////////////////// - jfieldID Mengine_JNI_GetStaticFieldID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) + jfieldID Mengine_JNI_GetStaticFieldID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jfieldID jfieldID = env->GetStaticFieldID( _jclass, _name, _signature ); + jfieldID jfieldID = _jenv->GetStaticFieldID( _jclass, _name, _signature ); return jfieldID; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_GetStaticObjectField( MengineJNIEnvThread * _jenv, jclass _jclass, jfieldID _fieldID ) + jobject Mengine_JNI_GetStaticObjectField( JNIEnv * _jenv, jclass _jclass, jfieldID _fieldID ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobjectField = env->GetStaticObjectField( _jclass, _fieldID ); + jobject jobjectField = _jenv->GetStaticObjectField( _jclass, _fieldID ); return jobjectField; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_CallVoidMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + void Mengine_JNI_CallVoidMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -660,21 +566,17 @@ namespace Mengine MENGINE_VA_LIST_END( args ); } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_CallVoidMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + void Mengine_JNI_CallVoidMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->CallVoidMethodV( _jobject, _methodID, _args ); + _jenv->CallVoidMethodV( _jobject, _methodID, _args ); } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_CallVoidMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + void Mengine_JNI_CallVoidMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->CallVoidMethodA( _jobject, _methodID, _args ); + _jenv->CallVoidMethodA( _jobject, _methodID, _args ); } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_CallBooleanMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jboolean Mengine_JNI_CallBooleanMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -686,25 +588,21 @@ namespace Mengine return jboolean_result; } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_CallBooleanMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jboolean Mengine_JNI_CallBooleanMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jboolean jboolean_result = env->CallBooleanMethodV( _jobject, _methodID, _args ); + jboolean jboolean_result = _jenv->CallBooleanMethodV( _jobject, _methodID, _args ); return jboolean_result; } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_CallBooleanMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jboolean Mengine_JNI_CallBooleanMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jboolean jboolean_result = env->CallBooleanMethodA( _jobject, _methodID, _args ); + jboolean jboolean_result = _jenv->CallBooleanMethodA( _jobject, _methodID, _args ); return jboolean_result; } ////////////////////////////////////////////////////////////////////////// - jchar Mengine_JNI_CallCharMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jchar Mengine_JNI_CallCharMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -716,25 +614,21 @@ namespace Mengine return jchar_result; } ////////////////////////////////////////////////////////////////////////// - jchar Mengine_JNI_CallCharMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jchar Mengine_JNI_CallCharMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jchar jchar_result = env->CallCharMethodV( _jobject, _methodID, _args ); + jchar jchar_result = _jenv->CallCharMethodV( _jobject, _methodID, _args ); return jchar_result; } ////////////////////////////////////////////////////////////////////////// - jchar Mengine_JNI_CallCharMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jchar Mengine_JNI_CallCharMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jchar jchar_result = env->CallCharMethodA( _jobject, _methodID, _args ); + jchar jchar_result = _jenv->CallCharMethodA( _jobject, _methodID, _args ); return jchar_result; } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_CallIntMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jint Mengine_JNI_CallIntMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -746,25 +640,21 @@ namespace Mengine return jint_result; } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_CallIntMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jint Mengine_JNI_CallIntMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jint jint_result = env->CallIntMethodV( _jobject, _methodID, _args ); + jint jint_result = _jenv->CallIntMethodV( _jobject, _methodID, _args ); return jint_result; } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_CallIntMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jint Mengine_JNI_CallIntMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jint jint_result = env->CallIntMethodA( _jobject, _methodID, _args ); + jint jint_result = _jenv->CallIntMethodA( _jobject, _methodID, _args ); return jint_result; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_CallLongMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jlong Mengine_JNI_CallLongMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -776,25 +666,21 @@ namespace Mengine return jlong_result; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_CallLongMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jlong Mengine_JNI_CallLongMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jlong jlong_result = env->CallLongMethodV( _jobject, _methodID, _args ); + jlong jlong_result = _jenv->CallLongMethodV( _jobject, _methodID, _args ); return jlong_result; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_CallLongMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jlong Mengine_JNI_CallLongMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jlong jlong_result = env->CallLongMethodA( _jobject, _methodID, _args ); + jlong jlong_result = _jenv->CallLongMethodA( _jobject, _methodID, _args ); return jlong_result; } ////////////////////////////////////////////////////////////////////////// - jfloat Mengine_JNI_CallFloatMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jfloat Mengine_JNI_CallFloatMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -806,25 +692,21 @@ namespace Mengine return jfloat_result; } ////////////////////////////////////////////////////////////////////////// - jfloat Mengine_JNI_CallFloatMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jfloat Mengine_JNI_CallFloatMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jfloat jfloat_result = env->CallFloatMethodV( _jobject, _methodID, _args ); + jfloat jfloat_result = _jenv->CallFloatMethodV( _jobject, _methodID, _args ); return jfloat_result; } ////////////////////////////////////////////////////////////////////////// - jfloat Mengine_JNI_CallFloatMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jfloat Mengine_JNI_CallFloatMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jfloat jfloat_result = env->CallFloatMethodA( _jobject, _methodID, _args ); + jfloat jfloat_result = _jenv->CallFloatMethodA( _jobject, _methodID, _args ); return jfloat_result; } ////////////////////////////////////////////////////////////////////////// - jdouble Mengine_JNI_CallDoubleMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jdouble Mengine_JNI_CallDoubleMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -836,25 +718,21 @@ namespace Mengine return jdouble_result; } ////////////////////////////////////////////////////////////////////////// - jdouble Mengine_JNI_CallDoubleMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jdouble Mengine_JNI_CallDoubleMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jdouble jdouble_result = env->CallDoubleMethodV( _jobject, _methodID, _args ); + jdouble jdouble_result = _jenv->CallDoubleMethodV( _jobject, _methodID, _args ); return jdouble_result; } ////////////////////////////////////////////////////////////////////////// - jdouble Mengine_JNI_CallDoubleMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jdouble Mengine_JNI_CallDoubleMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jdouble jdouble_result = env->CallDoubleMethodA( _jobject, _methodID, _args ); + jdouble jdouble_result = _jenv->CallDoubleMethodA( _jobject, _methodID, _args ); return jdouble_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_CallObjectMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ) + jobject Mengine_JNI_CallObjectMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -866,25 +744,21 @@ namespace Mengine return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_CallObjectMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) + jobject Mengine_JNI_CallObjectMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobject_result = env->CallObjectMethodV( _jobject, _methodID, _args ); + jobject jobject_result = _jenv->CallObjectMethodV( _jobject, _methodID, _args ); return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_CallObjectMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) + jobject Mengine_JNI_CallObjectMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobject_result = env->CallObjectMethodA( _jobject, _methodID, _args ); + jobject jobject_result = _jenv->CallObjectMethodA( _jobject, _methodID, _args ); return jobject_result; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_CallStaticVoidMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ) + void Mengine_JNI_CallStaticVoidMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -894,21 +768,17 @@ namespace Mengine MENGINE_VA_LIST_END( args ); } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_CallStaticVoidMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) + void Mengine_JNI_CallStaticVoidMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->CallStaticVoidMethodV( _jclass, _methodID, _args ); + _jenv->CallStaticVoidMethodV( _jclass, _methodID, _args ); } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_CallStaticVoidMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) + void Mengine_JNI_CallStaticVoidMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->CallStaticVoidMethodA( _jclass, _methodID, _args ); + _jenv->CallStaticVoidMethodA( _jclass, _methodID, _args ); } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_CallStaticIntMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ) + jint Mengine_JNI_CallStaticIntMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -920,25 +790,21 @@ namespace Mengine return jint_result; } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_CallStaticIntMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) + jint Mengine_JNI_CallStaticIntMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jint jint_result = env->CallStaticIntMethodV( _jclass, _methodID, _args ); + jint jint_result = _jenv->CallStaticIntMethodV( _jclass, _methodID, _args ); return jint_result; } ////////////////////////////////////////////////////////////////////////// - jint Mengine_JNI_CallStaticIntMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) + jint Mengine_JNI_CallStaticIntMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jint jint_result = env->CallStaticIntMethodA( _jclass, _methodID, _args ); + jint jint_result = _jenv->CallStaticIntMethodA( _jclass, _methodID, _args ); return jint_result; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_CallStaticLongMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ) + jlong Mengine_JNI_CallStaticLongMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -950,25 +816,21 @@ namespace Mengine return jlong_result; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_CallStaticLongMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) + jlong Mengine_JNI_CallStaticLongMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jlong jlong_result = env->CallStaticLongMethodV( _jclass, _methodID, _args ); + jlong jlong_result = _jenv->CallStaticLongMethodV( _jclass, _methodID, _args ); return jlong_result; } ////////////////////////////////////////////////////////////////////////// - jlong Mengine_JNI_CallStaticLongMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) + jlong Mengine_JNI_CallStaticLongMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jlong jlong_result = env->CallStaticLongMethodA( _jclass, _methodID, _args ); + jlong jlong_result = _jenv->CallStaticLongMethodA( _jclass, _methodID, _args ); return jlong_result; } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_CallStaticBooleanMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ) + jboolean Mengine_JNI_CallStaticBooleanMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -980,7 +842,7 @@ namespace Mengine return jboolean_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_CallStaticObjectMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ) + jobject Mengine_JNI_CallStaticObjectMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -992,43 +854,35 @@ namespace Mengine return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_CallStaticBooleanMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) + jboolean Mengine_JNI_CallStaticBooleanMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jboolean jboolean_result = env->CallStaticBooleanMethodV( _jclass, _methodID, _args ); + jboolean jboolean_result = _jenv->CallStaticBooleanMethodV( _jclass, _methodID, _args ); return jboolean_result; } ////////////////////////////////////////////////////////////////////////// - jboolean Mengine_JNI_CallStaticBooleanMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) + jboolean Mengine_JNI_CallStaticBooleanMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jboolean jboolean_result = env->CallStaticBooleanMethodA( _jclass, _methodID, _args ); + jboolean jboolean_result = _jenv->CallStaticBooleanMethodA( _jclass, _methodID, _args ); return jboolean_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_CallStaticObjectMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) + jobject Mengine_JNI_CallStaticObjectMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobject_result = env->CallStaticObjectMethodV( _jclass, _methodID, _args ); + jobject jobject_result = _jenv->CallStaticObjectMethodV( _jclass, _methodID, _args ); return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_CallStaticObjectMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) + jobject Mengine_JNI_CallStaticObjectMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobject_result = env->CallStaticObjectMethodA( _jclass, _methodID, _args ); + jobject jobject_result = _jenv->CallStaticObjectMethodA( _jclass, _methodID, _args ); return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_NewObject( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ) + jobject Mengine_JNI_NewObject( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ) { MENGINE_VA_LIST_TYPE args; MENGINE_VA_LIST_START( args, _methodID ); @@ -1040,132 +894,106 @@ namespace Mengine return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_NewObjectV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) + jobject Mengine_JNI_NewObjectV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobject_result = env->NewObjectV( _jclass, _methodID, _args ); + jobject jobject_result = _jenv->NewObjectV( _jclass, _methodID, _args ); return jobject_result; } ////////////////////////////////////////////////////////////////////////// - jstring Mengine_JNI_NewStringUTF( MengineJNIEnvThread * _jenv, const Char * _str ) + jstring Mengine_JNI_NewStringUTF( JNIEnv * _jenv, const Char * _str ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jstring jstr = env->NewStringUTF( _str ); + jstring jstr = _jenv->NewStringUTF( _str ); return jstr; } ////////////////////////////////////////////////////////////////////////// - const Char * Mengine_JNI_GetStringUTFChars( MengineJNIEnvThread * _jenv, jstring _jstring, jboolean * const _isCopy ) + const Char * Mengine_JNI_GetStringUTFChars( JNIEnv * _jenv, jstring _jstring, jboolean * const _isCopy ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - const Char * str = env->GetStringUTFChars( _jstring, _isCopy ); + const Char * str = _jenv->GetStringUTFChars( _jstring, _isCopy ); return str; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_ReleaseStringUTFChars( MengineJNIEnvThread * _jenv, jstring _jstring, const Char * _cstr ) + void Mengine_JNI_ReleaseStringUTFChars( JNIEnv * _jenv, jstring _jstring, const Char * _cstr ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->ReleaseStringUTFChars( _jstring, _cstr ); + _jenv->ReleaseStringUTFChars( _jstring, _cstr ); } ////////////////////////////////////////////////////////////////////////// - jsize Mengine_JNI_GetStringLength( MengineJNIEnvThread * _jenv, jstring _jstring ) + jsize Mengine_JNI_GetStringLength( JNIEnv * _jenv, jstring _jstring ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jsize length = env->GetStringLength( _jstring ); + jsize length = _jenv->GetStringLength( _jstring ); return length; } ////////////////////////////////////////////////////////////////////////// - jsize Mengine_JNI_GetArrayLength( MengineJNIEnvThread * _jenv, jobjectArray _jarray ) + jsize Mengine_JNI_GetArrayLength( JNIEnv * _jenv, jobjectArray _jarray ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jsize length = env->GetArrayLength( _jarray ); + jsize length = _jenv->GetArrayLength( _jarray ); return length; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_GetObjectArrayElement( MengineJNIEnvThread * _jenv, jobjectArray _jarray, jsize _index ) + jobject Mengine_JNI_GetObjectArrayElement( JNIEnv * _jenv, jobjectArray _jarray, jsize _index ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jobject_element = env->GetObjectArrayElement( _jarray, _index ); + jobject jobject_element = _jenv->GetObjectArrayElement( _jarray, _index ); return jobject_element; } ////////////////////////////////////////////////////////////////////////// - jbyteArray Mengine_JNI_NewByteArray( MengineJNIEnvThread * _jenv, jsize _length ) + jbyteArray Mengine_JNI_NewByteArray( JNIEnv * _jenv, jsize _length ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jbyteArray jbyte_array = env->NewByteArray( _length ); + jbyteArray jbyte_array = _jenv->NewByteArray( _length ); return jbyte_array; } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_SetByteArrayRegion( MengineJNIEnvThread * _jenv, jbyteArray _jarray, jsize _start, jsize _len, const jbyte * _buf ) + void Mengine_JNI_SetByteArrayRegion( JNIEnv * _jenv, jbyteArray _jarray, jsize _start, jsize _len, const jbyte * _buf ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->SetByteArrayRegion( _jarray, _start, _len, _buf ); + _jenv->SetByteArrayRegion( _jarray, _start, _len, _buf ); } ////////////////////////////////////////////////////////////////////////// - void Mengine_JNI_ReleaseByteArrayElements( MengineJNIEnvThread * _jenv, jbyteArray _jarray, jbyte * _elements, jint _mode ) + void Mengine_JNI_ReleaseByteArrayElements( JNIEnv * _jenv, jbyteArray _jarray, jbyte * _elements, jint _mode ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - env->ReleaseByteArrayElements( _jarray, _elements, _mode ); + _jenv->ReleaseByteArrayElements( _jarray, _elements, _mode ); } ////////////////////////////////////////////////////////////////////////// - jbyte * Mengine_JNI_GetByteArrayElements( MengineJNIEnvThread * _jenv, jbyteArray _jarray, jboolean * const _isCopy ) + jbyte * Mengine_JNI_GetByteArrayElements( JNIEnv * _jenv, jbyteArray _jarray, jboolean * const _isCopy ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jbyte * byte_elements = env->GetByteArrayElements( _jarray, _isCopy ); + jbyte * byte_elements = _jenv->GetByteArrayElements( _jarray, _isCopy ); return byte_elements; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_NewDirectByteBuffer( MengineJNIEnvThread * _jenv, void * _address, jlong _capacity ) + jobject Mengine_JNI_NewDirectByteBuffer( JNIEnv * _jenv, void * _address, jlong _capacity ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - jobject jbyte_buffer = env->NewDirectByteBuffer( _address, _capacity ); + jobject jbyte_buffer = _jenv->NewDirectByteBuffer( _address, _capacity ); return jbyte_buffer; } ////////////////////////////////////////////////////////////////////////// - void * Mengine_JNI_GetDirectBufferAddress( MengineJNIEnvThread * _jenv, jobject _jbuffer ) + void * Mengine_JNI_GetDirectBufferAddress( JNIEnv * _jenv, jobject _jbuffer ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - void * address = env->GetDirectBufferAddress( _jbuffer ); + void * address = _jenv->GetDirectBufferAddress( _jbuffer ); return address; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassMengineCallback( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassMengineCallback( JNIEnv * _jenv ) { - jclass jclass_MengineCallback = _jenv->jclass_MengineCallback; + jclass jclass_MengineCallback = Mengine_JNI_LoadClass( _jenv, "org/Mengine/Base/MengineCallback" ); return jclass_MengineCallback; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassApplication( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassApplication( JNIEnv * _jenv ) { - jclass jclass_MengineApplication = _jenv->jclass_MengineApplication; + jclass jclass_MengineApplication = Mengine_JNI_LoadClass( _jenv, "org/Mengine/Base/MengineApplication" ); return jclass_MengineApplication; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_GetObjectApplication( MengineJNIEnvThread * _jenv ) + jobject Mengine_JNI_GetObjectApplication( JNIEnv * _jenv ) { jclass jclass_MengineApplication = Mengine_JNI_GetClassApplication( _jenv ); @@ -1173,31 +1001,37 @@ namespace Mengine if( jfield_INSTANCE == nullptr ) { + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineApplication ); + return nullptr; } jobject jobject_MengineApplication = Mengine_JNI_GetStaticObjectField( _jenv, jclass_MengineApplication, jfield_INSTANCE ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineApplication ); + return jobject_MengineApplication; } ////////////////////////////////////////////////////////////////////////// - jmethodID Mengine_JNI_GetMethodApplication( MengineJNIEnvThread * _jenv, const char * _methodName, const char * _signature ) + jmethodID Mengine_JNI_GetMethodApplication( JNIEnv * _jenv, const char * _methodName, const char * _signature ) { jclass jclass_MengineApplication = Mengine_JNI_GetClassApplication( _jenv ); jmethodID jmethod_MengineApplication = Mengine_JNI_GetMethodID( _jenv, jclass_MengineApplication, _methodName, _signature ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineApplication ); + return jmethod_MengineApplication; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassActivity( MengineJNIEnvThread * _jenv ) + jclass Mengine_JNI_GetClassActivity( JNIEnv * _jenv ) { - jclass jclass_MengineActivity = _jenv->jclass_MengineActivity; + jclass jclass_MengineActivity = Mengine_JNI_LoadClass( _jenv, "org/Mengine/Base/MengineActivity" ); return jclass_MengineActivity; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_GetObjectActivity( MengineJNIEnvThread * _jenv ) + jobject Mengine_JNI_GetObjectActivity( JNIEnv * _jenv ) { jclass jclass_MengineActivity = Mengine_JNI_GetClassActivity( _jenv ); @@ -1205,24 +1039,30 @@ namespace Mengine if( jfield_INSTANCE == nullptr ) { + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return nullptr; } jobject jobject_MengineActivity = Mengine_JNI_GetStaticObjectField( _jenv, jclass_MengineActivity, jfield_INSTANCE ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return jobject_MengineActivity; } ////////////////////////////////////////////////////////////////////////// - jmethodID Mengine_JNI_GetMethodActivity( MengineJNIEnvThread * _jenv, const Char * _methodName, const Char * _signature ) + jmethodID Mengine_JNI_GetMethodActivity( JNIEnv * _jenv, const Char * _methodName, const Char * _signature ) { jclass jclass_MengineActivity = Mengine_JNI_GetClassActivity( _jenv ); jmethodID jmethodId_MengineActivity = Mengine_JNI_GetMethodID( _jenv, jclass_MengineActivity, _methodName, _signature ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineActivity ); + return jmethodId_MengineActivity; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_GetClassFragment( MengineJNIEnvThread * _jenv, const Char * _fragmentName ) + jclass Mengine_JNI_GetClassFragment( JNIEnv * _jenv, const Char * _fragmentName ) { Char fragmentClassName[256 + 1] = { '\0' }; StdString::strcpy_safe( fragmentClassName, "org/Mengine/Base/", 256 ); @@ -1233,7 +1073,7 @@ namespace Mengine return jclass_FragmentClassName; } ////////////////////////////////////////////////////////////////////////// - jobject Mengine_JNI_GetObjectFragment( MengineJNIEnvThread * _jenv, const Char * _fragmentName ) + jobject Mengine_JNI_GetObjectFragment( JNIEnv * _jenv, const Char * _fragmentName ) { jclass jclass_Fragment = Mengine_JNI_GetClassFragment( _jenv, _fragmentName ); @@ -1263,7 +1103,7 @@ namespace Mengine return jobject_INSTANCE; } ////////////////////////////////////////////////////////////////////////// - jmethodID Mengine_JNI_GetMethodFragment( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ) + jmethodID Mengine_JNI_GetMethodFragment( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ) { jclass jclass_Fragment = Mengine_JNI_GetClassFragment( _jenv, _fragment ); @@ -1279,10 +1119,11 @@ namespace Mengine return methodId; } ////////////////////////////////////////////////////////////////////////// - jclass Mengine_JNI_LoadClass( MengineJNIEnvThread * _jenv, const Char * _className ) + jclass Mengine_JNI_LoadClass( JNIEnv * _jenv, const Char * _className ) { jclass jclass_ClassLoader = Mengine_JNI_GetClassClassLoader( _jenv ); jmethodID jmethodID_ClassLoader_loadClass = Mengine_JNI_GetMethodID( _jenv, jclass_ClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_ClassLoader ); jstring jstring_className = Mengine_JNI_NewStringUTF( _jenv, _className ); jclass jclass_FindClass = (jclass)Mengine_JNI_CallObjectMethod( _jenv, g_jobject_MengineClassLoader, jmethodID_ClassLoader_loadClass, jstring_className ); @@ -1291,20 +1132,16 @@ namespace Mengine return jclass_FindClass; } ////////////////////////////////////////////////////////////////////////// - AAssetManager * Mengine_JNI_GetAssetManagerFromJava( MengineJNIEnvThread * _jenv, jobject _jassetManager ) + AAssetManager * Mengine_JNI_GetAssetManagerFromJava( JNIEnv * _jenv, jobject _jassetManager ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - AAssetManager * assetManager = AAssetManager_fromJava( env, _jassetManager ); + AAssetManager * assetManager = AAssetManager_fromJava( _jenv, _jassetManager ); return assetManager; } ////////////////////////////////////////////////////////////////////////// - ANativeWindow * Mengine_JNI_ANativeWindow_fromSurface( MengineJNIEnvThread * _jenv, jobject _surface ) + ANativeWindow * Mengine_JNI_ANativeWindow_fromSurface( JNIEnv * _jenv, jobject _surface ) { - JNIEnv * env = Mengine_JNI_GetEnv( _jenv ); - - ANativeWindow * nativeWindow = ANativeWindow_fromSurface( env, _surface ); + ANativeWindow * nativeWindow = ANativeWindow_fromSurface( _jenv, _surface ); return nativeWindow; } diff --git a/src/Environment/Android/AndroidEnv.h b/src/Environment/Android/AndroidEnv.h index 7c20680ee4..421dea52a7 100644 --- a/src/Environment/Android/AndroidEnv.h +++ b/src/Environment/Android/AndroidEnv.h @@ -9,177 +9,148 @@ namespace Mengine int Mengine_JNI_Initialize( JNIEnv * _env ); int Mengine_JNI_SetupThread(); - struct MengineJNIEnvThread { - JNIEnv * env; - - jclass jclass_Boolean; - jclass jclass_Character; - jclass jclass_Integer; - jclass jclass_Long; - jclass jclass_Float; - jclass jclass_Double; - jclass jclass_String; - jclass jclass_Exception; - jclass jclass_List; - jclass jclass_Map; - jclass jclass_Set; - jclass jclass_ArrayList; - jclass jclass_HashMap; - jclass jclass_MapEntry; - jclass jclass_Iterator; - jclass jclass_Rect; - jclass jclass_JSONObject; - jclass jclass_JSONArray; - jclass jclass_Class; - jclass jclass_ClassLoader; - - jclass jclass_MengineCallback; - jclass jclass_MengineApplication; - jclass jclass_MengineActivity; - }; - - MengineJNIEnvThread * Mengine_JNI_GetEnvThread(); - - jboolean Mengine_JNI_IsInstanceOf( MengineJNIEnvThread * _jenv, jobject _jobject, jclass _jclass ); - - jclass Mengine_JNI_GetClassBoolean( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassCharacter( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassInteger( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassLong( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassFloat( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassDouble( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassString( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassException( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassList( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassMap( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassSet( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassArrayList( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassHashMap( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassMapEntry( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassIterator( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassRect( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassJSONObject( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassJSONArray( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassClass( MengineJNIEnvThread * _jenv ); - jclass Mengine_JNI_GetClassClassLoader( MengineJNIEnvThread * _jenv ); - - jclass Mengine_JNI_GetObjectClass( MengineJNIEnvThread * _jenv, jobject _jobject ); - - void Mengine_JNI_DeleteLocalRef( MengineJNIEnvThread * _jenv, jobject _jobject ); - jobject Mengine_JNI_NewGlobalRef( MengineJNIEnvThread * _jenv, jobject _jobject ); - void Mengine_JNI_DeleteGlobalRef( MengineJNIEnvThread * _jenv, jobject _jobject ); - - int Mengine_JNI_ExceptionCheck( MengineJNIEnvThread * _jenv ); - jthrowable Mengine_JNI_ExceptionOccurred( MengineJNIEnvThread * _jenv ); - void Mengine_JNI_ExceptionClear( MengineJNIEnvThread * _jenv ); - - int Mengine_JNI_PushLocalFrame( MengineJNIEnvThread * _jenv, jint _capacity ); - jobject Mengine_JNI_PopLocalFrame( MengineJNIEnvThread * _jenv, jobject _result ); - - jclass Mengine_JNI_FindClass( MengineJNIEnvThread * _jenv, const Char * _name ); - - jmethodID Mengine_JNI_GetMethodID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); - jmethodID Mengine_JNI_GetStaticMethodID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); - - jfieldID Mengine_JNI_GetFieldID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); - jint Mengine_JNI_GetIntField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - jboolean Mengine_JNI_GetBooleanField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - jchar Mengine_JNI_GetCharField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - jlong Mengine_JNI_GetLongField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - jfloat Mengine_JNI_GetFloatField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - jdouble Mengine_JNI_GetDoubleField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - jobject Mengine_JNI_GetObjectField( MengineJNIEnvThread * _jenv, jobject _jobject, jfieldID _fieldID ); - - jfieldID Mengine_JNI_GetStaticFieldID( MengineJNIEnvThread * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); - jobject Mengine_JNI_GetStaticObjectField( MengineJNIEnvThread * _jenv, jclass _jclass, jfieldID _fieldID ); - - void Mengine_JNI_CallVoidMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - void Mengine_JNI_CallVoidMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - void Mengine_JNI_CallVoidMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jboolean Mengine_JNI_CallBooleanMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jboolean Mengine_JNI_CallBooleanMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jboolean Mengine_JNI_CallBooleanMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jchar Mengine_JNI_CallCharMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jchar Mengine_JNI_CallCharMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jchar Mengine_JNI_CallCharMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jint Mengine_JNI_CallIntMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jint Mengine_JNI_CallIntMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jint Mengine_JNI_CallIntMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jlong Mengine_JNI_CallLongMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jlong Mengine_JNI_CallLongMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jlong Mengine_JNI_CallLongMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jfloat Mengine_JNI_CallFloatMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jfloat Mengine_JNI_CallFloatMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jfloat Mengine_JNI_CallFloatMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jdouble Mengine_JNI_CallDoubleMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jdouble Mengine_JNI_CallDoubleMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jdouble Mengine_JNI_CallDoubleMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - jobject Mengine_JNI_CallObjectMethod( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, ... ); - jobject Mengine_JNI_CallObjectMethodV( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); - jobject Mengine_JNI_CallObjectMethodA( MengineJNIEnvThread * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); - - void Mengine_JNI_CallStaticVoidMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ); - void Mengine_JNI_CallStaticVoidMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); - void Mengine_JNI_CallStaticVoidMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); - - jint Mengine_JNI_CallStaticIntMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ); - jint Mengine_JNI_CallStaticIntMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); - jint Mengine_JNI_CallStaticIntMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); - - jlong Mengine_JNI_CallStaticLongMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ); - jlong Mengine_JNI_CallStaticLongMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); - jlong Mengine_JNI_CallStaticLongMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); - - jboolean Mengine_JNI_CallStaticBooleanMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ); - jboolean Mengine_JNI_CallStaticBooleanMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); - jboolean Mengine_JNI_CallStaticBooleanMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); - - jobject Mengine_JNI_CallStaticObjectMethod( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ); - jobject Mengine_JNI_CallStaticObjectMethodV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); - jobject Mengine_JNI_CallStaticObjectMethodA( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); - - jobject Mengine_JNI_NewObject( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, ... ); - jobject Mengine_JNI_NewObjectV( MengineJNIEnvThread * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); - - jstring Mengine_JNI_NewStringUTF( MengineJNIEnvThread * _jenv, const Char * _str ); - const Char * Mengine_JNI_GetStringUTFChars( MengineJNIEnvThread * _jenv, jstring _jstring, jboolean * const _isCopy ); - void Mengine_JNI_ReleaseStringUTFChars( MengineJNIEnvThread * _jenv, jstring _jstring, const Char * _cstr ); - jsize Mengine_JNI_GetStringLength( MengineJNIEnvThread * _jenv, jstring _jstring ); + JNIEnv * Mengine_JNI_GetEnv(); + + jboolean Mengine_JNI_IsInstanceOf( JNIEnv * _jenv, jobject _jobject, jclass _jclass ); + + jclass Mengine_JNI_GetClassBoolean( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassCharacter( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassInteger( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassLong( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassFloat( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassDouble( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassString( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassException( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassList( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassMap( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassSet( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassArrayList( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassHashMap( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassMapEntry( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassIterator( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassRect( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassJSONObject( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassJSONArray( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassClass( JNIEnv * _jenv ); + jclass Mengine_JNI_GetClassClassLoader( JNIEnv * _jenv ); + + jclass Mengine_JNI_GetObjectClass( JNIEnv * _jenv, jobject _jobject ); + + void Mengine_JNI_DeleteLocalRef( JNIEnv * _jenv, jobject _jobject ); + jobject Mengine_JNI_NewGlobalRef( JNIEnv * _jenv, jobject _jobject ); + void Mengine_JNI_DeleteGlobalRef( JNIEnv * _jenv, jobject _jobject ); + + int Mengine_JNI_ExceptionCheck( JNIEnv * _jenv ); + jthrowable Mengine_JNI_ExceptionOccurred( JNIEnv * _jenv ); + void Mengine_JNI_ExceptionClear( JNIEnv * _jenv ); + + int Mengine_JNI_PushLocalFrame( JNIEnv * _jenv, jint _capacity ); + jobject Mengine_JNI_PopLocalFrame( JNIEnv * _jenv, jobject _result ); + + jclass Mengine_JNI_FindClass( JNIEnv * _jenv, const Char * _name ); + + jmethodID Mengine_JNI_GetMethodID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); + jmethodID Mengine_JNI_GetStaticMethodID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); + + jfieldID Mengine_JNI_GetFieldID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); + jint Mengine_JNI_GetIntField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + jboolean Mengine_JNI_GetBooleanField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + jchar Mengine_JNI_GetCharField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + jlong Mengine_JNI_GetLongField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + jfloat Mengine_JNI_GetFloatField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + jdouble Mengine_JNI_GetDoubleField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + jobject Mengine_JNI_GetObjectField( JNIEnv * _jenv, jobject _jobject, jfieldID _fieldID ); + + jfieldID Mengine_JNI_GetStaticFieldID( JNIEnv * _jenv, jclass _jclass, const Char * _name, const Char * _signature ); + jobject Mengine_JNI_GetStaticObjectField( JNIEnv * _jenv, jclass _jclass, jfieldID _fieldID ); + + void Mengine_JNI_CallVoidMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + void Mengine_JNI_CallVoidMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + void Mengine_JNI_CallVoidMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jboolean Mengine_JNI_CallBooleanMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jboolean Mengine_JNI_CallBooleanMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jboolean Mengine_JNI_CallBooleanMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jchar Mengine_JNI_CallCharMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jchar Mengine_JNI_CallCharMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jchar Mengine_JNI_CallCharMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jint Mengine_JNI_CallIntMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jint Mengine_JNI_CallIntMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jint Mengine_JNI_CallIntMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jlong Mengine_JNI_CallLongMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jlong Mengine_JNI_CallLongMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jlong Mengine_JNI_CallLongMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jfloat Mengine_JNI_CallFloatMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jfloat Mengine_JNI_CallFloatMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jfloat Mengine_JNI_CallFloatMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jdouble Mengine_JNI_CallDoubleMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jdouble Mengine_JNI_CallDoubleMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jdouble Mengine_JNI_CallDoubleMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + jobject Mengine_JNI_CallObjectMethod( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, ... ); + jobject Mengine_JNI_CallObjectMethodV( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, va_list _args ); + jobject Mengine_JNI_CallObjectMethodA( JNIEnv * _jenv, jobject _jobject, jmethodID _methodID, const jvalue * _args ); + + void Mengine_JNI_CallStaticVoidMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ); + void Mengine_JNI_CallStaticVoidMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); + void Mengine_JNI_CallStaticVoidMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); + + jint Mengine_JNI_CallStaticIntMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ); + jint Mengine_JNI_CallStaticIntMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); + jint Mengine_JNI_CallStaticIntMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); + + jlong Mengine_JNI_CallStaticLongMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ); + jlong Mengine_JNI_CallStaticLongMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); + jlong Mengine_JNI_CallStaticLongMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); + + jboolean Mengine_JNI_CallStaticBooleanMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ); + jboolean Mengine_JNI_CallStaticBooleanMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); + jboolean Mengine_JNI_CallStaticBooleanMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); + + jobject Mengine_JNI_CallStaticObjectMethod( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ); + jobject Mengine_JNI_CallStaticObjectMethodV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); + jobject Mengine_JNI_CallStaticObjectMethodA( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, const jvalue * _args ); + + jobject Mengine_JNI_NewObject( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, ... ); + jobject Mengine_JNI_NewObjectV( JNIEnv * _jenv, jclass _jclass, jmethodID _methodID, va_list _args ); + + jstring Mengine_JNI_NewStringUTF( JNIEnv * _jenv, const Char * _str ); + const Char * Mengine_JNI_GetStringUTFChars( JNIEnv * _jenv, jstring _jstring, jboolean * const _isCopy ); + void Mengine_JNI_ReleaseStringUTFChars( JNIEnv * _jenv, jstring _jstring, const Char * _cstr ); + jsize Mengine_JNI_GetStringLength( JNIEnv * _jenv, jstring _jstring ); - jsize Mengine_JNI_GetArrayLength( MengineJNIEnvThread * _jenv, jobjectArray _jarray ); - jobject Mengine_JNI_GetObjectArrayElement( MengineJNIEnvThread * _jenv, jobjectArray _jarray, jsize _index ); + jsize Mengine_JNI_GetArrayLength( JNIEnv * _jenv, jobjectArray _jarray ); + jobject Mengine_JNI_GetObjectArrayElement( JNIEnv * _jenv, jobjectArray _jarray, jsize _index ); - jbyteArray Mengine_JNI_NewByteArray( MengineJNIEnvThread * _jenv, jsize _length ); - void Mengine_JNI_SetByteArrayRegion( MengineJNIEnvThread * _jenv, jbyteArray _jarray, jsize _start, jsize _len, const jbyte * _buf ); - void Mengine_JNI_ReleaseByteArrayElements( MengineJNIEnvThread * _jenv, jbyteArray _jarray, jbyte * _elements, jint _mode ); - jbyte * Mengine_JNI_GetByteArrayElements( MengineJNIEnvThread * _jenv, jbyteArray _jarray, jboolean * const _isCopy ); + jbyteArray Mengine_JNI_NewByteArray( JNIEnv * _jenv, jsize _length ); + void Mengine_JNI_SetByteArrayRegion( JNIEnv * _jenv, jbyteArray _jarray, jsize _start, jsize _len, const jbyte * _buf ); + void Mengine_JNI_ReleaseByteArrayElements( JNIEnv * _jenv, jbyteArray _jarray, jbyte * _elements, jint _mode ); + jbyte * Mengine_JNI_GetByteArrayElements( JNIEnv * _jenv, jbyteArray _jarray, jboolean * const _isCopy ); - jobject Mengine_JNI_NewDirectByteBuffer( MengineJNIEnvThread * _jenv, void * _address, jlong _capacity ); - void * Mengine_JNI_GetDirectBufferAddress( MengineJNIEnvThread * _jenv, jobject _jbuffer ); + jobject Mengine_JNI_NewDirectByteBuffer( JNIEnv * _jenv, void * _address, jlong _capacity ); + void * Mengine_JNI_GetDirectBufferAddress( JNIEnv * _jenv, jobject _jbuffer ); - jclass Mengine_JNI_GetClassMengineCallback( MengineJNIEnvThread * _jenv ); + jclass Mengine_JNI_GetClassMengineCallback( JNIEnv * _jenv ); - jclass Mengine_JNI_GetClassApplication( MengineJNIEnvThread * _jenv ); - jobject Mengine_JNI_GetObjectApplication( MengineJNIEnvThread * _jenv ); - jmethodID Mengine_JNI_GetMethodApplication( MengineJNIEnvThread * _jenv, const Char * _method, const Char * _signature ); + jclass Mengine_JNI_GetClassApplication( JNIEnv * _jenv ); + jobject Mengine_JNI_GetObjectApplication( JNIEnv * _jenv ); + jmethodID Mengine_JNI_GetMethodApplication( JNIEnv * _jenv, const Char * _method, const Char * _signature ); - jclass Mengine_JNI_GetClassActivity( MengineJNIEnvThread * _jenv ); - jobject Mengine_JNI_GetObjectActivity( MengineJNIEnvThread * _jenv ); - jmethodID Mengine_JNI_GetMethodActivity( MengineJNIEnvThread * _jenv, const Char * _method, const Char * _signature ); + jclass Mengine_JNI_GetClassActivity( JNIEnv * _jenv ); + jobject Mengine_JNI_GetObjectActivity( JNIEnv * _jenv ); + jmethodID Mengine_JNI_GetMethodActivity( JNIEnv * _jenv, const Char * _method, const Char * _signature ); - jclass Mengine_JNI_GetClassFragment( MengineJNIEnvThread * _jenv, const Char * _fragment ); - jobject Mengine_JNI_GetObjectFragment( MengineJNIEnvThread * _jenv, const Char * _fragment ); - jmethodID Mengine_JNI_GetMethodFragment( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ); + jclass Mengine_JNI_GetClassFragment( JNIEnv * _jenv, const Char * _fragment ); + jobject Mengine_JNI_GetObjectFragment( JNIEnv * _jenv, const Char * _fragment ); + jmethodID Mengine_JNI_GetMethodFragment( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ); - jclass Mengine_JNI_LoadClass( MengineJNIEnvThread * _jenv, const Char * _class ); + jclass Mengine_JNI_LoadClass( JNIEnv * _jenv, const Char * _class ); - AAssetManager * Mengine_JNI_GetAssetManagerFromJava( MengineJNIEnvThread * _jenv, jobject _assetManager ); - ANativeWindow * Mengine_JNI_ANativeWindow_fromSurface( MengineJNIEnvThread * _jenv, jobject _surface ); + AAssetManager * Mengine_JNI_GetAssetManagerFromJava( JNIEnv * _jenv, jobject _assetManager ); + ANativeWindow * Mengine_JNI_ANativeWindow_fromSurface( JNIEnv * _jenv, jobject _surface ); } \ No newline at end of file diff --git a/src/Environment/Android/AndroidEnvironmentService.cpp b/src/Environment/Android/AndroidEnvironmentService.cpp index 1fe3f18f7a..90f6653019 100644 --- a/src/Environment/Android/AndroidEnvironmentService.cpp +++ b/src/Environment/Android/AndroidEnvironmentService.cpp @@ -21,7 +21,7 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// template - static void getAndroidInfo( MengineJNIEnvThread * _jenv, const Char * _method, StaticString * const _value ) + static void getAndroidInfo( JNIEnv * _jenv, const Char * _method, StaticString * const _value ) { jstring jobject_AndroidInfo = (jstring)Helper::AndroidCallObjectApplicationMethod( _jenv, _method, "()Ljava/lang/String;" ); @@ -30,14 +30,14 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jobject_AndroidInfo ); } ////////////////////////////////////////////////////////////////////////// - static void getAndroidInfo( MengineJNIEnvThread * _jenv, const Char * _method, Timestamp * const _value ) + static void getAndroidInfo( JNIEnv * _jenv, const Char * _method, Timestamp * const _value ) { jlong jinfo = Helper::AndroidCallLongApplicationMethod( _jenv, _method, "()J" ); *_value = (Timestamp)jinfo; } ////////////////////////////////////////////////////////////////////////// - static void getAndroidInfo( MengineJNIEnvThread * _jenv, const Char * _method, int64_t * const _value ) + static void getAndroidInfo( JNIEnv * _jenv, const Char * _method, int64_t * const _value ) { jlong jinfo = Helper::AndroidCallLongApplicationMethod( _jenv, _method, "()J" ); @@ -61,7 +61,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidEnvironmentService::_initializeService() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Environment/Android/AndroidFragmentHelper.cpp b/src/Environment/Android/AndroidFragmentHelper.cpp index e1c6de863a..e44fa96fb2 100644 --- a/src/Environment/Android/AndroidFragmentHelper.cpp +++ b/src/Environment/Android/AndroidFragmentHelper.cpp @@ -13,7 +13,7 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) + void AndroidCallVoidFragmentMethod( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) { jmethodID jmethod_Fragment = Helper::AndroidEnvGetMethodFragment( _jenv, _fragment, _method, _signature ); @@ -31,7 +31,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jobject_Fragment ); } ////////////////////////////////////////////////////////////////////////// - jobject AndroidCallObjectFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) + jobject AndroidCallObjectFragmentMethod( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) { jmethodID jmethod_Fragment = Helper::AndroidEnvGetMethodFragment( _jenv, _fragment, _method, _signature ); @@ -51,7 +51,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jboolean AndroidCallBooleanFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) + jboolean AndroidCallBooleanFragmentMethod( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) { jmethodID jmethod_Fragment = Helper::AndroidEnvGetMethodFragment( _jenv, _fragment, _method, _signature ); @@ -71,7 +71,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jint AndroidCallIntApplicationMethod( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) + jint AndroidCallIntApplicationMethod( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) { jmethodID jmethod_Fragment = Helper::AndroidEnvGetMethodFragment( _jenv, _fragment, _method, _signature ); @@ -91,7 +91,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jlong AndroidCallLongFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) + jlong AndroidCallLongFragmentMethod( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature, ... ) { jmethodID jmethod_Fragment = Helper::AndroidEnvGetMethodFragment( _jenv, _fragment, _method, _signature ); diff --git a/src/Environment/Android/AndroidFragmentHelper.h b/src/Environment/Android/AndroidFragmentHelper.h index 2424da987e..1e4537ba6f 100644 --- a/src/Environment/Android/AndroidFragmentHelper.h +++ b/src/Environment/Android/AndroidFragmentHelper.h @@ -9,11 +9,11 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); - MENGINE_NODISCARD jobject AndroidCallObjectFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); - jboolean AndroidCallBooleanFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); - jint AndroidCallIntFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); - jlong AndroidCallLongFragmentMethod( MengineJNIEnvThread * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); + void AndroidCallVoidFragmentMethod( JNIEnv * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); + MENGINE_NODISCARD jobject AndroidCallObjectFragmentMethod( JNIEnv * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); + jboolean AndroidCallBooleanFragmentMethod( JNIEnv * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); + jint AndroidCallIntFragmentMethod( JNIEnv * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); + jlong AndroidCallLongFragmentMethod( JNIEnv * _jenv, const Char * _fragmentName, const Char * _methodName, const Char * _methodSignature, ... ); ////////////////////////////////////////////////////////////////////////// } } diff --git a/src/Environment/Android/AndroidHelper.cpp b/src/Environment/Android/AndroidHelper.cpp index 67d57215b9..4feb46cb5c 100644 --- a/src/Environment/Android/AndroidHelper.cpp +++ b/src/Environment/Android/AndroidHelper.cpp @@ -21,12 +21,14 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - StaticString<1024> AndroidGetJavaClassName( MengineJNIEnvThread * _jenv, jclass _jclass ) + StaticString<1024> AndroidGetJavaClassName( JNIEnv * _jenv, jclass _jclass ) { jclass jclass_Class = Mengine_JNI_GetClassClass( _jenv ); jmethodID jmethodID_getName = Mengine_JNI_GetMethodID( _jenv, jclass_Class, "getName", "()Ljava/lang/String;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Class ); + jstring jobject_ClassName = (jstring)Mengine_JNI_CallObjectMethod( _jenv, _jclass, jmethodID_getName ); Helper::AndroidEnvExceptionCheck( _jenv ); @@ -42,7 +44,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jclass AndroidEnvFindClass( MengineJNIEnvThread * _jenv, const Char * _className ) + jclass AndroidEnvFindClass( JNIEnv * _jenv, const Char * _className ) { jclass jclass_FindClass = Mengine_JNI_LoadClass( _jenv, _className ); @@ -60,7 +62,7 @@ namespace Mengine return jclass_FindClass; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidEnvGetObjectFragment( MengineJNIEnvThread * _jenv, const Char * _fragment ) + jobject AndroidEnvGetObjectFragment( JNIEnv * _jenv, const Char * _fragment ) { jobject jobject_Fragment = Mengine_JNI_GetObjectFragment( _jenv, _fragment ); @@ -78,7 +80,7 @@ namespace Mengine return jobject_Fragment; } ////////////////////////////////////////////////////////////////////////// - jmethodID AndroidEnvGetMethodFragment( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ) + jmethodID AndroidEnvGetMethodFragment( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ) { jmethodID jmethod_Fragment = Mengine_JNI_GetMethodFragment( _jenv, _fragment, _method, _signature ); @@ -98,7 +100,7 @@ namespace Mengine return jmethod_Fragment; } ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidStaticClassMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ) + void AndroidCallVoidStaticClassMethod( JNIEnv * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ) { jclass jclass_name = Helper::AndroidEnvFindClass( _jenv, _name ); @@ -122,7 +124,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jclass_name ); } ////////////////////////////////////////////////////////////////////////// - jobject AndroidCallObjectStaticClassMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ) + jobject AndroidCallObjectStaticClassMethod( JNIEnv * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ) { jclass jclass_name = Helper::AndroidEnvFindClass( _jenv, _name ); @@ -148,7 +150,7 @@ namespace Mengine return jresult; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectPointer( MengineJNIEnvThread * _jenv, void * _value ) + jobject AndroidMakeJObjectPointer( JNIEnv * _jenv, void * _value ) { int64_t pointer_value = (int64_t)_value; @@ -157,7 +159,7 @@ namespace Mengine return jpointer; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectBoolean( MengineJNIEnvThread * _jenv, bool _value ) + jobject AndroidMakeJObjectBoolean( JNIEnv * _jenv, bool _value ) { jclass jclass_Boolean = Mengine_JNI_GetClassBoolean( _jenv ); @@ -165,10 +167,12 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_Boolean, Boolean_constructor, _value ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Boolean ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectCharacter( MengineJNIEnvThread * _jenv, Char _value ) + jobject AndroidMakeJObjectCharacter( JNIEnv * _jenv, Char _value ) { jclass jclass_Character = Mengine_JNI_GetClassCharacter( _jenv ); @@ -176,21 +180,25 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_Character, Character_constructor, _value ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Character ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectInteger( MengineJNIEnvThread * _jenv, int32_t _value ) + jobject AndroidMakeJObjectInteger( JNIEnv * _jenv, int32_t _value ) { jclass jclass_Integer = Mengine_JNI_GetClassInteger( _jenv ); jmethodID Integer_constructor = Mengine_JNI_GetMethodID( _jenv, jclass_Integer, "", "(I)V" ); jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_Integer, Integer_constructor, (jint)_value ); + + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Integer ); return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectLong( MengineJNIEnvThread * _jenv, int64_t _value ) + jobject AndroidMakeJObjectLong( JNIEnv * _jenv, int64_t _value ) { jclass jclass_Long = Mengine_JNI_GetClassLong( _jenv ); @@ -198,10 +206,12 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_Long, Long_constructor, (jlong)_value ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Long ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectFloat( MengineJNIEnvThread * _jenv, float _value ) + jobject AndroidMakeJObjectFloat( JNIEnv * _jenv, float _value ) { jclass jclass_Float = Mengine_JNI_GetClassFloat( _jenv ); @@ -209,10 +219,12 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_Float, Float_constructor, _value ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Float ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectDouble( MengineJNIEnvThread * _jenv, double _value ) + jobject AndroidMakeJObjectDouble( JNIEnv * _jenv, double _value ) { jclass jclass_Double = Mengine_JNI_GetClassDouble( _jenv ); @@ -220,10 +232,12 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_Double, Double_constructor, _value ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Double ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const Char * _value ) + jobject AndroidMakeJObjectString( JNIEnv * _jenv, const Char * _value ) { MENGINE_ASSERTION_VALIDATE_UTF8( _value, MENGINE_UNKNOWN_SIZE ); @@ -232,7 +246,7 @@ namespace Mengine return value_jstring; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const String & _value ) + jobject AndroidMakeJObjectString( JNIEnv * _jenv, const String & _value ) { const Char * value_str = _value.c_str(); @@ -241,7 +255,7 @@ namespace Mengine return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const ConstString & _value ) + jobject AndroidMakeJObjectString( JNIEnv * _jenv, const ConstString & _value ) { const Char * value_str = _value.c_str(); @@ -250,7 +264,7 @@ namespace Mengine return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectArrayList( MengineJNIEnvThread * _jenv, int32_t _count ) + jobject AndroidMakeJObjectArrayList( JNIEnv * _jenv, int32_t _count ) { jclass jclass_ArrayList = Mengine_JNI_GetClassArrayList( _jenv ); @@ -258,10 +272,12 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_ArrayList, ArrayList_constructor, (jint)_count ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_ArrayList ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidMakeJObjectHashMap( MengineJNIEnvThread * _jenv, int32_t _count ) + jobject AndroidMakeJObjectHashMap( JNIEnv * _jenv, int32_t _count ) { jclass jclass_HashMap = Mengine_JNI_GetClassHashMap( _jenv ); @@ -269,10 +285,12 @@ namespace Mengine jobject value_jobject = Mengine_JNI_NewObject( _jenv, jclass_HashMap, HashMap_constructor, (jint)_count ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_HashMap ); + return value_jobject; } ////////////////////////////////////////////////////////////////////////// - MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( MengineJNIEnvThread * _jenv, const Params & _params ) + MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( JNIEnv * _jenv, const Params & _params ) { Params::size_type size = _params.size(); @@ -325,7 +343,7 @@ namespace Mengine return jmap; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidGetJObjectEnum( MengineJNIEnvThread * _jenv, const Char * _className, const Char * _enumName ) + jobject AndroidGetJObjectEnum( JNIEnv * _jenv, const Char * _className, const Char * _enumName ) { jclass jclass_enum = Helper::AndroidEnvFindClass( _jenv, _className ); @@ -343,7 +361,7 @@ namespace Mengine return jobject_enum; } ////////////////////////////////////////////////////////////////////////// - jboolean AndroidAddJObjectList( MengineJNIEnvThread * _jenv, jobject _list, jobject _value ) + jboolean AndroidAddJObjectList( JNIEnv * _jenv, jobject _list, jobject _value ) { jclass jclass_ArrayList = Mengine_JNI_GetClassList( _jenv ); @@ -356,12 +374,14 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - void AndroidPutJObjectMap( MengineJNIEnvThread * _jenv, jobject _map, jobject _key, jobject _value ) + void AndroidPutJObjectMap( JNIEnv * _jenv, jobject _map, jobject _key, jobject _value ) { jclass jclass_Map = Mengine_JNI_GetClassMap( _jenv ); jmethodID Map_put = Mengine_JNI_GetMethodID( _jenv, jclass_Map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Map ); + jobject jresult = Mengine_JNI_CallObjectMethod( _jenv, _map, Map_put, _key, _value ); Helper::AndroidEnvExceptionCheck( _jenv ); @@ -369,12 +389,16 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jresult ); } ////////////////////////////////////////////////////////////////////////// - jobject AndroidGetJObjectMap( MengineJNIEnvThread * _jenv, jobject _map, jobject _key ) + jobject AndroidGetJObjectMap( JNIEnv * _jenv, jobject _map, jobject _key ) { jclass jclass_Map = Mengine_JNI_GetClassMap( _jenv ); jmethodID Map_get = Mengine_JNI_GetMethodID( _jenv, jclass_Map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Map ); + + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Map ); + jobject value = Mengine_JNI_CallObjectMethod( _jenv, _map, Map_get, _key ); Helper::AndroidEnvExceptionCheck( _jenv ); @@ -382,7 +406,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jboolean AndroidGetJavaObjectValueBoolean( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ) + jboolean AndroidGetJavaObjectValueBoolean( JNIEnv * _jenv, jclass _jclass, jobject _jobject ) { jmethodID jmethod_Value = Mengine_JNI_GetMethodID( _jenv, _jclass, "booleanValue", "()Z" ); @@ -395,7 +419,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jchar AndroidGetJavaObjectValueCharacter( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ) + jchar AndroidGetJavaObjectValueCharacter( JNIEnv * _jenv, jclass _jclass, jobject _jobject ) { jmethodID jmethod_Value = Mengine_JNI_GetMethodID( _jenv, _jclass, "charValue", "()C" ); @@ -408,7 +432,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jint AndroidGetJavaObjectValueInteger( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ) + jint AndroidGetJavaObjectValueInteger( JNIEnv * _jenv, jclass _jclass, jobject _jobject ) { jmethodID jmethod_Value = Mengine_JNI_GetMethodID( _jenv, _jclass, "intValue", "()I" ); @@ -421,7 +445,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jlong AndroidGetJavaObjectValueLong( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ) + jlong AndroidGetJavaObjectValueLong( JNIEnv * _jenv, jclass _jclass, jobject _jobject ) { jmethodID jmethod_Value = Mengine_JNI_GetMethodID( _jenv, _jclass, "longValue", "()J" ); @@ -434,7 +458,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jfloat AndroidGetJavaObjectValueFloat( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ) + jfloat AndroidGetJavaObjectValueFloat( JNIEnv * _jenv, jclass _jclass, jobject _jobject ) { jmethodID jmethod_Value = Mengine_JNI_GetMethodID( _jenv, _jclass, "floatValue", "()F" ); @@ -447,7 +471,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - jdouble AndroidGetJavaObjectValueDouble( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ) + jdouble AndroidGetJavaObjectValueDouble( JNIEnv * _jenv, jclass _jclass, jobject _jobject ) { jmethodID jmethod_Value = Mengine_JNI_GetMethodID( _jenv, _jclass, "doubleValue", "()D" ); @@ -460,7 +484,7 @@ namespace Mengine return value; } ////////////////////////////////////////////////////////////////////////// - ConstString AndroidMakeConstStringFromJString( MengineJNIEnvThread * _jenv, jstring _value ) + ConstString AndroidMakeConstStringFromJString( JNIEnv * _jenv, jstring _value ) { ConstString value_cstr; ANDROID_KERNEL_SERVICE() @@ -469,7 +493,7 @@ namespace Mengine return value_cstr; } ////////////////////////////////////////////////////////////////////////// - FilePath AndroidMakeFilePathFromJString( MengineJNIEnvThread * _jenv, jstring _value ) + FilePath AndroidMakeFilePathFromJString( JNIEnv * _jenv, jstring _value ) { ConstString value_cstr; ANDROID_KERNEL_SERVICE() @@ -478,7 +502,7 @@ namespace Mengine return FilePath( value_cstr ); } ////////////////////////////////////////////////////////////////////////// - String AndroidMakeStringFromJString( MengineJNIEnvThread * _jenv, jstring _value ) + String AndroidMakeStringFromJString( JNIEnv * _jenv, jstring _value ) { const Char * value_str = Mengine_JNI_GetStringUTFChars( _jenv, _value, nullptr ); jsize value_size = Mengine_JNI_GetStringLength( _jenv, _value ); @@ -490,7 +514,7 @@ namespace Mengine return value_string; } ////////////////////////////////////////////////////////////////////////// - size_t AndroidCopyStringFromJString( MengineJNIEnvThread * _jenv, jstring _value, Char * const _str, size_t _capacity ) + size_t AndroidCopyStringFromJString( JNIEnv * _jenv, jstring _value, Char * const _str, size_t _capacity ) { const Char * value_str = Mengine_JNI_GetStringUTFChars( _jenv, _value, nullptr ); jsize value_size = Mengine_JNI_GetStringLength( _jenv, _value ); @@ -502,7 +526,7 @@ namespace Mengine return value_size; } ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaJSONObject( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jjson, const LambdaJavaJSONObjectForeach & _lambda ) + void AndroidForeachJavaJSONObject( JNIEnv * _jenv, jclass _jclass, jobject _jjson, const LambdaJavaJSONObjectForeach & _lambda ) { jmethodID JSONObject_keys = Mengine_JNI_GetMethodID( _jenv, _jclass, "keys", "()Ljava/util/Iterator;" ); @@ -511,6 +535,8 @@ namespace Mengine jmethodID Iterator_hasNext = Mengine_JNI_GetMethodID( _jenv, jclass_Iterator, "hasNext", "()Z" ); jmethodID Iterator_next = Mengine_JNI_GetMethodID( _jenv, jclass_Iterator, "next", "()Ljava/lang/Object;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Iterator ); + jmethodID JSONObject_opt = Mengine_JNI_GetMethodID( _jenv, _jclass, "opt", "(Ljava/lang/String;)Ljava/lang/Object;" ); jobject jkeys = Mengine_JNI_CallObjectMethod( _jenv, _jjson, JSONObject_keys ); @@ -544,7 +570,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jkeys ); } ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaJSONArray( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jarray, const LambdaJavaJSONArrayForeach & _lambda ) + void AndroidForeachJavaJSONArray( JNIEnv * _jenv, jclass _jclass, jobject _jarray, const LambdaJavaJSONArrayForeach & _lambda ) { jmethodID JSONArray_length = Mengine_JNI_GetMethodID( _jenv, _jclass, "length", "()I" ); jmethodID JSONArray_get = Mengine_JNI_GetMethodID( _jenv, _jclass, "get", "(I)Ljava/lang/Object;" ); @@ -565,7 +591,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaSet( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jset, const LambdaJavaSetForeach & _lambda ) + void AndroidForeachJavaSet( JNIEnv * _jenv, jclass _jclass, jobject _jset, const LambdaJavaSetForeach & _lambda ) { jclass jclass_Iterator = Mengine_JNI_GetClassIterator( _jenv ); @@ -573,6 +599,8 @@ namespace Mengine jmethodID jmethodID_Iterator_hasNext = Mengine_JNI_GetMethodID( _jenv, jclass_Iterator, "hasNext", "()Z" ); jmethodID jmethodID_Iterator_next = Mengine_JNI_GetMethodID( _jenv, jclass_Iterator, "next", "()Ljava/lang/Object;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Iterator ); + jobject jobject_iterator = Mengine_JNI_CallObjectMethod( _jenv, _jset, jmethodID_Set_iterator ); Helper::AndroidEnvExceptionCheck( _jenv ); @@ -599,7 +627,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jobject_iterator ); } ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaMap( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jmap, const LambdaJavaMapForeach & _lambda ) + void AndroidForeachJavaMap( JNIEnv * _jenv, jclass _jclass, jobject _jmap, const LambdaJavaMapForeach & _lambda ) { jclass jclass_Set = Mengine_JNI_GetClassSet( _jenv ); jclass jclass_Iterator = Mengine_JNI_GetClassIterator( _jenv ); @@ -612,6 +640,10 @@ namespace Mengine jmethodID jmethodID_MapEntry_getKey = Mengine_JNI_GetMethodID( _jenv, jclass_MapEntry, "getKey", "()Ljava/lang/Object;" ); jmethodID jmethodID_MapEntry_getValue = Mengine_JNI_GetMethodID( _jenv, jclass_MapEntry, "getValue", "()Ljava/lang/Object;" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Set ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Iterator ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MapEntry ); + jobject jset = Mengine_JNI_CallObjectMethod( _jenv, _jmap, jmethodID_Map_entrySet ); Helper::AndroidEnvExceptionCheck( _jenv ); @@ -653,7 +685,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jset ); } ////////////////////////////////////////////////////////////////////////// - uint32_t AndroidGetJavaListSize( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jlist ) + uint32_t AndroidGetJavaListSize( JNIEnv * _jenv, jclass _jclass, jobject _jlist ) { jmethodID List_size = Mengine_JNI_GetMethodID( _jenv, _jclass, "size", "()I"); @@ -664,7 +696,7 @@ namespace Mengine return (uint32_t)list_size; } ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaList( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jlist, const LambdaJavaListForeach & _lambda ) + void AndroidForeachJavaList( JNIEnv * _jenv, jclass _jclass, jobject _jlist, const LambdaJavaListForeach & _lambda ) { jmethodID List_size = Mengine_JNI_GetMethodID( _jenv, _jclass, "size", "()I"); jmethodID List_get = Mengine_JNI_GetMethodID( _jenv, _jclass, "get", "(I)Ljava/lang/Object;"); @@ -685,7 +717,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void AndroidGetJavaRect( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jrect, Viewport * const _viewport ) + void AndroidGetJavaRect( JNIEnv * _jenv, jclass _jclass, jobject _jrect, Viewport * const _viewport ) { jfieldID jfieldID_Rect_left = Mengine_JNI_GetFieldID( _jenv, _jclass, "left", "I" ); jfieldID jfieldID_Rect_top = Mengine_JNI_GetFieldID( _jenv, _jclass, "top", "I" ); @@ -703,7 +735,7 @@ namespace Mengine _viewport->end.y = (float)bottom; } ////////////////////////////////////////////////////////////////////////// - bool AndroidGetApplicationFilesDirCanonicalPath( MengineJNIEnvThread * _jenv, Char * const _path ) + bool AndroidGetApplicationFilesDirCanonicalPath( JNIEnv * _jenv, Char * const _path ) { jobject jobject_MengineApplication = Mengine_JNI_GetObjectApplication( _jenv ); @@ -744,7 +776,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidGetActivitySurface( MengineJNIEnvThread * _jenv ) + jobject AndroidGetActivitySurface( JNIEnv * _jenv ) { jobject jobject_MengineActivity = Mengine_JNI_GetObjectActivity( _jenv ); @@ -763,7 +795,7 @@ namespace Mengine return jSurface; } ////////////////////////////////////////////////////////////////////////// - void AndroidEnvExceptionCheck( MengineJNIEnvThread * _jenv ) + void AndroidEnvExceptionCheck( JNIEnv * _jenv ) { if( Mengine_JNI_ExceptionCheck( _jenv ) == JNI_FALSE ) { diff --git a/src/Environment/Android/AndroidHelper.h b/src/Environment/Android/AndroidHelper.h index 68fc5dc065..118edf9389 100644 --- a/src/Environment/Android/AndroidHelper.h +++ b/src/Environment/Android/AndroidHelper.h @@ -19,54 +19,54 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - StaticString<1024> AndroidGetJavaClassName( MengineJNIEnvThread * _jenv, jclass _jclass ); - jclass AndroidEnvFindClass( MengineJNIEnvThread * _jenv, const Char * _className ); - jobject AndroidEnvGetObjectFragment( MengineJNIEnvThread * _jenv, const Char * _fragment ); - jmethodID AndroidEnvGetMethodFragment( MengineJNIEnvThread * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ); - ////////////////////////////////////////////////////////////////////////// - void AndroidCallVoidStaticClassMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ); - MENGINE_NODISCARD jobject AndroidCallObjectStaticClassMethod( MengineJNIEnvThread * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ); - ////////////////////////////////////////////////////////////////////////// - MENGINE_NODISCARD jobject AndroidMakeJObjectPointer( MengineJNIEnvThread * _jenv, void * _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectBoolean( MengineJNIEnvThread * _jenv, bool _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectCharacter( MengineJNIEnvThread * _jenv, Char _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectInteger( MengineJNIEnvThread * _jenv, int32_t _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectLong( MengineJNIEnvThread * _jenv, int64_t _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectFloat( MengineJNIEnvThread * _jenv, float _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectDouble( MengineJNIEnvThread * _jenv, double _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const Char * _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const String & _value ); - MENGINE_NODISCARD jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const ConstString & _value ); + StaticString<1024> AndroidGetJavaClassName( JNIEnv * _jenv, jclass _jclass ); + jclass AndroidEnvFindClass( JNIEnv * _jenv, const Char * _className ); + jobject AndroidEnvGetObjectFragment( JNIEnv * _jenv, const Char * _fragment ); + jmethodID AndroidEnvGetMethodFragment( JNIEnv * _jenv, const Char * _fragment, const Char * _method, const Char * _signature ); + ////////////////////////////////////////////////////////////////////////// + void AndroidCallVoidStaticClassMethod( JNIEnv * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ); + MENGINE_NODISCARD jobject AndroidCallObjectStaticClassMethod( JNIEnv * _jenv, const Char * _name, const Char * _method, const Char * _signature, ... ); + ////////////////////////////////////////////////////////////////////////// + MENGINE_NODISCARD jobject AndroidMakeJObjectPointer( JNIEnv * _jenv, void * _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectBoolean( JNIEnv * _jenv, bool _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectCharacter( JNIEnv * _jenv, Char _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectInteger( JNIEnv * _jenv, int32_t _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectLong( JNIEnv * _jenv, int64_t _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectFloat( JNIEnv * _jenv, float _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectDouble( JNIEnv * _jenv, double _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectString( JNIEnv * _jenv, const Char * _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectString( JNIEnv * _jenv, const String & _value ); + MENGINE_NODISCARD jobject AndroidMakeJObjectString( JNIEnv * _jenv, const ConstString & _value ); template - MENGINE_NODISCARD jobject AndroidMakeJObjectString( MengineJNIEnvThread * _jenv, const StaticString & _value ) + MENGINE_NODISCARD jobject AndroidMakeJObjectString( JNIEnv * _jenv, const StaticString & _value ) { return Helper::AndroidMakeJObjectString( _jenv, _value.c_str() ); } - MENGINE_NODISCARD jobject AndroidMakeJObjectArrayList( MengineJNIEnvThread * _jenv, int32_t _count ); - MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( MengineJNIEnvThread * _jenv, int32_t _count ); - MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( MengineJNIEnvThread * _jenv, int32_t _count ); - MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( MengineJNIEnvThread * _jenv, const Params & _params ); - ////////////////////////////////////////////////////////////////////////// - jobject AndroidGetJObjectEnum( MengineJNIEnvThread * _jenv, const Char * _className, const Char * _enumName ); - ////////////////////////////////////////////////////////////////////////// - jboolean AndroidAddJObjectList( MengineJNIEnvThread * _jenv, jobject _list, jobject _value ); - void AndroidPutJObjectMap( MengineJNIEnvThread * _jenv, jobject _map, jobject _key, jobject _value ); - MENGINE_NODISCARD jobject AndroidGetJObjectMap( MengineJNIEnvThread * _jenv, jobject _map, jobject _key ); - ////////////////////////////////////////////////////////////////////////// - jboolean AndroidGetJavaObjectValueBoolean( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ); - jchar AndroidGetJavaObjectValueCharacter( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ); - jint AndroidGetJavaObjectValueInteger( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ); - jlong AndroidGetJavaObjectValueLong( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ); - jfloat AndroidGetJavaObjectValueFloat( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ); - jdouble AndroidGetJavaObjectValueDouble( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jobject ); - ////////////////////////////////////////////////////////////////////////// - ConstString AndroidMakeConstStringFromJString( MengineJNIEnvThread * _jenv, jstring _value ); - FilePath AndroidMakeFilePathFromJString( MengineJNIEnvThread * _jenv, jstring _value ); - String AndroidMakeStringFromJString( MengineJNIEnvThread * _jenv, jstring _value ); - size_t AndroidCopyStringFromJString( MengineJNIEnvThread * _jenv, jstring _value, Char * const _str, size_t _capacity ); + MENGINE_NODISCARD jobject AndroidMakeJObjectArrayList( JNIEnv * _jenv, int32_t _count ); + MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( JNIEnv * _jenv, int32_t _count ); + MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( JNIEnv * _jenv, int32_t _count ); + MENGINE_NODISCARD jobject AndroidMakeJObjectHashMap( JNIEnv * _jenv, const Params & _params ); + ////////////////////////////////////////////////////////////////////////// + jobject AndroidGetJObjectEnum( JNIEnv * _jenv, const Char * _className, const Char * _enumName ); + ////////////////////////////////////////////////////////////////////////// + jboolean AndroidAddJObjectList( JNIEnv * _jenv, jobject _list, jobject _value ); + void AndroidPutJObjectMap( JNIEnv * _jenv, jobject _map, jobject _key, jobject _value ); + MENGINE_NODISCARD jobject AndroidGetJObjectMap( JNIEnv * _jenv, jobject _map, jobject _key ); + ////////////////////////////////////////////////////////////////////////// + jboolean AndroidGetJavaObjectValueBoolean( JNIEnv * _jenv, jclass _jclass, jobject _jobject ); + jchar AndroidGetJavaObjectValueCharacter( JNIEnv * _jenv, jclass _jclass, jobject _jobject ); + jint AndroidGetJavaObjectValueInteger( JNIEnv * _jenv, jclass _jclass, jobject _jobject ); + jlong AndroidGetJavaObjectValueLong( JNIEnv * _jenv, jclass _jclass, jobject _jobject ); + jfloat AndroidGetJavaObjectValueFloat( JNIEnv * _jenv, jclass _jclass, jobject _jobject ); + jdouble AndroidGetJavaObjectValueDouble( JNIEnv * _jenv, jclass _jclass, jobject _jobject ); + ////////////////////////////////////////////////////////////////////////// + ConstString AndroidMakeConstStringFromJString( JNIEnv * _jenv, jstring _value ); + FilePath AndroidMakeFilePathFromJString( JNIEnv * _jenv, jstring _value ); + String AndroidMakeStringFromJString( JNIEnv * _jenv, jstring _value ); + size_t AndroidCopyStringFromJString( JNIEnv * _jenv, jstring _value, Char * const _str, size_t _capacity ); /////////////////////////////////////////////////////////////////////// template - size_t AndroidCopyStringFromJString( MengineJNIEnvThread * _jenv, jstring _value, StaticString * const _str ) + size_t AndroidCopyStringFromJString( JNIEnv * _jenv, jstring _value, StaticString * const _str ) { Char * data = _str->data(); size_t capacity = _str->capacity(); @@ -78,32 +78,32 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// typedef Lambda LambdaJavaJSONObjectForeach; ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaJSONObject( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jjson, const LambdaJavaJSONObjectForeach & _lambda ); + void AndroidForeachJavaJSONObject( JNIEnv * _jenv, jclass _jclass, jobject _jjson, const LambdaJavaJSONObjectForeach & _lambda ); ////////////////////////////////////////////////////////////////////////// typedef Lambda LambdaJavaJSONArrayForeach; ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaJSONArray( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jarray, const LambdaJavaJSONArrayForeach & _lambda ); + void AndroidForeachJavaJSONArray( JNIEnv * _jenv, jclass _jclass, jobject _jarray, const LambdaJavaJSONArrayForeach & _lambda ); ////////////////////////////////////////////////////////////////////////// typedef Lambda LambdaJavaSetForeach; ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaSet( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jset, const LambdaJavaSetForeach & _lambda ); + void AndroidForeachJavaSet( JNIEnv * _jenv, jclass _jclass, jobject _jset, const LambdaJavaSetForeach & _lambda ); ////////////////////////////////////////////////////////////////////////// typedef Lambda LambdaJavaMapForeach; ////////////////////////////////////////////////////////////////////////// - void AndroidForeachJavaMap( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jmap, const LambdaJavaMapForeach & _lambda ); + void AndroidForeachJavaMap( JNIEnv * _jenv, jclass _jclass, jobject _jmap, const LambdaJavaMapForeach & _lambda ); ////////////////////////////////////////////////////////////////////////// typedef Lambda LambdaJavaListForeach; ////////////////////////////////////////////////////////////////////////// - uint32_t AndroidGetJavaListSize( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jlist ); - void AndroidForeachJavaList( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jlist, const LambdaJavaListForeach & _lambda ); + uint32_t AndroidGetJavaListSize( JNIEnv * _jenv, jclass _jclass, jobject _jlist ); + void AndroidForeachJavaList( JNIEnv * _jenv, jclass _jclass, jobject _jlist, const LambdaJavaListForeach & _lambda ); ////////////////////////////////////////////////////////////////////////// - void AndroidGetJavaRect( MengineJNIEnvThread * _jenv, jclass _jclass, jobject _jrect, Viewport * const _viewport ); + void AndroidGetJavaRect( JNIEnv * _jenv, jclass _jclass, jobject _jrect, Viewport * const _viewport ); ////////////////////////////////////////////////////////////////////////// - bool AndroidGetApplicationFilesDirCanonicalPath( MengineJNIEnvThread * _jenv, Char * const _path ); + bool AndroidGetApplicationFilesDirCanonicalPath( JNIEnv * _jenv, Char * const _path ); ////////////////////////////////////////////////////////////////////////// - MENGINE_NODISCARD jobject AndroidGetActivitySurface( MengineJNIEnvThread * _jenv ); + MENGINE_NODISCARD jobject AndroidGetActivitySurface( JNIEnv * _jenv ); ////////////////////////////////////////////////////////////////////////// - void AndroidEnvExceptionCheck( MengineJNIEnvThread * _jenv ); + void AndroidEnvExceptionCheck( JNIEnv * _jenv ); ////////////////////////////////////////////////////////////////////////// } } \ No newline at end of file diff --git a/src/Environment/Android/AndroidKernelService.cpp b/src/Environment/Android/AndroidKernelService.cpp index 2790b0fe52..8dfc259ce3 100644 --- a/src/Environment/Android/AndroidKernelService.cpp +++ b/src/Environment/Android/AndroidKernelService.cpp @@ -20,10 +20,8 @@ extern "C" { ////////////////////////////////////////////////////////////////////////// - JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1call )(JNIEnv *, jclass cls, jstring _plugin, jstring _method, jobjectArray _args) + JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1call )(JNIEnv * env, jclass cls, jstring _plugin, jstring _method, jobjectArray _args) { - Mengine::MengineJNIEnvThread * env = Mengine::Mengine_JNI_GetEnvThread(); - Mengine::ConstString plugin = Mengine::Helper::AndroidMakeConstStringFromJString( env, _plugin ); Mengine::ConstString method = Mengine::Helper::AndroidMakeConstStringFromJString( env, _method ); @@ -41,7 +39,7 @@ extern "C" jobjectArray jobject_NewArgs = (jobjectArray)Mengine::Mengine_JNI_NewGlobalRef( env, _args ); Mengine::Helper::dispatchMainThreadEvent( [plugin, method, jobject_NewArgs]() { - Mengine::MengineJNIEnvThread * main_jenv = Mengine::Mengine_JNI_GetEnvThread(); + JNIEnv * main_jenv = Mengine::Mengine_JNI_GetEnv(); ANDROID_KERNEL_SERVICE() ->callPluginMethod( main_jenv, plugin, method, jobject_NewArgs ); @@ -50,10 +48,8 @@ extern "C" } ); } ////////////////////////////////////////////////////////////////////////// - JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1addPlugin )(JNIEnv *, jclass cls, jstring _plugin, jobject _jmodule) + JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1addPlugin )(JNIEnv * env, jclass cls, jstring _plugin, jobject _jmodule) { - Mengine::MengineJNIEnvThread * env = Mengine::Mengine_JNI_GetEnvThread(); - Mengine::ConstString plugin = Mengine::Helper::AndroidMakeConstStringFromJString( env, _plugin ); jobject new_jmodule = Mengine::Mengine_JNI_NewGlobalRef( env, _jmodule ); @@ -62,10 +58,8 @@ extern "C" ->addPlugin( plugin, new_jmodule ); } ////////////////////////////////////////////////////////////////////////// - JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1removePlugin )(JNIEnv *, jclass cls, jstring _name) + JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1removePlugin )(JNIEnv * env, jclass cls, jstring _name) { - Mengine::MengineJNIEnvThread * env = Mengine::Mengine_JNI_GetEnvThread(); - Mengine::ConstString plugin = Mengine::Helper::AndroidMakeConstStringFromJString( env, _name ); jobject jmodule = ANDROID_KERNEL_SERVICE() @@ -74,10 +68,8 @@ extern "C" Mengine::Mengine_JNI_DeleteGlobalRef( env, jmodule ); } ////////////////////////////////////////////////////////////////////////// - JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1activateSemaphore )(JNIEnv *, jclass cls, jstring _name) + JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidKernelService_1activateSemaphore )(JNIEnv * env, jclass cls, jstring _name) { - Mengine::MengineJNIEnvThread * env = Mengine::Mengine_JNI_GetEnvThread(); - Mengine::ConstString semaphore = Mengine::Helper::AndroidMakeConstStringFromJString( env, _name ); ANDROID_KERNEL_SERVICE() @@ -116,7 +108,7 @@ namespace Mengine { m_mutexJStrings = nullptr; - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -154,7 +146,7 @@ namespace Mengine m_plugins.clear(); } ////////////////////////////////////////////////////////////////////////// - void AndroidKernelService::stringize( MengineJNIEnvThread * _jenv, jstring _value, ConstString * const _cstr ) + void AndroidKernelService::stringize( JNIEnv * _jenv, jstring _value, ConstString * const _cstr ) { jsize value_length = Mengine_JNI_GetStringLength( _jenv, _value ); @@ -248,7 +240,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void AndroidKernelService::callPluginMethod( MengineJNIEnvThread * _jenv, const ConstString & _plugin, const ConstString & _method, jobjectArray _args ) const + void AndroidKernelService::callPluginMethod( JNIEnv * _jenv, const ConstString & _plugin, const ConstString & _method, jobjectArray _args ) const { MENGINE_THREAD_MUTEX_SCOPE( m_callbacksMutex ); @@ -363,7 +355,7 @@ namespace Mengine , _semaphore.c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Environment/Android/AndroidKernelService.h b/src/Environment/Android/AndroidKernelService.h index 115a2cde00..629c27c3aa 100644 --- a/src/Environment/Android/AndroidKernelService.h +++ b/src/Environment/Android/AndroidKernelService.h @@ -26,7 +26,7 @@ namespace Mengine void _finalizeService() override; public: - void stringize( MengineJNIEnvThread * _jenv, jstring _value, ConstString * const _cstr ) override; + void stringize( JNIEnv * _jenv, jstring _value, ConstString * const _cstr ) override; public: void addPlugin( const ConstString & _plugin, jobject _jmodule ) override; @@ -35,7 +35,7 @@ namespace Mengine public: bool hasPluginMethod( const ConstString & _plugin, const ConstString & _method ) const override; - void callPluginMethod( MengineJNIEnvThread * _jenv, const ConstString & _plugin, const ConstString & _method, jobjectArray _args ) const override; + void callPluginMethod( JNIEnv * _jenv, const ConstString & _plugin, const ConstString & _method, jobjectArray _args ) const override; public: AndroidPluginCallbackInterfacePtr addPluginCallback( const ConstString & _plugin, const ConstString & _method, const AndroidPluginCallbackInterfacePtr & _callback ) override; diff --git a/src/Environment/Android/AndroidKernelServiceInterface.h b/src/Environment/Android/AndroidKernelServiceInterface.h index 74bf4666d9..7ef18506fc 100644 --- a/src/Environment/Android/AndroidKernelServiceInterface.h +++ b/src/Environment/Android/AndroidKernelServiceInterface.h @@ -17,7 +17,7 @@ namespace Mengine SERVICE_DECLARE( "AndroidKernelService" ) public: - virtual void stringize( MengineJNIEnvThread * _jenv, jstring _value, ConstString * const _cstr ) = 0; + virtual void stringize( JNIEnv * _jenv, jstring _value, ConstString * const _cstr ) = 0; public: virtual void addPlugin( const ConstString & _plugin, jobject _jmodule ) = 0; @@ -26,7 +26,7 @@ namespace Mengine public: virtual bool hasPluginMethod( const ConstString & _plugin, const ConstString & _method ) const = 0; - virtual void callPluginMethod( MengineJNIEnvThread * _jenv, const ConstString & _plugin, const ConstString & _method, jobjectArray _args ) const = 0; + virtual void callPluginMethod( JNIEnv * _jenv, const ConstString & _plugin, const ConstString & _method, jobjectArray _args ) const = 0; public: virtual AndroidPluginCallbackInterfacePtr addPluginCallback( const ConstString & _plugin, const ConstString & _method, const AndroidPluginCallbackInterfacePtr & _callback ) = 0; diff --git a/src/Environment/Android/AndroidLogger.cpp b/src/Environment/Android/AndroidLogger.cpp index 915c6b9233..08b65dc517 100644 --- a/src/Environment/Android/AndroidLogger.cpp +++ b/src/Environment/Android/AndroidLogger.cpp @@ -87,7 +87,7 @@ namespace Mengine StdString::strzcat_safe( buffer, data, data_size, MENGINE_LOGGER_MAX_MESSAGE ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); if( jenv == nullptr ) { @@ -141,6 +141,8 @@ namespace Mengine if( jclass_UtilLog_method == nullptr ) { + Mengine_JNI_DeleteLocalRef( jenv, jclass_UtilLog ); + return; } diff --git a/src/Environment/Android/AndroidPluginCallbackInterface.h b/src/Environment/Android/AndroidPluginCallbackInterface.h index 23beb51e7c..699216b4c4 100644 --- a/src/Environment/Android/AndroidPluginCallbackInterface.h +++ b/src/Environment/Android/AndroidPluginCallbackInterface.h @@ -11,7 +11,7 @@ namespace Mengine : public ServantInterface { public: - virtual void invoke( MengineJNIEnvThread * _jenv, jobjectArray _args ) = 0; + virtual void invoke( JNIEnv * _jenv, jobjectArray _args ) = 0; }; //////////////////////////////////////////////////////////////////// typedef IntrusivePtr AndroidPluginCallbackInterfacePtr; diff --git a/src/Environment/Android/ConstStringHolderJString.cpp b/src/Environment/Android/ConstStringHolderJString.cpp index 240c2726c3..11b82ffe5d 100644 --- a/src/Environment/Android/ConstStringHolderJString.cpp +++ b/src/Environment/Android/ConstStringHolderJString.cpp @@ -15,7 +15,7 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - void ConstStringHolderJString::setJString( MengineJNIEnvThread * _jenv, jstring _value ) + void ConstStringHolderJString::setJString( JNIEnv * _jenv, jstring _value ) { m_value = (jstring)Mengine_JNI_NewGlobalRef( _jenv, (jobject)_value ); @@ -27,7 +27,7 @@ namespace Mengine this->setup( data, (ConstStringHolder::size_type)size, (ConstStringHolder::hash_type)hash ); } ////////////////////////////////////////////////////////////////////////// - void ConstStringHolderJString::removeJString( MengineJNIEnvThread * _jenv ) + void ConstStringHolderJString::removeJString( JNIEnv * _jenv ) { const Char * data = this->data(); Mengine_JNI_ReleaseStringUTFChars( _jenv, m_value, data ); diff --git a/src/Environment/Android/ConstStringHolderJString.h b/src/Environment/Android/ConstStringHolderJString.h index 45eb89741a..98d7212254 100644 --- a/src/Environment/Android/ConstStringHolderJString.h +++ b/src/Environment/Android/ConstStringHolderJString.h @@ -18,8 +18,8 @@ namespace Mengine ~ConstStringHolderJString() override; public: - void setJString( MengineJNIEnvThread * _jenv, jstring _value ); - void removeJString( MengineJNIEnvThread * _jenv ); + void setJString( JNIEnv * _jenv, jstring _value ); + void removeJString( JNIEnv * _jenv ); protected: jstring m_value; diff --git a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp index ef719edc4a..e850e87a0b 100644 --- a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp +++ b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp @@ -19,7 +19,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); if( jenv == nullptr ) { @@ -115,7 +115,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); if( jenv == nullptr ) { @@ -133,7 +133,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidAnalyticsEventProvider::onAnalyticsFlush() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); if( jenv == nullptr ) { diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index b9fa6ed68f..ed055823c8 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -576,7 +576,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// size_t AndroidPlatformService::getUserPath( Char * const _userPath ) const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -617,7 +617,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidPlatformService::getUserLocaleLanguage( Char * const _userLocaleLanguage ) const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -847,7 +847,7 @@ namespace Mengine NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_RUN ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -969,7 +969,7 @@ namespace Mengine , _url ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -990,7 +990,7 @@ namespace Mengine , _body ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1011,7 +1011,7 @@ namespace Mengine { LOGGER_MESSAGE( "open delete account" ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1022,7 +1022,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::notifyBootstrapperInitializeBaseServices_() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1031,7 +1031,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::notifyBootstrapperCreateApplication_() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1042,7 +1042,7 @@ namespace Mengine { NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_STOP ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1239,7 +1239,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidPlatformService::isDebuggerPresent() const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1301,7 +1301,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::showKeyboard() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1310,7 +1310,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::hideKeyboard() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1319,7 +1319,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidPlatformService::isShowKeyboard() const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1400,7 +1400,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::messageBox( const Char * _caption, const Char * _format, ... ) const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1433,7 +1433,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidPlatformService::setClipboardText( const Char * _value ) const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1448,7 +1448,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidPlatformService::getClipboardText( Char * _value, size_t _capacity ) const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1681,7 +1681,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// size_t AndroidPlatformService::androidNativeGetAndroidId( Char * _androidId, size_t _capacity ) const { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp b/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp index f14f225c32..9665afbc50 100644 --- a/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp +++ b/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp @@ -43,7 +43,7 @@ namespace Mengine MENGINE_ASSERTION_VALIDATE_UTF8( message.category, MENGINE_UNKNOWN_SIZE ); MENGINE_ASSERTION_VALIDATE_UTF8( message.data, message.size ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.cpp b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.cpp index c4b30abc94..64d4b8ab50 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.cpp +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.cpp @@ -19,7 +19,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// AndroidNativePythonCallback::~AndroidNativePythonCallback() { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -40,7 +40,7 @@ namespace Mengine return m_kernel; } ////////////////////////////////////////////////////////////////////////// - void AndroidNativePythonCallback::setJavaFunctor( MengineJNIEnvThread * _jenv, jobject _functor ) + void AndroidNativePythonCallback::setJavaFunctor( JNIEnv * _jenv, jobject _functor ) { if( m_functor != nullptr ) { @@ -57,7 +57,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidNativePythonCallback::call( bool _result, const Params & _params ) { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.h b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.h index 7ebafa4fe9..a14672d3f4 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.h +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonCallback.h @@ -25,7 +25,7 @@ namespace Mengine pybind::kernel_interface * getKernel() const; public: - void setJavaFunctor( MengineJNIEnvThread * _jenv, jobject _functor ); + void setJavaFunctor( JNIEnv * _jenv, jobject _functor ); MENGINE_NODISCARD jobject getJavaFunctor() const; public: diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp index 5e72a9a324..e27c141a96 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp @@ -18,7 +18,7 @@ namespace Mengine namespace Helper { ////////////////////////////////////////////////////////////////////////// - PyObject * androidNativePythonMakePyObject( pybind::kernel_interface * _kernel, MengineJNIEnvThread * _jenv, jobject _obj, const DocumentInterfacePtr & _doc ) + PyObject * androidNativePythonMakePyObject( pybind::kernel_interface * _kernel, JNIEnv * _jenv, jobject _obj, const DocumentInterfacePtr & _doc ) { PyObject * py_value = nullptr; @@ -210,10 +210,26 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jclass_Class ); } + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Boolean ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Character ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Integer ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Long ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Float ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Double ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_String ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Exception ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_List ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Map ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Set ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_Rect ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_JSONObject ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_JSONArray ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_MengineCallback ); + return py_value; } ////////////////////////////////////////////////////////////////////////// - jobject androidNativePythonListMakeJavaObject( MengineJNIEnvThread * _jenv, const pybind::list & _list ) + jobject androidNativePythonListMakeJavaObject( JNIEnv * _jenv, const pybind::list & _list ) { pybind::list::size_type s = _list.size(); @@ -235,7 +251,7 @@ namespace Mengine return jobject_list; } ////////////////////////////////////////////////////////////////////////// - jobject androidNativePythonDictMakeJavaObject( MengineJNIEnvThread * _jenv, const pybind::dict & _dict ) + jobject androidNativePythonDictMakeJavaObject( JNIEnv * _jenv, const pybind::dict & _dict ) { pybind::dict::size_type s = _dict.size(); @@ -262,7 +278,7 @@ namespace Mengine return jobject_map; } ////////////////////////////////////////////////////////////////////////// - jobject androidNativePythonMakeJavaObject( MengineJNIEnvThread * _jenv, const pybind::object & _obj ) + jobject androidNativePythonMakeJavaObject( JNIEnv * _jenv, const pybind::object & _obj ) { jobject jresult; diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.h b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.h index f65bc67bb4..6ee95b3ce3 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.h +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.h @@ -10,9 +10,9 @@ namespace Mengine { namespace Helper { - MENGINE_NODISCARD PyObject * androidNativePythonMakePyObject( pybind::kernel_interface * _kernel, MengineJNIEnvThread * _jenv, jobject _obj, const DocumentInterfacePtr & _doc ); - MENGINE_NODISCARD jobject androidNativePythonListMakeJavaObject( MengineJNIEnvThread * _jenv, const pybind::list & _list ); - MENGINE_NODISCARD jobject androidNativePythonDictMakeJavaObject( MengineJNIEnvThread * _jenv, const pybind::dict & _dict ); - MENGINE_NODISCARD jobject androidNativePythonMakeJavaObject( MengineJNIEnvThread * _jenv, const pybind::object & _obj ); + MENGINE_NODISCARD PyObject * androidNativePythonMakePyObject( pybind::kernel_interface * _kernel, JNIEnv * _jenv, jobject _obj, const DocumentInterfacePtr & _doc ); + MENGINE_NODISCARD jobject androidNativePythonListMakeJavaObject( JNIEnv * _jenv, const pybind::list & _list ); + MENGINE_NODISCARD jobject androidNativePythonDictMakeJavaObject( JNIEnv * _jenv, const pybind::dict & _dict ); + MENGINE_NODISCARD jobject androidNativePythonMakeJavaObject( JNIEnv * _jenv, const pybind::object & _obj ); } } \ No newline at end of file diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp index 459e6ffe8a..1b81e6bc3d 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp @@ -70,7 +70,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -103,7 +103,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -137,7 +137,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -171,7 +171,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -205,7 +205,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -239,7 +239,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -273,7 +273,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -316,7 +316,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -352,7 +352,7 @@ namespace Mengine , _args.repr().c_str() ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -380,7 +380,7 @@ namespace Mengine return py_result; } ////////////////////////////////////////////////////////////////////////// - bool AndroidNativePythonService::getAndroidMethod( MengineJNIEnvThread * _jenv, const ConstString & _plugin, const ConstString & _method, const pybind::args & _args, const Char * _retType, jvalue * const _jargs, jobject * const _jplugin, jmethodID * const _jmethodId ) const + bool AndroidNativePythonService::getAndroidMethod( JNIEnv * _jenv, const ConstString & _plugin, const ConstString & _method, const pybind::args & _args, const Char * _retType, jvalue * const _jargs, jobject * const _jplugin, jmethodID * const _jmethodId ) const { MENGINE_ASSERTION_FATAL( _args.size() <= 32, "android method plugin '%s' method '%s' max args [32 < %zu]" , _plugin.c_str() diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.h b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.h index b031b950ce..2698c1d374 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.h +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.h @@ -37,7 +37,7 @@ namespace Mengine PyObject * androidJSONObjectMethod( const ConstString & _plugin, const ConstString & _method, const pybind::args & _args ) const override; protected: - bool getAndroidMethod( MengineJNIEnvThread * _jenv, const ConstString & _plugin, const ConstString & _method, const pybind::args & _args, const Char * _retType, jvalue * const _jargs, jobject * const _jplugin, jmethodID * const _jmethodId ) const; + bool getAndroidMethod( JNIEnv * _jenv, const ConstString & _plugin, const ConstString & _method, const pybind::args & _args, const Char * _retType, jvalue * const _jargs, jobject * const _jplugin, jmethodID * const _jmethodId ) const; protected: pybind::kernel_interface * m_kernel; diff --git a/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.cpp b/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.cpp index fb7e030f06..08987ab24f 100644 --- a/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.cpp +++ b/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.cpp @@ -19,7 +19,7 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - void PythonAndroidPluginCallback::invoke( MengineJNIEnvThread * _jenv, jobjectArray _args ) + void PythonAndroidPluginCallback::invoke( JNIEnv * _jenv, jobjectArray _args ) { uint32_t cb_args_size = m_kernel->tuple_size( m_args ); diff --git a/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.h b/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.h index 0fc85dffdf..e1eaa63cfc 100644 --- a/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.h +++ b/src/Plugins/AndroidNativePythonPlugin/PythonAndroidPluginCallback.h @@ -14,7 +14,7 @@ namespace Mengine ~PythonAndroidPluginCallback() override; protected: - void invoke( MengineJNIEnvThread * _jenv, jobjectArray _args ) override; + void invoke( JNIEnv * _jenv, jobjectArray _args ) override; protected: pybind::kernel_interface * m_kernel; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequest.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequest.cpp index d70867dd37..bf728addb8 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequest.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequest.cpp @@ -48,7 +48,7 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( m_response, "not setup 'response'" ); MENGINE_ASSERTION_MEMORY_PANIC( m_receiver, "not setup 'receiver'" ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequest.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequest.h index 60b34bb859..b6d26beb85 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequest.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequest.h @@ -20,7 +20,7 @@ namespace Mengine bool _onThreadTaskProcess() override; protected: - virtual jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _basses ) = 0; + virtual jobject _onHttp( JNIEnv * _jenv, jobject _basses ) = 0; protected: void _onThreadTaskComplete( bool _successful ) override; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.cpp index 7db3baf443..f0e6a46895 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.cpp @@ -17,7 +17,7 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - jobject AndroidHttpRequestDeleteMessage::_onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) + jobject AndroidHttpRequestDeleteMessage::_onHttp( JNIEnv * _jenv, jobject _jrequest ) { jobject jresponse = Helper::AndroidCallObjectStaticClassMethod( _jenv, "org/Mengine/Base/MengineNetwork", "httpRequestDeleteMessage", "(Lorg/Mengine/Base/MengineParamHttpRequest;)Lorg/Mengine/Base/MengineParamHttpResponse;" , _jrequest diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.h index a8ceec8e37..7f7478c1c0 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestDeleteMessage.h @@ -15,7 +15,7 @@ namespace Mengine ~AndroidHttpRequestDeleteMessage() override; protected: - jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _basses ) override; + jobject _onHttp( JNIEnv * _jenv, jobject _basses ) override; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr AndroidHttpRequestDeleteMessagePtr; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.cpp index bbf6619929..f12f59002f 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.cpp @@ -78,7 +78,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidHttpRequestGetAsset::_onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) + jobject AndroidHttpRequestGetAsset::_onHttp( JNIEnv * _jenv, jobject _jrequest ) { jobject jobject_login = Helper::AndroidMakeJObjectString( _jenv, m_login ); jobject jobject_password = Helper::AndroidMakeJObjectString( _jenv, m_password ); diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.h index 64890de632..6a66d317d8 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetAsset.h @@ -31,7 +31,7 @@ namespace Mengine bool _onThreadTaskRun() override; protected: - jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _basses ) override; + jobject _onHttp( JNIEnv * _jenv, jobject _basses ) override; protected: void _onThreadTaskComplete( bool _successful ) override; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.cpp index ad6f7deef9..529db7c977 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.cpp @@ -17,7 +17,7 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - jobject AndroidHttpRequestGetMessage::_onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) + jobject AndroidHttpRequestGetMessage::_onHttp( JNIEnv * _jenv, jobject _jrequest ) { jobject jresponse = Helper::AndroidCallObjectStaticClassMethod( _jenv, "org/Mengine/Base/MengineNetwork", "httpRequestGetMessage", "(Lorg/Mengine/Base/MengineParamHttpRequest;)Lorg/Mengine/Base/MengineParamHttpResponse;" , _jrequest diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.h index c0d7c88e55..933fd84acb 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestGetMessage.h @@ -15,7 +15,7 @@ namespace Mengine ~AndroidHttpRequestGetMessage() override; protected: - jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _basses ) override; + jobject _onHttp( JNIEnv * _jenv, jobject _basses ) override; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr AndroidHttpRequestGetMessagePtr; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.cpp index cc39bce9f1..4fbcdce27c 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.cpp @@ -28,7 +28,7 @@ namespace Mengine return m_data; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidHttpRequestHeaderData::_onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) + jobject AndroidHttpRequestHeaderData::_onHttp( JNIEnv * _jenv, jobject _jrequest ) { const Data::value_type * data_buffer = m_data.data(); Data::size_type data_size = m_data.size(); diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.h index 6f1529063f..6f243ebc0d 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestHeaderData.h @@ -19,7 +19,7 @@ namespace Mengine const Data & getData() const; protected: - jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _basses ) override; + jobject _onHttp( JNIEnv * _jenv, jobject _basses ) override; protected: Data m_data; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.cpp index af7843f3b1..2f08f7075e 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.cpp @@ -17,7 +17,7 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - jobject AndroidHttpRequestPing::_onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) + jobject AndroidHttpRequestPing::_onHttp( JNIEnv * _jenv, jobject _jrequest ) { jobject jresponse = Helper::AndroidCallObjectStaticClassMethod( _jenv, "org/Mengine/Base/MengineNetwork", "httpRequestPing", "(Lorg/Mengine/Base/MengineParamHttpRequest;)Lorg/Mengine/Base/MengineParamHttpResponse;" , _jrequest diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.h index 92b6b89167..bf96ae7f4b 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPing.h @@ -15,7 +15,7 @@ namespace Mengine ~AndroidHttpRequestPing() override; protected: - jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _basses ) override; + jobject _onHttp( JNIEnv * _jenv, jobject _basses ) override; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr AndroidHttpRequestPingPtr; diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.cpp b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.cpp index 171ae57cb6..79c5b41b1c 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.cpp +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.cpp @@ -28,7 +28,7 @@ namespace Mengine return m_properties; } ////////////////////////////////////////////////////////////////////////// - jobject AndroidHttpRequestPostMessage::_onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) + jobject AndroidHttpRequestPostMessage::_onHttp( JNIEnv * _jenv, jobject _jrequest ) { HttpRequestPostProperties::size_type properties_size = m_properties.size(); diff --git a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.h b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.h index 4a1fc81894..71a404fead 100644 --- a/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.h +++ b/src/Systems/AndroidHttpSystem/AndroidHttpRequestPostMessage.h @@ -19,7 +19,7 @@ namespace Mengine const HttpRequestPostProperties & getPostProperties() const; protected: - jobject _onHttp( MengineJNIEnvThread * _jenv, jobject _jrequest ) override; + jobject _onHttp( JNIEnv * _jenv, jobject _jrequest ) override; protected: HttpRequestPostProperties m_properties; From 0c9faa984d924d25faafa3b4a936b9f4448b2dc9 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 4 Sep 2025 14:08:15 +0300 Subject: [PATCH 013/169] update android com.android.tools.build:gradle 8.13.0 --- gradle/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/build.gradle b/gradle/build.gradle index ab4cf4e17c..ed1830005e 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -13,7 +13,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.12.2' + classpath 'com.android.tools.build:gradle:8.13.0' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0' From adaccd474c5ad2eee01d1fd17ec1f503807e251e Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 4 Sep 2025 15:54:40 +0300 Subject: [PATCH 014/169] improve ttf glyph error detected --- src/Plugins/TTFPlugin/TTFFontConfigLoader.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Plugins/TTFPlugin/TTFFontConfigLoader.cpp b/src/Plugins/TTFPlugin/TTFFontConfigLoader.cpp index 35fd43a305..640e4850b5 100644 --- a/src/Plugins/TTFPlugin/TTFFontConfigLoader.cpp +++ b/src/Plugins/TTFPlugin/TTFFontConfigLoader.cpp @@ -65,10 +65,15 @@ namespace Mengine const TTFFontGlyphPtr & glyph = FONT_SERVICE() ->getGlyph( glyphName ); - MENGINE_ASSERTION_MEMORY_PANIC( glyph, "invalid font '%s' don't load glyph '%s'" - , name.c_str() - , glyphName.c_str() - ); + if( glyph == nullptr ) + { + LOGGER_ERROR( "invalid font '%s' don't found glyph '%s'" + , name.c_str() + , glyphName.c_str() + ); + + return false; + } font->setTTFFontGlyph( glyph ); From 7d74a89f50a90b476531f1082c7b845bfed43a7f Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 5 Sep 2025 15:58:43 +0300 Subject: [PATCH 015/169] improve android MengineAdService --- .../org/Mengine/Base/MengineAdService.java | 19 +++++++++++++++ .../org/Mengine/Base/MengineSurfaceView.java | 2 +- .../AppLovin/Core/MengineAppLovinBase.java | 13 +++++----- .../MengineAppLovinInterstitialAd.java | 20 ++++++++++++---- .../RewardedAd/MengineAppLovinRewardedAd.java | 24 +++++++++++++++---- .../AppLovin/MengineAppLovinPlugin.java | 16 ++++++------- .../MengineGooglePlayBillingPlugin.java | 2 -- .../MengineSplashScreenPlugin.java | 5 +--- .../PythonFramework/PythonScriptModule.cpp | 19 +++++++++++++++ 9 files changed, 89 insertions(+), 31 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java index 8c2098813d..ea5688d8ed 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java @@ -42,6 +42,9 @@ public class MengineAdService extends MengineService implements DefaultLifecycle protected long m_countShowRewarded = 0; protected long m_countShowAppOpen = 0; + protected boolean m_adInterstitialShowing = false; + protected boolean m_adRewardedShowing = false; + protected boolean m_optionNoAds = false; protected boolean m_noAds = false; @@ -336,6 +339,22 @@ public boolean getNoAds() { return false; } + public void setInterstitialAdShowing(boolean showing) { + m_adInterstitialShowing = showing; + } + + public boolean isInterstitialAdShowing() { + return m_adInterstitialShowing; + } + + public void setRewardedAdShowing(boolean showing) { + m_adRewardedShowing = showing; + } + + public boolean isRewardedAdShowing() { + return m_adRewardedShowing; + } + @Override public boolean hasBanner() { if (m_adProvider == null) { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineSurfaceView.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineSurfaceView.java index 615adf73dc..b32d06b072 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineSurfaceView.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineSurfaceView.java @@ -104,7 +104,7 @@ public void handlePause() { return; } - MengineLog.logInfo(TAG, "handlePause"); + MengineLog.logDebug(TAG, "handlePause"); m_paused = true; diff --git a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java index b60f12d34f..8aba79dd89 100644 --- a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java +++ b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java @@ -32,9 +32,9 @@ import java.util.concurrent.TimeUnit; public class MengineAppLovinBase implements MengineAppLovinAdInterface { + protected final MengineAdService m_adService; protected final MengineAppLovinPluginInterface m_plugin; protected final MaxAdFormat m_adFormat; - protected final MengineAdResponseInterface m_adResponse; protected String m_adUnitId; @@ -43,14 +43,11 @@ public class MengineAppLovinBase implements MengineAppLovinAdInterface { protected int m_requestAttempt; protected long m_requestTimestamp; - public MengineAppLovinBase(@NonNull MengineAppLovinPluginInterface plugin, MaxAdFormat adFormat) { + public MengineAppLovinBase(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin, MaxAdFormat adFormat) { + m_adService = adService; m_plugin = plugin; m_adFormat = adFormat; - MengineAdService adService = plugin.getService(MengineAdService.class); - - m_adResponse = adService.getAdResponse(); - m_enumeratorRequest = 0; m_requestId = 0; m_requestAttempt = 0; @@ -517,7 +514,9 @@ protected void revenuePaid(MaxAd ad) { MengineFragmentAdRevenue.INSTANCE.adRevenue(revenue); - m_adResponse.onAdRevenuePaid(mediation, adFormat, placement, revenueValue); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdRevenuePaid(mediation, adFormat, placement, revenueValue); } protected void invalidInitialize(String format, Object ... args) throws MengineServiceInvalidInitializeException { diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index 49ca981ff3..3294117200 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -17,6 +17,8 @@ import org.Mengine.Base.MengineActivity; import org.Mengine.Base.MengineAdFormat; import org.Mengine.Base.MengineAdMediation; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; import org.Mengine.Base.MengineNetwork; import org.Mengine.Base.MengineServiceInvalidInitializeException; @@ -32,8 +34,8 @@ public class MengineAppLovinInterstitialAd extends MengineAppLovinBase implement private MaxInterstitialAd m_interstitialAd; - public MengineAppLovinInterstitialAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.INTERSTITIAL); + public MengineAppLovinInterstitialAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.INTERSTITIAL); String MengineAppLovinPlugin_Interstitial_AdUnitId = plugin.getResourceString(METADATA_INTERSTITIAL_ADUNITID); @@ -217,6 +219,8 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setInterstitialState("displayed." + placement + "." + ad.getNetworkName()); + + m_adService.setInterstitialAdShowing(true); } @Override @@ -232,8 +236,12 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setInterstitialState("hidden." + placement + "." + ad.getNetworkName()); + m_adService.setInterstitialAdShowing(false); + MengineUtils.performOnMainThread(() -> { - m_adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_INTERSTITIAL, placement); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_INTERSTITIAL, placement); this.loadAd(); }); @@ -286,8 +294,12 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setInterstitialState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); + m_adService.setInterstitialAdShowing(false); + MengineUtils.performOnMainThread(() -> { - m_adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_INTERSTITIAL, placement, errorCode); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_INTERSTITIAL, placement, errorCode); this.loadAd(); }); diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index 26e0ade1ae..f9926f9635 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -18,6 +18,8 @@ import org.Mengine.Base.MengineActivity; import org.Mengine.Base.MengineAdFormat; import org.Mengine.Base.MengineAdMediation; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; import org.Mengine.Base.MengineNetwork; import org.Mengine.Base.MengineServiceInvalidInitializeException; @@ -34,8 +36,8 @@ public class MengineAppLovinRewardedAd extends MengineAppLovinBase implements Me private MaxRewardedAd m_rewardedAd; - public MengineAppLovinRewardedAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.REWARDED); + public MengineAppLovinRewardedAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.REWARDED); String MengineAppLovinPlugin_Rewarded_AdUnitId = plugin.getResourceString(METADATA_REWARDED_ADUNITID); @@ -232,7 +234,9 @@ public void onUserRewarded(@NonNull MaxAd ad, @NonNull MaxReward reward) { .addParameterLong("reward_amount", amount) .log(); - m_adResponse.onAdUserRewarded(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_REWARDED, placement, label, amount); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdUserRewarded(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_REWARDED, placement, label, amount); } @Override @@ -260,6 +264,8 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setRewardedState("displayed." + placement + "." + ad.getNetworkName()); + + m_adService.setRewardedAdShowing(true); } @Override @@ -275,8 +281,12 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setRewardedState("hidden." + placement + "." + ad.getNetworkName()); + m_adService.setRewardedAdShowing(false); + MengineUtils.performOnMainThread(() -> { - m_adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_REWARDED, placement); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_REWARDED, placement); this.loadAd(); }); @@ -329,8 +339,12 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setRewardedState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); + m_adService.setRewardedAdShowing(false); + MengineUtils.performOnMainThread(() -> { - m_adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_REWARDED, placement, errorCode); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_REWARDED, placement, errorCode); this.loadAd(); }); diff --git a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java index ad5b927be8..a1dacffda8 100644 --- a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java +++ b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java @@ -85,8 +85,8 @@ protected AppLovinSdk getAppLovinSdkInstance() { } @SuppressWarnings("unchecked") - protected T createAd(@NonNull List adUnitIds, @NonNull String className) throws MengineServiceInvalidInitializeException { - T ad = (T)this.newInstance(className, true, this); + protected T createAd(@NonNull MengineAdService adService, @NonNull List adUnitIds, @NonNull String className) throws MengineServiceInvalidInitializeException { + T ad = (T)this.newInstance(className, true, adService, this); if (ad == null) { this.invalidInitialize("not found AppLovin extension ad: %s" @@ -126,37 +126,37 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS List adUnitIds = new ArrayList<>(); if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_BANNERAD == true && noAds == false) { - m_bannerAd = this.createAd(adUnitIds, "org.Mengine.Plugin.AppLovin.BannerAd.MengineAppLovinBannerAd"); + m_bannerAd = this.createAd(adService, adUnitIds, "org.Mengine.Plugin.AppLovin.BannerAd.MengineAppLovinBannerAd"); m_ads.add(m_bannerAd); } if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_INTERSTITIALAD == true && noAds == false) { - m_interstitialAd = this.createAd(adUnitIds, "org.Mengine.Plugin.AppLovin.InterstitialAd.MengineAppLovinInterstitialAd"); + m_interstitialAd = this.createAd(adService, adUnitIds, "org.Mengine.Plugin.AppLovin.InterstitialAd.MengineAppLovinInterstitialAd"); m_ads.add(m_interstitialAd); } if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_REWARDEDAD == true) { - m_rewardedAd = this.createAd(adUnitIds, "org.Mengine.Plugin.AppLovin.RewardedAd.MengineAppLovinRewardedAd"); + m_rewardedAd = this.createAd(adService, adUnitIds, "org.Mengine.Plugin.AppLovin.RewardedAd.MengineAppLovinRewardedAd"); m_ads.add(m_rewardedAd); } if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_APPOPENAD == true && noAds == false) { - m_appOpenAd = this.createAd(adUnitIds, "org.Mengine.Plugin.AppLovin.AppOpenAd.MengineAppLovinAppOpenAd"); + m_appOpenAd = this.createAd(adService, adUnitIds, "org.Mengine.Plugin.AppLovin.AppOpenAd.MengineAppLovinAppOpenAd"); m_ads.add(m_appOpenAd); } if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_MRECAD == true && noAds == false) { - m_MRECAd = this.createAd(adUnitIds, "org.Mengine.Plugin.AppLovin.MRECAd.MengineAppLovinMRECAd"); + m_MRECAd = this.createAd(adService, adUnitIds, "org.Mengine.Plugin.AppLovin.MRECAd.MengineAppLovinMRECAd"); m_ads.add(m_MRECAd); } if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_NATIVEAD == true && noAds == false) { - m_nativeAd = this.createAd(adUnitIds, "org.Mengine.Plugin.AppLovin.NativeAd.MengineAppLovinNativeAd"); + m_nativeAd = this.createAd(adService, adUnitIds, "org.Mengine.Plugin.AppLovin.NativeAd.MengineAppLovinNativeAd"); m_ads.add(m_nativeAd); } diff --git a/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java b/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java index 00d0f3606c..da31287599 100644 --- a/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java +++ b/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java @@ -230,8 +230,6 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat @Override public void onResume(@NonNull MengineActivity activity) { - this.logInfo("onResume"); - if (m_billingClient == null) { return; } diff --git a/gradle/plugins/SplashScreen/src/main/java/org/Mengine/Plugin/SplashScreen/MengineSplashScreenPlugin.java b/gradle/plugins/SplashScreen/src/main/java/org/Mengine/Plugin/SplashScreen/MengineSplashScreenPlugin.java index 026ea890a1..e1562a35ab 100644 --- a/gradle/plugins/SplashScreen/src/main/java/org/Mengine/Plugin/SplashScreen/MengineSplashScreenPlugin.java +++ b/gradle/plugins/SplashScreen/src/main/java/org/Mengine/Plugin/SplashScreen/MengineSplashScreenPlugin.java @@ -153,14 +153,11 @@ public void onDestroy(@NonNull MengineActivity activity) { @Override public void onPause(@NonNull MengineActivity activity) { - this.logInfo("onPause"); - + //Empty } @Override public void onResume(@NonNull MengineActivity activity) { - this.logInfo("onResume"); - if (m_differedHideOnResume == true) { this.logInfo("deferred hide splash screen on resume"); diff --git a/src/Frameworks/PythonFramework/PythonScriptModule.cpp b/src/Frameworks/PythonFramework/PythonScriptModule.cpp index c81d6528a2..9a5061a19f 100644 --- a/src/Frameworks/PythonFramework/PythonScriptModule.cpp +++ b/src/Frameworks/PythonFramework/PythonScriptModule.cpp @@ -43,6 +43,16 @@ namespace Mengine pybind::object module_function = m_module.get_attr( _method.c_str() ); + if( module_function.is_invalid() == true ) + { + LOGGER_ERROR( "module '%s' invalid get initializer '%s'" + , m_module.repr().c_str() + , _method.c_str() + ); + + return false; + } + pybind::object py_result = module_function.call(); #if defined(MENGINE_DEBUG) @@ -88,6 +98,15 @@ namespace Mengine pybind::object module_function = m_module.get_attr( _method.c_str() ); + if( module_function.is_invalid() == true ) + { + LOGGER_ERROR( "invalid get finalizer '%s'" + , _method.c_str() + ); + + return false; + } + module_function.call(); return true; From 482d68477ec3e6b5fb2fcd255ecbd5a917ef35d5 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 5 Sep 2025 17:55:35 +0300 Subject: [PATCH 016/169] improve logging change locale --- src/Engine/Application.cpp | 7 ++++- src/Plugins/TTFPlugin/TTFFont.cpp | 9 +++++++ .../PackageService/PackageService.cpp | 26 +++++++++++++++++-- src/Services/PackageService/PackageService.h | 2 +- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Engine/Application.cpp b/src/Engine/Application.cpp index 812a4f61a2..77bf545ca8 100644 --- a/src/Engine/Application.cpp +++ b/src/Engine/Application.cpp @@ -2270,7 +2270,7 @@ namespace Mengine m_locale = _locale; - LOGGER_INFO( "system", "set locale '%s' old '%s'" + LOGGER_INFO( "system", "begin change locale '%s' old '%s'" , m_locale.c_str() , prevLocale.c_str() ); @@ -2278,6 +2278,11 @@ namespace Mengine NOTIFICATION_NOTIFY( NOTIFICATOR_CHANGE_LOCALE_PREPARE, prevLocale, _locale ); NOTIFICATION_NOTIFY( NOTIFICATOR_CHANGE_LOCALE, prevLocale, _locale ); NOTIFICATION_NOTIFY( NOTIFICATOR_CHANGE_LOCALE_POST, prevLocale, _locale ); + + LOGGER_INFO( "system", "end change locale '%s' old '%s'" + , m_locale.c_str() + , prevLocale.c_str() + ); } ////////////////////////////////////////////////////////////////////////// const ConstString & Application::getLocale() const diff --git a/src/Plugins/TTFPlugin/TTFFont.cpp b/src/Plugins/TTFPlugin/TTFFont.cpp index c0806aa32f..574dbcf6a1 100644 --- a/src/Plugins/TTFPlugin/TTFFont.cpp +++ b/src/Plugins/TTFPlugin/TTFFont.cpp @@ -109,6 +109,15 @@ namespace Mengine } } + if( m_glyph == nullptr ) + { + LOGGER_ERROR( "ttf font '%s' not setup glyph" + , this->getName().c_str() + ); + + return false; + } + if( m_glyph->compile() == false ) { return false; diff --git a/src/Services/PackageService/PackageService.cpp b/src/Services/PackageService/PackageService.cpp index 437e1ad1d5..f50bf3c378 100644 --- a/src/Services/PackageService/PackageService.cpp +++ b/src/Services/PackageService/PackageService.cpp @@ -93,7 +93,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool PackageService::_initializeService() { - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_LOCALE, &PackageService::notifyChangeLocale, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_LOCALE, &PackageService::notifyChangeLocale_, MENGINE_DOCUMENT_FACTORABLE ); m_factoryPackage = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); @@ -560,6 +560,10 @@ namespace Mengine if( package->enable() == false ) { + LOGGER_ERROR( "invalid enable package '%s'" + , package->getPackageDesc().name.c_str() + ); + return false; } } @@ -606,6 +610,10 @@ namespace Mengine { if( package->enable() == false ) { + LOGGER_ERROR( "invalid enable package '%s'" + , package->getPackageDesc().name.c_str() + ); + return false; } } @@ -638,6 +646,10 @@ namespace Mengine { if( package->disable() == false ) { + LOGGER_ERROR( "invalid disable package '%s'" + , package->getPackageDesc().name.c_str() + ); + return false; } } @@ -645,11 +657,16 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void PackageService::notifyChangeLocale( const ConstString & _prevLocale, const ConstString & _currentlocale ) + void PackageService::notifyChangeLocale_( const ConstString & _prevLocale, const ConstString & _currentlocale ) { MENGINE_UNUSED( _prevLocale ); MENGINE_UNUSED( _currentlocale ); + LOGGER_INFO( "package", "begin change locale '%s' -> '%s'" + , _prevLocale.c_str() + , _currentlocale.c_str() + ); + const Tags & platformTags = PLATFORM_SERVICE() ->getPlatformTags(); @@ -672,6 +689,11 @@ namespace Mengine return; } + + LOGGER_INFO( "package", "end change locale '%s' -> '%s'" + , _prevLocale.c_str() + , _currentlocale.c_str() + ); } ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Services/PackageService/PackageService.h b/src/Services/PackageService/PackageService.h index 16b7cf604f..09d12f1b9e 100644 --- a/src/Services/PackageService/PackageService.h +++ b/src/Services/PackageService/PackageService.h @@ -46,7 +46,7 @@ namespace Mengine bool disableLocalePackage( const ConstString & _locale, const Tags & _platformTag ); protected: - void notifyChangeLocale( const ConstString & _prevLocale, const ConstString & _currentlocale ); + void notifyChangeLocale_( const ConstString & _prevLocale, const ConstString & _currentlocale ); protected: typedef Vector VectorPackages; From 2382e0293cd537ff969153dbff95892b08beac5a Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 6 Sep 2025 21:27:23 +0300 Subject: [PATCH 017/169] fix android rewarded&interstitial showing flag --- .../src/main/java/org/Mengine/Base/MengineAdService.java | 4 ++++ .../InterstitialAd/MengineAppLovinInterstitialAd.java | 2 -- .../Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java index ea5688d8ed..d9a67bbb16 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java @@ -508,6 +508,8 @@ public boolean showInterstitial(String placement) { m_lastShowInterstitial = MengineUtils.getTimestamp(); m_countShowInterstitial += 1; + this.setInterstitialAdShowing(true); + adPoint.showAd(); return true; @@ -601,6 +603,8 @@ public boolean showRewarded(String placement) { m_lastShowRewarded = MengineUtils.getTimestamp(); m_countShowRewarded += 1; + this.setRewardedAdShowing(true); + adPoint.showAd(); return true; diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index 3294117200..12a8974764 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -219,8 +219,6 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setInterstitialState("displayed." + placement + "." + ad.getNetworkName()); - - m_adService.setInterstitialAdShowing(true); } @Override diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index f9926f9635..59c1838729 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -264,8 +264,6 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setRewardedState("displayed." + placement + "." + ad.getNetworkName()); - - m_adService.setRewardedAdShowing(true); } @Override From 9f117593b1aad4739301337b3b7fd3536acad793 Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 6 Sep 2025 23:25:15 +0300 Subject: [PATCH 018/169] remove MENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE --- cmake/dev_options_template.cmake | 1 - cmake/macro_template.cmake | 1 - cmake/master_options_template.cmake | 1 - cmake/mengine_template.cmake | 4 ---- gradle/app.gradle | 2 -- gradle/libraries/Mengine/build.gradle | 2 -- src/Services/LoggerService/LoggerService.cpp | 12 ------------ 7 files changed, 23 deletions(-) diff --git a/cmake/dev_options_template.cmake b/cmake/dev_options_template.cmake index 489765979d..2000b0fdb2 100644 --- a/cmake/dev_options_template.cmake +++ b/cmake/dev_options_template.cmake @@ -1,6 +1,5 @@ OPTION(MENGINE_BUILD_MENGINE_MASTER_RELEASE "Mengine build master release" OFF) OPTION(MENGINE_BUILD_MENGINE_BUILD_PUBLISH "Mengine build publish" OFF) -OPTION(MENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE "Mengine set logger level verbose" OFF) OPTION(MENGINE_BUILD_MENGINE_DEVELOPMENT "Mengine build development" OFF) OPTION(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED "Mengine script embedded" ON) OPTION(MENGINE_EXTERNAL_PDB "Mengine external pdb" OFF) diff --git a/cmake/macro_template.cmake b/cmake/macro_template.cmake index 84c357789a..a7bb2f7731 100644 --- a/cmake/macro_template.cmake +++ b/cmake/macro_template.cmake @@ -195,7 +195,6 @@ MACRO(SET_MENGINE_ENVIRONMENT MENGINE_TARGET MENGINE_RENDER MENGINE_PLATFORM MEN MESSAGE("MENGINE_PROJECT_NAME: ${MENGINE_PROJECT_NAME}") MESSAGE("MENGINE_BUILD_MENGINE_MASTER_RELEASE: ${MENGINE_BUILD_MENGINE_MASTER_RELEASE}") MESSAGE("MENGINE_BUILD_MENGINE_BUILD_PUBLISH: ${MENGINE_BUILD_MENGINE_BUILD_PUBLISH}") - MESSAGE("MENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE: ${MENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE}") MESSAGE("MENGINE_BUILD_MENGINE_DEVELOPMENT: ${MENGINE_BUILD_MENGINE_DEVELOPMENT}") MESSAGE("MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED: ${MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED}") MESSAGE("MENGINE_USE_ADDRESS_SANITIZE: ${MENGINE_USE_ADDRESS_SANITIZE}") diff --git a/cmake/master_options_template.cmake b/cmake/master_options_template.cmake index 9dbf1157cb..ac5d2b4f60 100644 --- a/cmake/master_options_template.cmake +++ b/cmake/master_options_template.cmake @@ -1,6 +1,5 @@ OPTION(MENGINE_BUILD_MENGINE_MASTER_RELEASE "Mengine build master release" ON) OPTION(MENGINE_BUILD_MENGINE_BUILD_PUBLISH "Mengine build publish" OFF) -OPTION(MENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE "Mengine set logger level verbose" OFF) OPTION(MENGINE_BUILD_MENGINE_DEVELOPMENT "Mengine build development" OFF) OPTION(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED "Mengine script embedded" ON) OPTION(MENGINE_EXTERNAL_PDB "Mengine external pdb" OFF) diff --git a/cmake/mengine_template.cmake b/cmake/mengine_template.cmake index 468c6e412d..c7d9de98a7 100644 --- a/cmake/mengine_template.cmake +++ b/cmake/mengine_template.cmake @@ -23,10 +23,6 @@ if(MENGINE_BUILD_MENGINE_BUILD_PUBLISH) MENGINE_ADD_DEFINITION(MENGINE_BUILD_PUBLISH) endif() -if(MENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE) - MENGINE_ADD_DEFINITION(MENGINE_LOGGER_LEVEL_FORCE_VERBOSE=1) -endif() - if(MENGINE_BUILD_MENGINE_DEVELOPMENT) MENGINE_ADD_DEFINITION(MENGINE_BUILD_DEVELOPMENT) endif() diff --git a/gradle/app.gradle b/gradle/app.gradle index 647252f15e..f8c045bc93 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -10,7 +10,6 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' def ANDROID_APP_BUILD_NUMBER = Utils.getIntegerProperty("ANDROID_APP_BUILD_NUMBER", 0) def ANDROID_APP_BUILD_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_VERSION", "0.0.0") def ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBLISH", false) -def ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE = Utils.getBooleanProperty("ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE", false) def ANDROID_APP_SPLIT_ENABLE = Utils.getBooleanProperty("ANDROID_APP_SPLIT_ENABLE", false) def ANDROID_APP_BUNDLE_ENABLE = Utils.getBooleanProperty("ANDROID_APP_BUNDLE_ENABLE", false) def ANDROID_APP_DELIVERY_PACKAGES = Utils.getStringProperty("ANDROID_APP_DELIVERY_PACKAGES", null) @@ -60,7 +59,6 @@ def MENGINE_APP_PLUGIN_AMPLITUDE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMPL Utils.logString("ANDROID_APP_DELIVERY_PACKAGES", ANDROID_APP_DELIVERY_PACKAGES) Utils.logAvailable("ANDROID_APP_BUILD_PUBLISH", ANDROID_APP_BUILD_PUBLISH) -Utils.logAvailable("ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE", ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE) Utils.logAvailable("ANDROID_APP_SPLIT_ENABLE", ANDROID_APP_SPLIT_ENABLE) Utils.logAvailable("ANDROID_APP_BUNDLE_ENABLE", ANDROID_APP_BUNDLE_ENABLE) Utils.logInteger("ANDROID_APP_BUILD_NUMBER", ANDROID_APP_BUILD_NUMBER) diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index 2e467f8bb8..ab770dd2bf 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -4,7 +4,6 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' def ANDROID_APP_BUILD_NUMBER = Utils.getIntegerProperty("ANDROID_APP_BUILD_NUMBER", 0) def ANDROID_APP_BUILD_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_VERSION", "0.0.0") def ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBLISH", false) -def ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE = Utils.getBooleanProperty("ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE", false) def MENGINE_APP_SECURE_VALUE = Utils.getStringProperty("MENGINE_APP_SECURE_VALUE", "0123456789A") def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") def MENGINE_APP_DEPLOY_PATH = Utils.getStringProperty("MENGINE_APP_DEPLOY_PATH", rootProject.projectDir.getAbsolutePath() + "/$ANDROID_APP_MAIN_PROJECT") @@ -57,7 +56,6 @@ android { cmake_arguments.add("-DMENGINE_BUILD_VERSION:STRING=${ANDROID_APP_BUILD_VERSION}") cmake_arguments.add("-DMENGINE_DEPENDENCIES_PROJECT:STRING=Depends_Android") cmake_arguments.add("-DMENGINE_BUILD_MENGINE_BUILD_PUBLISH:BOOLEAN=" + (ANDROID_APP_BUILD_PUBLISH ? "ON" : "OFF")) - cmake_arguments.add("-DMENGINE_BUILD_MENGINE_LOGGER_LEVEL_FORCE_VERBOSE:BOOLEAN=" + (ANDROID_APP_LOGGER_LEVEL_FORCE_VERBOSE ? "ON" : "OFF")) cmake_arguments.add("-DMENGINE_SECURE_VALUE:STRING=${MENGINE_APP_SECURE_VALUE}") cmake_arguments.add("-DMENGINE_DEPLOY_PATH:STRING=${MENGINE_APP_DEPLOY_PATH}") diff --git a/src/Services/LoggerService/LoggerService.cpp b/src/Services/LoggerService/LoggerService.cpp index ac61dd850f..a51e4642c2 100644 --- a/src/Services/LoggerService/LoggerService.cpp +++ b/src/Services/LoggerService/LoggerService.cpp @@ -31,14 +31,6 @@ #include "Config/StdString.h" #include "Config/StdAlgorithm.h" -#ifndef MENGINE_LOGGER_LEVEL_FORCE_VERBOSE -#define MENGINE_LOGGER_LEVEL_FORCE_VERBOSE 0 -#endif - -#if MENGINE_LOGGER_LEVEL_FORCE_VERBOSE == 1 -# define MENGINE_LOGGER_LEVEL_FORCE_VERBOSE_ENABLE -#endif - #ifndef MENGINE_LOGGER_MESSAGE_BUFFER_MAX #define MENGINE_LOGGER_MESSAGE_BUFFER_MAX 64 #endif @@ -126,10 +118,6 @@ namespace Mengine logLevel = LM_VERBOSE; } -#if defined(MENGINE_LOGGER_LEVEL_FORCE_VERBOSE_ENABLE) - logLevel = LM_VERBOSE; -#endif - this->setVerboseLevel( logLevel ); uint32_t verboseFilter = 0xFFFFFFFF; From 5af94c048c7c352ee522861ac863f2908d487dac Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 7 Sep 2025 14:02:26 +0300 Subject: [PATCH 019/169] add android MENGINE_APP_BUILD_LOGGER_INFO --- cmake/win32_template.cmake | 2 +- gradle/libraries/Mengine/build.gradle | 11 +++++++- src/Engine/Application.cpp | 8 +++--- src/Environment/Android/AndroidEnv.cpp | 2 +- .../PythonFramework/PythonScriptService.cpp | 8 +++--- src/Kernel/BuildMode.cpp | 8 +++--- src/Kernel/BuildMode.h | 8 +++--- src/Kernel/Factorable.h | 2 +- .../Win32SentryPlugin/Win32SentryService.cpp | 2 +- src/Services/LoggerService/LoggerService.cpp | 28 +++++++++++++------ src/Services/SoundService/SoundService.cpp | 4 +-- .../DX9RenderSystem/DX9RenderErrorHelper.h | 2 ++ 12 files changed, 53 insertions(+), 32 deletions(-) diff --git a/cmake/win32_template.cmake b/cmake/win32_template.cmake index 0dcf96e0e9..9c4aeea972 100644 --- a/cmake/win32_template.cmake +++ b/cmake/win32_template.cmake @@ -31,7 +31,7 @@ set(CMAKE_C_FLAGS "/DWIN32 /D_WINDOWS /W4") set(CMAKE_C_FLAGS_DEBUG "${MENGINE_C_DEBUG_INFORMATION_FORMAT} /Od /RTC1") set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /GL") -set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /W4 /wd4121 /wd4250 /wd5105 /MP /EHsc /GR /UMBCS /D_UNICODE /DUNICODE") +set(CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /W4 /wd4121 /wd4250 /wd5105 /wd4324 /MP /EHsc /GR /UMBCS /D_UNICODE /DUNICODE") set(CMAKE_CXX_FLAGS_DEBUG "${MENGINE_CXX_DEBUG_INFORMATION_FORMAT} /Od /RTC1") set(CMAKE_CXX_FLAGS_RELEASE "/DNDEBUG /wd4702 /O2 /GL") diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index ab770dd2bf..e5781def06 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -7,7 +7,8 @@ def ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBL def MENGINE_APP_SECURE_VALUE = Utils.getStringProperty("MENGINE_APP_SECURE_VALUE", "0123456789A") def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") def MENGINE_APP_DEPLOY_PATH = Utils.getStringProperty("MENGINE_APP_DEPLOY_PATH", rootProject.projectDir.getAbsolutePath() + "/$ANDROID_APP_MAIN_PROJECT") -def MENGINE_APP_BUILD_ASSERTION_DEBUG= Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -1) +def MENGINE_APP_BUILD_ASSERTION_DEBUG = Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -1) +def MENGINE_APP_BUILD_LOGGER_INFO = Utils.getIntegerProperty("MENGINE_APP_BUILD_LOGGER_INFO", -1) def MENGINE_APP_ENABLE_STRICT_MODE = Utils.getBooleanProperty("MENGINE_APP_ENABLE_STRICT_MODE", false) def ANDROID_APP_SCREEN_ORIENTATION = Utils.getStringProperty("ANDROID_APP_SCREEN_ORIENTATION", "sensorPortrait") @@ -71,6 +72,10 @@ android { if (MENGINE_APP_BUILD_ASSERTION_DEBUG != -1) { cppFlags += ["-DMENGINE_ASSERTION_DEBUG=${MENGINE_APP_BUILD_ASSERTION_DEBUG}"] } + + if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { + cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] + } } } } @@ -87,6 +92,10 @@ android { if (MENGINE_APP_BUILD_ASSERTION_DEBUG != -1) { cppFlags += ["-DMENGINE_ASSERTION_DEBUG=${MENGINE_APP_BUILD_ASSERTION_DEBUG}"] } + + if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { + cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] + } } } } diff --git a/src/Engine/Application.cpp b/src/Engine/Application.cpp index 77bf545ca8..5d4d221de4 100644 --- a/src/Engine/Application.cpp +++ b/src/Engine/Application.cpp @@ -306,10 +306,10 @@ namespace Mengine ->messageBox( "Mengine", "author: IROV\nemail for support/feedbacks/improvement request and suggestions: irov13@mail.ru" ); } - const Char * engineGitURL = Helper::getEngineGITURL(); - const Char * engineGitSHA1 = Helper::getEngineGITSHA1(); - const Char * engineGitBranch = Helper::getEngineGITBranch(); - const Char * engineGitDate = Helper::getEngineGITDate(); + const Char * engineGitURL = Helper::getEngineGitURL(); + const Char * engineGitSHA1 = Helper::getEngineGitSHA1(); + const Char * engineGitBranch = Helper::getEngineGitBranch(); + const Char * engineGitDate = Helper::getEngineGitDate(); if( HAS_OPTION( "engineinfo" ) == true ) { diff --git a/src/Environment/Android/AndroidEnv.cpp b/src/Environment/Android/AndroidEnv.cpp index b65d39acf9..7fbe4c5839 100644 --- a/src/Environment/Android/AndroidEnv.cpp +++ b/src/Environment/Android/AndroidEnv.cpp @@ -41,7 +41,7 @@ extern "C" ////////////////////////////////////////////////////////////////////////// JNIEXPORT jstring JNICALL MENGINE_JAVA_INTERFACE( AndroidEnv_1getEngineGITSHA1 )( JNIEnv * env, jclass cls ) { - const Mengine::Char * ENGINE_GIT_SHA1 = Mengine::Helper::getEngineGITSHA1(); + const Mengine::Char * ENGINE_GIT_SHA1 = Mengine::Helper::getEngineGitSHA1(); jstring result = env->NewStringUTF( ENGINE_GIT_SHA1 ); diff --git a/src/Frameworks/PythonFramework/PythonScriptService.cpp b/src/Frameworks/PythonFramework/PythonScriptService.cpp index 1861c07ee7..10d2c5de24 100644 --- a/src/Frameworks/PythonFramework/PythonScriptService.cpp +++ b/src/Frameworks/PythonFramework/PythonScriptService.cpp @@ -321,16 +321,16 @@ namespace Mengine uint32_t python_version = kernel->get_python_version(); this->addGlobalModuleT( "_PYTHON_VERSION", python_version ); - const Char * engineGITSHA1 = Helper::getEngineGITSHA1(); + const Char * engineGITSHA1 = Helper::getEngineGitSHA1(); this->addGlobalModuleT( "_ENGINE_GITSHA1", engineGITSHA1 ); - const Char * engineGITURL = Helper::getEngineGITURL(); + const Char * engineGITURL = Helper::getEngineGitURL(); this->addGlobalModuleT( "_ENGINE_GITURL", engineGITURL ); - const Char * engineGITBranch = Helper::getEngineGITBranch(); + const Char * engineGITBranch = Helper::getEngineGitBranch(); this->addGlobalModuleT( "_ENGINE_GITBRANCH", engineGITBranch ); - const Char * engineGITData = Helper::getEngineGITDate(); + const Char * engineGITData = Helper::getEngineGitDate(); this->addGlobalModuleT( "_ENGINE_GITDATA", engineGITData ); const Char * contentCommit = Helper::getContentCommit(); diff --git a/src/Kernel/BuildMode.cpp b/src/Kernel/BuildMode.cpp index 95b17544a7..2736738c65 100644 --- a/src/Kernel/BuildMode.cpp +++ b/src/Kernel/BuildMode.cpp @@ -89,28 +89,28 @@ namespace Mengine return windowDebug; } ////////////////////////////////////////////////////////////////////////// - const Char * getEngineGITSHA1() + const Char * getEngineGitSHA1() { const Char * ENGINE_GIT_SHA1 = MENGINE_ENGINE_GIT_SHA1; return ENGINE_GIT_SHA1; } ////////////////////////////////////////////////////////////////////////// - const Char * getEngineGITURL() + const Char * getEngineGitURL() { const Char * ENGINE_GIT_URL = MENGINE_ENGINE_GIT_URL; return ENGINE_GIT_URL; } ////////////////////////////////////////////////////////////////////////// - const Char * getEngineGITBranch() + const Char * getEngineGitBranch() { const Char * ENGINE_GIT_BRANCH = MENGINE_ENGINE_GIT_BRANCH; return ENGINE_GIT_BRANCH; } ////////////////////////////////////////////////////////////////////////// - const Char * getEngineGITDate() + const Char * getEngineGitDate() { const Char * ENGINE_GIT_DATE = MENGINE_ENGINE_GIT_DATE; diff --git a/src/Kernel/BuildMode.h b/src/Kernel/BuildMode.h index 4b24b8dbdf..9584f85525 100644 --- a/src/Kernel/BuildMode.h +++ b/src/Kernel/BuildMode.h @@ -14,10 +14,10 @@ namespace Mengine bool isBuildPublish(); bool isMasterRelease(); bool isWindowsDebug(); - const Char * getEngineGITSHA1(); - const Char * getEngineGITURL(); - const Char * getEngineGITBranch(); - const Char * getEngineGITDate(); + const Char * getEngineGitSHA1(); + const Char * getEngineGitURL(); + const Char * getEngineGitBranch(); + const Char * getEngineGitDate(); const Char * getEngineVersion(); const Char * getContentCommit(); const Char * getBuildSolutionName(); diff --git a/src/Kernel/Factorable.h b/src/Kernel/Factorable.h index 5b319e1e3e..14141528f0 100644 --- a/src/Kernel/Factorable.h +++ b/src/Kernel/Factorable.h @@ -8,7 +8,7 @@ #include "Config/UniqueId.h" #if defined(MENGINE_DEBUG) -#include "Config/Timestamp.h" +# include "Config/Timestamp.h" #endif ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/Win32SentryPlugin/Win32SentryService.cpp b/src/Plugins/Win32SentryPlugin/Win32SentryService.cpp index 6c562cd197..b53ce26852 100644 --- a/src/Plugins/Win32SentryPlugin/Win32SentryService.cpp +++ b/src/Plugins/Win32SentryPlugin/Win32SentryService.cpp @@ -464,7 +464,7 @@ namespace Mengine sentry_set_extra( "Publish", sentry_value_new_bool( publishMode ) ); - const Char * ENGINE_GIT_SHA1 = Helper::getEngineGITSHA1(); + const Char * ENGINE_GIT_SHA1 = Helper::getEngineGitSHA1(); LOGGER_INFO_PROTECTED( "sentry", "Sentry set extra [Engine Commit: %s]" , ENGINE_GIT_SHA1 diff --git a/src/Services/LoggerService/LoggerService.cpp b/src/Services/LoggerService/LoggerService.cpp index a51e4642c2..95fe9e6be4 100644 --- a/src/Services/LoggerService/LoggerService.cpp +++ b/src/Services/LoggerService/LoggerService.cpp @@ -124,8 +124,8 @@ namespace Mengine this->setVerboseFilter( verboseFilter ); - const Char * verboses[MENGINE_OPTIONS_VALUES_MAX]; - uint32_t verboses_count; + const Char * verboses[MENGINE_OPTIONS_VALUES_MAX] = {nullptr}; + uint32_t verboses_count = 0; if( OPTIONS_SERVICE() ->getOptionValues( "verboses", verboses, &verboses_count ) == true ) { @@ -158,7 +158,7 @@ namespace Mengine "SILENT", // LM_SILENT "FATAL", // LM_FATAL "MESSAGE_RELEASE", // LM_MESSAGE_RELEASE - "ERROR", // LM_ERROR + "ERROR", // LM_ERROR "WARNING", // LM_WARNING "MESSAGE", // LM_MESSAGE "INFO", // LM_INFO @@ -168,15 +168,25 @@ namespace Mengine const Char * loggerLevel = loggerLevels[logLevel]; + const Char * buildVersion = Helper::getBuildVersion(); + const Char * buildNumber = Helper::getBuildNumberString(); + const Char * engineGitSHA1 = Helper::getEngineGitSHA1(); + const Char * contentCommit = Helper::getContentCommit(); bool developmentMode = Helper::isDevelopmentMode(); - Char loggerLevelMessage[256 + 1] = {'\0'}; - size_t loggerLevelMessageLen = MENGINE_SNPRINTF( loggerLevelMessage, 256, "start logger with verbose level [%s] Mode [%s] Debug [%s] Master [%s] Publish [%s]" + + Char loggerLevelMessage[512 + 1] = {'\0'}; + size_t loggerLevelMessageLen = MENGINE_SNPRINTF( loggerLevelMessage, 512, + "logger: %s [%s] [%s] [%s] [%s] %s [%s] %.8s | %.8s" , loggerLevel - , developmentMode == true ? "Dev" : "Normal" - , MENGINE_DEBUG_VALUE( "True", "False" ) - , MENGINE_MASTER_RELEASE_VALUE( "True", "False" ) - , MENGINE_BUILD_PUBLISH_VALUE( "True", "False" ) + , developmentMode == true ? "dev" : "prod" + , MENGINE_DEBUG_VALUE( "debug", "release" ) + , MENGINE_MASTER_RELEASE_VALUE( "master", "RC" ) + , MENGINE_BUILD_PUBLISH_VALUE( "publish", "manual" ) + , buildVersion + , buildNumber + , engineGitSHA1 + , contentCommit ); LoggerMessage msg; diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index f4843a0b19..6560b8ada8 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -1513,12 +1513,12 @@ namespace Mengine if( playCount > Limit_MaxSoundPlay ) { - Timestamp timestamp = Helper::getSystemTimestamp(); - Stringstream ss; ss << "max sound play count exceeded: " << Limit_MaxSoundPlay; #if defined(MENGINE_DEBUG) + Timestamp timestamp = Helper::getSystemTimestamp(); + for( const SoundIdentityInterfacePtr & identity : m_soundIdentities ) { ss << "\n" diff --git a/src/Systems/DX9RenderSystem/DX9RenderErrorHelper.h b/src/Systems/DX9RenderSystem/DX9RenderErrorHelper.h index 24944b1548..88f807952f 100644 --- a/src/Systems/DX9RenderSystem/DX9RenderErrorHelper.h +++ b/src/Systems/DX9RenderSystem/DX9RenderErrorHelper.h @@ -42,6 +42,7 @@ namespace Mengine if( Object != nullptr )\ {\ ULONG ref = Object -> Release();\ + MENGINE_UNUSED( ref );\ MENGINE_ASSERTION_FATAL( ref == 0, "release dx object ref != 0" );\ Object = nullptr;\ }\ @@ -63,6 +64,7 @@ namespace Mengine if( Object != nullptr )\ {\ ULONG ref = Object -> Release();\ + MENGINE_UNUSED( ref );\ Object = nullptr;\ }\ }while(false) From 8f8ad3ce2d3ff04932061fc99873ae8ebc91995a Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 7 Sep 2025 19:50:02 +0300 Subject: [PATCH 020/169] improve PackageInterface --- src/Interface/PackageInterface.h | 4 + src/Services/PackageService/Package.h | 4 +- .../PackageService/PackageService.cpp | 81 ++++++++++++++----- src/Services/PackageService/PackageService.h | 11 ++- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src/Interface/PackageInterface.h b/src/Interface/PackageInterface.h index 5f26ec18c1..2ff0f00d4c 100644 --- a/src/Interface/PackageInterface.h +++ b/src/Interface/PackageInterface.h @@ -17,6 +17,10 @@ namespace Mengine class PackageInterface : public ServantInterface { + public: + virtual bool initialize( const FileGroupInterfacePtr & _baseFileGroup, const PackageDesc & _desc ) = 0; + virtual void finalize() = 0; + public: virtual const PackageDesc & getPackageDesc() const = 0; diff --git a/src/Services/PackageService/Package.h b/src/Services/PackageService/Package.h index 6c2086f06a..a49eb11f71 100644 --- a/src/Services/PackageService/Package.h +++ b/src/Services/PackageService/Package.h @@ -21,8 +21,8 @@ namespace Mengine ~Package() override; public: - bool initialize( const FileGroupInterfacePtr & _baseFileGroup, const PackageDesc & _desc ); - void finalize(); + bool initialize( const FileGroupInterfacePtr & _baseFileGroup, const PackageDesc & _desc ) override; + void finalize() override; public: const PackageDesc & getPackageDesc() const override; diff --git a/src/Services/PackageService/PackageService.cpp b/src/Services/PackageService/PackageService.cpp index f50bf3c378..f52958aa38 100644 --- a/src/Services/PackageService/PackageService.cpp +++ b/src/Services/PackageService/PackageService.cpp @@ -106,7 +106,7 @@ namespace Mengine { NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_CHANGE_LOCALE ); - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { package->finalize(); } @@ -266,7 +266,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool PackageService::hasPackage( const ConstString & _name ) const { - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -366,7 +366,7 @@ namespace Mengine it != it_end; ++it ) { - const PackagePtr & package = *it; + const PackageInterfacePtr & package = *it; const PackageDesc & desc = package->getPackageDesc(); @@ -389,7 +389,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// const PackageInterfacePtr & PackageService::getPackage( const ConstString & _name ) const { - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -406,7 +406,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool PackageService::existLocalePackage( const ConstString & _locale, const Tags & _platformTags ) const { - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -438,7 +438,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void PackageService::foreachPackages( const LambdaPackage & _lambda ) const { - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { _lambda( package ); } @@ -450,7 +450,7 @@ namespace Mengine localesSet.insert( m_defaultLocale ); - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -471,7 +471,7 @@ namespace Mengine { bool hasLocale = false; - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -499,7 +499,7 @@ namespace Mengine VectorPackages packages; - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -544,7 +544,7 @@ namespace Mengine } } - for( const PackagePtr & package : packages ) + for( const PackageInterfacePtr & package : packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -585,11 +585,11 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool PackageService::enableLocalePackage( const ConstString & _locale, const Tags & _platformTag ) + bool PackageService::enableLocalePackages( const ConstString & _locale, const Tags & _platformTag ) { VectorPackages packages; - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -606,7 +606,7 @@ namespace Mengine packages.emplace_back( package ); } - for( const PackagePtr & package : packages ) + for( const PackageInterfacePtr & package : packages ) { if( package->enable() == false ) { @@ -621,11 +621,11 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool PackageService::disableLocalePackage( const ConstString & _locale, const Tags & _platformTag ) + bool PackageService::disableLocalePackages( const ConstString & _locale, const Tags & _platformTag ) { VectorPackages packages; - for( const PackagePtr & package : m_packages ) + for( const PackageInterfacePtr & package : m_packages ) { const PackageDesc & desc = package->getPackageDesc(); @@ -642,7 +642,48 @@ namespace Mengine packages.emplace_back( package ); } - for( const PackagePtr & package : packages ) + for( const PackageInterfacePtr & package : packages ) + { + if( package->disable() == false ) + { + LOGGER_ERROR( "invalid disable package '%s'" + , package->getPackageDesc().name.c_str() + ); + + return false; + } + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// + bool PackageService::disableAllLocalesPackages( const Tags & _platformTag ) + { + VectorPackages packages; + + for( const PackageInterfacePtr & package : m_packages ) + { + if( package->isEnable() == false ) + { + continue; + } + + const PackageDesc & desc = package->getPackageDesc(); + + if( _platformTag.hasTags( desc.platform ) == false ) + { + continue; + } + + if( desc.locales.empty() == true ) + { + continue; + } + + packages.emplace_back( package ); + } + + for( const PackageInterfacePtr & package : packages ) { if( package->disable() == false ) { @@ -670,17 +711,17 @@ namespace Mengine const Tags & platformTags = PLATFORM_SERVICE() ->getPlatformTags(); - if( this->disableLocalePackage( _prevLocale, platformTags ) == false ) + if( this->disableAllLocalesPackages( platformTags ) == false ) { - LOGGER_ERROR( "invalid disable locale package '%s' platform '%s'" - , _prevLocale.c_str() + LOGGER_ERROR( "invalid disable all locale package [platform: %s]" + , Helper::tagsToString( platformTags ).c_str() ); return; } - if( this->enableLocalePackage( _currentlocale, platformTags ) == false ) + if( this->enableLocalePackages( _currentlocale, platformTags ) == false ) { LOGGER_ERROR( "invalid enable locale package '%s' platform '%s'" , _currentlocale.c_str() diff --git a/src/Services/PackageService/PackageService.h b/src/Services/PackageService/PackageService.h index 09d12f1b9e..e51847dc0c 100644 --- a/src/Services/PackageService/PackageService.h +++ b/src/Services/PackageService/PackageService.h @@ -41,15 +41,18 @@ namespace Mengine public: bool enablePackages( const ConstString & _locale, const Tags & _platformTags ) override; - public: - bool enableLocalePackage( const ConstString & _locale, const Tags & _platformTag ); - bool disableLocalePackage( const ConstString & _locale, const Tags & _platformTag ); + protected: + bool enableLocalePackages( const ConstString & _locale, const Tags & _platformTag ); + bool disableLocalePackages( const ConstString & _locale, const Tags & _platformTag ); + + protected: + bool disableAllLocalesPackages( const Tags & _platformTag ); protected: void notifyChangeLocale_( const ConstString & _prevLocale, const ConstString & _currentlocale ); protected: - typedef Vector VectorPackages; + typedef Vector VectorPackages; VectorPackages m_packages; FactoryInterfacePtr m_factoryPackage; From 1cb6790c591f780e7101a7fb081068dca540fe22 Mon Sep 17 00:00:00 2001 From: Yuriy Levchenko Date: Mon, 8 Sep 2025 00:13:12 +0300 Subject: [PATCH 021/169] Add Android file logger service (#127) --- gradle/app.gradle | 7 ++ .../Base/MengineFileLoggerService.java | 107 ++++++++++++++++++ .../Base/MengineProcedureSendMail.java | 47 ++++++++ .../java/org/Mengine/Base/MengineUtils.java | 2 - gradle/settings.gradle.kts | 2 +- src/Environment/Android/AndroidHelper.cpp | 4 +- .../AndroidNativePythonHelper.cpp | 6 + .../AndroidNativePythonService.cpp | 12 +- 8 files changed, 178 insertions(+), 9 deletions(-) create mode 100644 gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java diff --git a/gradle/app.gradle b/gradle/app.gradle index f8c045bc93..583829da8c 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -20,6 +20,7 @@ def MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OP def MENGINE_APP_SERVICE_AD = Utils.existAppService("MENGINE_APP_SERVICE_AD") def MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS = Utils.existAppService("MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS") +def MENGINE_APP_SERVICE_FILELOGGER = Utils.existAppService("MENGINE_APP_SERVICE_FILELOGGER") def MENGINE_APP_PLUGIN_SPLASHSCREEN = Utils.existAppPlugin("MENGINE_APP_PLUGIN_SPLASHSCREEN") def MENGINE_APP_PLUGIN_LOCAL_NOTIFICATIONS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_LOCAL_NOTIFICATIONS") @@ -387,6 +388,12 @@ if (MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS == true) { android.ext.plugins += 'org.Mengine.Base.MengineMonitorConnectivityStatusService' } +Utils.logAvailable("MENGINE_APP_SERVICE_FILELOGGER", MENGINE_APP_SERVICE_FILELOGGER) + +if (MENGINE_APP_SERVICE_FILELOGGER == true) { + android.ext.plugins += 'org.Mengine.Base.MengineFileLoggerService' +} + Utils.logAvailable("MENGINE_APP_PLUGIN_SPLASHSCREEN", MENGINE_APP_PLUGIN_SPLASHSCREEN) if (MENGINE_APP_PLUGIN_SPLASHSCREEN == true) { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java new file mode 100644 index 0000000000..fe5a6e0e26 --- /dev/null +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java @@ -0,0 +1,107 @@ +package org.Mengine.Base; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Map; + +public class MengineFileLoggerService extends MengineService implements MengineListenerApplication, MengineListenerLogger { + public static final String SERVICE_NAME = "FileLogger"; + public static final boolean SERVICE_EMBEDDING = true; + + private File m_logFile; + private FileWriter m_writer; + + public File getLogFile() { + return m_logFile; + } + + @Override + public void onAppInit(@NonNull MengineApplication application, boolean isMainProcess) throws MengineServiceInvalidInitializeException { + if (isMainProcess == false) { + return; + } + + Context context = application.getApplicationContext(); + + m_logFile = MengineUtils.createTempFile(context, "mng_log_", ".log"); + + if (m_logFile == null) { + this.logError("invalid create log file"); + + return; + } + + try { + m_writer = new FileWriter(m_logFile, true); + } catch (IOException e) { + this.logException(e, Map.of("file", m_logFile.getAbsolutePath())); + } + } + + @Override + public void onAppFinalize(@NonNull MengineApplication application) { + super.onAppFinalize(application); + + if (m_writer != null) { + try { + m_writer.close(); + } catch (IOException ignored) { + // ignore + } + + m_writer = null; + } + + m_logFile = null; + } + + private void writeLine(String line) { + if (m_writer == null) { + return; + } + + try { + m_writer.write(line); + m_writer.flush(); + } catch (IOException ignored) { + // ignore + } + } + + private static String makeTimestamp() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US).format(new Date()); + } + + @Override + public void onMengineLog(@NonNull MengineApplication application, @NonNull MengineParamLoggerMessage message) { + String timestamp = MengineFileLoggerService.makeTimestamp(); + + String line = String.format(Locale.US, "%s |%s| [%s] %s" + , timestamp + , message.MESSAGE_THREAD + , message.MESSAGE_CATEGORY.toString() + , message.MESSAGE_DATA); + + this.writeLine(line); + } + + @Override + public void onMengineException(@NonNull MengineApplication application, @NonNull MengineParamLoggerException exception) { + String timestamp = MengineFileLoggerService.makeTimestamp(); + + String line = String.format(Locale.US, "%s [EXCEPTION] %s: %s" + , timestamp + , exception.EXCEPTION_CATEGORY + , exception.EXCEPTION_THROWABLE); + + this.writeLine(line); + } +} diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java index af77c15329..2b4bb8f423 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java @@ -227,6 +227,53 @@ public boolean execute(@NonNull MengineActivity activity) { ); } + MengineFileLoggerService fileLoggerService = application.getService(MengineFileLoggerService.class); + + if (fileLoggerService != null) { + File logFileAndroid = fileLoggerService.getLogFile(); + + if (logFileAndroid != null && logFileAndroid.exists()) { + File fileLoggerZipFile = MengineUtils.createTempFile(context, "mng_android_log_", ".zip"); + + if (fileLoggerZipFile != null && MengineUtils.zipFiles(logFileAndroid, fileLoggerZipFile) == true) { + Uri fileLoggerZipFileUri = MengineUtils.getUriForFile(context, fileLoggerZipFile); + + if (fileLoggerZipFileUri == null) { + return false; + } + + MengineLog.logInfo(TAG, "linkingOpenMail attach android log file '%s' for mail: %s subject: %s", + fileLoggerZipFileUri, + m_email, + m_subject + ); + + fileUris.add(fileLoggerZipFileUri); + } else { + body_builder.append("\n\n[ERROR] invalid zip file logger android log file"); + + MengineLog.logMessage(TAG, "linkingOpenMail invalid zip file logger android log file for mail: %s subject: %s", + m_email, + m_subject + ); + } + } else { + body_builder.append("\n\nNOT_FOUND_FILE_LOGGER_LOG"); + + MengineLog.logMessage(TAG, "linkingOpenMail not found file logger android log file for mail: %s subject: %s", + m_email, + m_subject + ); + } + } else { + body_builder.append("\n\nNOT_FOUND_FILE_LOGGER_SERVICE"); + + MengineLog.logMessage(TAG, "linkingOpenMail not found file logger service for mail: %s subject: %s", + m_email, + m_subject + ); + } + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, fileUris); } catch (IOException e) { body_builder.append("\n\n[ERROR] invalid attaches file"); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java index a1ac2e0b00..8a9b2ee40d 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java @@ -1461,8 +1461,6 @@ static public String getPrintDeviceInfo() { return deviceInfo.toString(); } - - static public Bundle getMetaDataBundle(@NonNull MengineApplication application) { Context context = application.getApplicationContext(); diff --git a/gradle/settings.gradle.kts b/gradle/settings.gradle.kts index b0a7b67e85..b7a335cc0e 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -189,4 +189,4 @@ includePlugin("MENGINE_APP_PLUGIN_DATADOG", ":plugins:DataDog") includePlugin("MENGINE_APP_PLUGIN_VIBRATOR", ":plugins:Vibrator") includePlugin("MENGINE_APP_PLUGIN_AMPLITUDE", ":plugins:Amplitude") -println("Mengine complete settings") \ No newline at end of file +println("Mengine complete settings") diff --git a/src/Environment/Android/AndroidHelper.cpp b/src/Environment/Android/AndroidHelper.cpp index 4feb46cb5c..17a4c7b799 100644 --- a/src/Environment/Android/AndroidHelper.cpp +++ b/src/Environment/Android/AndroidHelper.cpp @@ -367,6 +367,8 @@ namespace Mengine jmethodID ArrayList_add = Mengine_JNI_GetMethodID( _jenv, jclass_ArrayList, "add", "(Ljava/lang/Object;)Z" ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_ArrayList ); + jboolean result = Mengine_JNI_CallBooleanMethod( _jenv, _list, ArrayList_add, _value ); Helper::AndroidEnvExceptionCheck( _jenv ); @@ -397,8 +399,6 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( _jenv, jclass_Map ); - Mengine_JNI_DeleteLocalRef( _jenv, jclass_Map ); - jobject value = Mengine_JNI_CallObjectMethod( _jenv, _map, Map_get, _key ); Helper::AndroidEnvExceptionCheck( _jenv ); diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp index e27c141a96..8b524796f8 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonHelper.cpp @@ -101,6 +101,8 @@ namespace Mengine py_value = _kernel->exception_new( obj_str ); Mengine_JNI_ReleaseStringUTFChars( _jenv, jstring_message, obj_str ); + + Mengine_JNI_DeleteLocalRef( _jenv, jstring_message ); } else if( Mengine_JNI_IsInstanceOf( _jenv, _obj, jclass_List ) == JNI_TRUE ) { @@ -239,6 +241,8 @@ namespace Mengine jobject jobject_list = Mengine_JNI_NewObject( _jenv, jclass_ArrayList, jmethod_List_constructor, (jsize)s ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_ArrayList ); + for( const pybind::object & o : _list ) { jobject jobject_element = Helper::androidNativePythonMakeJavaObject( _jenv, o ); @@ -261,6 +265,8 @@ namespace Mengine jobject jobject_map = Mengine_JNI_NewObject( _jenv, jclass_HashMap, jmethod_HashMap_constructor ); + Mengine_JNI_DeleteLocalRef( _jenv, jclass_HashMap ); + for( const pybind::dict_pair_value & pair : _dict ) { const Char * key = pair.key(); diff --git a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp index 1b81e6bc3d..1e3f31dc58 100644 --- a/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp +++ b/src/Plugins/AndroidNativePythonPlugin/AndroidNativePythonService.cpp @@ -294,8 +294,6 @@ namespace Mengine Helper::AndroidEnvExceptionCheck( jenv ); - Mengine_JNI_PopLocalFrame( jenv, nullptr ); - const Char * jresult_str = Mengine_JNI_GetStringUTFChars( jenv, jstring_result, nullptr ); jsize jresult_size = Mengine_JNI_GetStringLength( jenv, jstring_result ); @@ -305,6 +303,8 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( jenv, jstring_result ); + Mengine_JNI_PopLocalFrame( jenv, nullptr ); + return py_value; } ////////////////////////////////////////////////////////////////////////// @@ -339,6 +339,8 @@ namespace Mengine PyObject * py_result = Helper::androidNativePythonMakePyObject( m_kernel, jenv, jresult, MENGINE_DOCUMENT_FACTORABLE ); + Mengine_JNI_DeleteLocalRef( jenv, jresult ); + Mengine_JNI_PopLocalFrame( jenv, nullptr ); return py_result; @@ -373,10 +375,12 @@ namespace Mengine Helper::AndroidEnvExceptionCheck( jenv ); - Mengine_JNI_PopLocalFrame( jenv, nullptr ); - PyObject * py_result = Helper::androidNativePythonMakePyObject( m_kernel, jenv, jresult, MENGINE_DOCUMENT_FACTORABLE ); + Mengine_JNI_DeleteLocalRef( jenv, jresult ); + + Mengine_JNI_PopLocalFrame( jenv, nullptr ); + return py_result; } ////////////////////////////////////////////////////////////////////////// From 5e2a9934ea94fcc8a451933d04cafe5b340765ac Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 8 Sep 2025 20:39:08 +0300 Subject: [PATCH 022/169] add android MengineLoggerMessageSource --- .../java/org/Mengine/Base/MengineFileLoggerService.java | 4 ++++ .../Mengine/src/main/java/org/Mengine/Base/MengineLog.java | 2 +- .../java/org/Mengine/Base/MengineLoggerMessageSource.java | 6 ++++++ .../java/org/Mengine/Base/MengineParamLoggerMessage.java | 4 +++- src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp | 6 +++++- 5 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLoggerMessageSource.java diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java index fe5a6e0e26..7769dd3d79 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java @@ -82,6 +82,10 @@ private static String makeTimestamp() { @Override public void onMengineLog(@NonNull MengineApplication application, @NonNull MengineParamLoggerMessage message) { + if (message.MESSAGE_SOURCE != MengineLoggerMessageSource.MengineLoggerMessageSource_Java) { + return; + } + String timestamp = MengineFileLoggerService.makeTimestamp(); String line = String.format(Locale.US, "%s |%s| [%s] %s" diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java index 355e96055e..08cc0d66e6 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java @@ -84,7 +84,7 @@ private static void logString(int level, @NonNull MengineTag category, int filte MengineUtils.Code code = MengineUtils.getCurrentThreadCode(6); - MengineParamLoggerMessage message = new MengineParamLoggerMessage(category, thread, level, filter, code.file, code.line, code.method, data); + MengineParamLoggerMessage message = new MengineParamLoggerMessage(MengineLoggerMessageSource.MengineLoggerMessageSource_Java, category, thread, level, filter, code.file, code.line, code.method, data); MengineFragmentLogger.INSTANCE.log(message); } diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLoggerMessageSource.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLoggerMessageSource.java new file mode 100644 index 0000000000..5adce79f2a --- /dev/null +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLoggerMessageSource.java @@ -0,0 +1,6 @@ +package org.Mengine.Base; + +public enum MengineLoggerMessageSource { + MengineLoggerMessageSource_Engine, + MengineLoggerMessageSource_Java, +} \ No newline at end of file diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineParamLoggerMessage.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineParamLoggerMessage.java index fb81eadbe6..01b69417a0 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineParamLoggerMessage.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineParamLoggerMessage.java @@ -4,7 +4,8 @@ import androidx.annotation.Nullable; public class MengineParamLoggerMessage { - public MengineParamLoggerMessage(@NonNull MengineTag category, @NonNull String thread, int level, int filter, @Nullable String file, int line, @Nullable String function, @NonNull String data) { + public MengineParamLoggerMessage(@NonNull MengineLoggerMessageSource source, @NonNull MengineTag category, @NonNull String thread, int level, int filter, @Nullable String file, int line, @Nullable String function, @NonNull String data) { + this.MESSAGE_SOURCE = source; this.MESSAGE_CATEGORY = category; this.MESSAGE_THREAD = thread; this.MESSAGE_LEVEL = level; @@ -15,6 +16,7 @@ public MengineParamLoggerMessage(@NonNull MengineTag category, @NonNull String t this.MESSAGE_DATA = data; } + @NonNull public final MengineLoggerMessageSource MESSAGE_SOURCE; @NonNull public final MengineTag MESSAGE_CATEGORY; @NonNull public final String MESSAGE_THREAD; public final int MESSAGE_LEVEL; diff --git a/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp b/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp index 9665afbc50..fbb4d76d38 100644 --- a/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp +++ b/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp @@ -49,7 +49,7 @@ namespace Mengine jclass jclass_MengineLoggerMessageParam = Helper::AndroidEnvFindClass( jenv, "org/Mengine/Base/MengineParamLoggerMessage" ); - jmethodID jmethod_MengineLoggerMessageParam_constructor = Mengine_JNI_GetMethodID( jenv, jclass_MengineLoggerMessageParam, "", "(Lorg/Mengine/Base/MengineTag;Ljava/lang/String;IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;)V" ); + jmethodID jmethod_MengineLoggerMessageParam_constructor = Mengine_JNI_GetMethodID( jenv, jclass_MengineLoggerMessageParam, "", "(Lorg/Mengine/Base/MengineLoggerMessageSource;Lorg/Mengine/Base/MengineTag;Ljava/lang/String;IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;)V" ); jstring jstring_category = Mengine_JNI_NewStringUTF( jenv, message.category ); @@ -59,6 +59,8 @@ namespace Mengine jobject jobject_CategoryTag = Mengine_JNI_CallStaticObjectMethod( jenv, jclass_MengineTag, mid_MengineTag_of, jstring_category ); + jobject jobject_source = Helper::AndroidGetJObjectEnum( jenv, "org/Mengine/Base/MengineLoggerMessageSource", "MengineLoggerMessageSource_Engine" ); + jstring jstring_thread = Mengine_JNI_NewStringUTF( jenv, message.thread.c_str() ); jint jlevel = message.level; @@ -77,6 +79,7 @@ namespace Mengine jstring jstring_data = Mengine_JNI_NewStringUTF( jenv, message.data ); jobject jstring_message = Mengine_JNI_NewObject( jenv, jclass_MengineLoggerMessageParam, jmethod_MengineLoggerMessageParam_constructor + , jobject_source , jobject_CategoryTag , jstring_thread , jlevel @@ -92,6 +95,7 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( jenv, jclass_MengineLoggerMessageParam ); Mengine_JNI_DeleteLocalRef( jenv, jclass_MengineTag ); + Mengine_JNI_DeleteLocalRef( jenv, jobject_source ); Mengine_JNI_DeleteLocalRef( jenv, jobject_CategoryTag ); Mengine_JNI_DeleteLocalRef( jenv, jstring_category ); Mengine_JNI_DeleteLocalRef( jenv, jstring_thread ); From f376b10792e1c370c2667b107d6b67dfd27c66ef Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 9 Sep 2025 01:23:30 +0300 Subject: [PATCH 023/169] fix SoundService --- .../PythonFramework/SoundScriptEmbedding.cpp | 42 ++++++-- src/Services/SoundService/SoundService.cpp | 95 ++++++++++--------- 2 files changed, 83 insertions(+), 54 deletions(-) diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index 63bef05c2b..b357e615b1 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -161,7 +161,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// FactoryInterfacePtr m_factorySoundNodeListener; ////////////////////////////////////////////////////////////////////////// - SoundIdentityInterfacePtr s_createSoundSource( const ConstString & _resourceName, bool _loop, ESoundSourceCategory _category, const pybind::object & _cbs, const pybind::args & _args, const DocumentInterfacePtr & _doc ) + SoundIdentityInterfacePtr s_createSoundIdentity( const ConstString & _resourceName, bool _loop, ESoundSourceCategory _category, const pybind::object & _cbs, const pybind::args & _args, const DocumentInterfacePtr & _doc ) { MENGINE_ASSERTION_RESOURCE_TYPE_BY_NAME( _resourceName, ResourceSoundPtr, nullptr, "resource '%s' type does not match 'ResourceSound'" , _resourceName.c_str() @@ -188,6 +188,10 @@ namespace Mengine if( soundBuffer == nullptr ) { + LOGGER_ERROR( "resource sound '%s' invalid create sound buffer" + , _resourceName.c_str() + ); + resource->release(); return nullptr; @@ -243,7 +247,7 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); - SoundIdentityInterfacePtr soundIdentity = s_createSoundSource( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); + SoundIdentityInterfacePtr soundIdentity = s_createSoundIdentity( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); if( soundIdentity == nullptr ) { @@ -262,6 +266,9 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -275,7 +282,7 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); - SoundIdentityInterfacePtr soundIdentity = s_createSoundSource( _resourceName, _loop, ES_SOURCE_CATEGORY_VOICE, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); + SoundIdentityInterfacePtr soundIdentity = s_createSoundIdentity( _resourceName, _loop, ES_SOURCE_CATEGORY_VOICE, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); if( soundIdentity == nullptr ) { @@ -294,6 +301,9 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -324,9 +334,9 @@ namespace Mengine , _position ); - SoundIdentityInterfacePtr sourceEmitter = s_createSoundSource( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); + SoundIdentityInterfacePtr soundIdentity = s_createSoundIdentity( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); - if( sourceEmitter == nullptr ) + if( soundIdentity == nullptr ) { LOGGER_ERROR( "invalid create sound source '%s'" , _resourceName.c_str() @@ -336,18 +346,21 @@ namespace Mengine } if( SOUND_SERVICE() - ->setPosition( sourceEmitter, _position ) == false ) + ->setPosition( soundIdentity, _position ) == false ) { LOGGER_ERROR( "resource sound '%s' invalid set pos '%f'" , _resourceName.c_str() , _position ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } if( SOUND_SERVICE() - ->playEmitter( sourceEmitter ) == false ) + ->playEmitter( soundIdentity ) == false ) { LOGGER_WARNING( "invalid voice play resource '%s' file '%s' from position '%f'" , _resourceName.c_str() @@ -355,10 +368,13 @@ namespace Mengine , _position ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } - return sourceEmitter; + return soundIdentity; } ////////////////////////////////////////////////////////////////////////// float soundGetPosition( const SoundIdentityInterfacePtr & _identity ) @@ -481,7 +497,7 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); - SoundIdentityInterfacePtr soundIdentity = s_createSoundSource( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); + SoundIdentityInterfacePtr soundIdentity = s_createSoundIdentity( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); if( soundIdentity == nullptr ) { @@ -499,6 +515,9 @@ namespace Mengine , _resourceName.c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -569,7 +588,7 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); - SoundIdentityInterfacePtr soundIdentity = s_createSoundSource( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); + SoundIdentityInterfacePtr soundIdentity = s_createSoundIdentity( _resourceName, _loop, ES_SOURCE_CATEGORY_SOUND, _cbs, _args, MENGINE_DOCUMENT_PYTHON ); if( soundIdentity == nullptr ) { @@ -587,6 +606,9 @@ namespace Mengine , _resourceName.c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 6560b8ada8..5af6443fd0 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -283,6 +283,11 @@ namespace Mengine continue; } + if( state == ESS_CANCEL ) + { + continue; + } + this->stopSoundBufferUpdate_( identity ); const SoundSourceInterfacePtr & source = identity->getSoundSource(); @@ -673,6 +678,13 @@ namespace Mengine { ESoundSourceState state = identity->getState(); + if( state == ESS_CANCEL ) + { + m_soundIdentitiesEndAux.emplace_back( identity ); + + continue; + } + if( state != ESS_PLAY ) { continue; @@ -702,64 +714,35 @@ namespace Mengine continue; } - if( state == ESS_CANCEL ) - { - m_soundIdentitiesEndAux.emplace_back( identity ); - } - else - { - const ThreadWorkerSoundBufferUpdatePtr & worker = identity->getWorkerUpdateBuffer(); + const ThreadWorkerSoundBufferUpdatePtr & worker = identity->getWorkerUpdateBuffer(); - float time_left = identity->getTimeLeft(); - float time_new = time_left - _context->time; + float time_left = identity->getTimeLeft(); + float time_new = time_left - _context->time; - if( worker != nullptr ) + if( worker != nullptr ) + { + if( worker->isDone() == true ) { - if( worker->isDone() == true ) - { - identity->setState( ESS_STOP ); - - this->stopSoundBufferUpdate_( identity ); + identity->setState( ESS_STOP ); - const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); + this->stopSoundBufferUpdate_( identity ); - if( soundSource != nullptr ) - { - soundSource->stop(); - } - - identity->setTimeLeft( 0.f ); + const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); - m_soundIdentitiesEndAux.emplace_back( identity ); - } - else + if( soundSource != nullptr ) { - if( time_new <= 0.f ) - { - identity->setTimeLeft( 0.f ); - } - else - { - identity->setTimeLeft( time_new ); - } + soundSource->stop(); } + + identity->setTimeLeft( 0.f ); + + m_soundIdentitiesEndAux.emplace_back( identity ); } else { if( time_new <= 0.f ) { - identity->setState( ESS_STOP ); - - const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); - - if( soundSource != nullptr ) - { - soundSource->stop(); - } - identity->setTimeLeft( 0.f ); - - m_soundIdentitiesEndAux.emplace_back( identity ); } else { @@ -767,6 +750,28 @@ namespace Mengine } } } + else + { + if( time_new <= 0.f ) + { + identity->setState( ESS_STOP ); + + const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); + + if( soundSource != nullptr ) + { + soundSource->stop(); + } + + identity->setTimeLeft( 0.f ); + + m_soundIdentitiesEndAux.emplace_back( identity ); + } + else + { + identity->setTimeLeft( time_new ); + } + } } if( process == true ) @@ -1511,6 +1516,8 @@ namespace Mengine uint32_t Limit_MaxSoundPlay = CONFIG_VALUE_INTEGER( "Limit", "MaxSoundPlay", 32 ); + LOGGER_MESSAGE( "[Sound] play count: %u all: %u", playCount, m_soundIdentities.size() ); + if( playCount > Limit_MaxSoundPlay ) { Stringstream ss; From b97873cfd2f9d8d6541ebc4c3c7522e1b24154a0 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 9 Sep 2025 01:23:57 +0300 Subject: [PATCH 024/169] fix commit --- src/Services/SoundService/SoundService.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 5af6443fd0..59dd00a662 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -1516,8 +1516,6 @@ namespace Mengine uint32_t Limit_MaxSoundPlay = CONFIG_VALUE_INTEGER( "Limit", "MaxSoundPlay", 32 ); - LOGGER_MESSAGE( "[Sound] play count: %u all: %u", playCount, m_soundIdentities.size() ); - if( playCount > Limit_MaxSoundPlay ) { Stringstream ss; From c8c57ac82248923cfb0b9db345cc4858ea1b6f48 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 9 Sep 2025 14:24:14 +0300 Subject: [PATCH 025/169] set account permanent save --- src/Services/AccountService/Account.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index d05ee97c5b..7548eef6c1 100644 --- a/src/Services/AccountService/Account.cpp +++ b/src/Services/AccountService/Account.cpp @@ -125,6 +125,14 @@ namespace Mengine m_settings.emplace( _setting, st ); + if( this->save() == false ) + { + LOGGER_ERROR( "account '%s' setting '%s' save failed" + , m_accountId.c_str() + , _setting.c_str() + ); + } + return true; } ////////////////////////////////////////////////////////////////////////// @@ -146,6 +154,14 @@ namespace Mengine st.value.assign( _value ); + if( this->save() == false ) + { + LOGGER_ERROR( "account '%s' setting '%s' save failed" + , m_accountId.c_str() + , _setting.c_str() + ); + } + if( st.provider != nullptr ) { st.provider->onChangeSetting( _value ); @@ -541,4 +557,4 @@ namespace Mengine return exist; } ////////////////////////////////////////////////////////////////////////// -} +} \ No newline at end of file From a735cdb3c05faa66d7b130a73969487b89626373 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 9 Sep 2025 16:11:16 +0300 Subject: [PATCH 026/169] fix Account fix PythonScriptService fix OpenALSoundBufferStream stopSource --- .../PythonFramework/PythonScriptService.cpp | 39 ++++++++++--------- .../PythonFramework/PythonScriptService.h | 1 + src/Services/AccountService/Account.cpp | 8 ---- .../OpenALSoundBufferStream.cpp | 21 ++++++++++ 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/Frameworks/PythonFramework/PythonScriptService.cpp b/src/Frameworks/PythonFramework/PythonScriptService.cpp index 10d2c5de24..6a36db64ee 100644 --- a/src/Frameworks/PythonFramework/PythonScriptService.cpp +++ b/src/Frameworks/PythonFramework/PythonScriptService.cpp @@ -281,6 +281,7 @@ namespace Mengine PythonScriptService::PythonScriptService() : m_kernel( nullptr ) , m_moduleMengine( nullptr ) + , m_pyOldExcepthook( nullptr ) , m_pyOldStdOutHandle( nullptr ) , m_pyOldStdErrorHandle( nullptr ) , m_initializeModules( false ) @@ -310,15 +311,18 @@ namespace Mengine m_kernel = kernel; - kernel->set_sys_excepthook( &Detail::py_excepthook, this ); + m_pyOldExcepthook = m_kernel->get_sys_excepthook(); + m_kernel->incref( m_pyOldExcepthook ); + + m_kernel->set_sys_excepthook_f( &Detail::py_excepthook, this ); m_moduleMengine = this->initModule( "Mengine" ); this->addGlobalModule( "Mengine", m_moduleMengine ); - kernel->set_current_module( m_moduleMengine ); + m_kernel->set_current_module( m_moduleMengine ); - uint32_t python_version = kernel->get_python_version(); + uint32_t python_version = m_kernel->get_python_version(); this->addGlobalModuleT( "_PYTHON_VERSION", python_version ); const Char * engineGITSHA1 = Helper::getEngineGitSHA1(); @@ -383,11 +387,11 @@ namespace Mengine .def_property( "softspace", &PythonScriptLogger::getSoftspace, &PythonScriptLogger::setSoftspace ) ; - m_pyOldStdOutHandle = kernel->getStdOutHandle(); - kernel->incref( m_pyOldStdOutHandle ); + m_pyOldStdOutHandle = m_kernel->getStdOutHandle(); + m_kernel->incref( m_pyOldStdOutHandle ); - m_pyOldStdErrorHandle = kernel->getStdErrorHandle(); - kernel->incref( m_pyOldStdErrorHandle ); + m_pyOldStdErrorHandle = m_kernel->getStdErrorHandle(); + m_kernel->incref( m_pyOldStdErrorHandle ); PythonScriptLoggerPtr loggerWarning = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); @@ -395,7 +399,7 @@ namespace Mengine loggerWarning->setLoggerLevel( LM_MESSAGE ); pybind::object py_logger = pybind::make_object_t( m_kernel, loggerWarning ); - kernel->setStdOutHandle( py_logger.ptr() ); + m_kernel->setStdOutHandle( py_logger.ptr() ); m_loggerWarning = loggerWarning; @@ -405,7 +409,7 @@ namespace Mengine loggerError->setLoggerLevel( LM_WARNING ); pybind::object py_loggerError = pybind::make_object_t( m_kernel, loggerError ); - kernel->setStdErrorHandle( py_loggerError.ptr() ); + m_kernel->setStdErrorHandle( py_loggerError.ptr() ); m_loggerError = loggerError; @@ -472,7 +476,7 @@ namespace Mengine m_moduleFinder->setEmbed( py_moduleFinder ); - kernel->set_module_finder( py_moduleFinder.ptr() ); + m_kernel->set_module_finder( py_moduleFinder.ptr() ); m_factoryScriptModule = Helper::makeFactoryPoolWithMutex( MENGINE_DOCUMENT_FACTORABLE ); m_factoryEntityEventable = Helper::makeFactoryPoolWithMutex( MENGINE_DOCUMENT_FACTORABLE ); @@ -670,16 +674,19 @@ namespace Mengine m_kernel->set_current_module( nullptr ); m_kernel->collect(); + if( m_pyOldExcepthook != nullptr ) + { + m_kernel->set_sys_excepthook( m_pyOldExcepthook ); + m_kernel->decref( m_pyOldExcepthook ); + m_pyOldExcepthook = nullptr; + } + if( m_pyOldStdOutHandle != nullptr ) { m_kernel->setStdOutHandle( m_pyOldStdOutHandle ); m_kernel->decref( m_pyOldStdOutHandle ); m_pyOldStdOutHandle = nullptr; } - else - { - m_kernel->setStdOutHandle( nullptr ); - } if( m_pyOldStdErrorHandle != nullptr ) { @@ -687,10 +694,6 @@ namespace Mengine m_kernel->decref( m_pyOldStdErrorHandle ); m_pyOldStdErrorHandle = nullptr; } - else - { - m_kernel->setStdErrorHandle( nullptr ); - } m_bootstrapperModules.clear(); m_prototypies.clear(); diff --git a/src/Frameworks/PythonFramework/PythonScriptService.h b/src/Frameworks/PythonFramework/PythonScriptService.h index 68770f939d..b940e3d1a2 100644 --- a/src/Frameworks/PythonFramework/PythonScriptService.h +++ b/src/Frameworks/PythonFramework/PythonScriptService.h @@ -120,6 +120,7 @@ namespace Mengine PythonScriptLoggerPtr m_loggerWarning; PythonScriptLoggerPtr m_loggerError; + PyObject * m_pyOldExcepthook; PyObject * m_pyOldStdOutHandle; PyObject * m_pyOldStdErrorHandle; diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index 7548eef6c1..8a82c5ca91 100644 --- a/src/Services/AccountService/Account.cpp +++ b/src/Services/AccountService/Account.cpp @@ -125,14 +125,6 @@ namespace Mengine m_settings.emplace( _setting, st ); - if( this->save() == false ) - { - LOGGER_ERROR( "account '%s' setting '%s' save failed" - , m_accountId.c_str() - , _setting.c_str() - ); - } - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp index 1c424392f0..64910c4262 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp @@ -169,6 +169,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool OpenALSoundBufferStream::playSource( ALuint _sourceId, bool _looped, float _position ) { + MENGINE_ASSERTION_FATAL( m_sourceId == 0, "source already playing %u" + , m_sourceId + ); + m_sourceId = _sourceId; m_looped = _looped; @@ -284,6 +288,23 @@ namespace Mengine ); this->setUpdating_( false ); + + MENGINE_THREAD_MUTEX_SCOPE( m_mutexUpdating ); + + MENGINE_OPENAL_CALL( alSourceStop, (_sourceId) ); + + ALint queued = 0; + MENGINE_OPENAL_CALL( alGetSourcei, (_sourceId, AL_BUFFERS_QUEUED, &queued) ); + + for( ALint i = 0; i != queued; ++i ) + { + ALuint bufferId = 0; + MENGINE_OPENAL_CALL( alSourceUnqueueBuffers, (_sourceId, 1, &bufferId) ); + } + + MENGINE_OPENAL_CALL( alSourcei, (_sourceId, AL_BUFFER, 0) ); + + m_sourceId = 0; } ////////////////////////////////////////////////////////////////////////// void OpenALSoundBufferStream::setUpdating_( bool _updating ) From e38426adb24400c9d007446aae4d4ecb78835db2 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 9 Sep 2025 18:22:19 +0300 Subject: [PATCH 027/169] clear code --- src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm | 2 -- src/Plugins/AppleAppLovinPlugin/CMakeLists.txt | 2 +- .../AppleNativePythonScriptEmbedding.mm | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm index 2a9e6f8fe6..69d59657ec 100644 --- a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm +++ b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm @@ -21,8 +21,6 @@ const ConstString & eventName = _event->getName(); const Char * eventName_str = eventName.c_str(); - uint32_t countParameters = _event->getCountParameters(); - NSMutableDictionary * parameters = [[NSMutableDictionary alloc] init]; _event->foreachParameters( [parameters]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) diff --git a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt index badc59e2c0..f9dc5538f2 100644 --- a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt @@ -121,7 +121,7 @@ ADD_APPLOVIN_MEDIATION(PANGLE "AppLovinMediationByteDanceAdapter" "7.1.1.1.0") # ADD_APPLOVIN_MEDIATION(PUBMATIC "AppLovinMediationPubMaticAdapter" "4.5.2.0") ADD_APPLOVIN_MEDIATION(SMAATO "AppLovinMediationSmaatoAdapter" "22.9.3.1") ADD_APPLOVIN_MEDIATION(TENCENT "AppLovinMediationTencentGDTAdapter" "4.15.21.1") -ADD_APPLOVIN_MEDIATION(UNITYADS "AppLovinMediationUnityAdsAdapter" "4.16.0.0") +ADD_APPLOVIN_MEDIATION(UNITYADS "AppLovinMediationUnityAdsAdapter" "4.16.1.0") ADD_APPLOVIN_MEDIATION(VERVE "AppLovinMediationVerveAdapter" "3.6.0.0") ADD_APPLOVIN_MEDIATION(MYTARGET "AppLovinMediationMyTargetAdapter" "5.31.0.0") #VK ADD_APPLOVIN_MEDIATION(YANDEX "AppLovinMediationYandexAdapter" "7.12.3.0") diff --git a/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm b/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm index 5453df98d0..91eb9d1634 100644 --- a/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm +++ b/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm @@ -69,8 +69,6 @@ bool apply( pybind::kernel_interface * _kernel, PyObject * _obj, value_type & _v { NSString * key_str = pybind::extract_t( _kernel, key ); - PyTypeObject * type = _kernel->get_object_type( value ); - if( _kernel->bool_check( value ) == true ) { bool value_bool = pybind::extract_t( _kernel, value ); @@ -203,8 +201,6 @@ bool apply( pybind::kernel_interface * _kernel, PyObject * _obj, value_type & _v PyObject * value; while( _kernel->iterator_next( it, &value ) ) { - PyTypeObject * type = _kernel->get_object_type( value ); - if( _kernel->bool_check( value ) == true ) { bool value_bool = pybind::extract_t( _kernel, value ); From 772e68150ed992397389e9e7f66e271cf296646b Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 10 Sep 2025 21:54:48 +0300 Subject: [PATCH 028/169] update android com.datadoghq:dd-sdk-android-logs 3.0.0 --- .../org/Mengine/Base/MengineApplication.java | 12 ++++++++++++ .../Mengine/Base/MengineProcedureSendMail.java | 5 +++-- .../main/java/org/Mengine/Base/MengineUtils.java | 4 ++-- gradle/plugins/DataDog/build.gradle | 2 +- .../Plugin/DataDog/MengineDataDogPlugin.java | 12 ++++++++++++ .../PythonFramework/AmplifierScriptEmbedding.cpp | 5 +++++ .../PythonFramework/SoundScriptEmbedding.cpp | 5 +++++ src/Interface/AmplifierServiceInterface.h | 1 + src/Interface/SoundIdentityInterface.h | 1 + src/Kernel/BaseAnimation.cpp | 12 ++++++++++-- src/Kernel/SurfaceSound.cpp | 7 +++++++ src/Kernel/SurfaceSound.h | 1 + .../AmplifierService/AmplifierSoundListener.cpp | 5 +++++ .../AmplifierService/AmplifierSoundListener.h | 1 + src/Services/SoundService/SoundService.cpp | 16 +++++++++++++++- .../OpenALSoundBufferStream.cpp | 12 +++++------- 16 files changed, 86 insertions(+), 15 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java index 2a11e45c43..f1fcfc2860 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java @@ -212,6 +212,18 @@ public String getSessionId() { return m_sessionId; } + public String getDeviceManufacturer() { + String deviceManufacturer = android.os.Build.MANUFACTURER; + + return deviceManufacturer; + } + + public String getDeviceBrand() { + String deviceBrand = android.os.Build.BRAND; + + return deviceBrand; + } + public String getDeviceModel() { String deviceName = android.os.Build.MODEL; diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java index 2b4bb8f423..ee0989c849 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java @@ -1,5 +1,6 @@ package org.Mengine.Base; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -296,11 +297,11 @@ public boolean execute(@NonNull MengineActivity activity) { Intent chooser = Intent.createChooser(intent, "Send Email"); - chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { activity.startActivity(chooser); - } catch (Exception e) { + } catch (final ActivityNotFoundException e) { MengineLog.logError(TAG, "[ERROR] linkingOpenMail failed start mail: %s subject: %s body: %s exception: %s" , m_email , m_subject diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java index 8a9b2ee40d..0826a8012b 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java @@ -673,13 +673,13 @@ public static Document parseDocument(@NonNull InputStream stream) { return null; } - public static boolean openUrl(@NonNull Context context, String url) { + public static boolean openUrl(@NonNull MengineActivity activity, String url) { Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addCategory(Intent.CATEGORY_BROWSABLE); try { - context.startActivity(intent); + activity.startActivity(intent); } catch (final ActivityNotFoundException e) { MengineLog.logWarning(TAG, "openUrl url: %s catch ActivityNotFoundException: %s" , url diff --git a/gradle/plugins/DataDog/build.gradle b/gradle/plugins/DataDog/build.gradle index 68264b2f66..51667baa00 100644 --- a/gradle/plugins/DataDog/build.gradle +++ b/gradle/plugins/DataDog/build.gradle @@ -15,5 +15,5 @@ android { } dependencies { - implementation 'com.datadoghq:dd-sdk-android-logs:2.25.0' + implementation 'com.datadoghq:dd-sdk-android-logs:3.0.0' } \ No newline at end of file diff --git a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java index bc90fffaaf..601b1ca18e 100644 --- a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java +++ b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java @@ -183,6 +183,18 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine long sessionRND = application.getSessionRND(); attributes.put("session.rnd", sessionRND); + String osVersion = application.getOSVersion(); + attributes.put("os.version", osVersion); + + int sdkVersion = application.getSDKVersion(); + attributes.put("os.sdk", sdkVersion); + + String deviceManufacturer = application.getDeviceManufacturer(); + attributes.put("device.manufacturer", deviceManufacturer); + + String deviceBrand = application.getDeviceBrand(); + attributes.put("device.brand", deviceBrand); + String deviceModel = application.getDeviceModel(); attributes.put("device.model", deviceModel); diff --git a/src/Frameworks/PythonFramework/AmplifierScriptEmbedding.cpp b/src/Frameworks/PythonFramework/AmplifierScriptEmbedding.cpp index 523224fb11..5f53b4af80 100644 --- a/src/Frameworks/PythonFramework/AmplifierScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/AmplifierScriptEmbedding.cpp @@ -76,6 +76,11 @@ namespace Mengine } protected: + void onMusicPlay( const SoundIdentityInterfacePtr & _identity ) override + { + this->call_method( "onAmplifierMusicPlay", _identity ); + } + void onMusicPause( const SoundIdentityInterfacePtr & _identity ) override { this->call_method( "onAmplifierMusicPause", _identity ); diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index b357e615b1..c2241f8849 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -90,6 +90,11 @@ namespace Mengine } protected: + void onSoundPlay( const SoundIdentityInterfacePtr & _identity ) override + { + this->call_method( "onSoundPlay", _identity ); + } + void onSoundPause( const SoundIdentityInterfacePtr & _identity ) override { this->call_method( "onSoundPause", _identity ); diff --git a/src/Interface/AmplifierServiceInterface.h b/src/Interface/AmplifierServiceInterface.h index 0a7a0a4f08..ac1ba973fb 100644 --- a/src/Interface/AmplifierServiceInterface.h +++ b/src/Interface/AmplifierServiceInterface.h @@ -13,6 +13,7 @@ namespace Mengine : public Mixin { public: + virtual void onMusicPlay( const SoundIdentityInterfacePtr & _identity ) = 0; virtual void onMusicPause( const SoundIdentityInterfacePtr & _identity ) = 0; virtual void onMusicResume( const SoundIdentityInterfacePtr & _identity ) = 0; virtual void onMusicStop( const SoundIdentityInterfacePtr & _identity ) = 0; diff --git a/src/Interface/SoundIdentityInterface.h b/src/Interface/SoundIdentityInterface.h index ffb79bd46e..60878b49f9 100644 --- a/src/Interface/SoundIdentityInterface.h +++ b/src/Interface/SoundIdentityInterface.h @@ -33,6 +33,7 @@ namespace Mengine : public Mixin { public: + virtual void onSoundPlay( const SoundIdentityInterfacePtr & _identity ) = 0; virtual void onSoundPause( const SoundIdentityInterfacePtr & _identity ) = 0; virtual void onSoundResume( const SoundIdentityInterfacePtr & _identity ) = 0; virtual void onSoundStop( const SoundIdentityInterfacePtr & _identity ) = 0; diff --git a/src/Kernel/BaseAnimation.cpp b/src/Kernel/BaseAnimation.cpp index a0b2f8f146..8633bd109f 100644 --- a/src/Kernel/BaseAnimation.cpp +++ b/src/Kernel/BaseAnimation.cpp @@ -328,11 +328,19 @@ namespace Mengine float delta = m_playTime - _context->current; totalTime -= delta; - MENGINE_ASSERTION_FATAL( totalTime >= 0.f, "totalTime %f < 0.f ['%s:%s']" - , totalTime + MENGINE_ASSERTION_FATAL( totalTime >= 0.f, "BaseAnimation name: %s type: %s calcTotalTime invalid totalTime %f < 0.f play time: %f context time: %f current: %f" , MENGINE_MIXIN_DEBUG_NAME( this ) , MENGINE_MIXIN_DEBUG_TYPE( this ) + , totalTime + , m_playTime + , _context->time + , _context->current ); + + if( totalTime < 0.f ) + { + return 0.f; + } } float speedFactor = this->getAnimationSpeedFactor(); diff --git a/src/Kernel/SurfaceSound.cpp b/src/Kernel/SurfaceSound.cpp index 327149ef5e..26b7159a8e 100644 --- a/src/Kernel/SurfaceSound.cpp +++ b/src/Kernel/SurfaceSound.cpp @@ -433,6 +433,13 @@ namespace Mengine return nullptr; } ////////////////////////////////////////////////////////////////////////// + void SurfaceSound::onSoundPlay( const SoundIdentityInterfacePtr & _identity ) + { + MENGINE_UNUSED( _identity ); + + // Empty + } + ////////////////////////////////////////////////////////////////////////// void SurfaceSound::onSoundPause( const SoundIdentityInterfacePtr & _identity ) { MENGINE_UNUSED( _identity ); diff --git a/src/Kernel/SurfaceSound.h b/src/Kernel/SurfaceSound.h index c3a0d0a981..de89bf9978 100644 --- a/src/Kernel/SurfaceSound.h +++ b/src/Kernel/SurfaceSound.h @@ -90,6 +90,7 @@ namespace Mengine void _setLoop( bool _value ) override; protected: + void onSoundPlay( const SoundIdentityInterfacePtr & _identity ) override; void onSoundPause( const SoundIdentityInterfacePtr & _identity ) override; void onSoundResume( const SoundIdentityInterfacePtr & _identity ) override; void onSoundStop( const SoundIdentityInterfacePtr & _identity ) override; diff --git a/src/Services/AmplifierService/AmplifierSoundListener.cpp b/src/Services/AmplifierService/AmplifierSoundListener.cpp index 5dd362f5e7..3b930e993e 100644 --- a/src/Services/AmplifierService/AmplifierSoundListener.cpp +++ b/src/Services/AmplifierService/AmplifierSoundListener.cpp @@ -12,6 +12,11 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// + void AmplifierSoundListener::onSoundPlay( const SoundIdentityInterfacePtr & _identity ) + { + m_callback->onMusicPlay( _identity ); + } + ////////////////////////////////////////////////////////////////////////// void AmplifierSoundListener::onSoundPause( const SoundIdentityInterfacePtr & _identity ) { m_callback->onMusicPause( _identity ); diff --git a/src/Services/AmplifierService/AmplifierSoundListener.h b/src/Services/AmplifierService/AmplifierSoundListener.h index 74819c0e50..061a8263e4 100644 --- a/src/Services/AmplifierService/AmplifierSoundListener.h +++ b/src/Services/AmplifierService/AmplifierSoundListener.h @@ -23,6 +23,7 @@ namespace Mengine ~AmplifierSoundListener() override; protected: + void onSoundPlay( const SoundIdentityInterfacePtr & _identity ) override; void onSoundPause( const SoundIdentityInterfacePtr & _identity ) override; void onSoundResume( const SoundIdentityInterfacePtr & _identity ) override; void onSoundStop( const SoundIdentityInterfacePtr & _identity ) override; diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 59dd00a662..ef0073532b 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -876,6 +876,14 @@ namespace Mengine this->playSoundBufferUpdate_( _identity ); } + + const SoundListenerInterfacePtr & listener = _identity->getSoundListener(); + + if( listener != nullptr ) + { + SoundListenerInterfacePtr keep_listener = listener; + keep_listener->onSoundPlay( _identity ); + } }break; case ESS_PAUSE: { @@ -1514,6 +1522,11 @@ namespace Mengine return _identity->getState() == ESS_PLAY; } ); + LOGGER_MESSAGE( "current play sound count: %u total: %u" + , playCount + , (uint32_t)m_soundIdentities.size() + ); + uint32_t Limit_MaxSoundPlay = CONFIG_VALUE_INTEGER( "Limit", "MaxSoundPlay", 32 ); if( playCount > Limit_MaxSoundPlay ) @@ -1521,7 +1534,7 @@ namespace Mengine Stringstream ss; ss << "max sound play count exceeded: " << Limit_MaxSoundPlay; -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_LOGGER_INFO) Timestamp timestamp = Helper::getSystemTimestamp(); for( const SoundIdentityInterfacePtr & identity : m_soundIdentities ) @@ -1536,6 +1549,7 @@ namespace Mengine << "(doc: " << MENGINE_DOCUMENT_STR( identity->getDocument() ) << ")"; } #endif + LOGGER_ASSERTION( "%s", ss.str().c_str() ); return false; diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp index 64910c4262..16703cfb2b 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp @@ -398,10 +398,6 @@ namespace Mengine switch( state ) { - case AL_INITIAL: - { - //Empty - }break; case AL_PLAYING: { //Empty @@ -410,6 +406,7 @@ namespace Mengine { //Empty }break; + case AL_INITIAL: case AL_STOPPED: { if( m_looped == false ) @@ -442,8 +439,8 @@ namespace Mengine decoder_data_body.size = MENGINE_OPENAL_STREAM_BUFFER_SIZE; size_t bytesWritten = m_soundDecoder->decode( &decoder_data_body ); - - if( bytesWritten != MENGINE_OPENAL_STREAM_BUFFER_SIZE && m_looped == true ) + + if( m_looped == true && bytesWritten != MENGINE_OPENAL_STREAM_BUFFER_SIZE ) { if( m_soundDecoder->rewind() == false ) { @@ -462,7 +459,8 @@ namespace Mengine bytesWritten += bytesWritten2; } - else if( bytesWritten == 0 ) + + if( bytesWritten == 0 ) { *_bytes = 0; From a54c6856d2f239e4093c62f1f03c4ee923f9e35f Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 11 Sep 2025 21:49:45 +0300 Subject: [PATCH 029/169] add MENGINE_DEBUG_FILE_PATH --- gradle/libraries/Mengine/build.gradle | 9 ++++++++ .../Plugin/DataDog/MengineDataDogPlugin.java | 10 ++++++++- .../PythonFramework/SoundScriptEmbedding.cpp | 4 ++-- src/Interface/DebugFileInterface.h | 22 ++++++++++++++++--- src/Kernel/BaseDebugFile.cpp | 6 ++++- src/Kernel/BaseDebugFile.h | 6 ++++- src/Kernel/DebugFileHelper.h | 8 +++---- .../Win32FileSystem/Win32FileInputStream.h | 6 ++--- .../Win32FileSystem/Win32FileOutputStream.h | 6 ++--- .../Win32MutexFileInputStream.h | 6 ++--- 10 files changed, 59 insertions(+), 24 deletions(-) diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index e5781def06..35131d7c86 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -9,6 +9,7 @@ def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT def MENGINE_APP_DEPLOY_PATH = Utils.getStringProperty("MENGINE_APP_DEPLOY_PATH", rootProject.projectDir.getAbsolutePath() + "/$ANDROID_APP_MAIN_PROJECT") def MENGINE_APP_BUILD_ASSERTION_DEBUG = Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -1) def MENGINE_APP_BUILD_LOGGER_INFO = Utils.getIntegerProperty("MENGINE_APP_BUILD_LOGGER_INFO", -1) +def MENGINE_APP_DEBUG_FILE_PATH = Utils.getIntegerProperty("MENGINE_APP_DEBUG_FILE_PATH", -1) def MENGINE_APP_ENABLE_STRICT_MODE = Utils.getBooleanProperty("MENGINE_APP_ENABLE_STRICT_MODE", false) def ANDROID_APP_SCREEN_ORIENTATION = Utils.getStringProperty("ANDROID_APP_SCREEN_ORIENTATION", "sensorPortrait") @@ -76,6 +77,10 @@ android { if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] } + + if (MENGINE_APP_DEBUG_FILE_PATH != -1) { + cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_DEBUG_FILE_PATH}"] + } } } } @@ -96,6 +101,10 @@ android { if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] } + + if (MENGINE_APP_DEBUG_FILE_PATH != -1) { + cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_DEBUG_FILE_PATH}"] + } } } } diff --git a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java index 601b1ca18e..15111d5c04 100644 --- a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java +++ b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java @@ -110,8 +110,10 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine boolean crashReportsEnabled = false; + boolean isBuildPublish = application.isBuildPublish(); + String clientToken = MengineDataDogPlugin_ClientToken; - String envName = (BuildConfig.DEBUG == true) ? "dev" : "prod"; + String envName = (isBuildPublish == true) ? "dev" : "prod"; String variant = ""; Configuration config = new Configuration.Builder(clientToken, envName, variant) @@ -203,6 +205,12 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine this.logException(e, Map.of()); } + if (BuildConfig.DEBUG == true) { + logger.addTag("debug"); + } else { + logger.addTag("release"); + } + m_loggerDataDog = logger; } diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index c2241f8849..bfc9d4b2d6 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -516,7 +516,7 @@ namespace Mengine if( SOUND_SERVICE() ->playEmitter( soundIdentity ) == false ) { - LOGGER_ERROR( "resource sound '%s' invalid play" + LOGGER_WARNING( "resource sound '%s' invalid play" , _resourceName.c_str() ); @@ -607,7 +607,7 @@ namespace Mengine if( SOUND_SERVICE() ->playEmitter( soundIdentity ) == false ) { - LOGGER_ERROR( "resource sound '%s' invalid play" + LOGGER_WARNING( "resource sound '%s' invalid play" , _resourceName.c_str() ); diff --git a/src/Interface/DebugFileInterface.h b/src/Interface/DebugFileInterface.h index 68a797524c..a119e724fe 100644 --- a/src/Interface/DebugFileInterface.h +++ b/src/Interface/DebugFileInterface.h @@ -1,7 +1,23 @@ #pragma once -#include "Kernel/Mixin.h" -#include "Kernel/FilePath.h" +#include "Config/Config.h" + +#if !defined(MENGINE_DEBUG_FILE_PATH) +# if defined(MENGINE_DEBUG) +# define MENGINE_DEBUG_FILE_PATH 1 +# else +# define MENGINE_DEBUG_FILE_PATH 0 +# endif +#endif + +#if MENGINE_DEBUG_FILE_PATH == 1 +# define MENGINE_DEBUG_FILE_PATH_ENABLE +#endif + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + +# include "Kernel/Mixin.h" +# include "Kernel/FilePath.h" namespace Mengine { @@ -19,4 +35,4 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// } - +#endif \ No newline at end of file diff --git a/src/Kernel/BaseDebugFile.cpp b/src/Kernel/BaseDebugFile.cpp index 910d48e063..8b2bebceba 100644 --- a/src/Kernel/BaseDebugFile.cpp +++ b/src/Kernel/BaseDebugFile.cpp @@ -1,5 +1,7 @@ #include "BaseDebugFile.h" +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + namespace Mengine { ////////////////////////////////////////////////////////////////////////// @@ -41,4 +43,6 @@ namespace Mengine return m_debugFilePath; } ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/Kernel/BaseDebugFile.h b/src/Kernel/BaseDebugFile.h index 7cf94f914b..b306885ee8 100644 --- a/src/Kernel/BaseDebugFile.h +++ b/src/Kernel/BaseDebugFile.h @@ -2,6 +2,8 @@ #include "Interface/DebugFileInterface.h" +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + namespace Mengine { class BaseDebugFile @@ -26,4 +28,6 @@ namespace Mengine FilePath m_debugFolderPath; FilePath m_debugFilePath; }; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/Kernel/DebugFileHelper.h b/src/Kernel/DebugFileHelper.h index 85e22b1b02..50c8aa6184 100644 --- a/src/Kernel/DebugFileHelper.h +++ b/src/Kernel/DebugFileHelper.h @@ -20,7 +20,7 @@ namespace Mengine { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) const DebugFileInterface * debug = Helper::dynamicCast( _ptr ); if( debug == nullptr ) @@ -41,7 +41,7 @@ namespace Mengine { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) const DebugFileInterface * base = Helper::dynamicCast( _ptr ); if( base == nullptr ) @@ -62,7 +62,7 @@ namespace Mengine { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) const DebugFileInterface * base = Helper::dynamicCast( _ptr ); if( base == nullptr ) @@ -83,7 +83,7 @@ namespace Mengine { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Path fullPath = {'\0'}; const FilePath & relationPath = Helper::getDebugRelationPath( _ptr ); diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.h b/src/Systems/Win32FileSystem/Win32FileInputStream.h index 8a84112216..f746c790a8 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.h @@ -7,9 +7,7 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuardScope.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif +#include "Kernel/BaseDebugFile.h" #ifndef MENGINE_WIN32_FILE_STREAM_BUFFER_SIZE #define MENGINE_WIN32_FILE_STREAM_BUFFER_SIZE 4096 @@ -21,7 +19,7 @@ namespace Mengine class Win32FileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) , public BaseDebugFile #endif { diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.h b/src/Systems/Win32FileSystem/Win32FileOutputStream.h index 94e78304ca..43bf7ac357 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.h @@ -6,16 +6,14 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif +#include "Kernel/BaseDebugFile.h" namespace Mengine { class Win32FileOutputStream : public FileOutputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) , public BaseDebugFile #endif { diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h index 4e5de62643..207ba12c30 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h @@ -7,9 +7,7 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif +#include "Kernel/BaseDebugFile.h" namespace Mengine { @@ -17,7 +15,7 @@ namespace Mengine class Win32MutexFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) , public BaseDebugFile #endif { From 35efb252f3099bd6247a19dc852574a03af6da27 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 11 Sep 2025 23:43:21 +0300 Subject: [PATCH 030/169] fix DebugFileHelper --- src/Kernel/DebugFileHelper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kernel/DebugFileHelper.h b/src/Kernel/DebugFileHelper.h index 50c8aa6184..a562b7c421 100644 --- a/src/Kernel/DebugFileHelper.h +++ b/src/Kernel/DebugFileHelper.h @@ -5,7 +5,7 @@ #include "Kernel/PathHelper.h" #include "Kernel/PathString.h" -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) # include "Config/Path.h" # include "Config/DynamicCast.h" #endif From 27ab9b7d2498156394f92072a7f8102280f5b114 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 12 Sep 2025 00:27:21 +0300 Subject: [PATCH 031/169] improve android MengineGoogleGameSocialPlugin --- .../org/Mengine/Base/MengineActivity.java | 11 ++- .../MengineGoogleGameSocialPlugin.java | 74 ++++++++++++++++++- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java index f11ee87b6b..299b031c60 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java @@ -21,6 +21,7 @@ import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultRegistry; +import androidx.activity.result.IntentSenderRequest; import androidx.activity.result.contract.ActivityResultContract; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; @@ -220,7 +221,7 @@ public void checkPermissionRationale(String permission, Runnable onSuccess, Runn } } - public ActivityResultLauncher registerForActivityResult(@NonNull ActivityResultCallback callback) { + public ActivityResultLauncher registerForActivityResultIntent(@NonNull ActivityResultCallback callback) { ActivityResultContract contract = new ActivityResultContracts.StartActivityForResult(); ActivityResultLauncher launcher = this.registerForActivityResult(contract, callback); @@ -228,6 +229,14 @@ public ActivityResultLauncher registerForActivityResult(@NonNull Activit return launcher; } + public ActivityResultLauncher registerForActivityResultIntentSender(@NonNull ActivityResultCallback callback) { + ActivityResultContract contract = new ActivityResultContracts.StartIntentSenderForResult(); + + ActivityResultLauncher launcher = this.registerForActivityResult(contract, callback); + + return launcher; + } + public ELifecycleState getLifecycleState() { return m_lifecycleState; } diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java index ae47e28d83..a9222a4b1c 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java @@ -1,12 +1,17 @@ package org.Mengine.Plugin.GoogleGameSocial; import android.app.Activity; +import android.app.PendingIntent; import android.content.Intent; +import android.content.IntentSender; import android.os.Bundle; import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.IntentSenderRequest; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; +import com.google.android.gms.common.api.ResolvableApiException; import com.google.android.gms.games.AchievementsClient; import com.google.android.gms.games.AuthenticationResult; import com.google.android.gms.games.EventsClient; @@ -34,6 +39,7 @@ public class MengineGoogleGameSocialPlugin extends MengineService implements Men private ActivityResultLauncher m_achievementLauncher; private ActivityResultLauncher m_leaderboardLauncher; + private ActivityResultLauncher m_gamesResolutionLauncher; private GamesSignInClient m_gamesSignInClient; private AchievementsClient m_achievementsClient; @@ -58,7 +64,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS @Override public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceState) throws MengineServiceInvalidInitializeException { - ActivityResultLauncher achievementLauncher = activity.registerForActivityResult(result -> { + ActivityResultLauncher achievementLauncher = activity.registerForActivityResultIntent(result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent data = result.getData(); @@ -72,7 +78,7 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat m_achievementLauncher = achievementLauncher; - ActivityResultLauncher leaderboardLauncher = activity.registerForActivityResult(result -> { + ActivityResultLauncher leaderboardLauncher = activity.registerForActivityResultIntent(result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent data = result.getData(); @@ -81,11 +87,35 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat ); this.nativeCall("onGoogleGameSocialShowLeaderboardSuccess"); + } else { + this.logInfo("leaderboardLauncher onActivityResult resultCode: %d" + , result.getResultCode() + ); } }); m_leaderboardLauncher = leaderboardLauncher; + + + ActivityResultLauncher gamesResolutionLauncher = activity.registerForActivityResultIntentSender(result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent data = result.getData(); + + this.logInfo("gamesResolutionLauncher onActivityResult intent: %s", + data + ); + + this.signInIntent(); + } else { + this.logInfo("gamesResolutionLauncher onActivityResult resultCode: %d", + result.getResultCode() + ); + } + }); + + m_gamesResolutionLauncher = gamesResolutionLauncher; + m_gamesSignInClient = PlayGames.getGamesSignInClient(activity); m_achievementsClient = PlayGames.getAchievementsClient(activity); m_leaderboardsClient = PlayGames.getLeaderboardsClient(activity); @@ -106,6 +136,12 @@ public void onDestroy(@NonNull MengineActivity activity) { m_leaderboardLauncher = null; } + if (m_gamesResolutionLauncher != null) { + m_gamesResolutionLauncher.unregister(); + + m_gamesResolutionLauncher = null; + } + m_gamesSignInClient = null; m_achievementsClient = null; m_leaderboardsClient = null; @@ -182,6 +218,40 @@ public void signInIntent() { if (task.isSuccessful() == false) { Exception e = task.getException(); + if (e instanceof ResolvableApiException) { + ResolvableApiException resolvable = (ResolvableApiException)e; + PendingIntent pendingIntent = resolvable.getResolution(); + + if (pendingIntent == null) { + this.logInfo("signInIntent ResolvableApiException resolution null"); + + this.nativeCall("onGoogleGameSocialSignInIntentError", e); + + return; + } + + try { + IntentSender sender = pendingIntent.getIntentSender(); + + IntentSenderRequest request = new IntentSenderRequest.Builder(sender) + .build(); + + if (m_gamesResolutionLauncher != null) { + m_gamesResolutionLauncher.launch(request); + } else { + this.logError("[ERROR] signInIntent gamesResolutionLauncher not available"); + + this.nativeCall("onGoogleGameSocialSignInIntentError", e); + } + } catch (Exception ex) { + this.logException(ex, Map.of()); + + this.nativeCall("onGoogleGameSocialSignInIntentError", ex); + } + + return; + } + if (e != null) { this.logException(e, Map.of()); } else { From ace0e46869393cd356dadd7392d8f482021eefd8 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 12 Sep 2025 11:47:00 +0300 Subject: [PATCH 032/169] fix MENGINE_DEBUG_FILE_PATH_ENABLE --- src/Systems/Win32FileSystem/Win32FileInputStream.cpp | 2 +- src/Systems/Win32FileSystem/Win32FileOutputStream.cpp | 2 +- src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp index 9296378d5f..407deb8e00 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp @@ -44,7 +44,7 @@ namespace Mengine { MENGINE_THREAD_GUARD_SCOPE( Win32FileInputStream, this ); -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) this->setDebugRelationPath( _relationPath ); this->setDebugFolderPath( _folderPath ); this->setDebugFilePath( _filePath ); diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp index fee8c5e2de..8cc73b4d55 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp @@ -31,7 +31,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Win32FileOutputStream::open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) { -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) this->setDebugRelationPath( _relationPath ); this->setDebugFolderPath( _folderPath ); this->setDebugFilePath( _filePath ); diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp index 4e0c33ee20..b6c914f1f2 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp @@ -52,7 +52,7 @@ namespace Mengine MENGINE_UNUSED( _streaming ); MENGINE_UNUSED( _share ); -#if defined(MENGINE_DEBUG) +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) this->setDebugRelationPath( _relationPath ); this->setDebugFolderPath( _folderPath ); this->setDebugFilePath( _filePath ); From 36a8d336ac8d646d611243bb7dfa0523ecb226e4 Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 13 Sep 2025 17:20:39 +0300 Subject: [PATCH 033/169] add android MENGINE_APP_BUILD_DEBUG_DOCUMENT rework debug file path --- gradle/libraries/Mengine/build.gradle | 24 +++- src/Config/Config.h | 14 ++- src/Interface/CMakeLists.txt | 1 - src/Interface/DebugFileInterface.h | 38 ------ src/Interface/DocumentInterface.h | 6 + src/Interface/FileServiceInterface.h | 13 ++ src/Kernel/BaseDebugFile.cpp | 48 ------- src/Kernel/BaseDebugFile.h | 33 ----- src/Kernel/CMakeLists.txt | 3 - src/Kernel/DebugFileHelper.h | 77 +++++++++--- src/Kernel/JSONHelper.h | 1 + src/Kernel/ValueHolder.h | 3 +- src/Plugins/ZipPlugin/FileGroupZip.cpp | 117 ++++++++++-------- src/Services/FileService/FileService.cpp | 95 ++++++++++++++ src/Services/FileService/FileService.h | 28 ++++- .../AndroidAssetInputStream.cpp | 23 ++-- .../AndroidAssetInputStream.h | 4 - .../AndroidFileInputStream.cpp | 25 ++-- .../AndroidFileInputStream.h | 7 -- .../AndroidFileOutputStream.cpp | 23 ++-- .../AndroidFileOutputStream.h | 7 -- .../AndroidMutexAssetInputStream.cpp | 15 ++- .../AndroidMutexAssetInputStream.h | 7 -- .../AndroidMutexFileInputStream.cpp | 15 ++- .../AndroidMutexFileInputStream.h | 7 -- .../AppleFileSystem/AppleFileInputStream.h | 4 - .../AppleFileSystem/AppleFileOutputStream.h | 7 -- .../AppleMutexFileInputStream.h | 4 - .../SDL2FileSystem/SDL2FileInputStream.h | 7 -- .../SDL2FileSystem/SDL2FileOutputStream.h | 7 -- .../SDL2FileSystem/SDL2MutexFileInputStream.h | 7 -- .../Win32FileSystem/Win32FileInputStream.cpp | 23 ++-- .../Win32FileSystem/Win32FileInputStream.h | 5 - .../Win32FileSystem/Win32FileOutputStream.cpp | 25 ++-- .../Win32FileSystem/Win32FileOutputStream.h | 5 - .../Win32MutexFileInputStream.cpp | 15 ++- .../Win32MutexFileInputStream.h | 5 - 37 files changed, 378 insertions(+), 370 deletions(-) delete mode 100644 src/Kernel/BaseDebugFile.cpp delete mode 100644 src/Kernel/BaseDebugFile.h diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index 35131d7c86..31f6a7bd5a 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -9,7 +9,8 @@ def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT def MENGINE_APP_DEPLOY_PATH = Utils.getStringProperty("MENGINE_APP_DEPLOY_PATH", rootProject.projectDir.getAbsolutePath() + "/$ANDROID_APP_MAIN_PROJECT") def MENGINE_APP_BUILD_ASSERTION_DEBUG = Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -1) def MENGINE_APP_BUILD_LOGGER_INFO = Utils.getIntegerProperty("MENGINE_APP_BUILD_LOGGER_INFO", -1) -def MENGINE_APP_DEBUG_FILE_PATH = Utils.getIntegerProperty("MENGINE_APP_DEBUG_FILE_PATH", -1) +def MENGINE_APP_BUILD_DEBUG_FILE_PATH = Utils.getIntegerProperty("MENGINE_APP_BUILD_DEBUG_FILE_PATH", -1) +def MENGINE_APP_BUILD_DEBUG_DOCUMENT = Utils.getIntegerProperty("MENGINE_APP_BUILD_DEBUG_DOCUMENT", -1) def MENGINE_APP_ENABLE_STRICT_MODE = Utils.getBooleanProperty("MENGINE_APP_ENABLE_STRICT_MODE", false) def ANDROID_APP_SCREEN_ORIENTATION = Utils.getStringProperty("ANDROID_APP_SCREEN_ORIENTATION", "sensorPortrait") @@ -21,6 +22,11 @@ def MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OP println("MENGINE_APP_SECURE_VALUE: $MENGINE_APP_SECURE_VALUE") println("MENGINE_APP_DEPLOY_PATH: $MENGINE_APP_DEPLOY_PATH") +println("MENGINE_APP_BUILD_ASSERTION_DEBUG: $MENGINE_APP_BUILD_ASSERTION_DEBUG") +println("MENGINE_APP_BUILD_LOGGER_INFO: $MENGINE_APP_BUILD_LOGGER_INFO") +println("MENGINE_APP_BUILD_DEBUG_FILE_PATH: $MENGINE_APP_BUILD_DEBUG_FILE_PATH") +println("MENGINE_APP_BUILD_DEBUG_DOCUMENT: $MENGINE_APP_BUILD_DEBUG_DOCUMENT") + println("MENGINE_APP_ENABLE_STRICT_MODE: $MENGINE_APP_ENABLE_STRICT_MODE") android { @@ -78,8 +84,12 @@ android { cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] } - if (MENGINE_APP_DEBUG_FILE_PATH != -1) { - cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_DEBUG_FILE_PATH}"] + if (MENGINE_APP_BUILD_DEBUG_FILE_PATH != -1) { + cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_BUILD_DEBUG_FILE_PATH}"] + } + + if (MENGINE_APP_BUILD_DEBUG_DOCUMENT != -1) { + cppFlags += ["-DMENGINE_DOCUMENT=${MENGINE_APP_BUILD_DEBUG_DOCUMENT}"] } } } @@ -102,8 +112,12 @@ android { cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] } - if (MENGINE_APP_DEBUG_FILE_PATH != -1) { - cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_DEBUG_FILE_PATH}"] + if (MENGINE_APP_BUILD_DEBUG_FILE_PATH != -1) { + cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_BUILD_DEBUG_FILE_PATH}"] + } + + if (MENGINE_APP_BUILD_DEBUG_DOCUMENT != -1) { + cppFlags += ["-DMENGINE_DOCUMENT=${MENGINE_APP_BUILD_DEBUG_DOCUMENT}"] } } } diff --git a/src/Config/Config.h b/src/Config/Config.h index d9c418fef8..79c59edbce 100644 --- a/src/Config/Config.h +++ b/src/Config/Config.h @@ -296,10 +296,16 @@ # define MENGINE_DOCUMENT_ARGUMENTS(...) #endif -#if defined(MENGINE_DOCUMENT_ENABLE) -# define MENGINE_DOCUMENT_STR(Doc) ((Doc)->getMessage()) -#else -# define MENGINE_DOCUMENT_STR(Doc) MENGINE_STRING_EMPTY +#if !defined(MENGINE_DEBUG_FILE_PATH) +# if defined(MENGINE_DEBUG) +# define MENGINE_DEBUG_FILE_PATH 1 +# else +# define MENGINE_DEBUG_FILE_PATH 0 +# endif +#endif + +#if MENGINE_DEBUG_FILE_PATH == 1 +# define MENGINE_DEBUG_FILE_PATH_ENABLE #endif #ifndef MENGINE_CONSTEXPR diff --git a/src/Interface/CMakeLists.txt b/src/Interface/CMakeLists.txt index d0b1e54168..8efa5c522e 100644 --- a/src/Interface/CMakeLists.txt +++ b/src/Interface/CMakeLists.txt @@ -129,7 +129,6 @@ Common DateTimeSystemInterface.h HttpServiceInterface.h HttpSystemInterface.h - DebugFileInterface.h TimerServiceInterface.h MixerMultiplicativeInterface.h MixerAveragingInterface.h diff --git a/src/Interface/DebugFileInterface.h b/src/Interface/DebugFileInterface.h index a119e724fe..e69de29bb2 100644 --- a/src/Interface/DebugFileInterface.h +++ b/src/Interface/DebugFileInterface.h @@ -1,38 +0,0 @@ -#pragma once - -#include "Config/Config.h" - -#if !defined(MENGINE_DEBUG_FILE_PATH) -# if defined(MENGINE_DEBUG) -# define MENGINE_DEBUG_FILE_PATH 1 -# else -# define MENGINE_DEBUG_FILE_PATH 0 -# endif -#endif - -#if MENGINE_DEBUG_FILE_PATH == 1 -# define MENGINE_DEBUG_FILE_PATH_ENABLE -#endif - -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - -# include "Kernel/Mixin.h" -# include "Kernel/FilePath.h" - -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - class DebugFileInterface - : public Mixin - { - public: - virtual const FilePath & getDebugRelationPath() const = 0; - virtual const FilePath & getDebugFolderPath() const = 0; - virtual const FilePath & getDebugFilePath() const = 0; - }; - ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr DebugFileInterfacePtr; - ////////////////////////////////////////////////////////////////////////// -} - -#endif \ No newline at end of file diff --git a/src/Interface/DocumentInterface.h b/src/Interface/DocumentInterface.h index 6cfa9903f7..de9e58492e 100644 --- a/src/Interface/DocumentInterface.h +++ b/src/Interface/DocumentInterface.h @@ -4,6 +4,12 @@ #include "Config/Char.h" +#if defined(MENGINE_DOCUMENT_ENABLE) +# define MENGINE_DOCUMENT_STR(Doc) ((Doc)->getMessage()) +#else +# define MENGINE_DOCUMENT_STR(Doc) MENGINE_STRING_EMPTY +#endif + namespace Mengine { ////////////////////////////////////////////////////////////////////////// diff --git a/src/Interface/FileServiceInterface.h b/src/Interface/FileServiceInterface.h index a5478f8f17..eb7845a645 100644 --- a/src/Interface/FileServiceInterface.h +++ b/src/Interface/FileServiceInterface.h @@ -6,6 +6,8 @@ #include "Kernel/ConstString.h" #include "Kernel/FilePath.h" +#include "Config/UniqueId.h" + namespace Mengine { class FileServiceInterface @@ -20,6 +22,17 @@ namespace Mengine public: virtual bool hasFileGroup( const ConstString & _fileGroupName, FileGroupInterfacePtr * const _fileGroup ) const = 0; virtual const FileGroupInterfacePtr & getFileGroup( const ConstString & _fileGroupName ) const = 0; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + public: + virtual void addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) = 0; + virtual void removeDebugFilePath( UniqueId _id ) = 0; + + public: + virtual const FilePath & getDebugRelationPath( UniqueId _id ) const = 0; + virtual const FilePath & getDebugFolderPath( UniqueId _id ) const = 0; + virtual const FilePath & getDebugFilePath( UniqueId _id ) const = 0; +#endif }; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Kernel/BaseDebugFile.cpp b/src/Kernel/BaseDebugFile.cpp deleted file mode 100644 index 8b2bebceba..0000000000 --- a/src/Kernel/BaseDebugFile.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "BaseDebugFile.h" - -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - BaseDebugFile::BaseDebugFile() - { - } - ////////////////////////////////////////////////////////////////////////// - BaseDebugFile::~BaseDebugFile() - { - } - ////////////////////////////////////////////////////////////////////////// - void BaseDebugFile::setDebugRelationPath( const FilePath & _relationPath ) - { - m_debugRelationPath = _relationPath; - } - ////////////////////////////////////////////////////////////////////////// - void BaseDebugFile::setDebugFolderPath( const FilePath & _folderPath ) - { - m_debugFolderPath = _folderPath; - } - ////////////////////////////////////////////////////////////////////////// - void BaseDebugFile::setDebugFilePath( const FilePath & _filePath ) - { - m_debugFilePath = _filePath; - } - ////////////////////////////////////////////////////////////////////////// - const FilePath & BaseDebugFile::getDebugRelationPath() const - { - return m_debugRelationPath; - } - ////////////////////////////////////////////////////////////////////////// - const FilePath & BaseDebugFile::getDebugFolderPath() const - { - return m_debugFolderPath; - } - ////////////////////////////////////////////////////////////////////////// - const FilePath & BaseDebugFile::getDebugFilePath() const - { - return m_debugFilePath; - } - ////////////////////////////////////////////////////////////////////////// -} - -#endif \ No newline at end of file diff --git a/src/Kernel/BaseDebugFile.h b/src/Kernel/BaseDebugFile.h deleted file mode 100644 index b306885ee8..0000000000 --- a/src/Kernel/BaseDebugFile.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "Interface/DebugFileInterface.h" - -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - -namespace Mengine -{ - class BaseDebugFile - : public DebugFileInterface - { - public: - BaseDebugFile(); - ~BaseDebugFile() override; - - protected: - void setDebugRelationPath( const FilePath & _relationPath ); - void setDebugFolderPath( const FilePath & _folderPath ); - void setDebugFilePath( const FilePath & _filePath ); - - protected: - const FilePath & getDebugRelationPath() const override; - const FilePath & getDebugFolderPath() const override; - const FilePath & getDebugFilePath() const override; - - private: - FilePath m_debugRelationPath; - FilePath m_debugFolderPath; - FilePath m_debugFilePath; - }; -} - -#endif \ No newline at end of file diff --git a/src/Kernel/CMakeLists.txt b/src/Kernel/CMakeLists.txt index 553e498ed6..5541ffacad 100644 --- a/src/Kernel/CMakeLists.txt +++ b/src/Kernel/CMakeLists.txt @@ -879,9 +879,6 @@ Core BaseDebuggerBoundingBox.h - BaseDebugFile.h - BaseDebugFile.cpp - DebugFileHelper.h Event.h diff --git a/src/Kernel/DebugFileHelper.h b/src/Kernel/DebugFileHelper.h index a562b7c421..25593015ad 100644 --- a/src/Kernel/DebugFileHelper.h +++ b/src/Kernel/DebugFileHelper.h @@ -1,6 +1,6 @@ #pragma once -#include "Interface/DebugFileInterface.h" +#include "Interface/FileServiceInterface.h" #include "Kernel/PathHelper.h" #include "Kernel/PathString.h" @@ -14,6 +14,51 @@ namespace Mengine { namespace Helper { + ////////////////////////////////////////////////////////////////////////// + template + void addDebugFilePath( const T * _ptr, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + { + MENGINE_UNUSED( _ptr ); + MENGINE_UNUSED( _relationPath ); + MENGINE_UNUSED( _folderPath ); + MENGINE_UNUSED( _filePath ); + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + const Factorable * factorable = Helper::dynamicCast( _ptr ); + + UniqueId id = factorable->getUniqueIdentity(); + + FILE_SERVICE() + ->addDebugFilePath( id, _relationPath, _folderPath, _filePath ); +#endif + } + ////////////////////////////////////////////////////////////////////////// + template + void addDebugFilePath( const IntrusivePtr & _ptr, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + { + return Helper::addDebugFilePath( _ptr.get(), _relationPath, _folderPath, _filePath ); + } + ////////////////////////////////////////////////////////////////////////// + template + void removeDebugFilePath( const T * _ptr ) + { + MENGINE_UNUSED( _ptr ); + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + const Factorable * factorable = Helper::dynamicCast( _ptr ); + + UniqueId id = factorable->getUniqueIdentity(); + + FILE_SERVICE() + ->removeDebugFilePath( id ); +#endif + } + ////////////////////////////////////////////////////////////////////////// + template + void removeDebugFilePath( const IntrusivePtr & _ptr ) + { + return Helper::removeDebugFilePath( _ptr.get() ); + } ////////////////////////////////////////////////////////////////////////// template const FilePath & getDebugRelationPath( const T * _ptr ) @@ -21,14 +66,12 @@ namespace Mengine MENGINE_UNUSED( _ptr ); #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - const DebugFileInterface * debug = Helper::dynamicCast( _ptr ); + const Factorable * factorable = Helper::dynamicCast( _ptr ); - if( debug == nullptr ) - { - return FilePath::none(); - } + UniqueId id = factorable->getUniqueIdentity(); - const FilePath & relationPath = debug->getDebugRelationPath(); + const FilePath & relationPath = FILE_SERVICE() + ->getDebugRelationPath( id ); return relationPath; #else @@ -42,14 +85,12 @@ namespace Mengine MENGINE_UNUSED( _ptr ); #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - const DebugFileInterface * base = Helper::dynamicCast( _ptr ); + const Factorable * factorable = Helper::dynamicCast( _ptr ); - if( base == nullptr ) - { - return FilePath::none(); - } + UniqueId id = factorable->getUniqueIdentity(); - const FilePath & folderPath = base->getDebugFolderPath(); + const FilePath & folderPath = FILE_SERVICE() + ->getDebugFolderPath( id ); return folderPath; #else @@ -63,14 +104,12 @@ namespace Mengine MENGINE_UNUSED( _ptr ); #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - const DebugFileInterface * base = Helper::dynamicCast( _ptr ); + const Factorable * factorable = Helper::dynamicCast( _ptr ); - if( base == nullptr ) - { - return FilePath::none(); - } + UniqueId id = factorable->getUniqueIdentity(); - const FilePath & filePath = base->getDebugFilePath(); + const FilePath & filePath = FILE_SERVICE() + ->getDebugFilePath( id ); return filePath; #else diff --git a/src/Kernel/JSONHelper.h b/src/Kernel/JSONHelper.h index a3a0256c28..1937d4d78e 100644 --- a/src/Kernel/JSONHelper.h +++ b/src/Kernel/JSONHelper.h @@ -4,6 +4,7 @@ #include "Interface/ContentInterface.h" #include "Interface/FileGroupInterface.h" #include "Interface/MemoryInterface.h" +#include "Interface/DocumentInterface.h" #include "Kernel/JSON.h" #include "Kernel/String.h" diff --git a/src/Kernel/ValueHolder.h b/src/Kernel/ValueHolder.h index 8e17640a9c..829477a96c 100644 --- a/src/Kernel/ValueHolder.h +++ b/src/Kernel/ValueHolder.h @@ -1,7 +1,8 @@ #pragma once +#include "Interface/DocumentInterface.h" + #include "Kernel/Factorable.h" -#include "Kernel/Documentable.h" #include "Kernel/AssertionMemoryPanic.h" namespace Mengine diff --git a/src/Plugins/ZipPlugin/FileGroupZip.cpp b/src/Plugins/ZipPlugin/FileGroupZip.cpp index be1e57ba24..bc16531176 100644 --- a/src/Plugins/ZipPlugin/FileGroupZip.cpp +++ b/src/Plugins/ZipPlugin/FileGroupZip.cpp @@ -19,6 +19,7 @@ #include "Kernel/StringFormat.h" #include "Kernel/ConfigHelper.h" #include "Kernel/ThreadMutexHelper.h" +#include "Kernel/DebugFileHelper.h" #include "Config/StdIO.h" #include "Config/Path.h" @@ -699,17 +700,41 @@ namespace Mengine return false; } } - - return true; } - - if( fi.compr_method == Z_NO_COMPRESSION ) + else { - if( fi.file_size < m_mappedThreshold || fi.zip->mappedFile == nullptr ) + if( fi.compr_method == Z_NO_COMPRESSION ) + { + if( fi.file_size < m_mappedThreshold || fi.zip->mappedFile == nullptr ) + { + MemoryInputInterface * memory = _stream.getT(); + + void * buffer = memory->newBuffer( fi.file_size ); + + MENGINE_ASSERTION_MEMORY_PANIC( buffer, "zip '%s' file '%s' failed new memory %zu" + , fi.zip->folderPath.c_str() + , _filePath.c_str() + , fi.unz_size + ); + + fi.zip->mutex->lock(); + fi.zip->stream->seek( file_offset ); + fi.zip->stream->read( buffer, fi.file_size ); + fi.zip->mutex->unlock(); + } + else + { + if( fi.zip->mappedFile->openInputStream( _stream, file_offset, fi.file_size ) == false ) + { + return false; + } + } + } + else { MemoryInputInterface * memory = _stream.getT(); - void * buffer = memory->newBuffer( fi.file_size ); + void * buffer = memory->newBuffer( fi.unz_size ); MENGINE_ASSERTION_MEMORY_PANIC( buffer, "zip '%s' file '%s' failed new memory %zu" , fi.zip->folderPath.c_str() @@ -717,63 +742,45 @@ namespace Mengine , fi.unz_size ); + MemoryInterfacePtr compress_buffer = Helper::createMemoryCacheBuffer( fi.file_size, MENGINE_DOCUMENT_FACTORABLE ); + + MENGINE_ASSERTION_MEMORY_PANIC( compress_buffer, "zip '%s' file '%s' failed create cache memory %zu" + , fi.zip->folderPath.c_str() + , _filePath.c_str() + , fi.file_size + ); + + void * compress_memory = compress_buffer->getBuffer(); + + MENGINE_ASSERTION_MEMORY_PANIC( compress_memory, "zip '%s' file '%s' failed get memory buffer %zu" + , fi.zip->folderPath.c_str() + , _filePath.c_str() + , fi.file_size + ); + fi.zip->mutex->lock(); fi.zip->stream->seek( file_offset ); - fi.zip->stream->read( buffer, fi.file_size ); + fi.zip->stream->read( compress_memory, fi.file_size ); fi.zip->mutex->unlock(); - } - else - { - if( fi.zip->mappedFile->openInputStream( _stream, file_offset, fi.file_size ) == false ) + + if( Detail::zip_inflate_memory( buffer, fi.unz_size, compress_memory, fi.file_size ) == false ) { + LOGGER_ERROR( "file group zip '%s' zip '%s' file '%s' failed inflate" + , m_folderPath.c_str() + , fi.zip->folderPath.c_str() + , _filePath.c_str() + ); + return false; } } } - else - { - MemoryInputInterface * memory = _stream.getT(); - - void * buffer = memory->newBuffer( fi.unz_size ); - MENGINE_ASSERTION_MEMORY_PANIC( buffer, "zip '%s' file '%s' failed new memory %zu" - , fi.zip->folderPath.c_str() - , _filePath.c_str() - , fi.unz_size - ); - - MemoryInterfacePtr compress_buffer = Helper::createMemoryCacheBuffer( fi.file_size, MENGINE_DOCUMENT_FACTORABLE ); - - MENGINE_ASSERTION_MEMORY_PANIC( compress_buffer, "zip '%s' file '%s' failed create cache memory %zu" - , fi.zip->folderPath.c_str() - , _filePath.c_str() - , fi.file_size - ); +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + const FilePath & relationPath = m_baseFileGroup->getRelationPath(); - void * compress_memory = compress_buffer->getBuffer(); - - MENGINE_ASSERTION_MEMORY_PANIC( compress_memory, "zip '%s' file '%s' failed get memory buffer %zu" - , fi.zip->folderPath.c_str() - , _filePath.c_str() - , fi.file_size - ); - - fi.zip->mutex->lock(); - fi.zip->stream->seek( file_offset ); - fi.zip->stream->read( compress_memory, fi.file_size ); - fi.zip->mutex->unlock(); - - if( Detail::zip_inflate_memory( buffer, fi.unz_size, compress_memory, fi.file_size ) == false ) - { - LOGGER_ERROR( "file group zip '%s' zip '%s' file '%s' failed inflate" - , m_folderPath.c_str() - , fi.zip->folderPath.c_str() - , _filePath.c_str() - ); - - return false; - } - } + Helper::addDebugFilePath( _stream, relationPath, fi.zip->folderPath, _filePath ); +#endif return true; } @@ -784,6 +791,10 @@ namespace Mengine //Empty +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( _stream ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/FileService/FileService.cpp b/src/Services/FileService/FileService.cpp index 3dba9c6cb9..f8b54ab288 100644 --- a/src/Services/FileService/FileService.cpp +++ b/src/Services/FileService/FileService.cpp @@ -45,11 +45,23 @@ namespace Mengine return false; } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + m_debugFilePathsMutex = Helper::createThreadMutex( MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// void FileService::_finalizeService() { +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + m_debugFilePathsMutex = nullptr; + + MENGINE_ASSERTION_CONTAINER_EMPTY( m_debugFilePaths ); + + m_debugFilePaths.clear(); +#endif + PROTOTYPE_SERVICE() ->removePrototype( STRINGIZE_STRING_LOCAL( "Content" ), STRINGIZE_STRING_LOCAL( "File" ), nullptr ); @@ -197,4 +209,87 @@ namespace Mengine return fileGroup; } ////////////////////////////////////////////////////////////////////////// +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + ////////////////////////////////////////////////////////////////////////// + void FileService::addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + { + MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); + + DebugFilePath dfp; + dfp.relationPath = _relationPath; + dfp.folderPath = _folderPath; + dfp.filePath = _filePath; + + auto result = m_debugFilePaths.emplace( _id, dfp ); + + MENGINE_UNUSED( result ); + + MENGINE_ASSERTION_FATAL( result.second == true, "already add debug file path id %u" + , _id + ); + } + ////////////////////////////////////////////////////////////////////////// + void FileService::removeDebugFilePath( UniqueId _id ) + { + MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); + + UnorderedMapDebugFilePaths::iterator it_found = m_debugFilePaths.find( _id ); + + MENGINE_ASSERTION_FATAL( it_found != m_debugFilePaths.end(), "not found debug file path id %u" + , _id + ); + + m_debugFilePaths.erase( it_found ); + } + ////////////////////////////////////////////////////////////////////////// + const FilePath & FileService::getDebugRelationPath( UniqueId _id ) const + { + MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); + + UnorderedMapDebugFilePaths::const_iterator it_found = m_debugFilePaths.find( _id ); + + if( it_found == m_debugFilePaths.end() ) + { + return FilePath::none(); + } + + const DebugFilePath & dfp = it_found->second; + + return dfp.relationPath; + } + ////////////////////////////////////////////////////////////////////////// + const FilePath & FileService::getDebugFolderPath( UniqueId _id ) const + { + MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); + + UnorderedMapDebugFilePaths::const_iterator it_found = m_debugFilePaths.find( _id ); + + if( it_found == m_debugFilePaths.end() ) + { + return FilePath::none(); + } + + const DebugFilePath & dfp = it_found->second; + + return dfp.folderPath; + } + ////////////////////////////////////////////////////////////////////////// + const FilePath & FileService::getDebugFilePath( UniqueId _id ) const + { + MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); + + UnorderedMapDebugFilePaths::const_iterator it_found = m_debugFilePaths.find( _id ); + + if( it_found == m_debugFilePaths.end() ) + { + return FilePath::none(); + } + + const DebugFilePath & dfp = it_found->second; + + return dfp.filePath; + } + ////////////////////////////////////////////////////////////////////////// +#endif + ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Services/FileService/FileService.h b/src/Services/FileService/FileService.h index 2218ef8a16..c0e7dd1c6e 100644 --- a/src/Services/FileService/FileService.h +++ b/src/Services/FileService/FileService.h @@ -6,8 +6,7 @@ #include "Kernel/ServiceBase.h" #include "Kernel/Hashtable.h" #include "Kernel/Vector.h" - -#include "Config/Atomic.h" +#include "Kernel/UnorderedMap.h" namespace Mengine { @@ -33,8 +32,33 @@ namespace Mengine bool hasFileGroup( const ConstString & _fileGroupName, FileGroupInterfacePtr * const _fileGroup ) const override; const FileGroupInterfacePtr & getFileGroup( const ConstString & _fileGroupName ) const override; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + public: + void addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) override; + void removeDebugFilePath( UniqueId _id ) override; + + public: + const FilePath & getDebugRelationPath( UniqueId _id ) const override; + const FilePath & getDebugFolderPath( UniqueId _id ) const override; + const FilePath & getDebugFilePath( UniqueId _id ) const override; +#endif + protected: typedef Hashtable HashtableFileGroups; HashtableFileGroups m_fileGroups; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + ThreadMutexInterfacePtr m_debugFilePathsMutex; + + struct DebugFilePath + { + FilePath relationPath; + FilePath folderPath; + FilePath filePath; + }; + + typedef UnorderedMap UnorderedMapDebugFilePaths; + UnorderedMapDebugFilePaths m_debugFilePaths; +#endif }; } diff --git a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp index 84a510879f..04feaf6b65 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp @@ -40,12 +40,6 @@ namespace Mengine { MENGINE_THREAD_GUARD_SCOPE( AndroidAssetInputStream, this ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_streaming = _streaming; m_share = _share; @@ -102,6 +96,10 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -135,10 +133,7 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, folderPath, filePath, true, m_streaming ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, _folderPath, _filePath, true, m_streaming ); } #endif @@ -157,8 +152,8 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, false, m_streaming ); } @@ -169,6 +164,10 @@ namespace Mengine m_asset = nullptr; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h index e0f9bca767..07d0c718d4 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h @@ -6,7 +6,6 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuard.h" -#include "Kernel/BaseDebugFile.h" #ifndef MENGINE_FILE_STREAM_BUFFER_SIZE #define MENGINE_FILE_STREAM_BUFFER_SIZE 4096 @@ -18,9 +17,6 @@ namespace Mengine class AndroidAssetInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AndroidAssetInputStream ); diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp index 1a57d73d4b..6d680d547b 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp @@ -40,12 +40,6 @@ namespace Mengine { MENGINE_THREAD_GUARD_SCOPE( AndroidFileInputStream, this ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_streaming = _streaming; m_share = _share; @@ -102,6 +96,10 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -135,10 +133,7 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, folderPath, filePath, true, m_streaming ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, _folderPath, _filePath, true, m_streaming ); } #endif @@ -155,8 +150,8 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, true, m_streaming ); } @@ -165,6 +160,12 @@ namespace Mengine ::fclose( m_file ); m_file = nullptr; + m_size = 0; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.h b/src/Systems/AndroidFileSystem/AndroidFileInputStream.h index 1f87f505c0..6d1483c174 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidFileInputStream.h @@ -5,10 +5,6 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuard.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - #ifndef MENGINE_FILE_STREAM_BUFFER_SIZE #define MENGINE_FILE_STREAM_BUFFER_SIZE 4096 #endif @@ -19,9 +15,6 @@ namespace Mengine class AndroidFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AndroidFileInputStream ); diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp index 2f6fa85cca..2e8e8bc696 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp @@ -30,12 +30,6 @@ namespace Mengine MENGINE_THREAD_GUARD_SCOPE( AndroidFileOutputStream, this ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - Path fullPath = {'\0'}; if( Helper::concatenateFilePath( {_relationPath, _folderPath, _filePath}, fullPath ) == false ) { @@ -65,13 +59,14 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, folderPath, filePath, false, false ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, _folderPath, _filePath, false, false ); } #endif +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -87,8 +82,8 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, false, false ); } @@ -99,6 +94,10 @@ namespace Mengine m_size = 0; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h index 853ecf2a4f..9b615da74c 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h @@ -5,19 +5,12 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuard.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class AndroidFileOutputStream : public FileOutputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AndroidFileOutputStream ); diff --git a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp index dc276a8427..2d5f11d43f 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp @@ -6,6 +6,7 @@ #include "Kernel/Logger.h" #include "Kernel/ThreadMutexScope.h" +#include "Kernel/DebugFileHelper.h" #include "stdex/memorycopy.h" @@ -42,12 +43,6 @@ namespace Mengine MENGINE_UNUSED( _streaming ); MENGINE_UNUSED( _share ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - size_t size = m_stream->size(); if( _size != ~0U ) @@ -81,6 +76,10 @@ namespace Mengine m_capacity = 0; m_reading = 0; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -89,6 +88,10 @@ namespace Mengine m_stream = nullptr; m_mutex = nullptr; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h index 2f216e8b64..a12b08e8f7 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h @@ -7,19 +7,12 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class AndroidMutexAssetInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AndroidMutexAssetInputStream ); diff --git a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp index 2e0d3089a0..37a062555f 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp @@ -4,6 +4,7 @@ #include "Kernel/Logger.h" #include "Kernel/ThreadMutexScope.h" +#include "Kernel/DebugFileHelper.h" #include "stdex/memorycopy.h" @@ -40,12 +41,6 @@ namespace Mengine MENGINE_UNUSED( _streaming ); MENGINE_UNUSED( _share ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - size_t size = m_stream->size(); if( _size != ~0U ) @@ -79,6 +74,10 @@ namespace Mengine m_capacity = 0; m_reading = 0; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -87,6 +86,10 @@ namespace Mengine m_stream = nullptr; m_mutex = nullptr; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h index eab7cca234..dbe40c7a9d 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h @@ -7,19 +7,12 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class AndroidMutexFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AndroidMutexFileInputStream ); diff --git a/src/Systems/AppleFileSystem/AppleFileInputStream.h b/src/Systems/AppleFileSystem/AppleFileInputStream.h index 6085099bea..f0186d0af5 100644 --- a/src/Systems/AppleFileSystem/AppleFileInputStream.h +++ b/src/Systems/AppleFileSystem/AppleFileInputStream.h @@ -6,7 +6,6 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuard.h" -#include "Kernel/BaseDebugFile.h" #ifndef MENGINE_FILE_STREAM_BUFFER_SIZE #define MENGINE_FILE_STREAM_BUFFER_SIZE 4096 @@ -18,9 +17,6 @@ namespace Mengine class AppleFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AppleFileInputStream ); diff --git a/src/Systems/AppleFileSystem/AppleFileOutputStream.h b/src/Systems/AppleFileSystem/AppleFileOutputStream.h index 899c16efe5..5c432ce1b8 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.h +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.h @@ -6,19 +6,12 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class AppleFileOutputStream : public FileOutputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AppleFileOutputStream ); diff --git a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h index f9f31aeb58..f8b7882910 100644 --- a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h +++ b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h @@ -6,7 +6,6 @@ #include "AppleFileInputStream.h" #include "Kernel/Factorable.h" -#include "Kernel/BaseDebugFile.h" namespace Mengine { @@ -14,9 +13,6 @@ namespace Mengine class AppleMutexFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( AppleMutexFileInputStream ); diff --git a/src/Systems/SDL2FileSystem/SDL2FileInputStream.h b/src/Systems/SDL2FileSystem/SDL2FileInputStream.h index 7e909c2fa9..3796ec2a79 100644 --- a/src/Systems/SDL2FileSystem/SDL2FileInputStream.h +++ b/src/Systems/SDL2FileSystem/SDL2FileInputStream.h @@ -7,10 +7,6 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuard.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - #ifndef MENGINE_FILE_STREAM_BUFFER_SIZE #define MENGINE_FILE_STREAM_BUFFER_SIZE 4096 #endif @@ -21,9 +17,6 @@ namespace Mengine class SDL2FileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( SDL2FileInputStream ); diff --git a/src/Systems/SDL2FileSystem/SDL2FileOutputStream.h b/src/Systems/SDL2FileSystem/SDL2FileOutputStream.h index dd866dcc3c..8bdcdc96df 100644 --- a/src/Systems/SDL2FileSystem/SDL2FileOutputStream.h +++ b/src/Systems/SDL2FileSystem/SDL2FileOutputStream.h @@ -6,19 +6,12 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class SDL2FileOutputStream : public FileOutputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( SDL2FileOutputStream ); diff --git a/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.h b/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.h index ecbfe7605e..e91024be16 100644 --- a/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.h +++ b/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.h @@ -9,19 +9,12 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class SDL2MutexFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( SDL2MutexFileInputStream ); diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp index 407deb8e00..9f7929f375 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp @@ -44,12 +44,6 @@ namespace Mengine { MENGINE_THREAD_GUARD_SCOPE( Win32FileInputStream, this ); -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_streaming = _streaming; m_share = _share; @@ -124,6 +118,10 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -137,8 +135,8 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, true, m_streaming ); } @@ -155,6 +153,10 @@ namespace Mengine ); } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -200,10 +202,7 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, folderPath, filePath, true, m_streaming ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, _folderPath, _filePath, true, m_streaming ); } #endif diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.h b/src/Systems/Win32FileSystem/Win32FileInputStream.h index f746c790a8..161f21844c 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.h @@ -7,8 +7,6 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuardScope.h" -#include "Kernel/BaseDebugFile.h" - #ifndef MENGINE_WIN32_FILE_STREAM_BUFFER_SIZE #define MENGINE_WIN32_FILE_STREAM_BUFFER_SIZE 4096 #endif @@ -19,9 +17,6 @@ namespace Mengine class Win32FileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( Win32FileInputStream ); diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp index 8cc73b4d55..d6b350ed0c 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp @@ -11,6 +11,7 @@ #include "Kernel/StatisticHelper.h" #include "Kernel/Assertion.h" #include "Kernel/Logger.h" +#include "Kernel/DebugFileHelper.h" #include "Config/Path.h" @@ -31,12 +32,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Win32FileOutputStream::open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) { -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_relationPath = _relationPath; m_folderPath = _folderPath; m_filePath = _filePath; @@ -96,13 +91,14 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, folderPath, filePath, false, false ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, m_folderPath, m_filePath, false, false ); } #endif +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -116,10 +112,7 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, false, false ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, m_folderPath, m_filePath, false, false ); } #endif @@ -164,6 +157,10 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return successful; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.h b/src/Systems/Win32FileSystem/Win32FileOutputStream.h index 43bf7ac357..d1846ada0e 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.h @@ -6,16 +6,11 @@ #include "Kernel/Factorable.h" -#include "Kernel/BaseDebugFile.h" - namespace Mengine { class Win32FileOutputStream : public FileOutputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( Win32FileOutputStream ); diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp index b6c914f1f2..0c64b853ce 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp @@ -13,6 +13,7 @@ #include "Kernel/Assertion.h" #include "Kernel/Logger.h" #include "Kernel/MemoryCopy.h" +#include "Kernel/DebugFileHelper.h" #include "Config/StdAlgorithm.h" @@ -52,12 +53,6 @@ namespace Mengine MENGINE_UNUSED( _streaming ); MENGINE_UNUSED( _share ); -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - size_t size = m_stream->size(); if( _size != MENGINE_UNKNOWN_SIZE ) @@ -89,6 +84,10 @@ namespace Mengine m_capacity = 0; m_reading = 0; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -97,6 +96,10 @@ namespace Mengine m_stream = nullptr; m_mutex = nullptr; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h index 207ba12c30..d4aaff3cd2 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h @@ -7,17 +7,12 @@ #include "Kernel/Factorable.h" -#include "Kernel/BaseDebugFile.h" - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class Win32MutexFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( Win32MutexFileInputStream ); From 608cd6ef66f9ce5784f3fa2209cd2b65b882b858 Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 13 Sep 2025 18:33:49 +0300 Subject: [PATCH 034/169] fix usage MENGINE_DOCUMENT_ARGUMENTS --- src/Plugins/MoviePlugin/MoviePlugin.cpp | 4 ++-- .../ResourcePrefetcherPlugin/ResourcePrefetcherService.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Plugins/MoviePlugin/MoviePlugin.cpp b/src/Plugins/MoviePlugin/MoviePlugin.cpp index 6064a425d0..a292c2d518 100644 --- a/src/Plugins/MoviePlugin/MoviePlugin.cpp +++ b/src/Plugins/MoviePlugin/MoviePlugin.cpp @@ -143,7 +143,7 @@ namespace Mengine m_movieInstance = ae_create_movie_instance( m_hashkey.c_str(), &Detail::stdex_movie_alloc, &Detail::stdex_movie_alloc_n, &Detail::stdex_movie_free, &Detail::stdex_movie_free_n, 0, &Detail::stdex_movie_logerror, this ); #if defined(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) - NOTIFICATION_ADDOBSERVERLAMBDA( NOTIFICATOR_SCRIPT_EMBEDDING, this, [MENGINE_DEBUG_ARGUMENTS( this )]() + NOTIFICATION_ADDOBSERVERLAMBDA( NOTIFICATOR_SCRIPT_EMBEDDING, this, [MENGINE_DOCUMENT_ARGUMENTS( this )]() { SCRIPT_SERVICE() ->addScriptEmbedding( Movie2ScriptEmbedding::getFactorableType(), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ) ); @@ -256,7 +256,7 @@ namespace Mengine VOCABULARY_REMOVE( STRINGIZE_STRING_LOCAL( "Validator" ), ResourceMovie2::getFactorableType() ); } ); - PLUGIN_SERVICE_WAIT( LoaderServiceInterface, [MENGINE_DEBUG_ARGUMENTS( this )]() + PLUGIN_SERVICE_WAIT( LoaderServiceInterface, [MENGINE_DOCUMENT_ARGUMENTS( this )]() { VOCABULARY_SET( MetabufLoaderInterface, STRINGIZE_STRING_LOCAL( "MetabufLoader" ), ResourceMovie2::getFactorableType(), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); diff --git a/src/Plugins/ResourcePrefetcherPlugin/ResourcePrefetcherService.cpp b/src/Plugins/ResourcePrefetcherPlugin/ResourcePrefetcherService.cpp index d387ef5d48..4c5feb0a83 100644 --- a/src/Plugins/ResourcePrefetcherPlugin/ResourcePrefetcherService.cpp +++ b/src/Plugins/ResourcePrefetcherPlugin/ResourcePrefetcherService.cpp @@ -41,7 +41,7 @@ namespace Mengine bool ResourcePrefetcherService::_initializeService() { #if defined(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) - NOTIFICATION_ADDOBSERVERLAMBDA_THIS( NOTIFICATOR_SCRIPT_EMBEDDING, [MENGINE_DEBUG_ARGUMENTS( this )]() + NOTIFICATION_ADDOBSERVERLAMBDA_THIS( NOTIFICATOR_SCRIPT_EMBEDDING, [MENGINE_DOCUMENT_ARGUMENTS( this )]() { SCRIPT_SERVICE() ->addScriptEmbedding( ResourcePrefetcherScriptEmbedding::getFactorableType(), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ) ); From bfb3d46f4ec72c835e2813a0069c4e82882f4884 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 15 Sep 2025 01:17:39 +0300 Subject: [PATCH 035/169] ref-in debug file path --- src/Engine/ResourceHIT.cpp | 4 +- .../PythonFramework/EngineScriptEmbedding.cpp | 16 ++- .../PythonFramework/SoundScriptEmbedding.cpp | 4 +- src/Interface/ContentInterface.h | 3 + src/Interface/DecoderInterface.h | 4 +- src/Interface/EncoderInterface.h | 11 +- src/Interface/FileServiceInterface.h | 2 +- src/Interface/PluginInterface.h | 4 - src/Interface/SoundServiceInterface.h | 2 +- src/Interface/SoundSystemInterface.h | 2 +- src/Kernel/DebugFileHelper.h | 10 +- src/Kernel/DecoderBase.h | 16 ++- src/Kernel/EncoderBase.h | 15 ++- src/Kernel/Factorable.cpp | 3 + src/Kernel/FileContent.cpp | 7 ++ src/Kernel/FileContent.h | 3 + src/Kernel/PluginBase.cpp | 13 +- src/Kernel/PluginBase.h | 6 - src/Kernel/PluginHelper.h | 2 +- src/Kernel/ResourceImageData.cpp | 12 +- .../AstralaxEmitterContainer.cpp | 2 + .../BitmapFontGlyphDescription.cpp | 2 + .../HotspotImageConverterPNGToHIT.cpp | 26 ++-- .../ImageConverterDDSToHTF.cpp | 18 ++- .../ImageConverterPNGToACF.cpp | 18 ++- .../ImageConverterPVRToHTF.cpp | 23 ++-- src/Plugins/INIPlugin/INIUtils.cpp | 2 + src/Plugins/JSONPlugin/JSONService.cpp | 2 + .../MoviePlugin/ResourceMovie2Validator.cpp | 10 +- .../ResourceOzzAnimation.cpp | 2 + .../OzzAnimationPlugin/ResourceOzzMesh.cpp | 2 + .../ResourceOzzSkeleton.cpp | 2 + .../ResourceHITValidator.cpp | 4 +- .../ResourceImageDataValidator.cpp | 8 +- .../ResourceImageDefaultValidator.cpp | 12 +- .../ResourceSoundValidator.cpp | 12 +- .../TTFPlugin/TTFFontTextureGlyphProvider.h | 3 +- src/Plugins/TTFPlugin/TTFInterface.h | 1 - .../ResourceTexturepacker.cpp | 8 +- src/Plugins/VideoPlugin/ResourceVideo.cpp | 14 +-- .../VideoPlugin/ResourceVideoValidator.cpp | 8 +- .../XmlToBinPlugin/XmlToBinConverter.cpp | 19 +-- src/Plugins/ZipPlugin/CMakeLists.txt | 2 + src/Plugins/ZipPlugin/FileGroupZip.cpp | 48 +++++--- src/Plugins/ZipPlugin/FileGroupZip.h | 3 + .../ZipPlugin/ZipMemoryInputStream.cpp | 112 ++++++++++++++++++ src/Plugins/ZipPlugin/ZipMemoryInputStream.h | 57 +++++++++ src/Services/ConfigService/ConfigService.cpp | 2 + .../ConverterService/ConverterService.cpp | 6 +- src/Services/FileService/FileService.cpp | 10 +- src/Services/FileService/FileService.h | 3 +- src/Services/LoaderService/LoaderService.cpp | 12 +- src/Services/MemoryService/MemoryInput.h | 1 - .../ThreadTaskPrefetchImageDecoder.cpp | 2 +- .../ThreadTaskPrefetchSoundDecoder.cpp | 9 +- .../ProviderService/ServiceProvider.cpp | 2 + .../DecoderRenderImageLoader.cpp | 24 ++-- .../RenderService/DecoderRenderImageLoader.h | 1 + .../RenderService/RenderTextureService.cpp | 2 +- src/Services/SoundService/SoundService.cpp | 16 +-- .../TextService/TextLocalePackage.cpp | 2 + .../UserdataService/UserdataService.cpp | 2 + .../AndroidAssetInputStream.cpp | 2 +- .../AndroidFileInputStream.cpp | 2 +- .../AndroidFileOutputStream.cpp | 5 +- .../AndroidMutexAssetInputStream.cpp | 3 +- .../AndroidMutexFileInputStream.cpp | 3 +- .../OpenALSoundSystem/OpenALSoundSystem.cpp | 4 +- .../OpenALSoundSystem/OpenALSoundSystem.h | 2 +- .../Win32FileGroupDirectory.cpp | 8 +- .../Win32FileSystem/Win32FileInputStream.cpp | 2 +- .../Win32FileSystem/Win32FileMapped.cpp | 9 ++ .../Win32FileSystem/Win32FileOutputStream.cpp | 2 +- .../Win32MutexFileInputStream.cpp | 2 +- 74 files changed, 512 insertions(+), 185 deletions(-) create mode 100644 src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp create mode 100644 src/Plugins/ZipPlugin/ZipMemoryInputStream.h diff --git a/src/Engine/ResourceHIT.cpp b/src/Engine/ResourceHIT.cpp index 66cf4f8175..a9bdf5882c 100644 --- a/src/Engine/ResourceHIT.cpp +++ b/src/Engine/ResourceHIT.cpp @@ -51,7 +51,7 @@ namespace Mengine , this->getContent()->getCodecType().c_str() ); - if( decoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_ERROR( "resource HIT '%s' file '%s' invalid initialize decoder '%s'" , this->getName().c_str() @@ -109,6 +109,8 @@ namespace Mengine m_mipmap = mipmap; m_mipmapsize = (uint32_t)mipmapsize; + decoder->finalize(); + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index d0e951f7be..f9e3f3c95d 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -1463,7 +1463,9 @@ namespace Mengine if( _maxSize.x < 0.f || _maxSize.y < 0.f ) { - InputStreamInterfacePtr stream = Helper::openInputStreamFile( fileGroup, _filePath, false, false, MENGINE_DOCUMENT_PYTHON ); + ContentInterfacePtr content = Helper::makeFileContent( fileGroup, _filePath, MENGINE_DOCUMENT_PYTHON ); + + InputStreamInterfacePtr stream = content->openInputStreamFile( false, false, MENGINE_DOCUMENT_PYTHON ); MENGINE_ASSERTION_MEMORY_PANIC( stream, "image file '%s' was not found" , Helper::getFileGroupFullPath( fileGroup, _filePath ).c_str() @@ -1476,23 +1478,25 @@ namespace Mengine ConstString codecType = CODEC_SERVICE() ->findCodecType( _filePath ); - ImageDecoderInterfacePtr imageDecoder = CODEC_SERVICE() + ImageDecoderInterfacePtr decoder = CODEC_SERVICE() ->createDecoder( codecType, MENGINE_DOCUMENT_PYTHON ); - MENGINE_ASSERTION_MEMORY_PANIC( imageDecoder, "invalid create decoder '%s' for '%s'" + MENGINE_ASSERTION_MEMORY_PANIC( decoder, "invalid create decoder '%s' for '%s'" , codecType.c_str() , Helper::getFileGroupFullPath( fileGroup, _filePath ).c_str() ); - if( imageDecoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { return nullptr; } - const ImageCodecDataInfo * dataInfo = imageDecoder->getCodecDataInfo(); + const ImageCodecDataInfo * dataInfo = decoder->getCodecDataInfo(); maxSize.x = (float)dataInfo->width; maxSize.y = (float)dataInfo->height; + + decoder->finalize(); } else { @@ -2219,6 +2223,8 @@ namespace Mengine return false; } + content->closeInputStreamFile( stream ); + resource->release(); return true; diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index bfc9d4b2d6..6f4582511a 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -205,9 +205,7 @@ namespace Mengine bool streamable = resource->isStreamable(); SoundIdentityInterfacePtr soundIdentity = SOUND_SERVICE() - ->createSoundIdentity( true, soundBuffer, _category, streamable - , _doc - ); + ->createSoundIdentity( true, soundBuffer, _category, streamable, _doc ); if( soundIdentity == nullptr ) { diff --git a/src/Interface/ContentInterface.h b/src/Interface/ContentInterface.h index 1a8a74d9d8..df13a48932 100644 --- a/src/Interface/ContentInterface.h +++ b/src/Interface/ContentInterface.h @@ -47,7 +47,10 @@ namespace Mengine public: virtual MemoryInterfacePtr createMemoryFile( bool _stream, bool _share, const DocumentInterfacePtr & _doc ) = 0; virtual MemoryInterfacePtr createMemoryFileString( bool _stream, bool _share, const DocumentInterfacePtr & _doc ) = 0; + virtual InputStreamInterfacePtr openInputStreamFile( bool _streaming, bool _share, const DocumentInterfacePtr & _doc ) = 0; + virtual bool closeInputStreamFile( const InputStreamInterfacePtr & _stream ) = 0; + virtual OutputStreamInterfacePtr openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) = 0; virtual bool closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) = 0; }; diff --git a/src/Interface/DecoderInterface.h b/src/Interface/DecoderInterface.h index ca51320758..741890af86 100644 --- a/src/Interface/DecoderInterface.h +++ b/src/Interface/DecoderInterface.h @@ -1,6 +1,7 @@ #pragma once #include "Interface/ServantInterface.h" +#include "Interface/ContentInterface.h" #include "Interface/InputStreamInterface.h" #include "Interface/ThreadMutexInterface.h" @@ -20,6 +21,7 @@ namespace Mengine virtual void finalize() = 0; public: + virtual const ContentInterfacePtr & getContent() const = 0; virtual const InputStreamInterfacePtr & getStream() const = 0; public: @@ -27,7 +29,7 @@ namespace Mengine virtual const CodecDataInfo * getCodecDataInfo() const = 0; public: - virtual bool prepareData( const InputStreamInterfacePtr & _stream ) = 0; + virtual bool prepareData( const ContentInterfacePtr & _content, const InputStreamInterfacePtr & _stream ) = 0; public: virtual size_t decode( const DecoderData * _data ) = 0; diff --git a/src/Interface/EncoderInterface.h b/src/Interface/EncoderInterface.h index 372b4a2db0..5134b34f5d 100644 --- a/src/Interface/EncoderInterface.h +++ b/src/Interface/EncoderInterface.h @@ -13,14 +13,17 @@ namespace Mengine : public ServantInterface { public: - virtual bool initialize( const OutputStreamInterfacePtr & _stream ) = 0; - virtual void finalize() = 0; + virtual const ContentInterfacePtr & getContent() const = 0; public: - virtual size_t encode( const EncoderData * _encoderData, const CodecDataInfo * _dataInfo ) = 0; + virtual OutputStreamInterfacePtr getStream() const = 0; public: - virtual OutputStreamInterfacePtr getStream() const = 0; + virtual bool initialize( const ContentInterfacePtr & _content, const OutputStreamInterfacePtr & _stream ) = 0; + virtual void finalize() = 0; + + public: + virtual size_t encode( const EncoderData * _encoderData, const CodecDataInfo * _dataInfo ) = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr EncoderInterfacePtr; diff --git a/src/Interface/FileServiceInterface.h b/src/Interface/FileServiceInterface.h index eb7845a645..1a4277943b 100644 --- a/src/Interface/FileServiceInterface.h +++ b/src/Interface/FileServiceInterface.h @@ -25,7 +25,7 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) public: - virtual void addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) = 0; + virtual void addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, const DocumentInterfacePtr & _doc ) = 0; virtual void removeDebugFilePath( UniqueId _id ) = 0; public: diff --git a/src/Interface/PluginInterface.h b/src/Interface/PluginInterface.h index 89498f453b..264d2f25d7 100644 --- a/src/Interface/PluginInterface.h +++ b/src/Interface/PluginInterface.h @@ -20,10 +20,6 @@ namespace Mengine public: virtual const ConstString & getPluginName() const = 0; - public: - virtual void setUID( UniqueId _uid ) = 0; - virtual UniqueId getUID() const = 0; - public: virtual void setDynamicLoad( bool _dynamicLoad ) = 0; virtual bool isDynamicLoad() const = 0; diff --git a/src/Interface/SoundServiceInterface.h b/src/Interface/SoundServiceInterface.h index c65a87e9d6..c15991b233 100644 --- a/src/Interface/SoundServiceInterface.h +++ b/src/Interface/SoundServiceInterface.h @@ -32,7 +32,7 @@ namespace Mengine virtual void updateVolume() = 0; public: - virtual SoundIdentityInterfacePtr createSoundIdentity( bool _isHeadMode, const SoundBufferInterfacePtr & _sample, ESoundSourceCategory _type, bool _streamable, const DocumentInterfacePtr & _doc ) = 0; + virtual SoundIdentityInterfacePtr createSoundIdentity( bool _isHeadMode, const SoundBufferInterfacePtr & _buffer, ESoundSourceCategory _type, bool _streamable, const DocumentInterfacePtr & _doc ) = 0; virtual bool releaseSoundIdentity( const SoundIdentityInterfacePtr & _identity ) = 0; public: diff --git a/src/Interface/SoundSystemInterface.h b/src/Interface/SoundSystemInterface.h index 45e36947a9..29f17756f9 100644 --- a/src/Interface/SoundSystemInterface.h +++ b/src/Interface/SoundSystemInterface.h @@ -32,7 +32,7 @@ namespace Mengine virtual void onTurnSound( bool _turn ) = 0; public: - virtual SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _soundDecoder, bool _streamable, const DocumentInterfacePtr & _doc ) = 0; + virtual SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _decoder, bool _streamable, const DocumentInterfacePtr & _doc ) = 0; public: virtual SoundSourceInterfacePtr createSoundSource( bool _isHeadMode, const SoundBufferInterfacePtr & _sample, const DocumentInterfacePtr & _doc ) = 0; diff --git a/src/Kernel/DebugFileHelper.h b/src/Kernel/DebugFileHelper.h index 25593015ad..5af0131dc0 100644 --- a/src/Kernel/DebugFileHelper.h +++ b/src/Kernel/DebugFileHelper.h @@ -1,6 +1,7 @@ #pragma once #include "Interface/FileServiceInterface.h" +#include "Interface/DocumentInterface.h" #include "Kernel/PathHelper.h" #include "Kernel/PathString.h" @@ -16,12 +17,13 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// template - void addDebugFilePath( const T * _ptr, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + void addDebugFilePath( const T * _ptr, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, const DocumentInterfacePtr & _doc ) { MENGINE_UNUSED( _ptr ); MENGINE_UNUSED( _relationPath ); MENGINE_UNUSED( _folderPath ); MENGINE_UNUSED( _filePath ); + MENGINE_UNUSED( _doc ); #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) const Factorable * factorable = Helper::dynamicCast( _ptr ); @@ -29,14 +31,14 @@ namespace Mengine UniqueId id = factorable->getUniqueIdentity(); FILE_SERVICE() - ->addDebugFilePath( id, _relationPath, _folderPath, _filePath ); + ->addDebugFilePath( id, _relationPath, _folderPath, _filePath, _doc ); #endif } ////////////////////////////////////////////////////////////////////////// template - void addDebugFilePath( const IntrusivePtr & _ptr, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + void addDebugFilePath( const IntrusivePtr & _ptr, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, const DocumentInterfacePtr & _doc ) { - return Helper::addDebugFilePath( _ptr.get(), _relationPath, _folderPath, _filePath ); + return Helper::addDebugFilePath( _ptr.get(), _relationPath, _folderPath, _filePath, _doc ); } ////////////////////////////////////////////////////////////////////////// template diff --git a/src/Kernel/DecoderBase.h b/src/Kernel/DecoderBase.h index 3a1fde0ae8..be70e335eb 100644 --- a/src/Kernel/DecoderBase.h +++ b/src/Kernel/DecoderBase.h @@ -68,6 +68,13 @@ namespace Mengine this->_finalize(); m_mutex = nullptr; + + if( m_content != nullptr ) + { + m_content->closeInputStreamFile( m_stream ); + } + + m_content = nullptr; m_stream = nullptr; } @@ -84,16 +91,22 @@ namespace Mengine } public: + const ContentInterfacePtr & getContent() const override + { + return m_content; + } + const InputStreamInterfacePtr & getStream() const override { return m_stream; } private: - bool prepareData( const InputStreamInterfacePtr & _stream ) override + bool prepareData( const ContentInterfacePtr & _content, const InputStreamInterfacePtr & _stream ) override { MENGINE_THREAD_MUTEX_SCOPE( m_mutex ); + m_content = _content; m_stream = _stream; if( this->_prepareData() == false ) @@ -183,6 +196,7 @@ namespace Mengine private: ThreadMutexInterfacePtr m_mutex; + ContentInterfacePtr m_content; InputStreamInterfacePtr m_stream; size_t m_rewindPos; diff --git a/src/Kernel/EncoderBase.h b/src/Kernel/EncoderBase.h index 362c0bccb7..5485dfcd02 100644 --- a/src/Kernel/EncoderBase.h +++ b/src/Kernel/EncoderBase.h @@ -24,13 +24,14 @@ namespace Mengine } public: - bool initialize( const OutputStreamInterfacePtr & _stream ) override + bool initialize( const ContentInterfacePtr & _content, const OutputStreamInterfacePtr & _stream ) override { if( m_initialize == true ) { return false; } + m_content = _content; m_stream = _stream; m_initialize = this->_initialize(); @@ -47,6 +48,12 @@ namespace Mengine this->_finalize(); + if( m_content != nullptr ) + { + m_content->closeOutputStreamFile( m_stream ); + } + + m_content = nullptr; m_stream = nullptr; } @@ -68,12 +75,18 @@ namespace Mengine } public: + const ContentInterfacePtr & getContent() const override + { + return m_content; + } + OutputStreamInterfacePtr getStream() const override { return m_stream; } protected: + ContentInterfacePtr m_content; OutputStreamInterfacePtr m_stream; bool m_initialize; diff --git a/src/Kernel/Factorable.cpp b/src/Kernel/Factorable.cpp index 8e5ed53075..7b2d3fbef2 100644 --- a/src/Kernel/Factorable.cpp +++ b/src/Kernel/Factorable.cpp @@ -3,6 +3,7 @@ #include "Interface/FactoryInterface.h" #include "Kernel/ExceptionHelper.h" +#include "Kernel/Assertion.h" namespace Mengine { @@ -18,6 +19,8 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// Factorable::~Factorable() { + MENGINE_ASSERTION_FATAL( m_factorableId != 0, "invalid factorable id (not set?)" ); + #if defined(MENGINE_FACTORABLE_DEBUG_ENABLE) if( m_factorableDestroy == false && m_factorableFactory != nullptr ) { diff --git a/src/Kernel/FileContent.cpp b/src/Kernel/FileContent.cpp index d551be40e5..67ced0ebbf 100644 --- a/src/Kernel/FileContent.cpp +++ b/src/Kernel/FileContent.cpp @@ -42,6 +42,13 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// + bool FileContent::closeInputStreamFile( const InputStreamInterfacePtr & _stream ) + { + bool successful = Helper::closeInputStreamFile( m_fileGroup, _stream ); + + return successful; + } + ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr FileContent::openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) { OutputStreamInterfacePtr stream = Helper::openOutputStreamFile( m_fileGroup, m_filePath, _withTemp, _doc ); diff --git a/src/Kernel/FileContent.h b/src/Kernel/FileContent.h index ea6eea4fd6..561c09882b 100644 --- a/src/Kernel/FileContent.h +++ b/src/Kernel/FileContent.h @@ -21,7 +21,10 @@ namespace Mengine public: MemoryInterfacePtr createMemoryFile( bool _stream, bool _share, const DocumentInterfacePtr & _doc ) override; MemoryInterfacePtr createMemoryFileString( bool _stream, bool _share, const DocumentInterfacePtr & _doc ) override; + InputStreamInterfacePtr openInputStreamFile( bool _streaming, bool _share, const DocumentInterfacePtr & _doc ) override; + bool closeInputStreamFile( const InputStreamInterfacePtr & _stream ) override; + OutputStreamInterfacePtr openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) override; bool closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) override; }; diff --git a/src/Kernel/PluginBase.cpp b/src/Kernel/PluginBase.cpp index 47b798c0a3..7b95755e14 100644 --- a/src/Kernel/PluginBase.cpp +++ b/src/Kernel/PluginBase.cpp @@ -15,8 +15,7 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// PluginBase::PluginBase() - : m_uid( INVALID_UNIQUE_ID ) - , m_dynamicLoad( false ) + : m_dynamicLoad( false ) , m_initializePlugin( false ) , m_availablePlugin( true ) , m_systemPlugin( false ) @@ -28,16 +27,6 @@ namespace Mengine //MENGINE_ASSERTION_OBSERVABLE -> move to ::_destroy } ////////////////////////////////////////////////////////////////////////// - void PluginBase::setUID( uint32_t _uid ) - { - m_uid = _uid; - } - ////////////////////////////////////////////////////////////////////////// - uint32_t PluginBase::getUID() const - { - return m_uid; - } - ////////////////////////////////////////////////////////////////////////// void PluginBase::setDynamicLoad( bool _dynamicLoad ) { m_dynamicLoad = _dynamicLoad; diff --git a/src/Kernel/PluginBase.h b/src/Kernel/PluginBase.h index 2d83087908..e536a7ea59 100644 --- a/src/Kernel/PluginBase.h +++ b/src/Kernel/PluginBase.h @@ -21,10 +21,6 @@ namespace Mengine PluginBase(); ~PluginBase() override; - protected: - void setUID( UniqueId _uid ) override; - UniqueId getUID() const override; - protected: void setDynamicLoad( bool _dynamicLoad ) override; bool isDynamicLoad() const override; @@ -57,8 +53,6 @@ namespace Mengine void removeModuleFactory( const ConstString & _name ); protected: - UniqueId m_uid; - bool m_dynamicLoad; bool m_initializePlugin; bool m_availablePlugin; diff --git a/src/Kernel/PluginHelper.h b/src/Kernel/PluginHelper.h index 57ab2b166e..ce2ce59457 100644 --- a/src/Kernel/PluginHelper.h +++ b/src/Kernel/PluginHelper.h @@ -19,7 +19,7 @@ if( _dynamic == true ){SERVICE_PROVIDER_SETUP(_serviceProvider);}\ Mengine::PluginInterface * plugin = Mengine::Helper::newT>();\ if( plugin == nullptr ){ return false; }\ - plugin->setUID( _uid );\ + plugin->setUniqueIdentity( _uid );\ plugin->setDynamicLoad( _dynamic );\ *_plugin = plugin;\ return true;}} diff --git a/src/Kernel/ResourceImageData.cpp b/src/Kernel/ResourceImageData.cpp index a918f2cf2f..1e9b1627a4 100644 --- a/src/Kernel/ResourceImageData.cpp +++ b/src/Kernel/ResourceImageData.cpp @@ -45,15 +45,15 @@ namespace Mengine const ConstString & codecType = content->getCodecType(); - ImageDecoderInterfacePtr imageDecoder = CODEC_SERVICE() + ImageDecoderInterfacePtr decoder = CODEC_SERVICE() ->createDecoder( codecType, MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( imageDecoder, "image decoder '%s' for file '%s' was not found" + MENGINE_ASSERTION_MEMORY_PANIC( decoder, "image decoder '%s' for file '%s' was not found" , this->getContent()->getCodecType().c_str() , Helper::getContentFullPath( this->getContent() ).c_str() ); - if( imageDecoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_ERROR( "image decoder '%s' for file '%s' was not found" , this->getContent()->getCodecType().c_str() @@ -63,7 +63,7 @@ namespace Mengine return false; } - const ImageCodecDataInfo * dataInfo = imageDecoder->getCodecDataInfo(); + const ImageCodecDataInfo * dataInfo = decoder->getCodecDataInfo(); uint32_t width = dataInfo->width; uint32_t height = dataInfo->height; @@ -81,7 +81,7 @@ namespace Mengine data.pitch = width * channels; data.format = format; - if( imageDecoder->decode( &data ) == 0 ) + if( decoder->decode( &data ) == 0 ) { LOGGER_ERROR( "image decoder '%s' for file '%s' invalid decode" , this->getContent()->getCodecType().c_str() @@ -91,6 +91,8 @@ namespace Mengine return false; } + decoder->finalize(); + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/AstralaxPlugin/AstralaxEmitterContainer.cpp b/src/Plugins/AstralaxPlugin/AstralaxEmitterContainer.cpp index 3857ee3c93..032f154b53 100644 --- a/src/Plugins/AstralaxPlugin/AstralaxEmitterContainer.cpp +++ b/src/Plugins/AstralaxPlugin/AstralaxEmitterContainer.cpp @@ -43,6 +43,8 @@ namespace Mengine ); memory = Helper::readStreamArchiveMagicMemory( stream, _archivator, GET_MAGIC_NUMBER( MAGIC_PTZ ), GET_MAGIC_VERSION( MAGIC_PTZ ), MENGINE_DOCUMENT_FACTORABLE ); + + _content->closeInputStreamFile( stream ); } MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid get data" ); diff --git a/src/Plugins/BitmapFontPlugin/BitmapFontGlyphDescription.cpp b/src/Plugins/BitmapFontPlugin/BitmapFontGlyphDescription.cpp index c11665ca0c..9e99d9a178 100644 --- a/src/Plugins/BitmapFontPlugin/BitmapFontGlyphDescription.cpp +++ b/src/Plugins/BitmapFontPlugin/BitmapFontGlyphDescription.cpp @@ -441,6 +441,8 @@ namespace Mengine stream->read( memory, xml_buffer_size ); memory[xml_buffer_size] = '\0'; + _content->closeInputStreamFile( stream ); + BitmapGlyphSaxCallback tmsc( this, _content ); xmlsax_callbacks_t callbacks; diff --git a/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp b/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp index b349600c4b..edfedc8a9a 100644 --- a/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp @@ -46,7 +46,7 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( decoder, "invalid create decoder" ); - if( decoder->prepareData( _stream ) == false ) + if( decoder->prepareData( nullptr, _stream ) == false ) { return false; } @@ -79,20 +79,20 @@ namespace Mengine /////////////////////////////////////////////////////////////////////////////////////////////// bool HotspotImageConverterPNGToHIT::convert() { - InputStreamInterfacePtr input_stream = m_options.inputContent->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); + InputStreamInterfacePtr stream_input = m_options.inputContent->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( input_stream, "Image file '%s' was not found" + MENGINE_ASSERTION_MEMORY_PANIC( stream_input, "Image file '%s' was not found" , Helper::getContentFullPath( m_options.inputContent ).c_str() ); - ImageDecoderInterfacePtr imageDecoder = CODEC_SERVICE() + ImageDecoderInterfacePtr decoder = CODEC_SERVICE() ->createDecoder( STRINGIZE_STRING_LOCAL( "pngImage" ), MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( imageDecoder, "Image decoder for file '%s' was not found" + MENGINE_ASSERTION_MEMORY_PANIC( decoder, "Image decoder for file '%s' was not found" , Helper::getContentFullPath( m_options.inputContent ).c_str() ); - if( imageDecoder->prepareData( input_stream ) == false ) + if( decoder->prepareData( m_options.inputContent, stream_input ) == false ) { LOGGER_ERROR( "image initialize for file '%s' was not found" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -101,7 +101,7 @@ namespace Mengine return false; } - const ImageCodecDataInfo * dataInfo = imageDecoder->getCodecDataInfo(); + const ImageCodecDataInfo * dataInfo = decoder->getCodecDataInfo(); uint32_t width = dataInfo->width; uint32_t height = dataInfo->height; @@ -126,7 +126,7 @@ namespace Mengine data.format = PF_L8; data.flags |= DF_IMAGE_READ_ALPHA_ONLY; - if( imageDecoder->decode( &data ) == 0 ) + if( decoder->decode( &data ) == 0 ) { LOGGER_ERROR( "invalid decode '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -135,13 +135,13 @@ namespace Mengine return false; } - input_stream = nullptr; + decoder->finalize(); this->makeMipMapLevel_( buffer, width, height, mimmap_level ); - OutputStreamInterfacePtr output_stream = m_options.outputContent->openOutputStreamFile( true, MENGINE_DOCUMENT_FACTORABLE ); + OutputStreamInterfacePtr stream_output = m_options.outputContent->openOutputStreamFile( true, MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( output_stream, "HIT file '%s' not create (open file)" + MENGINE_ASSERTION_MEMORY_PANIC( stream_output, "HIT file '%s' not create (open file)" , Helper::getContentFullPath( m_options.outputContent ).c_str() ); @@ -152,7 +152,7 @@ namespace Mengine , Helper::getContentFullPath( m_options.outputContent ).c_str() ); - if( encoder->initialize( output_stream ) == false ) + if( encoder->initialize( m_options.outputContent, stream_output ) == false ) { LOGGER_ERROR( "HIT file '%s' not initialize (createEncoder hitPick)" , Helper::getContentFullPath( m_options.outputContent ).c_str() @@ -175,7 +175,7 @@ namespace Mengine encoder->finalize(); - if( m_options.outputContent->closeOutputStreamFile( output_stream ) == false ) + if( m_options.outputContent->closeOutputStreamFile( stream_output ) == false ) { LOGGER_ERROR( "HIT file '%s' invalid close" , Helper::getContentFullPath( m_options.outputContent ).c_str() diff --git a/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp b/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp index db33750869..25f917bdb5 100644 --- a/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp @@ -54,9 +54,11 @@ namespace Mengine FilePath full_inputFilePath = Helper::concatenateFilePath( {inputFolderPath, inputFilePath} ); FilePath full_outputFilePath = Helper::concatenateFilePath( {outputFolderPath, outputFilePath} ); - InputStreamInterfacePtr stream_intput = Helper::openInputStreamFile( m_fileGroupDev, full_inputFilePath, false, false, MENGINE_DOCUMENT_FACTORABLE ); + ContentInterfacePtr content_input = Helper::makeFileContent( m_fileGroupDev, full_inputFilePath, MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( stream_intput, "invalid open input file '%s'" + InputStreamInterfacePtr stream_input = content_input->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); + + MENGINE_ASSERTION_MEMORY_PANIC( stream_input, "invalid open input file '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() ); @@ -67,7 +69,7 @@ namespace Mengine , Helper::getContentFullPath( m_options.inputContent ).c_str() ); - if( decoder->prepareData( stream_intput ) == false ) + if( decoder->prepareData( content_input, stream_input ) == false ) { LOGGER_ERROR( "invalid prepare decoder for '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -122,7 +124,11 @@ namespace Mengine miplevel_data_memory += miplevel_data_size; } - OutputStreamInterfacePtr stream_output = Helper::openOutputStreamFile( m_fileGroupDev, full_outputFilePath, true, MENGINE_DOCUMENT_FACTORABLE ); + decoder->finalize(); + + ContentInterfacePtr content_output = Helper::makeFileContent( m_fileGroupDev, full_outputFilePath, MENGINE_DOCUMENT_FACTORABLE ); + + OutputStreamInterfacePtr stream_output = content_output->openOutputStreamFile( true, MENGINE_DOCUMENT_FACTORABLE ); MENGINE_ASSERTION_MEMORY_PANIC( stream_output, "invalid open output '%s' for '%s'" , full_outputFilePath.c_str() @@ -134,7 +140,7 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( encoder, "invalid create encoder 'htfImage'" ); - if( encoder->initialize( stream_output ) == false ) + if( encoder->initialize( content_output, stream_output ) == false ) { LOGGER_ERROR( "'%s' invalid initialize encoder" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -158,7 +164,7 @@ namespace Mengine encoder->finalize(); - if( Helper::closeOutputStreamFile( m_fileGroupDev, stream_output ) == false ) + if( content_output->closeOutputStreamFile( stream_output ) == false ) { LOGGER_ERROR( "'%s' invalid close output '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() diff --git a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp index ec30b542f5..8f37df424b 100644 --- a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp @@ -53,9 +53,11 @@ namespace Mengine FilePath full_inputFilePath = Helper::concatenateFilePath( {inputFolderPath, inputFilePath} ); FilePath full_outputFilePath = Helper::concatenateFilePath( {outputFolderPath, outputFilePath} ); - InputStreamInterfacePtr stream_intput = Helper::openInputStreamFile( m_fileGroupDev, full_inputFilePath, false, false, MENGINE_DOCUMENT_FACTORABLE ); + ContentInterfacePtr content_input = Helper::makeFileContent( m_fileGroupDev, full_inputFilePath, MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( stream_intput, "invalid open input file '%s'" + InputStreamInterfacePtr stream_input = content_input->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); + + MENGINE_ASSERTION_MEMORY_PANIC( stream_input, "invalid open input file '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() ); @@ -66,7 +68,7 @@ namespace Mengine , Helper::getContentFullPath( m_options.inputContent ).c_str() ); - if( decoder->prepareData( stream_intput ) == false ) + if( decoder->prepareData( content_input, stream_input ) == false ) { LOGGER_ERROR( "invalid prepare decoder '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -102,7 +104,11 @@ namespace Mengine return false; } - OutputStreamInterfacePtr stream_output = Helper::openOutputStreamFile( m_fileGroupDev, full_outputFilePath, true, MENGINE_DOCUMENT_FACTORABLE ); + decoder->finalize(); + + ContentInterfacePtr content_output = Helper::makeFileContent( m_fileGroupDev, full_outputFilePath, MENGINE_DOCUMENT_FACTORABLE ); + + OutputStreamInterfacePtr stream_output = content_output->openOutputStreamFile( true, MENGINE_DOCUMENT_FACTORABLE ); MENGINE_ASSERTION_MEMORY_PANIC( stream_output, "'%s' invalid open output '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -116,7 +122,7 @@ namespace Mengine , Helper::getContentFullPath( m_options.inputContent ).c_str() ); - if( encoder->initialize( stream_output ) == false ) + if( encoder->initialize( content_output, stream_output ) == false ) { LOGGER_ERROR( "%s invalid initialize encoder" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -140,7 +146,7 @@ namespace Mengine encoder->finalize(); - if( Helper::closeOutputStreamFile( m_fileGroupDev, stream_output ) == false ) + if( content_output->closeOutputStreamFile( stream_output ) == false ) { LOGGER_ERROR( "%s invalid close output '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() diff --git a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp index d1fd2d16b5..e622793a3d 100644 --- a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp @@ -53,9 +53,11 @@ namespace Mengine FilePath full_inputFilePath = Helper::concatenateFilePath( {inputFolderPath, inputFilePath} ); FilePath full_outputFilePath = Helper::concatenateFilePath( {outputFolderPath, outputFilePath} ); - InputStreamInterfacePtr stream_intput = Helper::openInputStreamFile( m_fileGroupDev, full_inputFilePath, false, false, MENGINE_DOCUMENT_FACTORABLE ); + ContentInterfacePtr content_input = Helper::makeFileContent( m_fileGroupDev, full_inputFilePath, MENGINE_DOCUMENT_FACTORABLE ); - MENGINE_ASSERTION_MEMORY_PANIC( stream_intput, "invalid open input file '%s'" + InputStreamInterfacePtr stream_input = content_input->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); + + MENGINE_ASSERTION_MEMORY_PANIC( stream_input, "invalid open input file '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() ); @@ -66,7 +68,7 @@ namespace Mengine , Helper::getContentFullPath( m_options.inputContent ).c_str() ); - if( decoder->prepareData( stream_intput ) == false ) + if( decoder->prepareData( content_input, stream_input ) == false ) { LOGGER_ERROR( "invalid prepare decoder for '%s'" , Helper::getContentFullPath( m_options.inputContent ).c_str() @@ -121,16 +123,11 @@ namespace Mengine miplevel_data_memory += miplevel_data_size; } - if( Helper::closeInputStreamFile( m_fileGroupDev, stream_intput ) == false ) - { - LOGGER_ERROR( "invalid close input file '%s'" - , Helper::getContentFullPath( m_options.inputContent ).c_str() - ); + decoder->finalize(); - return false; - } + ContentInterfacePtr content_output = Helper::makeFileContent( m_fileGroupDev, full_inputFilePath, MENGINE_DOCUMENT_FACTORABLE ); - OutputStreamInterfacePtr stream_output = Helper::openOutputStreamFile( m_fileGroupDev, full_outputFilePath, true, MENGINE_DOCUMENT_FACTORABLE ); + OutputStreamInterfacePtr stream_output = content_output->openOutputStreamFile( true, MENGINE_DOCUMENT_FACTORABLE ); MENGINE_ASSERTION_MEMORY_PANIC( stream_output, "invalid open output '%s' for file '%s'" , Helper::getContentFullPath( m_options.outputContent ).c_str() @@ -142,7 +139,7 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( encoder, "invalid create encoder 'htfImage'" ); - if( encoder->initialize( stream_output ) == false ) + if( encoder->initialize( content_output, stream_output ) == false ) { LOGGER_ERROR( "invalid initialize encoder '%s'" , Helper::getContentFullPath( m_options.outputContent ).c_str() @@ -166,7 +163,7 @@ namespace Mengine encoder->finalize(); - if( Helper::closeOutputStreamFile( m_fileGroupDev, stream_output ) == false ) + if( content_output->closeOutputStreamFile( stream_output ) == false ) { LOGGER_ERROR( "invalid close output '%s'" , Helper::getContentFullPath( m_options.outputContent ).c_str() diff --git a/src/Plugins/INIPlugin/INIUtils.cpp b/src/Plugins/INIPlugin/INIUtils.cpp index 302476c55b..4a696c285f 100644 --- a/src/Plugins/INIPlugin/INIUtils.cpp +++ b/src/Plugins/INIPlugin/INIUtils.cpp @@ -39,6 +39,8 @@ namespace Mengine bool successful = INIUtils::loadIni( _ini, stream, _doc ); + _content->closeInputStreamFile( stream ); + return successful; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/JSONPlugin/JSONService.cpp b/src/Plugins/JSONPlugin/JSONService.cpp index 6d3ba8ef98..357e3ef114 100644 --- a/src/Plugins/JSONPlugin/JSONService.cpp +++ b/src/Plugins/JSONPlugin/JSONService.cpp @@ -41,6 +41,8 @@ namespace Mengine jpp::object json = Helper::loadJSONStream( stream, _doc ); + _content->closeInputStreamFile( stream ); + if( json.invalid() == true ) { return false; diff --git a/src/Plugins/MoviePlugin/ResourceMovie2Validator.cpp b/src/Plugins/MoviePlugin/ResourceMovie2Validator.cpp index 12bf508dbd..d38549a7c0 100644 --- a/src/Plugins/MoviePlugin/ResourceMovie2Validator.cpp +++ b/src/Plugins/MoviePlugin/ResourceMovie2Validator.cpp @@ -62,7 +62,7 @@ namespace Mengine { case AE_MOVIE_RESOURCE_IMAGE: { - const aeMovieResourceImage * resource_image = (const aeMovieResourceImage *)_resource; + const aeMovieResourceImage * resource_image = reinterpret_cast(_resource); const Char * resource_image_name = resource_image->name; @@ -81,7 +81,7 @@ namespace Mengine }break; case AE_MOVIE_RESOURCE_VIDEO: { - const aeMovieResourceVideo * resource_video = (const aeMovieResourceVideo *)_resource; + const aeMovieResourceVideo * resource_video = reinterpret_cast(_resource); const Char * resource_video_name = resource_video->name; @@ -100,7 +100,7 @@ namespace Mengine }break; case AE_MOVIE_RESOURCE_SOUND: { - const aeMovieResourceSound * resource_sound = (const aeMovieResourceSound *)_resource; + const aeMovieResourceSound * resource_sound = reinterpret_cast(_resource); const Char * resource_sound_name = resource_sound->name; @@ -119,7 +119,7 @@ namespace Mengine }break; case AE_MOVIE_RESOURCE_PARTICLE: { - const aeMovieResourceParticle * resource_particle = (const aeMovieResourceParticle *)_resource; + const aeMovieResourceParticle * resource_particle = reinterpret_cast(_resource); const Char * resource_particle_name = resource_particle->name; @@ -408,6 +408,8 @@ namespace Mengine MemoryInterfacePtr memory = Helper::readStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_AEZ ), GET_MAGIC_VERSION( MAGIC_AEZ ), MENGINE_DOCUMENT_FACTORABLE ); + content->closeInputStreamFile( stream ); + if( memory == nullptr ) { LOGGER_MESSAGE_RELEASE_ERROR( "movie2 '%s' group '%s' can`t load stream archive file '%s'" diff --git a/src/Plugins/OzzAnimationPlugin/ResourceOzzAnimation.cpp b/src/Plugins/OzzAnimationPlugin/ResourceOzzAnimation.cpp index adb63374d6..3bec40e7c2 100644 --- a/src/Plugins/OzzAnimationPlugin/ResourceOzzAnimation.cpp +++ b/src/Plugins/OzzAnimationPlugin/ResourceOzzAnimation.cpp @@ -40,6 +40,8 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid create memory" ); + content->closeInputStreamFile( stream ); + const void * memory_buffer = memory->getBuffer(); size_t memory_size = memory->getSize(); diff --git a/src/Plugins/OzzAnimationPlugin/ResourceOzzMesh.cpp b/src/Plugins/OzzAnimationPlugin/ResourceOzzMesh.cpp index 9371abf8bd..3bc47d68eb 100644 --- a/src/Plugins/OzzAnimationPlugin/ResourceOzzMesh.cpp +++ b/src/Plugins/OzzAnimationPlugin/ResourceOzzMesh.cpp @@ -44,6 +44,8 @@ namespace Mengine , Helper::getContentFullPath( content ).c_str() ); + content->closeInputStreamFile( stream ); + const void * memory_buffer = memory->getBuffer(); size_t memory_size = memory->getSize(); diff --git a/src/Plugins/OzzAnimationPlugin/ResourceOzzSkeleton.cpp b/src/Plugins/OzzAnimationPlugin/ResourceOzzSkeleton.cpp index 29e346669a..52556ede8c 100644 --- a/src/Plugins/OzzAnimationPlugin/ResourceOzzSkeleton.cpp +++ b/src/Plugins/OzzAnimationPlugin/ResourceOzzSkeleton.cpp @@ -40,6 +40,8 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( memory, "invalid create memory" ); + content->closeInputStreamFile( stream ); + const void * memory_buffer = memory->getBuffer(); size_t memory_size = memory->getSize(); diff --git a/src/Plugins/ResourceValidatePlugin/ResourceHITValidator.cpp b/src/Plugins/ResourceValidatePlugin/ResourceHITValidator.cpp index f863b5a099..6df778fcfd 100644 --- a/src/Plugins/ResourceValidatePlugin/ResourceHITValidator.cpp +++ b/src/Plugins/ResourceValidatePlugin/ResourceHITValidator.cpp @@ -60,7 +60,7 @@ namespace Mengine return false; } - if( decoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' file '%s' decoder initialize failed '%s'" , _resource->getName().c_str() @@ -72,6 +72,8 @@ namespace Mengine return false; } + decoder->finalize(); + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/ResourceValidatePlugin/ResourceImageDataValidator.cpp b/src/Plugins/ResourceValidatePlugin/ResourceImageDataValidator.cpp index 7e1832f2ce..a76009611a 100644 --- a/src/Plugins/ResourceValidatePlugin/ResourceImageDataValidator.cpp +++ b/src/Plugins/ResourceValidatePlugin/ResourceImageDataValidator.cpp @@ -72,10 +72,10 @@ namespace Mengine const ConstString & codecType = content->getCodecType(); - ImageDecoderInterfacePtr imageDecoder = CODEC_SERVICE() + ImageDecoderInterfacePtr decoder = CODEC_SERVICE() ->createDecoder( codecType, MENGINE_DOCUMENT_FACTORABLE ); - if( imageDecoder == nullptr ) + if( decoder == nullptr ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' file '%s' invalid decoder '%s'" , _resource->getName().c_str() @@ -87,7 +87,7 @@ namespace Mengine return false; } - if( imageDecoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' file '%s' decoder initialize failed '%s'" , _resource->getName().c_str() @@ -99,6 +99,8 @@ namespace Mengine return false; } + decoder->finalize(); + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/ResourceValidatePlugin/ResourceImageDefaultValidator.cpp b/src/Plugins/ResourceValidatePlugin/ResourceImageDefaultValidator.cpp index fa342429e6..a0374a488e 100644 --- a/src/Plugins/ResourceValidatePlugin/ResourceImageDefaultValidator.cpp +++ b/src/Plugins/ResourceValidatePlugin/ResourceImageDefaultValidator.cpp @@ -146,10 +146,10 @@ namespace Mengine const ConstString & codecType = content->getCodecType(); - ImageDecoderInterfacePtr imageDecoder = CODEC_SERVICE() + ImageDecoderInterfacePtr decoder = CODEC_SERVICE() ->createDecoder( codecType, MENGINE_DOCUMENT_FACTORABLE ); - if( imageDecoder == nullptr ) + if( decoder == nullptr ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' file '%s' invalid decoder '%s'" , _resource->getName().c_str() @@ -161,7 +161,7 @@ namespace Mengine return false; } - if( imageDecoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' file '%s' decoder initialize failed '%s'" , _resource->getName().c_str() @@ -175,7 +175,7 @@ namespace Mengine bool successful = true; - const ImageCodecDataInfo * dataInfo = imageDecoder->getCodecDataInfo(); + const ImageCodecDataInfo * dataInfo = decoder->getCodecDataInfo(); uint32_t Limit_TextureWidth = CONFIG_VALUE_INTEGER( "Limit", "TextureWidth", 2048U ); uint32_t Limit_TextureHeight = CONFIG_VALUE_INTEGER( "Limit", "TextureHeight", 2048U ); @@ -253,7 +253,7 @@ namespace Mengine data.pitch = dataInfo->width * 4; data.format = PF_A8R8G8B8; - if( imageDecoder->decode( &data ) == 0 ) + if( decoder->decode( &data ) == 0 ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' file '%s' invalid decode '%s'" , _resource->getName().c_str() @@ -295,6 +295,8 @@ namespace Mengine } } + decoder->finalize(); + return successful; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/ResourceValidatePlugin/ResourceSoundValidator.cpp b/src/Plugins/ResourceValidatePlugin/ResourceSoundValidator.cpp index 47bcf61df7..95f8d4ed6b 100644 --- a/src/Plugins/ResourceValidatePlugin/ResourceSoundValidator.cpp +++ b/src/Plugins/ResourceValidatePlugin/ResourceSoundValidator.cpp @@ -56,7 +56,7 @@ namespace Mengine return false; } - if( decoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' can't initialize sound decoder for file '%s'" , _resource->getName().c_str() @@ -67,6 +67,8 @@ namespace Mengine return false; } + bool successful = true; + const SoundCodecDataInfo * dataInfo = decoder->getCodecDataInfo(); float Limit_MinimalStreamSoundDuration = CONFIG_VALUE_FLOAT( "Limit", "MinimalStreamSoundDuration", 2000.f ); //4kb @@ -81,7 +83,7 @@ namespace Mengine , Helper::getContentFullPath( _resource->getContent() ).c_str() ); - return false; + successful = false; } float limitNoStreamSoundDurationWarning = CONFIG_VALUE_FLOAT( "Limit", "NoStreamSoundDurationWarning", 2000.f ); //4kb @@ -109,11 +111,11 @@ namespace Mengine , Helper::getContentFullPath( _resource->getContent() ).c_str() ); - return false; + successful = false; } + decoder->finalize(); decoder = nullptr; - stream = nullptr; SoundBufferInterfacePtr soundBuffer = _resource->createSoundBuffer( MENGINE_DOCUMENT_FACTORABLE ); @@ -131,7 +133,7 @@ namespace Mengine soundBuffer->acquireSoundBuffer(); soundBuffer->releaseSoundBuffer(); - return true; + return successful; } ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Plugins/TTFPlugin/TTFFontTextureGlyphProvider.h b/src/Plugins/TTFPlugin/TTFFontTextureGlyphProvider.h index f6c4f673cf..759e66e59d 100644 --- a/src/Plugins/TTFPlugin/TTFFontTextureGlyphProvider.h +++ b/src/Plugins/TTFPlugin/TTFFontTextureGlyphProvider.h @@ -8,11 +8,10 @@ namespace Mengine { class TTFFontTextureGlyphProvider : public TTFTextureGlyphProviderInterface - , public Factorable { public: TTFFontTextureGlyphProvider( uint32_t _width, uint32_t _height, const void * _ttfmemory, size_t _ttfpitch, uint32_t _ttfchannel ); - ~TTFFontTextureGlyphProvider() override; + ~TTFFontTextureGlyphProvider(); public: bool onTextureGlyphFill( uint8_t * const _memory, size_t _pitch, uint32_t _channel, uint32_t _border ) const override; diff --git a/src/Plugins/TTFPlugin/TTFInterface.h b/src/Plugins/TTFPlugin/TTFInterface.h index e80e1b51e8..c2b2388405 100644 --- a/src/Plugins/TTFPlugin/TTFInterface.h +++ b/src/Plugins/TTFPlugin/TTFInterface.h @@ -23,7 +23,6 @@ namespace Mengine }; ////////////////////////////////////////////////////////////////////////// class TTFTextureGlyphProviderInterface - : public Mixin { public: virtual bool onTextureGlyphFill( uint8_t * const _memory, size_t _pitch, uint32_t _channel, uint32_t _border ) const = 0; diff --git a/src/Plugins/TexturepackerPlugin/ResourceTexturepacker.cpp b/src/Plugins/TexturepackerPlugin/ResourceTexturepacker.cpp index 3daedd2ad9..620e797a66 100644 --- a/src/Plugins/TexturepackerPlugin/ResourceTexturepacker.cpp +++ b/src/Plugins/TexturepackerPlugin/ResourceTexturepacker.cpp @@ -278,7 +278,9 @@ namespace Mengine } else { - InputStreamInterfacePtr stream = Helper::openInputStreamFile( fileGroup, newFilePath, false, false, MENGINE_DOCUMENT_FACTORABLE ); + ContentInterfacePtr content = Helper::makeFileContent( fileGroup, newFilePath, MENGINE_DOCUMENT_FACTORABLE ); + + InputStreamInterfacePtr stream = content->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); MENGINE_ASSERTION_FATAL( stream->size() != 0, "empty stream '%s' codec '%s'" , Helper::getFileGroupFullPath( fileGroup, newFilePath ).c_str() @@ -293,7 +295,7 @@ namespace Mengine , codecType.c_str() ); - if( decoder->prepareData( stream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { return false; } @@ -302,6 +304,8 @@ namespace Mengine atlasSize.x = (float)dataInfo->width; atlasSize.y = (float)dataInfo->height; + + decoder->finalize(); } resourceImage->setMaxSize( atlasSize ); diff --git a/src/Plugins/VideoPlugin/ResourceVideo.cpp b/src/Plugins/VideoPlugin/ResourceVideo.cpp index 0efe0b963b..b2eef8aaf7 100644 --- a/src/Plugins/VideoPlugin/ResourceVideo.cpp +++ b/src/Plugins/VideoPlugin/ResourceVideo.cpp @@ -122,9 +122,9 @@ namespace Mengine const ContentInterfacePtr & content = this->getContent(); - InputStreamInterfacePtr videoStream = content->openInputStreamFile( true, false, _doc ); + InputStreamInterfacePtr stream = content->openInputStreamFile( true, false, _doc ); - MENGINE_ASSERTION_MEMORY_PANIC( videoStream, "group '%s' name '%s' can't open video file '%s'" + MENGINE_ASSERTION_MEMORY_PANIC( stream, "group '%s' name '%s' can't open video file '%s'" , this->getGroupName().c_str() , this->getName().c_str() , Helper::getContentFullPath( this->getContent() ).c_str() @@ -132,16 +132,16 @@ namespace Mengine const ConstString & codecType = content->getCodecType(); - VideoDecoderInterfacePtr videoDecoder = CODEC_SERVICE() + VideoDecoderInterfacePtr decoder = CODEC_SERVICE() ->createDecoder( codecType, _doc ); - MENGINE_ASSERTION_MEMORY_PANIC( videoDecoder, "group '%s' name '%s' can't create video decoder for file '%s'" + MENGINE_ASSERTION_MEMORY_PANIC( decoder, "group '%s' name '%s' can't create video decoder for file '%s'" , this->getGroupName().c_str() , this->getName().c_str() , Helper::getContentFullPath( this->getContent() ).c_str() ); - if( videoDecoder->prepareData( videoStream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_ERROR( "resource video '%s' group '%s' can't initialize video decoder for file '%s'" , this->getName().c_str() @@ -152,9 +152,9 @@ namespace Mengine return nullptr; } - m_videoDecoderCacher.addCache( videoDecoder ); + m_videoDecoderCacher.addCache( decoder ); - return videoDecoder; + return decoder; } ////////////////////////////////////////////////////////////////////////// void ResourceVideo::destroyVideoDecoder( const VideoDecoderInterfacePtr & _decoder ) diff --git a/src/Plugins/VideoPlugin/ResourceVideoValidator.cpp b/src/Plugins/VideoPlugin/ResourceVideoValidator.cpp index bc8d5b171b..6867504f1f 100644 --- a/src/Plugins/VideoPlugin/ResourceVideoValidator.cpp +++ b/src/Plugins/VideoPlugin/ResourceVideoValidator.cpp @@ -139,9 +139,9 @@ namespace Mengine return false; } - InputStreamInterfacePtr videoStream = content->openInputStreamFile( true, false, MENGINE_DOCUMENT_FACTORABLE ); + InputStreamInterfacePtr stream = content->openInputStreamFile( true, false, MENGINE_DOCUMENT_FACTORABLE ); - if( videoStream == nullptr ) + if( stream == nullptr ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' can't open video file '%s'" , _resource->getName().c_str() @@ -168,7 +168,7 @@ namespace Mengine return false; } - if( decoder->prepareData( videoStream ) == false ) + if( decoder->prepareData( content, stream ) == false ) { LOGGER_MESSAGE_RELEASE_ERROR( "resource '%s' group '%s' can't initialize video decoder for file '%s'" , _resource->getName().c_str() @@ -181,6 +181,8 @@ namespace Mengine bool valid = s_checkValidVideoDecoder( _resource, decoder ); + decoder->finalize(); + return valid; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/XmlToBinPlugin/XmlToBinConverter.cpp b/src/Plugins/XmlToBinPlugin/XmlToBinConverter.cpp index ef675b6a3b..a7866c5b6a 100644 --- a/src/Plugins/XmlToBinPlugin/XmlToBinConverter.cpp +++ b/src/Plugins/XmlToBinPlugin/XmlToBinConverter.cpp @@ -105,7 +105,7 @@ namespace Mengine { const ConverterOptions & options = this->getOptions(); - ContentInterfacePtr protocolContent = Helper::getParam( options.params, STRINGIZE_STRING_LOCAL( "protocolContent" ), ContentInterfacePtr::none() ); + ContentInterfacePtr protocol_content = Helper::getParam( options.params, STRINGIZE_STRING_LOCAL( "protocolContent" ), ContentInterfacePtr::none() ); ParamInteger useProtocolVersion = Helper::getParam( options.params, STRINGIZE_STRING_LOCAL( "useProtocolVersion" ), 0LL ); ParamInteger useProtocolCrc32 = Helper::getParam( options.params, STRINGIZE_STRING_LOCAL( "useProtocolCrc32" ), 0LL ); @@ -115,10 +115,10 @@ namespace Mengine , (int32_t)useProtocolVersion ); - InputStreamInterfacePtr protocol_stream = protocolContent->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); + InputStreamInterfacePtr protocol_stream = protocol_content->openInputStreamFile( false, false, MENGINE_DOCUMENT_FACTORABLE ); MENGINE_ASSERTION_MEMORY_PANIC( protocol_stream, "error open protocol '%s'" - , Helper::getContentFullPath( protocolContent ).c_str() + , Helper::getContentFullPath( protocol_content ).c_str() ); size_t protocol_size = protocol_stream->size(); @@ -137,12 +137,13 @@ namespace Mengine if( protocol_stream->read( memory_protocol_buffer, protocol_size ) != protocol_size ) { LOGGER_ERROR( "error read protocol '%s' error invalid read size" - , Helper::getContentFullPath( protocolContent ).c_str() + , Helper::getContentFullPath( protocol_content ).c_str() ); return false; } + protocol_content->closeInputStreamFile( protocol_stream ); protocol_stream = nullptr; Metabuf::XmlProtocol xml_protocol; @@ -150,7 +151,7 @@ namespace Mengine if( xml_protocol.readProtocol( memory_protocol_buffer, protocol_size ) == false ) { LOGGER_ERROR( "error read protocol '%s' error:\n%s" - , Helper::getContentFullPath( protocolContent ).c_str() + , Helper::getContentFullPath( protocol_content ).c_str() , xml_protocol.getError().c_str() ); @@ -160,7 +161,7 @@ namespace Mengine if( useProtocolVersion != xml_protocol.getVersion() ) { LOGGER_ERROR( "protocol '%s' invalid version '%u' use '%" MENGINE_PRIu64 "'" - , Helper::getContentFullPath( protocolContent ).c_str() + , Helper::getContentFullPath( protocol_content ).c_str() , xml_protocol.getVersion() , useProtocolVersion ); @@ -171,7 +172,7 @@ namespace Mengine if( useProtocolCrc32 != xml_protocol.getCrc32() ) { LOGGER_ERROR( "protocol '%s' invalid crc32 '%u' use '%" MENGINE_PRIu64 "'" - , Helper::getContentFullPath( protocolContent ).c_str() + , Helper::getContentFullPath( protocol_content ).c_str() , xml_protocol.getVersion() , useProtocolCrc32 ); @@ -218,12 +219,13 @@ namespace Mengine return false; } + options.inputContent->closeInputStreamFile( xml_stream ); xml_stream = nullptr; const Metabuf::XmlMeta * xml_meta = xml_protocol.getMeta( "Data" ); MENGINE_ASSERTION_MEMORY_PANIC( xml_meta, "invalid get meta 'Data' from protocol '%s'" - , Helper::getContentFullPath( protocolContent ).c_str() + , Helper::getContentFullPath( protocol_content ).c_str() ); Metabuf::Xml2Metabuf xml_metabuf( &xml_protocol, xml_meta ); @@ -313,6 +315,7 @@ namespace Mengine bin_stream->flush(); options.outputContent->closeOutputStreamFile( bin_stream ); + bin_stream = nullptr; return true; } diff --git a/src/Plugins/ZipPlugin/CMakeLists.txt b/src/Plugins/ZipPlugin/CMakeLists.txt index ec08d0630a..426e1ea791 100644 --- a/src/Plugins/ZipPlugin/CMakeLists.txt +++ b/src/Plugins/ZipPlugin/CMakeLists.txt @@ -10,6 +10,8 @@ src FileGroupZip.cpp ArchivatorZip.h ArchivatorZip.cpp + ZipMemoryInputStream.h + ZipMemoryInputStream.cpp ) INCLUDE_DIRECTORIES(${THIRDPARTY_CONFIG_DIR}/zlib) diff --git a/src/Plugins/ZipPlugin/FileGroupZip.cpp b/src/Plugins/ZipPlugin/FileGroupZip.cpp index bc16531176..473aff244f 100644 --- a/src/Plugins/ZipPlugin/FileGroupZip.cpp +++ b/src/Plugins/ZipPlugin/FileGroupZip.cpp @@ -5,6 +5,8 @@ #include "Interface/MemoryServiceInterface.h" #include "Interface/FileServiceInterface.h" +#include "ZipMemoryInputStream.h" + #include "Kernel/Logger.h" #include "Kernel/FilePath.h" #include "Kernel/FilePathHelper.h" @@ -19,7 +21,8 @@ #include "Kernel/StringFormat.h" #include "Kernel/ConfigHelper.h" #include "Kernel/ThreadMutexHelper.h" -#include "Kernel/DebugFileHelper.h" +#include "Kernel/FactoryPool.h" +#include "Kernel/AssertionFactory.h" #include "Config/StdIO.h" #include "Config/Path.h" @@ -161,6 +164,8 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool FileGroupZip::_initialize() { + m_factoryZipMemoryInputStream = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); + uint32_t ZipPlugin_ReserveFiles = CONFIG_VALUE_INTEGER( "ZipPlugin", "ReserveFiles", 16 * 1024 ); m_files.reserve( ZipPlugin_ReserveFiles ); @@ -187,6 +192,10 @@ namespace Mengine m_files.clear(); m_zips.clear(); m_indexes.clear(); + + MENGINE_ASSERTION_FACTORY_EMPTY( m_factoryZipMemoryInputStream ); + + m_factoryZipMemoryInputStream = nullptr; } ////////////////////////////////////////////////////////////////////////// bool FileGroupZip::loadHeaders_() @@ -628,7 +637,16 @@ namespace Mengine , _filePath.c_str() ); - return memory; + ZipMemoryInputStreamPtr zip_memory = m_factoryZipMemoryInputStream->createObject( _doc ); + + MENGINE_ASSERTION_MEMORY_PANIC( zip_memory, "zip '%s' file '%s' invalid create zip memory stream" + , fi.zip->folderPath.c_str() + , _filePath.c_str() + ); + + zip_memory->setMemoryInputStream( memory ); + + return zip_memory; } InputStreamInterfacePtr stream = fi.zip->mappedFile->createInputStream( _doc ); @@ -707,9 +725,9 @@ namespace Mengine { if( fi.file_size < m_mappedThreshold || fi.zip->mappedFile == nullptr ) { - MemoryInputInterface * memory = _stream.getT(); + ZipMemoryInputStream * zip_memory = _stream.getT(); - void * buffer = memory->newBuffer( fi.file_size ); + void * buffer = zip_memory->newBuffer( fi.file_size ); MENGINE_ASSERTION_MEMORY_PANIC( buffer, "zip '%s' file '%s' failed new memory %zu" , fi.zip->folderPath.c_str() @@ -721,6 +739,10 @@ namespace Mengine fi.zip->stream->seek( file_offset ); fi.zip->stream->read( buffer, fi.file_size ); fi.zip->mutex->unlock(); + + const FilePath & relationPath = this->getRelationPath(); + + zip_memory->open( relationPath, fi.zip->folderPath, _filePath ); } else { @@ -732,9 +754,9 @@ namespace Mengine } else { - MemoryInputInterface * memory = _stream.getT(); + ZipMemoryInputStream * zip_memory = _stream.getT(); - void * buffer = memory->newBuffer( fi.unz_size ); + void * buffer = zip_memory->newBuffer( fi.unz_size ); MENGINE_ASSERTION_MEMORY_PANIC( buffer, "zip '%s' file '%s' failed new memory %zu" , fi.zip->folderPath.c_str() @@ -773,14 +795,12 @@ namespace Mengine return false; } - } - } -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - const FilePath & relationPath = m_baseFileGroup->getRelationPath(); + const FilePath & relationPath = this->getRelationPath(); - Helper::addDebugFilePath( _stream, relationPath, fi.zip->folderPath, _filePath ); -#endif + zip_memory->open( relationPath, fi.zip->folderPath, _filePath ); + } + } return true; } @@ -791,10 +811,6 @@ namespace Mengine //Empty -#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::removeDebugFilePath( _stream ); -#endif - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/ZipPlugin/FileGroupZip.h b/src/Plugins/ZipPlugin/FileGroupZip.h index 18a680c58f..1f48160261 100644 --- a/src/Plugins/ZipPlugin/FileGroupZip.h +++ b/src/Plugins/ZipPlugin/FileGroupZip.h @@ -3,6 +3,7 @@ #include "Interface/InputStreamInterface.h" #include "Interface/FileMappedInterface.h" #include "Interface/ThreadMutexInterface.h" +#include "Interface/FactoryInterface.h" #include "Kernel/Factorable.h" #include "Kernel/BaseFileGroup.h" @@ -73,6 +74,8 @@ namespace Mengine bool loadMappedFile( const FilePath & _folderPath, FileMappedInterfacePtr * const _mappedFile ) const; protected: + FactoryInterfacePtr m_factoryZipMemoryInputStream; + uint32_t m_mappedThreshold; struct ZipInfo diff --git a/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp new file mode 100644 index 0000000000..04320e47e5 --- /dev/null +++ b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp @@ -0,0 +1,112 @@ +#include "ZipMemoryInputStream.h" + +#include "Kernel/DebugFileHelper.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + ZipMemoryInputStream::ZipMemoryInputStream() + { + } + ////////////////////////////////////////////////////////////////////////// + ZipMemoryInputStream::~ZipMemoryInputStream() + { + this->close(); + } + ////////////////////////////////////////////////////////////////////////// + void ZipMemoryInputStream::setMemoryInputStream( const MemoryInputInterfacePtr & _stream ) + { + m_stream = _stream; + } + ////////////////////////////////////////////////////////////////////////// + const MemoryInputInterfacePtr & ZipMemoryInputStream::getMemoryInputStream() const + { + return m_stream; + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + { +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif + + return true; + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::close() + { + m_stream = nullptr; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + + return true; + } + ////////////////////////////////////////////////////////////////////////// + Pointer ZipMemoryInputStream::newBuffer( size_t _size ) + { + return m_stream->newBuffer( _size ); + } + ////////////////////////////////////////////////////////////////////////// + Pointer ZipMemoryInputStream::getBuffer() const + { + return m_stream->getBuffer(); + } + ////////////////////////////////////////////////////////////////////////// + size_t ZipMemoryInputStream::getSize() const + { + return m_stream->getSize(); + } + ////////////////////////////////////////////////////////////////////////// + size_t ZipMemoryInputStream::read( void * const _buffer, size_t _size ) + { + return m_stream->read( _buffer, _size ); + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::seek( size_t _carriage ) + { + return m_stream->seek( _carriage ); + } + ////////////////////////////////////////////////////////////////////////// + void ZipMemoryInputStream::rewind() + { + m_stream->rewind(); + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::rseek( size_t _carriage ) + { + return m_stream->rseek( _carriage ); + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::skip( size_t _offset ) + { + return m_stream->skip( _offset ); + } + ////////////////////////////////////////////////////////////////////////// + size_t ZipMemoryInputStream::tell() const + { + return m_stream->tell(); + } + ////////////////////////////////////////////////////////////////////////// + size_t ZipMemoryInputStream::size() const + { + return m_stream->size(); + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::eof() const + { + return m_stream->eof(); + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::time( uint64_t * const _time ) const + { + return m_stream->time( _time ); + } + ////////////////////////////////////////////////////////////////////////// + bool ZipMemoryInputStream::memory( void ** const _memory, size_t * const _size ) + { + return m_stream->memory( _memory, _size ); + } + ////////////////////////////////////////////////////////////////////////// +} \ No newline at end of file diff --git a/src/Plugins/ZipPlugin/ZipMemoryInputStream.h b/src/Plugins/ZipPlugin/ZipMemoryInputStream.h new file mode 100644 index 0000000000..698c9671ba --- /dev/null +++ b/src/Plugins/ZipPlugin/ZipMemoryInputStream.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Interface/MemoryInterface.h" + +#include "Kernel/Factorable.h" +#include "Kernel/FilePath.h" + +namespace Mengine +{ + class ZipMemoryInputStream + : public MemoryInputInterface + , public Factorable + { + DECLARE_FACTORABLE( ZipMemoryInputStream ); + + public: + ZipMemoryInputStream(); + ~ZipMemoryInputStream() override; + + public: + void setMemoryInputStream( const MemoryInputInterfacePtr & _stream ); + const MemoryInputInterfacePtr & getMemoryInputStream() const; + + public: + bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ); + bool close(); + + public: + Pointer newBuffer( size_t _size ) override; + + public: + Pointer getBuffer() const override; + size_t getSize() const override; + + public: + size_t read( void * const _buffer, size_t _size ) override; + bool seek( size_t _carriage ) override; + void rewind() override; + bool rseek( size_t _carriage ) override; + bool skip( size_t _offset ) override; + size_t tell() const override; + size_t size() const override; + bool eof() const override; + + public: + bool time( uint64_t * const _time ) const override; + + public: + bool memory( void ** const _memory, size_t * const _size ) override; + + protected: + MemoryInputInterfacePtr m_stream; + }; + ////////////////////////////////////////////////////////////////////////// + typedef IntrusivePtr ZipMemoryInputStreamPtr; + ////////////////////////////////////////////////////////////////////////// +} \ No newline at end of file diff --git a/src/Services/ConfigService/ConfigService.cpp b/src/Services/ConfigService/ConfigService.cpp index 6661c0cfe0..b160de47b6 100644 --- a/src/Services/ConfigService/ConfigService.cpp +++ b/src/Services/ConfigService/ConfigService.cpp @@ -171,6 +171,8 @@ namespace Mengine return nullptr; } + _content->closeInputStreamFile( stream ); + return config; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/ConverterService/ConverterService.cpp b/src/Services/ConverterService/ConverterService.cpp index 46402330b7..b2e07c06d1 100644 --- a/src/Services/ConverterService/ConverterService.cpp +++ b/src/Services/ConverterService/ConverterService.cpp @@ -160,7 +160,9 @@ namespace Mengine oldFile = nullptr; - InputStreamInterfacePtr newFile = Helper::openInputStreamFile( outputFileGroup, outputFilePath, false, false, _doc ); + ContentInterfacePtr newContent = Helper::makeFileContent( outputFileGroup, outputFilePath, MENGINE_DOCUMENT_FACTORABLE ); + + InputStreamInterfacePtr newFile = newContent->openInputStreamFile( false, false, _doc ); MENGINE_ASSERTION_MEMORY_PANIC( newFile, "converter '%s' can't open output file '%s' (time)" , _converterType.c_str() @@ -183,6 +185,8 @@ namespace Mengine , Helper::getContentFullPath( options.outputContent ).c_str() ); } + + newContent->closeInputStreamFile( newFile ); } LOGGER_MESSAGE( "converter '%s'\nfrom: %s\nto: '%s'\n" diff --git a/src/Services/FileService/FileService.cpp b/src/Services/FileService/FileService.cpp index f8b54ab288..809fdc3e89 100644 --- a/src/Services/FileService/FileService.cpp +++ b/src/Services/FileService/FileService.cpp @@ -211,7 +211,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) ////////////////////////////////////////////////////////////////////////// - void FileService::addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) + void FileService::addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, const DocumentInterfacePtr & _doc ) { MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); @@ -219,13 +219,19 @@ namespace Mengine dfp.relationPath = _relationPath; dfp.folderPath = _folderPath; dfp.filePath = _filePath; + dfp.doc = _doc; auto result = m_debugFilePaths.emplace( _id, dfp ); MENGINE_UNUSED( result ); - MENGINE_ASSERTION_FATAL( result.second == true, "already add debug file path id %u" + MENGINE_ASSERTION_FATAL( result.second == true, "already add debug file path id %u path: %s%s%s [doc: %s] prev [doc: %s]" , _id + , _relationPath.c_str() + , _folderPath.c_str() + , _filePath.c_str() + , MENGINE_DOCUMENT_STR( _doc ) + , MENGINE_DOCUMENT_STR( result.first->second.doc ) ); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/FileService/FileService.h b/src/Services/FileService/FileService.h index c0e7dd1c6e..329e64637b 100644 --- a/src/Services/FileService/FileService.h +++ b/src/Services/FileService/FileService.h @@ -34,7 +34,7 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) public: - void addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) override; + void addDebugFilePath( UniqueId _id, const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, const DocumentInterfacePtr & _doc ) override; void removeDebugFilePath( UniqueId _id ) override; public: @@ -55,6 +55,7 @@ namespace Mengine FilePath relationPath; FilePath folderPath; FilePath filePath; + DocumentInterfacePtr doc; }; typedef UnorderedMap UnorderedMapDebugFilePaths; diff --git a/src/Services/LoaderService/LoaderService.cpp b/src/Services/LoaderService/LoaderService.cpp index 2ee52a369a..4bfb99a100 100644 --- a/src/Services/LoaderService/LoaderService.cpp +++ b/src/Services/LoaderService/LoaderService.cpp @@ -107,6 +107,8 @@ namespace Mengine bool reimport = false; bool done = this->importBin_( file_bin, _metadata, _metaVersion, &reimport, _doc ); + _content->closeInputStreamFile( file_bin ); + #if defined(MENGINE_MASTER_RELEASE_DISABLE) if( reimport == true ) { @@ -130,9 +132,13 @@ namespace Mengine return false; } - file_bin = Helper::openInputStreamFile( fileGroup, filePath, false, false, MENGINE_DOCUMENT_FACTORABLE ); + ContentInterfacePtr reimport_content_bin = Helper::makeFileContent( fileGroup, filePath, _doc ); + + InputStreamInterfacePtr reimport_stream_bin = reimport_content_bin->openInputStreamFile( false, false, _doc ); - done = this->importBin_( file_bin, _metadata, _metaVersion, nullptr, _doc ); + done = this->importBin_( reimport_stream_bin, _metadata, _metaVersion, nullptr, _doc ); + + reimport_content_bin->closeInputStreamFile( reimport_stream_bin ); } #endif @@ -158,6 +164,8 @@ namespace Mengine uint8_t header_buff[Metacode::header_size]; stream->read( header_buff, Metacode::header_size ); + _content->closeInputStreamFile( stream ); + size_t header_read = 0; uint32_t readVersion; uint32_t needVersion; diff --git a/src/Services/MemoryService/MemoryInput.h b/src/Services/MemoryService/MemoryInput.h index 0c1c4c003b..cfb52b3c8c 100644 --- a/src/Services/MemoryService/MemoryInput.h +++ b/src/Services/MemoryService/MemoryInput.h @@ -1,6 +1,5 @@ #pragma once -#include "Interface/ServiceInterface.h" #include "Interface/MemoryInterface.h" #include "Kernel/Factorable.h" diff --git a/src/Services/PrefetcherService/ThreadTaskPrefetchImageDecoder.cpp b/src/Services/PrefetcherService/ThreadTaskPrefetchImageDecoder.cpp index 51183002f6..433b060085 100644 --- a/src/Services/PrefetcherService/ThreadTaskPrefetchImageDecoder.cpp +++ b/src/Services/PrefetcherService/ThreadTaskPrefetchImageDecoder.cpp @@ -117,7 +117,7 @@ namespace Mengine return false; } - if( m_imageDecoder->prepareData( m_memoryInput ) == false ) + if( m_imageDecoder->prepareData( nullptr, m_memoryInput ) == false ) { LOGGER_ERROR( "decoder for file '%s' codec '%s' was not initialize" , Helper::getContentFullPath( m_content ).c_str() diff --git a/src/Services/PrefetcherService/ThreadTaskPrefetchSoundDecoder.cpp b/src/Services/PrefetcherService/ThreadTaskPrefetchSoundDecoder.cpp index b5c0c2dd3c..0846af4642 100644 --- a/src/Services/PrefetcherService/ThreadTaskPrefetchSoundDecoder.cpp +++ b/src/Services/PrefetcherService/ThreadTaskPrefetchSoundDecoder.cpp @@ -28,8 +28,13 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void ThreadTaskPrefetchSoundDecoder::_finalize() { - m_soundDecoder = nullptr; m_memoryInput = nullptr; + + if( m_soundDecoder != nullptr ) + { + m_soundDecoder->finalize(); + m_soundDecoder = nullptr; + } } ////////////////////////////////////////////////////////////////////////// bool ThreadTaskPrefetchSoundDecoder::_onThreadTaskRun() @@ -107,7 +112,7 @@ namespace Mengine return false; } - if( m_soundDecoder->prepareData( m_memoryInput ) == false ) + if( m_soundDecoder->prepareData( nullptr, m_memoryInput ) == false ) { LOGGER_ERROR( "decoder for file '%s' was not initialize" , Helper::getContentFullPath( m_content ).c_str() diff --git a/src/Services/ProviderService/ServiceProvider.cpp b/src/Services/ProviderService/ServiceProvider.cpp index da3e494e4e..9e5ff11d91 100644 --- a/src/Services/ProviderService/ServiceProvider.cpp +++ b/src/Services/ProviderService/ServiceProvider.cpp @@ -49,6 +49,8 @@ namespace Mengine MENGINE_ASSERTION_MEMORY_PANIC( service, "invalid generate service" ); + service->setUniqueIdentity( ~0U ); + #if defined(MENGINE_DOCUMENT_ENABLE) service->setDocument( _doc ); #endif diff --git a/src/Services/RenderService/DecoderRenderImageLoader.cpp b/src/Services/RenderService/DecoderRenderImageLoader.cpp index 969564d814..d28e71ad69 100644 --- a/src/Services/RenderService/DecoderRenderImageLoader.cpp +++ b/src/Services/RenderService/DecoderRenderImageLoader.cpp @@ -33,12 +33,6 @@ namespace Mengine if( Helper::getPrefetchImageDecoder( _content, &decoder ) == false ) { decoder = this->createImageDecoder_( _content ); - - MENGINE_ASSERTION_MEMORY_PANIC( decoder, "invalid create decoder '%s' codec '%s' (doc: %s)" - , Helper::getContentFullPath( _content ).c_str() - , _content->getCodecType().c_str() - , MENGINE_DOCUMENTABLE_STR( this, "DecoderRenderImageLoader" ) - ); } else { @@ -54,12 +48,28 @@ namespace Mengine } } + if( decoder == nullptr ) + { + LOGGER_ERROR( "invalid create decoder '%s' codec '%s' (doc: %s)" + , Helper::getContentFullPath( _content ).c_str() + , _content->getCodecType().c_str() + , MENGINE_DOCUMENTABLE_STR( this, "DecoderRenderImageLoader" ) + ); + + return false; + } + m_decoder = decoder; m_codecFlags = _codecFlags; return true; } ////////////////////////////////////////////////////////////////////////// + void DecoderRenderImageLoader::finalize() + { + m_decoder = nullptr; + } + ////////////////////////////////////////////////////////////////////////// void DecoderRenderImageLoader::getImageDesc( RenderImageDesc * const _desc ) const { const ImageCodecDataInfo * dataInfo = m_decoder->getCodecDataInfo(); @@ -224,7 +234,7 @@ namespace Mengine , MENGINE_DOCUMENTABLE_STR( this, "DecoderRenderImageLoader" ) ); - if( decoder->prepareData( stream ) == false ) + if( decoder->prepareData( _content, stream ) == false ) { LOGGER_ERROR( "invalid prepare data '%s' codec '%s' (doc: %s)" , Helper::getContentFullPath( _content ).c_str() diff --git a/src/Services/RenderService/DecoderRenderImageLoader.h b/src/Services/RenderService/DecoderRenderImageLoader.h index 0b7032e40b..fae78460ed 100644 --- a/src/Services/RenderService/DecoderRenderImageLoader.h +++ b/src/Services/RenderService/DecoderRenderImageLoader.h @@ -24,6 +24,7 @@ namespace Mengine public: bool initialize( const ContentInterfacePtr & _content, uint32_t _codecFlags ); + void finalize(); protected: void getImageDesc( RenderImageDesc * const _desc ) const override; diff --git a/src/Services/RenderService/RenderTextureService.cpp b/src/Services/RenderService/RenderTextureService.cpp index 455ca9af52..1a784ee7d2 100644 --- a/src/Services/RenderService/RenderTextureService.cpp +++ b/src/Services/RenderService/RenderTextureService.cpp @@ -150,7 +150,7 @@ namespace Mengine , Helper::getContentFullPath( _content ).c_str() ); - if( imageEncoder->initialize( stream ) == false ) + if( imageEncoder->initialize( _content, stream ) == false ) { LOGGER_ERROR( "can't initialize encoder for file '%s'" , Helper::getContentFullPath( _content ).c_str() diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index ef0073532b..378a5803bd 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -457,7 +457,7 @@ namespace Mengine , Helper::getContentFullPath( _content ).c_str() ); - if( soundDecoder->prepareData( stream ) == false ) + if( soundDecoder->prepareData( _content, stream ) == false ) { LOGGER_ERROR( "can't initialize sound decoder for file '%s'" , Helper::getContentFullPath( _content ).c_str() @@ -487,16 +487,16 @@ namespace Mengine _streamable = false; } - SoundDecoderInterfacePtr soundDecoder; + SoundDecoderInterfacePtr decoder; if( _streamable == false ) { - if( Helper::getPrefetchSoundDecoder( _content, &soundDecoder ) == false ) + if( Helper::getPrefetchSoundDecoder( _content, &decoder ) == false ) { - soundDecoder = this->createSoundDecoder_( _content, false, _doc ); + decoder = this->createSoundDecoder_( _content, false, _doc ); } else { - if( soundDecoder->rewind() == false ) + if( decoder->rewind() == false ) { LOGGER_ERROR( "invalid rewind decoder '%s'" , Helper::getContentFullPath( _content ).c_str() @@ -508,10 +508,10 @@ namespace Mengine } else { - soundDecoder = this->createSoundDecoder_( _content, true, _doc ); + decoder = this->createSoundDecoder_( _content, true, _doc ); } - if( soundDecoder == nullptr ) + if( decoder == nullptr ) { LOGGER_ERROR( "invalid create sound decoder '%s' codec '%s' streamable [%s]" , Helper::getContentFullPath( _content ).c_str() @@ -523,7 +523,7 @@ namespace Mengine } SoundBufferInterfacePtr buffer = SOUND_SYSTEM() - ->createSoundBuffer( soundDecoder, _streamable, _doc ); + ->createSoundBuffer( decoder, _streamable, _doc ); if( buffer == nullptr ) { diff --git a/src/Services/TextService/TextLocalePackage.cpp b/src/Services/TextService/TextLocalePackage.cpp index 98ab6eefda..bf46513c74 100644 --- a/src/Services/TextService/TextLocalePackage.cpp +++ b/src/Services/TextService/TextLocalePackage.cpp @@ -45,6 +45,8 @@ namespace Mengine stream->read( memory_buffer, xml_buffer_size ); memory_buffer[xml_buffer_size] = '\0'; + m_content->closeInputStreamFile( stream ); + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/UserdataService/UserdataService.cpp b/src/Services/UserdataService/UserdataService.cpp index e717b518a8..66bb97f9f3 100644 --- a/src/Services/UserdataService/UserdataService.cpp +++ b/src/Services/UserdataService/UserdataService.cpp @@ -133,6 +133,8 @@ namespace Mengine , Helper::getContentFullPath( desc.content ).c_str() ); + content->closeInputStreamFile( stream ); + return binaryBuffer; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp index 04feaf6b65..c9ae4cb144 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp @@ -97,7 +97,7 @@ namespace Mengine } #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp index 6d680d547b..653304a404 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp @@ -97,7 +97,7 @@ namespace Mengine } #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp index 2e8e8bc696..fdf31c99b3 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp @@ -7,6 +7,7 @@ #include "Kernel/DebugFileHelper.h" #include "Kernel/ThreadGuardScope.h" #include "Kernel/NotificationHelper.h" +#include "Kernel/DocumentHelper.h" #include "Config/Path.h" @@ -64,7 +65,7 @@ namespace Mengine #endif #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; @@ -76,7 +77,7 @@ namespace Mengine if( m_file == nullptr ) { - return false; + return true; } #if defined(MENGINE_DEBUG) diff --git a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp index 2d5f11d43f..1a553d536b 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp @@ -7,6 +7,7 @@ #include "Kernel/Logger.h" #include "Kernel/ThreadMutexScope.h" #include "Kernel/DebugFileHelper.h" +#include "Kernel/DocumentHelper.h" #include "stdex/memorycopy.h" @@ -77,7 +78,7 @@ namespace Mengine m_reading = 0; #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; diff --git a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp index 37a062555f..4129817c2e 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp @@ -5,6 +5,7 @@ #include "Kernel/Logger.h" #include "Kernel/ThreadMutexScope.h" #include "Kernel/DebugFileHelper.h" +#include "Kernel/DocumentHelper.h" #include "stdex/memorycopy.h" @@ -75,7 +76,7 @@ namespace Mengine m_reading = 0; #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp index 61f0da0c6a..4f3e0f2863 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp @@ -203,7 +203,7 @@ namespace Mengine return soundSource; } ////////////////////////////////////////////////////////////////////////// - SoundBufferInterfacePtr OpenALSoundSystem::createSoundBuffer( const SoundDecoderInterfacePtr & _soundDecoder, bool _isStream, const DocumentInterfacePtr & _doc ) + SoundBufferInterfacePtr OpenALSoundSystem::createSoundBuffer( const SoundDecoderInterfacePtr & _decoder, bool _isStream, const DocumentInterfacePtr & _doc ) { OpenALSoundBufferBasePtr base = nullptr; @@ -224,7 +224,7 @@ namespace Mengine base = buffer; } - if( base->load( _soundDecoder ) == false ) + if( base->load( _decoder ) == false ) { LOGGER_ASSERTION( "failed to create sound buffer from stream" ); diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h index ba2e1d8255..aa040c4299 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h +++ b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h @@ -40,7 +40,7 @@ namespace Mengine public: SoundSourceInterfacePtr createSoundSource( bool _isHeadMode, const SoundBufferInterfacePtr & _sample, const DocumentInterfacePtr & _doc ) override; - SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _soundDecoder, bool _isStream, const DocumentInterfacePtr & _doc ) override; + SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _decoder, bool _isStream, const DocumentInterfacePtr & _doc ) override; public: ALuint genSourceId() override; diff --git a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp index 3c7103d462..e05ffbf885 100644 --- a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp +++ b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp @@ -242,7 +242,13 @@ namespace Mengine bool result = file->close(); - MENGINE_ASSERTION( result == true, "failed close file '%s'" + if( result == false ) + { + return false; + } + + MENGINE_ASSERTION( result == true, "failed close file '%s%s'" + , m_relationPath.c_str() , m_folderPath.c_str() ); diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp index 9f7929f375..4a976c68ba 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp @@ -119,7 +119,7 @@ namespace Mengine } #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; diff --git a/src/Systems/Win32FileSystem/Win32FileMapped.cpp b/src/Systems/Win32FileSystem/Win32FileMapped.cpp index 0d94e32b53..3b24d8fe46 100644 --- a/src/Systems/Win32FileSystem/Win32FileMapped.cpp +++ b/src/Systems/Win32FileSystem/Win32FileMapped.cpp @@ -14,6 +14,7 @@ #include "Kernel/Logger.h" #include "Kernel/AssertionMemoryPanic.h" #include "Kernel/FactoryPool.h" +#include "Kernel/DebugFileHelper.h" #include "Config/Path.h" @@ -103,6 +104,10 @@ namespace Mengine m_factoryFileMappedInputStream = Helper::makeFactoryPoolWithMutex( MENGINE_DOCUMENT_FACTORABLE ); +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -124,6 +129,10 @@ namespace Mengine m_factoryFileMappedInputStream = nullptr; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp index d6b350ed0c..6e72fe3df9 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp @@ -96,7 +96,7 @@ namespace Mengine #endif #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp index 0c64b853ce..6780069925 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp @@ -85,7 +85,7 @@ namespace Mengine m_reading = 0; #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath ); + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; From a48105f2495597a0ec65cddae1964b82cecea9c1 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 15 Sep 2025 14:39:32 +0300 Subject: [PATCH 036/169] fix OpenGLRenderImageTarget --- .../OpenGLRenderImageTarget.cpp | 15 +++++++++++++-- .../OpenGLRenderTargetTexture.cpp | 7 +++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Systems/OpenGLRenderSystem/OpenGLRenderImageTarget.cpp b/src/Systems/OpenGLRenderSystem/OpenGLRenderImageTarget.cpp index 86b24fd75f..85d1712b3a 100644 --- a/src/Systems/OpenGLRenderSystem/OpenGLRenderImageTarget.cpp +++ b/src/Systems/OpenGLRenderSystem/OpenGLRenderImageTarget.cpp @@ -136,12 +136,23 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void OpenGLRenderImageTarget::onRenderReset() { - //Empty + if( m_renderTarget != nullptr ) + { + m_renderTarget->onRenderReset(); + } } ////////////////////////////////////////////////////////////////////////// bool OpenGLRenderImageTarget::onRenderRestore() { - //Empty + if( m_renderTarget == nullptr ) + { + return false; + } + + if( m_renderTarget->onRenderRestore() == false ) + { + return false; + } return true; } diff --git a/src/Systems/OpenGLRenderSystem/OpenGLRenderTargetTexture.cpp b/src/Systems/OpenGLRenderSystem/OpenGLRenderTargetTexture.cpp index 3ed601172d..1b6890cddd 100644 --- a/src/Systems/OpenGLRenderSystem/OpenGLRenderTargetTexture.cpp +++ b/src/Systems/OpenGLRenderSystem/OpenGLRenderTargetTexture.cpp @@ -258,12 +258,15 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void OpenGLRenderTargetTexture::onRenderReset() { - //Empty + this->release(); } ////////////////////////////////////////////////////////////////////////// bool OpenGLRenderTargetTexture::onRenderRestore() { - //Empty + if( this->create() == false ) + { + return false; + } return true; } From ff139bef7a47107f7718f082a811f5a70c2b8bc7 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 16 Sep 2025 00:43:56 +0300 Subject: [PATCH 037/169] fix SoundService --- .../PythonFramework/SoundScriptEmbedding.cpp | 3 + src/Services/SoundService/SoundService.cpp | 63 ++++++++++++------- src/Services/SoundService/SoundService.h | 6 +- .../ThreadWorkerSoundBufferUpdate.cpp | 5 ++ .../ThreadWorkerSoundBufferUpdate.h | 1 + 5 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index 6f4582511a..cda81053e6 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -231,6 +231,9 @@ namespace Mengine , volume ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + resource->release(); return nullptr; diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 378a5803bd..6db8907731 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -251,6 +251,8 @@ namespace Mengine { LOGGER_ASSERTION( "invalid resume (play)" ); + identity->setState( ESS_CANCEL ); + continue; } @@ -265,7 +267,14 @@ namespace Mengine continue; } - this->playSoundBufferUpdate_( identity ); + if( this->playSoundBufferUpdate_( identity ) == false ) + { + LOGGER_MESSAGE( "invalid play sound buffer update" ); + + identity->setState( ESS_CANCEL ); + + continue; + } } } } @@ -874,7 +883,14 @@ namespace Mengine return false; } - this->playSoundBufferUpdate_( _identity ); + if( this->playSoundBufferUpdate_( _identity ) == false ) + { + LOGGER_MESSAGE( "invalid play sound buffer update" ); + + _identity->setState( ESS_CANCEL ); + + return false; + } } const SoundListenerInterfacePtr & listener = _identity->getSoundListener(); @@ -915,6 +931,8 @@ namespace Mengine , _identity->getUniqueIdentity() ); + _identity->setState( ESS_CANCEL ); + return false; } @@ -1050,6 +1068,8 @@ namespace Mengine , _identity->getUniqueIdentity() ); + _identity->setState( ESS_CANCEL ); + return false; } @@ -1388,6 +1408,8 @@ namespace Mengine , _identity->getUniqueIdentity() ); + _identity->setState( ESS_CANCEL ); + return false; } } @@ -1400,16 +1422,16 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool SoundService::stopSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) + void SoundService::stopSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) { if( _identity->getStreamable() == false ) { - return false; + return; } if( _identity->getWorkerUpdateBuffer() == nullptr ) { - return false; + return; } if( m_threadJobSoundBufferUpdate != nullptr ) @@ -1421,15 +1443,13 @@ namespace Mengine _identity->setWorkerUpdateBuffer( nullptr ); _identity->setWorkerId( INVALID_UNIQUE_ID ); - - return true; } ////////////////////////////////////////////////////////////////////////// bool SoundService::playSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) { if( _identity->getStreamable() == false ) { - return false; + return true; } if( _identity->getWorkerUpdateBuffer() != nullptr ) @@ -1457,9 +1477,14 @@ namespace Mengine { LOGGER_ERROR( "identity worker invalid add worker" ); + worker->finalize(); + + _identity->setWorkerUpdateBuffer( nullptr ); + return false; } + _identity->setWorkerUpdateBuffer( worker ); _identity->setWorkerId( workerId ); } else @@ -1471,16 +1496,16 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool SoundService::pauseSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) + void SoundService::pauseSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) { if( _identity->getStreamable() == false ) { - return false; + return; } if( _identity->getWorkerUpdateBuffer() == nullptr ) { - return false; + return; } if( m_threadJobSoundBufferUpdate != nullptr ) @@ -1489,20 +1514,18 @@ namespace Mengine m_threadJobSoundBufferUpdate->pauseWorker( workerId ); } - - return true; } ////////////////////////////////////////////////////////////////////////// - bool SoundService::resumeSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) + void SoundService::resumeSoundBufferUpdate_( const SoundIdentityInterfacePtr & _identity ) { if( _identity->getStreamable() == false ) { - return false; + return; } if( _identity->getWorkerUpdateBuffer() == nullptr ) { - return false; + return; } if( m_threadJobSoundBufferUpdate != nullptr ) @@ -1511,8 +1534,6 @@ namespace Mengine m_threadJobSoundBufferUpdate->resumeWorker( workerId ); } - - return true; } ////////////////////////////////////////////////////////////////////////// bool SoundService::checkMaxSoundPlay_() const @@ -1522,11 +1543,6 @@ namespace Mengine return _identity->getState() == ESS_PLAY; } ); - LOGGER_MESSAGE( "current play sound count: %u total: %u" - , playCount - , (uint32_t)m_soundIdentities.size() - ); - uint32_t Limit_MaxSoundPlay = CONFIG_VALUE_INTEGER( "Limit", "MaxSoundPlay", 32 ); if( playCount > Limit_MaxSoundPlay ) @@ -1544,6 +1560,7 @@ namespace Mengine << (identity->getStreamable() == true ? "streamable" : "instance") << " " << "category: " << identity->getCategory() << " " << "state: " << identity->getState() << " " + << "volume: " << identity->getMixerVolume()->mixValue() << " " << "time: " << timestamp - identity->getStateTimestamp() << " " << "source: " << Helper::getDebugFullPath( identity->getSoundSource()->getSoundBuffer()->getDecoder()->getStream() ).c_str() << " " << "(doc: " << MENGINE_DOCUMENT_STR( identity->getDocument() ) << ")"; diff --git a/src/Services/SoundService/SoundService.h b/src/Services/SoundService/SoundService.h index c493c0a5d8..6b4554b964 100644 --- a/src/Services/SoundService/SoundService.h +++ b/src/Services/SoundService/SoundService.h @@ -127,9 +127,9 @@ namespace Mengine protected: bool playSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); - bool stopSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); - bool pauseSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); - bool resumeSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); + void stopSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); + void pauseSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); + void resumeSoundBufferUpdate_( const SoundIdentityInterfacePtr & _source ); protected: bool checkMaxSoundPlay_() const; diff --git a/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.cpp b/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.cpp index 76d1b24368..d570a3e6f1 100644 --- a/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.cpp +++ b/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.cpp @@ -21,6 +21,11 @@ namespace Mengine m_soundBuffer = _soundBuffer; } ////////////////////////////////////////////////////////////////////////// + void ThreadWorkerSoundBufferUpdate::finalize() + { + m_soundBuffer = nullptr; + } + ////////////////////////////////////////////////////////////////////////// bool ThreadWorkerSoundBufferUpdate::isDone() const { return m_done; diff --git a/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.h b/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.h index 9ae1b29ac4..609743af98 100644 --- a/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.h +++ b/src/Services/SoundService/ThreadWorkerSoundBufferUpdate.h @@ -21,6 +21,7 @@ namespace Mengine public: void initialize( const SoundBufferInterfacePtr & _soundSource ); + void finalize(); public: bool isDone() const; From 9124d9c0c857e0b996b4fe3a3a86b0b4bd5d9695 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 16 Sep 2025 13:41:38 +0300 Subject: [PATCH 038/169] rename soundFadeIn|soundFadeOut improve embedded SoundIdentityInterface remove ESS_CANCEL --- .../PythonFramework/SoundScriptEmbedding.cpp | 42 +++++++++++++------ src/Interface/SoundIdentityInterface.h | 1 - .../AmplifierService/AmplifierService.cpp | 2 - src/Services/SoundService/SoundService.cpp | 36 ++++++++-------- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index cda81053e6..1089c27d7f 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -465,11 +465,11 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// IntrusivePtr> m_affectorCreatorSound; ////////////////////////////////////////////////////////////////////////// - bool soundFadeIn( const SoundIdentityInterfacePtr & _identity, float _time, const ConstString & _easingType, const pybind::object & _cb, const pybind::args & _args ) + bool soundFadeOut( const SoundIdentityInterfacePtr & _identity, float _time, const ConstString & _easingType, const pybind::object & _cb, const pybind::args & _args ) { if( _identity == nullptr ) { - LOGGER_ERROR( "soundFadeIn invalid emitter" ); + LOGGER_ERROR( "soundFadeOut invalid emitter" ); return false; } @@ -496,9 +496,9 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - SoundIdentityInterfacePtr soundFadeOut( const ConstString & _resourceName, bool _loop, float _time, const ConstString & _easingType, const pybind::object & _cbs, const pybind::args & _args ) + SoundIdentityInterfacePtr soundFadeIn( const ConstString & _resourceName, bool _loop, float _time, const ConstString & _easingType, const pybind::object & _cbs, const pybind::args & _args ) { - LOGGER_INFO( "sound", "[script] sound fade out resource '%s' file '%s'" + LOGGER_INFO( "sound", "[script] sound fade in resource '%s' file '%s'" , _resourceName.c_str() , Helper::getResourceFilePathByName( _resourceName ).c_str() ); @@ -553,11 +553,11 @@ namespace Mengine return soundIdentity; } ////////////////////////////////////////////////////////////////////////// - bool soundFadeInTo( const SoundIdentityInterfacePtr & _identity, float _to, float _time, const ConstString & _easingType, const pybind::object & _cb, const pybind::args & _args ) + bool soundFadeOutTo( const SoundIdentityInterfacePtr & _identity, float _to, float _time, const ConstString & _easingType, const pybind::object & _cb, const pybind::args & _args ) { if( _identity == nullptr ) { - LOGGER_ERROR( "soundFadeInTo invalid emitter" ); + LOGGER_ERROR( "soundFadeOutTo invalid emitter" ); return false; } @@ -587,9 +587,9 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - SoundIdentityInterfacePtr soundFadeOutTo( const ConstString & _resourceName, bool _loop, float _to, float _time, const ConstString & _easingType, const pybind::object & _cbs, const pybind::args & _args ) + SoundIdentityInterfacePtr soundFadeInTo( const ConstString & _resourceName, bool _loop, float _to, float _time, const ConstString & _easingType, const pybind::object & _cbs, const pybind::args & _args ) { - LOGGER_INFO( "sound", "[script] sound fade out to resource '%s' file '%s'" + LOGGER_INFO( "sound", "[script] sound fade in to resource '%s' file '%s'" , _resourceName.c_str() , Helper::getResourceFilePathByName( _resourceName ).c_str() ); @@ -808,10 +808,26 @@ namespace Mengine return false; } - pybind::interface_>( _kernel, "SoundIdentity" ) - .def( "isStreamable", &SoundIdentityInterface::getStreamable ) + pybind::enum_( _kernel, "ESoundSourceCategory" ) + .def( "ES_SOURCE_CATEGORY_SOUND", ES_SOURCE_CATEGORY_SOUND ) + .def( "ES_SOURCE_CATEGORY_MUSIC", ES_SOURCE_CATEGORY_MUSIC ) + .def( "ES_SOURCE_CATEGORY_VOICE", ES_SOURCE_CATEGORY_VOICE ) + ; + + pybind::enum_( _kernel, "ESoundSourceState" ) + .def( "ESS_STOP", ESS_STOP ) + .def( "ESS_PLAY", ESS_PLAY ) + .def( "ESS_PAUSE", ESS_PAUSE ) + ; + + pybind::interface_>( _kernel, "SoundIdentityInterface" ) .def( "getStreamable", &SoundIdentityInterface::getStreamable ) .def( "getLoop", &SoundIdentityInterface::getLoop ) + .def( "getTurn", &SoundIdentityInterface::getTurn ) + .def( "getCategory", &SoundIdentityInterface::getCategory ) + .def( "getState", &SoundIdentityInterface::getState ) + .def( "getStateTimestamp", &SoundIdentityInterface::getStateTimestamp ) + .def( "getTimeLeft", &SoundIdentityInterface::getTimeLeft ) ; pybind::def_functor( _kernel, "hasSound", soundScriptMethod, &SoundScriptMethod::hasSound ); @@ -836,11 +852,11 @@ namespace Mengine pybind::def_functor( _kernel, "soundGetVolume", soundScriptMethod, &SoundScriptMethod::soundGetVolume ); pybind::def_functor( _kernel, "soundGetPosition", soundScriptMethod, &SoundScriptMethod::soundGetPosition ); pybind::def_functor( _kernel, "soundSetPosition", soundScriptMethod, &SoundScriptMethod::soundSetPosition ); - pybind::def_functor_args( _kernel, "soundFadeIn", soundScriptMethod, &SoundScriptMethod::soundFadeIn ); pybind::def_functor_args( _kernel, "soundFadeOut", soundScriptMethod, &SoundScriptMethod::soundFadeOut ); - pybind::def_functor_args( _kernel, "soundFadeInTo", soundScriptMethod, &SoundScriptMethod::soundFadeInTo ); + pybind::def_functor_args( _kernel, "soundFadeIn", soundScriptMethod, &SoundScriptMethod::soundFadeIn ); pybind::def_functor_args( _kernel, "soundFadeOutTo", soundScriptMethod, &SoundScriptMethod::soundFadeOutTo ); - + pybind::def_functor_args( _kernel, "soundFadeInTo", soundScriptMethod, &SoundScriptMethod::soundFadeInTo ); + pybind::def_functor_args( _kernel, "voicePlay", soundScriptMethod, &SoundScriptMethod::voicePlay ); pybind::def_functor( _kernel, "voiceStop", soundScriptMethod, &SoundScriptMethod::voiceStop ); pybind::def_functor( _kernel, "voicePause", soundScriptMethod, &SoundScriptMethod::voicePause ); diff --git a/src/Interface/SoundIdentityInterface.h b/src/Interface/SoundIdentityInterface.h index 60878b49f9..040fe3be7a 100644 --- a/src/Interface/SoundIdentityInterface.h +++ b/src/Interface/SoundIdentityInterface.h @@ -24,7 +24,6 @@ namespace Mengine ESS_STOP = 0, ESS_PLAY = 1, ESS_PAUSE = 2, - ESS_CANCEL = 3, }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr SoundIdentityInterfacePtr; diff --git a/src/Services/AmplifierService/AmplifierService.cpp b/src/Services/AmplifierService/AmplifierService.cpp index f1e200c143..6f1d9319d2 100644 --- a/src/Services/AmplifierService/AmplifierService.cpp +++ b/src/Services/AmplifierService/AmplifierService.cpp @@ -69,8 +69,6 @@ namespace Mengine SOUND_SERVICE() ->releaseSoundIdentity( keep_soundIdentity ); }break; - case ESS_CANCEL: - break; default: break; } diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 6db8907731..e04b52a6b0 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -251,7 +251,7 @@ namespace Mengine { LOGGER_ASSERTION( "invalid resume (play)" ); - identity->setState( ESS_CANCEL ); + identity->setState( ESS_STOP ); continue; } @@ -271,7 +271,7 @@ namespace Mengine { LOGGER_MESSAGE( "invalid play sound buffer update" ); - identity->setState( ESS_CANCEL ); + identity->setState( ESS_STOP ); continue; } @@ -292,11 +292,6 @@ namespace Mengine continue; } - if( state == ESS_CANCEL ) - { - continue; - } - this->stopSoundBufferUpdate_( identity ); const SoundSourceInterfacePtr & source = identity->getSoundSource(); @@ -687,7 +682,7 @@ namespace Mengine { ESoundSourceState state = identity->getState(); - if( state == ESS_CANCEL ) + if( state == ESS_STOP ) { m_soundIdentitiesEndAux.emplace_back( identity ); @@ -845,7 +840,7 @@ namespace Mengine { if( this->checkMaxSoundPlay_() == false ) { - _identity->setState( ESS_CANCEL ); + _identity->setState( ESS_STOP ); return false; } @@ -887,7 +882,7 @@ namespace Mengine { LOGGER_MESSAGE( "invalid play sound buffer update" ); - _identity->setState( ESS_CANCEL ); + _identity->setState( ESS_STOP ); return false; } @@ -905,7 +900,7 @@ namespace Mengine { if( this->checkMaxSoundPlay_() == false ) { - _identity->setState( ESS_CANCEL ); + _identity->setState( ESS_STOP ); return false; } @@ -931,7 +926,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_CANCEL ); + _identity->setState( ESS_STOP ); return false; } @@ -1068,7 +1063,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_CANCEL ); + _identity->setState( ESS_STOP ); return false; } @@ -1104,13 +1099,14 @@ namespace Mengine { MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid stop identity" ); - LOGGER_INFO( "sound", "stop sound identity: %u state: %d category: %d streamable: %d turn: %d source: %s" + LOGGER_INFO( "sound", "stop sound identity: %u state: %d category: %d streamable: %d turn: %d source: %s (doc: %s)" , _identity->getUniqueIdentity() , _identity->getState() , _identity->getCategory() , _identity->getStreamable() , _identity->getTurn() , Helper::getDebugFullPath( _identity->getSoundSource()->getSoundBuffer()->getDecoder()->getStream() ).c_str() + , MENGINE_DOCUMENT_STR( _identity->getDocument() ) ); ESoundSourceState state = _identity->getState(); @@ -1140,17 +1136,21 @@ namespace Mengine source->stop(); } - if( _identity->getSoundListener() != nullptr ) + const SoundListenerInterfacePtr & listener = _identity->getSoundListener(); + + if( listener != nullptr ) { - SoundListenerInterfacePtr keep_listener = _identity->getSoundListener(); + SoundListenerInterfacePtr keep_listener = listener; keep_listener->onSoundStop( _identity ); } }break; default: { #if defined(MENGINE_DEBUG) - LOGGER_WARNING( "invalid state [%u] (doc: %s)" + LOGGER_WARNING( "invalid stop sound identity: %u state: %u source: %s (doc: %s)" + , _identity->getUniqueIdentity() , _identity->getState() + , Helper::getDebugFullPath( _identity->getSoundSource()->getSoundBuffer()->getDecoder()->getStream() ).c_str() , MENGINE_DOCUMENT_STR( _identity->getDocument() ) ); #endif @@ -1408,7 +1408,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_CANCEL ); + _identity->setState( ESS_STOP ); return false; } From 54136d71a211d0adc5bc45620c8c907d9b67210d Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 16 Sep 2025 20:49:31 +0300 Subject: [PATCH 039/169] fix SoundService --- .../PythonFramework/SoundScriptEmbedding.cpp | 31 +--- src/Interface/SoundIdentityInterface.h | 4 +- src/Interface/SoundServiceInterface.h | 5 - src/Kernel/SurfaceSound.cpp | 47 +++--- .../AmplifierService/AmplifierService.cpp | 8 +- src/Services/SoundService/SoundIdentity.cpp | 6 +- src/Services/SoundService/SoundService.cpp | 143 ++++++------------ src/Services/SoundService/SoundService.h | 5 - 8 files changed, 94 insertions(+), 155 deletions(-) diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index 1089c27d7f..e2543b8070 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -671,30 +671,6 @@ namespace Mengine ->resumeEmitter( _identity ); } ////////////////////////////////////////////////////////////////////////// - bool isSoundStop( const SoundIdentityInterfacePtr & _identity ) - { - MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid sound check stop identity" ); - - return SOUND_SERVICE() - ->isEmitterStop( _identity ); - } - ////////////////////////////////////////////////////////////////////////// - bool isSoundPlay( const SoundIdentityInterfacePtr & _identity ) - { - MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid sound check play identity" ); - - return SOUND_SERVICE() - ->isEmitterPlay( _identity ); - } - ////////////////////////////////////////////////////////////////////////// - bool isSoundPause( const SoundIdentityInterfacePtr & _identity ) - { - MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid sound check pause identity" ); - - return SOUND_SERVICE() - ->isEmitterPause( _identity ); - } - ////////////////////////////////////////////////////////////////////////// void voiceStop( const SoundIdentityInterfacePtr & _identity ) { MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid voice stop identity" ); @@ -815,9 +791,11 @@ namespace Mengine ; pybind::enum_( _kernel, "ESoundSourceState" ) - .def( "ESS_STOP", ESS_STOP ) + .def( "ESS_INIT", ESS_INIT ) .def( "ESS_PLAY", ESS_PLAY ) .def( "ESS_PAUSE", ESS_PAUSE ) + .def( "ESS_STOP", ESS_STOP ) + .def( "ESS_END", ESS_END ) ; pybind::interface_>( _kernel, "SoundIdentityInterface" ) @@ -843,9 +821,6 @@ namespace Mengine pybind::def_functor( _kernel, "soundStop", soundScriptMethod, &SoundScriptMethod::soundStop ); pybind::def_functor( _kernel, "soundPause", soundScriptMethod, &SoundScriptMethod::soundPause ); pybind::def_functor( _kernel, "soundResume", soundScriptMethod, &SoundScriptMethod::soundResume ); - pybind::def_functor( _kernel, "isSoundStop", soundScriptMethod, &SoundScriptMethod::isSoundStop ); - pybind::def_functor( _kernel, "isSoundPlay", soundScriptMethod, &SoundScriptMethod::isSoundPlay ); - pybind::def_functor( _kernel, "isSoundPause", soundScriptMethod, &SoundScriptMethod::isSoundPause ); pybind::def_functor( _kernel, "soundSourceSetVolume", soundScriptMethod, &SoundScriptMethod::soundSourceSetVolume ); pybind::def_functor( _kernel, "soundSourceGetVolume", soundScriptMethod, &SoundScriptMethod::soundSourceGetVolume ); pybind::def_functor( _kernel, "soundSetVolume", soundScriptMethod, &SoundScriptMethod::soundSetVolume ); diff --git a/src/Interface/SoundIdentityInterface.h b/src/Interface/SoundIdentityInterface.h index 040fe3be7a..5078c008c4 100644 --- a/src/Interface/SoundIdentityInterface.h +++ b/src/Interface/SoundIdentityInterface.h @@ -21,9 +21,11 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// enum ESoundSourceState { - ESS_STOP = 0, + ESS_INIT = 0, ESS_PLAY = 1, ESS_PAUSE = 2, + ESS_STOP = 3, + ESS_END = 4, }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr SoundIdentityInterfacePtr; diff --git a/src/Interface/SoundServiceInterface.h b/src/Interface/SoundServiceInterface.h index c15991b233..09d0b8202c 100644 --- a/src/Interface/SoundServiceInterface.h +++ b/src/Interface/SoundServiceInterface.h @@ -73,11 +73,6 @@ namespace Mengine virtual bool resumeEmitter( const SoundIdentityInterfacePtr & _identity ) = 0; virtual bool stopEmitter( const SoundIdentityInterfacePtr & _identity ) = 0; - public: - virtual bool isEmitterStop( const SoundIdentityInterfacePtr & _identity ) const = 0; - virtual bool isEmitterPlay( const SoundIdentityInterfacePtr & _identity ) const = 0; - virtual bool isEmitterPause( const SoundIdentityInterfacePtr & _identity ) const = 0; - public: virtual bool setLoop( const SoundIdentityInterfacePtr & _identity, bool _looped ) = 0; virtual bool getLoop( const SoundIdentityInterfacePtr & _identity ) const = 0; diff --git a/src/Kernel/SurfaceSound.cpp b/src/Kernel/SurfaceSound.cpp index 26b7159a8e..a704069440 100644 --- a/src/Kernel/SurfaceSound.cpp +++ b/src/Kernel/SurfaceSound.cpp @@ -200,9 +200,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_play( UniqueId _enumerator, float _time ) { - MENGINE_UNUSED( _enumerator ); - MENGINE_UNUSED( _time ); - if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -230,23 +227,31 @@ namespace Mengine return false; } + EVENTABLE_METHOD( EVENT_ANIMATION_PLAY ) + ->onAnimationPlay( _enumerator, _time ); + return true; } ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_restart( UniqueId _enumerator, float _time ) { - MENGINE_UNUSED( _time ); - MENGINE_UNUSED( _enumerator ); + if( this->isCompile() == false ) + { + LOGGER_ERROR( "surface sound '%s' not compile" + , this->getName().c_str() + ); + + return false; + } - //ToDo + EVENTABLE_METHOD( EVENT_ANIMATION_RESTART ) + ->onAnimationRestart( _enumerator, _time ); return false; } ////////////////////////////////////////////////////////////////////////// void SurfaceSound::_pause( UniqueId _enumerator ) { - MENGINE_UNUSED( _enumerator ); - if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -258,13 +263,13 @@ namespace Mengine SOUND_SERVICE() ->pauseEmitter( m_soundIdentity ); + + EVENTABLE_METHOD( EVENT_ANIMATION_PAUSE ) + ->onAnimationPause( _enumerator ); } ////////////////////////////////////////////////////////////////////////// void SurfaceSound::_resume( UniqueId _enumerator, float _time ) { - MENGINE_UNUSED( _time ); - MENGINE_UNUSED( _enumerator ); - if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -276,18 +281,26 @@ namespace Mengine SOUND_SERVICE() ->resumeEmitter( m_soundIdentity ); + + EVENTABLE_METHOD( EVENT_ANIMATION_RESUME ) + ->onAnimationResume( _enumerator, _time ); } ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_stop( UniqueId _enumerator ) { + if( this->isCompile() == false ) + { + LOGGER_ERROR( "surface sound '%s' not compile" + , this->getName().c_str() + ); + + return false; + } + if( m_soundIdentity != nullptr ) { - if( SOUND_SERVICE() - ->isEmitterStop( m_soundIdentity ) == false ) - { - SOUND_SERVICE() - ->stopEmitter( m_soundIdentity ); - } + SOUND_SERVICE() + ->stopEmitter( m_soundIdentity ); } EVENTABLE_METHOD( EVENT_ANIMATION_END ) diff --git a/src/Services/AmplifierService/AmplifierService.cpp b/src/Services/AmplifierService/AmplifierService.cpp index 6f1d9319d2..74176a7020 100644 --- a/src/Services/AmplifierService/AmplifierService.cpp +++ b/src/Services/AmplifierService/AmplifierService.cpp @@ -57,7 +57,7 @@ namespace Mengine switch( state ) { - case ESS_STOP: + case ESS_INIT: break; case ESS_PAUSE: break; @@ -69,7 +69,9 @@ namespace Mengine SOUND_SERVICE() ->releaseSoundIdentity( keep_soundIdentity ); }break; - default: + case ESS_STOP: + break; + case ESS_END: break; } } @@ -189,7 +191,7 @@ namespace Mengine ESoundSourceState state = keep_soundIdentity->getState(); - if( state != ESS_STOP ) + if( state == ESS_PAUSE && state == ESS_PLAY ) { SOUND_SERVICE() ->stopEmitter( keep_soundIdentity ); diff --git a/src/Services/SoundService/SoundIdentity.cpp b/src/Services/SoundService/SoundIdentity.cpp index e00c4329c3..2653d24997 100644 --- a/src/Services/SoundService/SoundIdentity.cpp +++ b/src/Services/SoundService/SoundIdentity.cpp @@ -12,7 +12,7 @@ namespace Mengine SoundIdentity::SoundIdentity() : m_workerId( INVALID_UNIQUE_ID ) , m_timeLeft( 0.f ) - , m_state( ESS_STOP ) + , m_state( ESS_INIT ) , m_category( ES_SOURCE_CATEGORY_SOUND ) , m_stateTimestamp( 0 ) , m_streamable( false ) @@ -52,7 +52,7 @@ namespace Mengine m_timeLeft = 0.f; - m_state = ESS_STOP; + m_state = ESS_INIT; m_category = _category; m_streamable = _streamable; @@ -84,7 +84,7 @@ namespace Mengine m_listener = nullptr; m_worker = nullptr; - m_state = ESS_STOP; + m_state = ESS_END; m_mixerVolume = nullptr; } diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index e04b52a6b0..1a6e9df3d8 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -251,7 +251,7 @@ namespace Mengine { LOGGER_ASSERTION( "invalid resume (play)" ); - identity->setState( ESS_STOP ); + identity->setState( ESS_END ); continue; } @@ -271,7 +271,7 @@ namespace Mengine { LOGGER_MESSAGE( "invalid play sound buffer update" ); - identity->setState( ESS_STOP ); + identity->setState( ESS_END ); continue; } @@ -287,7 +287,7 @@ namespace Mengine ESoundSourceState state = identity->getState(); - if( state == ESS_STOP ) + if( state == ESS_INIT || state == ESS_STOP || state == ESS_END ) { continue; } @@ -682,15 +682,25 @@ namespace Mengine { ESoundSourceState state = identity->getState(); - if( state == ESS_STOP ) + if( state == ESS_INIT ) { - m_soundIdentitiesEndAux.emplace_back( identity ); + continue; + } + + if( state == ESS_PAUSE ) + { + continue; + } + if( state == ESS_STOP ) + { continue; } - if( state != ESS_PLAY ) + if( state == ESS_END ) { + m_soundIdentitiesEndAux.emplace_back( identity ); + continue; } @@ -727,18 +737,7 @@ namespace Mengine { if( worker->isDone() == true ) { - identity->setState( ESS_STOP ); - - this->stopSoundBufferUpdate_( identity ); - - const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); - - if( soundSource != nullptr ) - { - soundSource->stop(); - } - - identity->setTimeLeft( 0.f ); + identity->setState( ESS_END ); m_soundIdentitiesEndAux.emplace_back( identity ); } @@ -758,16 +757,7 @@ namespace Mengine { if( time_new <= 0.f ) { - identity->setState( ESS_STOP ); - - const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); - - if( soundSource != nullptr ) - { - soundSource->stop(); - } - - identity->setTimeLeft( 0.f ); + identity->setState( ESS_END ); m_soundIdentitiesEndAux.emplace_back( identity ); } @@ -785,6 +775,17 @@ namespace Mengine for( const SoundIdentityInterfacePtr & identity : m_soundIdentitiesEndAux ) { + this->stopSoundBufferUpdate_( identity ); + + const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); + + if( soundSource != nullptr ) + { + soundSource->stop(); + } + + identity->setTimeLeft( 0.f ); + SoundListenerInterfacePtr listener = identity->popSoundListener(); if( listener == nullptr ) @@ -832,19 +833,18 @@ namespace Mengine , Helper::getDebugFullPath( _identity->getSoundSource()->getSoundBuffer()->getDecoder()->getStream() ).c_str() ); + if( this->checkMaxSoundPlay_() == false ) + { + return false; + } + ESoundSourceState state = _identity->getState(); switch( state ) { + case ESS_INIT: case ESS_STOP: { - if( this->checkMaxSoundPlay_() == false ) - { - _identity->setState( ESS_STOP ); - - return false; - } - this->updateSourceVolume_( _identity ); const SoundSourceInterfacePtr & source = _identity->getSoundSource(); @@ -882,7 +882,7 @@ namespace Mengine { LOGGER_MESSAGE( "invalid play sound buffer update" ); - _identity->setState( ESS_STOP ); + _identity->setState( ESS_END ); return false; } @@ -898,13 +898,6 @@ namespace Mengine }break; case ESS_PAUSE: { - if( this->checkMaxSoundPlay_() == false ) - { - _identity->setState( ESS_STOP ); - - return false; - } - this->updateSourceVolume_( _identity ); const SoundSourceInterfacePtr & source = _identity->getSoundSource(); @@ -926,7 +919,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_STOP ); + _identity->setState( ESS_END ); return false; } @@ -1032,17 +1025,17 @@ namespace Mengine , Helper::getDebugFullPath( _identity->getSoundSource()->getSoundBuffer()->getDecoder()->getStream() ).c_str() ); + if( this->checkMaxSoundPlay_() == false ) + { + return false; + } + ESoundSourceState state = _identity->getState(); switch( state ) { case ESS_PAUSE: { - if( this->checkMaxSoundPlay_() == false ) - { - return false; - } - this->updateSourceVolume_( _identity ); const SoundSourceInterfacePtr & source = _identity->getSoundSource(); @@ -1063,7 +1056,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_STOP ); + _identity->setState( ESS_END ); return false; } @@ -1162,48 +1155,6 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool SoundService::isEmitterStop( const SoundIdentityInterfacePtr & _identity ) const - { - MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid stop identity" ); - - ESoundSourceState state = _identity->getState(); - - if( state != ESS_STOP ) - { - return false; - } - - return true; - } - ////////////////////////////////////////////////////////////////////////// - bool SoundService::isEmitterPlay( const SoundIdentityInterfacePtr & _identity ) const - { - MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid play identity" ); - - ESoundSourceState state = _identity->getState(); - - if( state != ESS_PLAY ) - { - return false; - } - - return true; - } - ////////////////////////////////////////////////////////////////////////// - bool SoundService::isEmitterPause( const SoundIdentityInterfacePtr & _identity ) const - { - MENGINE_ASSERTION_MEMORY_PANIC( _identity, "invalid pause identity" ); - - ESoundSourceState state = _identity->getState(); - - if( state != ESS_PAUSE ) - { - return false; - } - - return true; - } - ////////////////////////////////////////////////////////////////////////// bool SoundService::setLoop( const SoundIdentityInterfacePtr & _identity, bool _looped ) { _identity->setLoop( _looped ); @@ -1397,6 +1348,12 @@ namespace Mengine if( source->setPosition( _position ) == false ) { + LOGGER_ASSERTION( "invalid set position identity: %u" + , _identity->getUniqueIdentity() + ); + + _identity->setState( ESS_END ); + return false; } @@ -1408,7 +1365,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_STOP ); + _identity->setState( ESS_END ); return false; } diff --git a/src/Services/SoundService/SoundService.h b/src/Services/SoundService/SoundService.h index 6b4554b964..06fa91a500 100644 --- a/src/Services/SoundService/SoundService.h +++ b/src/Services/SoundService/SoundService.h @@ -91,11 +91,6 @@ namespace Mengine bool resumeEmitter( const SoundIdentityInterfacePtr & _identity ) override; bool stopEmitter( const SoundIdentityInterfacePtr & _identity ) override; - public: - bool isEmitterStop( const SoundIdentityInterfacePtr & _identity ) const override; - bool isEmitterPlay( const SoundIdentityInterfacePtr & _identity ) const override; - bool isEmitterPause( const SoundIdentityInterfacePtr & _identity ) const override; - public: bool setLoop( const SoundIdentityInterfacePtr & _identity, bool _looped ) override; bool getLoop( const SoundIdentityInterfacePtr & _identity ) const override; From 8ec4c44283d07d9f4ac7bc1234be0cd249d41aaa Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 17 Sep 2025 12:40:37 +0300 Subject: [PATCH 040/169] update android dependencies --- gradle/build.gradle | 4 ++-- gradle/gms.gradle | 4 ++-- gradle/plugins/AppLovin/Core/build.gradle | 14 +++++++------- gradle/plugins/Firebase/build.gradle | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gradle/build.gradle b/gradle/build.gradle index ed1830005e..37f3073ab2 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -34,11 +34,11 @@ buildscript { } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPLOVIN") == true && project.hasProperty("MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY") == true) { - classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:5.9.8' + classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:5.10.0' } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_DATADOG") == true) { - classpath 'com.datadoghq:dd-sdk-android-gradle-plugin:1.19.0' + classpath 'com.datadoghq:dd-sdk-android-gradle-plugin:1.20.0' } } } diff --git a/gradle/gms.gradle b/gradle/gms.gradle index 38db08a71b..a3ff25c7a4 100644 --- a/gradle/gms.gradle +++ b/gradle/gms.gradle @@ -1,6 +1,6 @@ dependencies { - implementation 'com.google.android.gms:play-services-base:18.7.2' - implementation 'com.google.android.gms:play-services-basement:18.7.1' + implementation 'com.google.android.gms:play-services-base:18.8.0' + implementation 'com.google.android.gms:play-services-basement:18.8.0' implementation 'com.google.android.gms:play-services-gcm:17.0.0' implementation 'com.google.android.gms:play-services-location:21.3.0' implementation 'com.google.android.gms:play-services-ads-identifier:18.2.0' diff --git a/gradle/plugins/AppLovin/Core/build.gradle b/gradle/plugins/AppLovin/Core/build.gradle index 43f50cbd48..3071b605ad 100644 --- a/gradle/plugins/AppLovin/Core/build.gradle +++ b/gradle/plugins/AppLovin/Core/build.gradle @@ -96,11 +96,11 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB == true) { - implementation 'com.applovin.mediation:google-adapter:24.5.0.0' + implementation 'com.applovin.mediation:google-adapter:24.6.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON == true) { - implementation 'com.applovin.mediation:amazon-tam-adapter:11.0.2.0' + implementation 'com.applovin.mediation:amazon-tam-adapter:11.0.4.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE == true) { @@ -120,7 +120,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER == true) { - implementation 'com.applovin.mediation:google-ad-manager-adapter:24.5.0.0' + implementation 'com.applovin.mediation:google-ad-manager-adapter:24.6.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX == true) { @@ -134,7 +134,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE == true) { - implementation 'com.applovin.mediation:ironsource-adapter:8.11.0.0.0' + implementation 'com.applovin.mediation:ironsource-adapter:8.11.1.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF == true) { @@ -142,7 +142,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE == true) { - implementation 'com.applovin.mediation:line-adapter:2025.7.18.0' + implementation 'com.applovin.mediation:line-adapter:2025.7.18.1' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO == true) { @@ -170,11 +170,11 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE == true) { - implementation 'com.applovin.mediation:bytedance-adapter:7.5.0.3.0' + implementation 'com.applovin.mediation:bytedance-adapter:7.6.0.2.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC == true) { - implementation 'com.applovin.mediation:pubmatic-adapter:4.8.0.0' + implementation 'com.applovin.mediation:pubmatic-adapter:4.9.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO == true) { diff --git a/gradle/plugins/Firebase/build.gradle b/gradle/plugins/Firebase/build.gradle index c79215f913..b8aed033df 100644 --- a/gradle/plugins/Firebase/build.gradle +++ b/gradle/plugins/Firebase/build.gradle @@ -7,5 +7,5 @@ android { dependencies { api enforcedPlatform('com.google.firebase:firebase-bom:34.2.0') - implementation 'com.google.firebase:firebase-common:22.0.0' + implementation 'com.google.firebase:firebase-common:22.0.1' } From ee2769a8b64fca1a8c6950e5177caa9325957f39 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 17 Sep 2025 14:58:25 +0300 Subject: [PATCH 041/169] fix python log up release log verbose to LM_WARNING --- src/Environment/Android/AndroidLogger.cpp | 2 +- .../PythonFramework/HelperScriptEmbedding.cpp | 18 ++++++++++++++++++ .../PythonFramework/SoundScriptEmbedding.cpp | 2 +- src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp | 4 ++++ src/Services/LoggerService/LoggerService.cpp | 2 +- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Environment/Android/AndroidLogger.cpp b/src/Environment/Android/AndroidLogger.cpp index 08b65dc517..f63e5fe661 100644 --- a/src/Environment/Android/AndroidLogger.cpp +++ b/src/Environment/Android/AndroidLogger.cpp @@ -158,4 +158,4 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( jenv, jclass_UtilLog ); } ////////////////////////////////////////////////////////////////////////// -} +} \ No newline at end of file diff --git a/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp index 6fe679d9e2..06152103f8 100644 --- a/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp @@ -1022,6 +1022,14 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void s_log( pybind::kernel_interface * _kernel, const StringView & _message, ELoggerLevel _level, uint32_t _color, uint32_t _flag ) { + ELoggerLevel verboseLevel = LOGGER_SERVICE() + ->getVerboseLevel(); + + if( verboseLevel < _level ) + { + return; + } + Path filename = {'\0'}; Char function[MENGINE_CODE_MAX_FUNCTION_NAME + 1] = {'\0'}; uint32_t lineno = 0; @@ -1047,12 +1055,22 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void s_logDebug( pybind::kernel_interface * _kernel, const StringView & _message ) { + MENGINE_UNUSED( _kernel ); + MENGINE_UNUSED( _message ); + +#if defined(MENGINE_LOGGER_INFO_ENABLE) s_log( _kernel, _message, LM_DEBUG, LCOLOR_BLUE, LFLAG_SHORT ); +#endif } ////////////////////////////////////////////////////////////////////////// void s_logInfo( pybind::kernel_interface * _kernel, const StringView & _message ) { + MENGINE_UNUSED( _kernel ); + MENGINE_UNUSED( _message ); + +#if defined(MENGINE_LOGGER_INFO_ENABLE) s_log( _kernel, _message, LM_INFO, LCOLOR_GREEN | LCOLOR_BLUE, LFLAG_SHORT ); +#endif } ////////////////////////////////////////////////////////////////////////// void s_logMessage( pybind::kernel_interface * _kernel, const StringView & _message ) diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index e2543b8070..366657cca9 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -764,7 +764,7 @@ namespace Mengine } }; ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr< SoundScriptMethod> SoundScriptMethodPtr; + typedef IntrusivePtr SoundScriptMethodPtr; ////////////////////////////////////////////////////////////////////////// } SoundScriptEmbedding::SoundScriptEmbedding() diff --git a/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp index 04320e47e5..7e09cb0d5f 100644 --- a/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp +++ b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp @@ -26,6 +26,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool ZipMemoryInputStream::open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ) { + MENGINE_UNUSED( _relationPath ); + MENGINE_UNUSED( _folderPath ); + MENGINE_UNUSED( _filePath ); + #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif diff --git a/src/Services/LoggerService/LoggerService.cpp b/src/Services/LoggerService/LoggerService.cpp index 95fe9e6be4..cb5dc57464 100644 --- a/src/Services/LoggerService/LoggerService.cpp +++ b/src/Services/LoggerService/LoggerService.cpp @@ -46,7 +46,7 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// LoggerService::LoggerService() - : m_verboseLevel( MENGINE_RELEASE_VALUE( LM_ERROR, LM_MESSAGE ) ) + : m_verboseLevel( MENGINE_RELEASE_VALUE( LM_WARNING, LM_MESSAGE ) ) , m_verboseFilter( 0xFFFFFFFF ) , m_silent( false ) , m_silentMessageRelease( false ) From b0b739900ba31927fa26cfdd15682774f19c8071 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 17 Sep 2025 15:26:50 +0300 Subject: [PATCH 042/169] improve android log --- .../src/main/java/org/Mengine/Base/MengineLog.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java index 08cc0d66e6..a9fb07b9f4 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java @@ -120,12 +120,20 @@ public static String logInfo(@NonNull MengineTag category, @NonNull String forma } public static String logMessage(@NonNull MengineTag category, @NonNull String format, Object ... args) { + if (BuildConfig.DEBUG == false) { + return ""; + } + String m = MengineLog.log(LM_MESSAGE, category, MengineLog.LFILTER_NONE, format, args); return m; } public static String logMessageProtected(@NonNull MengineTag category, @NonNull String format, Object ... args) { + if (BuildConfig.DEBUG == false) { + return ""; + } + String m = MengineLog.log(LM_MESSAGE, category, MengineLog.LFILTER_PROTECTED, format, args); return m; From c2ed4b053640801aceae877bb057be9cab28cd8a Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 17 Sep 2025 20:52:01 +0300 Subject: [PATCH 043/169] rework android MengineGoogleGameSocialPlugin fix SurfaceSound --- gradle/ci/res/values/strings.xml | 2 + gradle/ci/res/xml/backup_descriptor.xml | 4 + gradle/ci/src/main/AndroidManifest.xml | 44 +------ gradle/gradle.properties.ci | 7 +- .../java/org/Mengine/Base/MengineLog.java | 4 + .../MengineGoogleGameSocialPlugin.java | 120 +++++++++++++++--- src/Kernel/SurfaceSound.cpp | 59 +++++++-- src/Services/SoundService/SoundService.cpp | 2 +- 8 files changed, 169 insertions(+), 73 deletions(-) create mode 100644 gradle/ci/res/xml/backup_descriptor.xml diff --git a/gradle/ci/res/values/strings.xml b/gradle/ci/res/values/strings.xml index bc2ca582ef..a46b41d94f 100644 --- a/gradle/ci/res/values/strings.xml +++ b/gradle/ci/res/values/strings.xml @@ -1,4 +1,6 @@ + Continuous Integration + https://en.wikipedia.org/wiki/Privacy_policy https://en.wikipedia.org/wiki/Terms_of_service diff --git a/gradle/ci/res/xml/backup_descriptor.xml b/gradle/ci/res/xml/backup_descriptor.xml new file mode 100644 index 0000000000..3983638021 --- /dev/null +++ b/gradle/ci/res/xml/backup_descriptor.xml @@ -0,0 +1,4 @@ + + + + diff --git a/gradle/ci/src/main/AndroidManifest.xml b/gradle/ci/src/main/AndroidManifest.xml index 9e9a83c7f4..1ce22a1c18 100644 --- a/gradle/ci/src/main/AndroidManifest.xml +++ b/gradle/ci/src/main/AndroidManifest.xml @@ -1,44 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/gradle/gradle.properties.ci b/gradle/gradle.properties.ci index 6a5f6e5cd2..04bd2939cf 100644 --- a/gradle/gradle.properties.ci +++ b/gradle/gradle.properties.ci @@ -11,9 +11,8 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Thu Dec 22 15:16:00 CET 2022 +ANDROID_APP_MAIN_PROJECT=ci + android.useAndroidX=true android.useFullClasspathForDexingTransform=true -android.enableJetifier=false -org.gradle.daemon=false - -ANDROID_APP_MAIN_PROJECT=ci \ No newline at end of file +android.enableJetifier=true \ No newline at end of file diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java index a9fb07b9f4..e9e3ec3e28 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java @@ -180,6 +180,10 @@ public static String logFatal(@NonNull MengineTag category, @NonNull String form } public static String logSingleMessage(@NonNull MengineTag category, @NonNull String format, Object ... args) { + if (BuildConfig.DEBUG == false) { + return ""; + } + String m = MengineLog.buildTotalMsg(format, args); synchronized (MengineLog.m_singlesLock) { diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java index a9222a4b1c..71a9ecb133 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java @@ -19,6 +19,8 @@ import com.google.android.gms.games.LeaderboardsClient; import com.google.android.gms.games.PlayGames; import com.google.android.gms.games.PlayGamesSdk; +import com.google.android.gms.games.achievement.Achievement; +import com.google.android.gms.games.achievement.AchievementBuffer; import org.Mengine.Base.MengineActivity; import org.Mengine.Base.MengineApplication; @@ -30,6 +32,9 @@ import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Plugin.GoogleService.MengineGoogleServicePlugin; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import java.util.Map; @@ -96,8 +101,6 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat m_leaderboardLauncher = leaderboardLauncher; - - ActivityResultLauncher gamesResolutionLauncher = activity.registerForActivityResultIntentSender(result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent data = result.getData(); @@ -200,6 +203,8 @@ private void signInSilently() { this.logInfo("google game social isAuthenticated success"); m_isAuthenticated = true; + + this.activateSemaphore("GoogleGameSocialAuthenticated"); }); } @@ -207,8 +212,6 @@ public void signInIntent() { if (MengineNetwork.isNetworkAvailable() == false) { this.logInfo("signInIntent network not available"); - this.nativeCall("onGoogleGameSocialSignInIntentError", new RuntimeException("network not available")); - return; } @@ -225,8 +228,6 @@ public void signInIntent() { if (pendingIntent == null) { this.logInfo("signInIntent ResolvableApiException resolution null"); - this.nativeCall("onGoogleGameSocialSignInIntentError", e); - return; } @@ -240,13 +241,9 @@ public void signInIntent() { m_gamesResolutionLauncher.launch(request); } else { this.logError("[ERROR] signInIntent gamesResolutionLauncher not available"); - - this.nativeCall("onGoogleGameSocialSignInIntentError", e); } } catch (Exception ex) { this.logException(ex, Map.of()); - - this.nativeCall("onGoogleGameSocialSignInIntentError", ex); } return; @@ -258,8 +255,6 @@ public void signInIntent() { this.logError("[ERROR] signInIntent failed: null exception"); } - this.nativeCall("onGoogleGameSocialSignInIntentError", e); - return; } @@ -270,8 +265,6 @@ public void signInIntent() { m_isAuthenticated = false; - this.nativeCall("onGoogleGameSocialSignInIntentFailed"); - return; } @@ -279,10 +272,99 @@ public void signInIntent() { m_isAuthenticated = true; - this.nativeCall("onGoogleGameSocialSignInIntentSuccess"); + this.activateSemaphore("GoogleGameSocialAuthenticated"); }); } + public void requestAchievementsState() { + if (MengineNetwork.isNetworkAvailable() == false) { + this.logInfo("requestAchievementsState network not available"); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateError", new RuntimeException("network not available")); + + return; + } + + if (m_isAuthenticated == false) { + this.logInfo("requestAchievementsState not authenticated"); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateError", new RuntimeException("not authenticated")); + + return; + } + + m_achievementsClient.load(true) + .addOnSuccessListener(achievementsData -> { + AchievementBuffer achievementBuffer = achievementsData.get(); + + if (achievementBuffer == null) { + this.logError("[ERROR] requestAchievementsState achievementBuffer null"); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateError", new RuntimeException("achievementBuffer null")); + + return; + } + + try { + int count = achievementBuffer.getCount(); + + JSONArray achievementsJSON = new JSONArray(); + + for (int index = 0; index < count; ++index) { + Achievement achievement = achievementBuffer.get(index).freeze(); + + JSONObject achievementJSON = new JSONObject(); + + achievementJSON.put("achievementId", achievement.getAchievementId()); + achievementJSON.put("name", achievement.getName()); + achievementJSON.put("description", achievement.getDescription()); + achievementJSON.put("state", achievement.getState()); + achievementJSON.put("type", achievement.getType()); + achievementJSON.put("xpValue", achievement.getXpValue()); + achievementJSON.put("lastUpdatedTimestamp", achievement.getLastUpdatedTimestamp()); + + if (achievement.getType() == Achievement.TYPE_INCREMENTAL) { + achievementJSON.put("currentSteps", achievement.getCurrentSteps()); + achievementJSON.put("totalSteps", achievement.getTotalSteps()); + } else { + achievementJSON.put("currentSteps", 0); + achievementJSON.put("totalSteps", 0); + } + + achievementsJSON.put(achievementJSON); + } + + this.logInfo("requestAchievementsState success %s", achievementsJSON); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateSuccessful", achievementsJSON); + } catch (JSONException exception) { + this.logException(exception, Map.of()); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateError", exception); + + return; + } catch (RuntimeException exception) { + this.logException(exception, Map.of()); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateError", exception); + + return; + } finally { + if (achievementBuffer != null) { + achievementBuffer.release(); + } + } + }).addOnFailureListener(e -> { + this.logException(e, Map.of()); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateError", e); + }).addOnCanceledListener(() -> { + this.logInfo("requestAchievementsState canceled"); + + this.nativeCall("onGoogleGameSocialRequestAchievementsStateCanceled"); + }); + } + public void showAchievements() { if (MengineNetwork.isNetworkAvailable() == false) { this.logInfo("showAchievements network not available"); @@ -292,6 +374,14 @@ public void showAchievements() { return; } + if (m_isAuthenticated == false) { + this.logInfo("showAchievements not authenticated"); + + this.nativeCall("onGoogleGameSocialShowAchievementError", new RuntimeException("not authenticated")); + + return; + } + this.logInfo("showAchievements"); m_achievementsClient.getAchievementsIntent() diff --git a/src/Kernel/SurfaceSound.cpp b/src/Kernel/SurfaceSound.cpp index a704069440..0adfc6241e 100644 --- a/src/Kernel/SurfaceSound.cpp +++ b/src/Kernel/SurfaceSound.cpp @@ -200,6 +200,9 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_play( UniqueId _enumerator, float _time ) { + MENGINE_UNUSED( _enumerator ); + MENGINE_UNUSED( _time ); + if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -227,14 +230,14 @@ namespace Mengine return false; } - EVENTABLE_METHOD( EVENT_ANIMATION_PLAY ) - ->onAnimationPlay( _enumerator, _time ); - return true; } ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_restart( UniqueId _enumerator, float _time ) { + MENGINE_UNUSED( _enumerator ); + MENGINE_UNUSED( _time ); + if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -244,6 +247,12 @@ namespace Mengine return false; } + LOGGER_INFO( "sound", "[surface] sound restart '%s' resource '%s' file '%s'" + , this->getName().c_str() + , m_resourceSound->getName().c_str() + , Helper::getResourceFilePath( m_resourceSound ).c_str() + ); + EVENTABLE_METHOD( EVENT_ANIMATION_RESTART ) ->onAnimationRestart( _enumerator, _time ); @@ -252,6 +261,8 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void SurfaceSound::_pause( UniqueId _enumerator ) { + MENGINE_UNUSED( _enumerator ); + if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -261,15 +272,21 @@ namespace Mengine return; } + LOGGER_INFO( "sound", "[surface] sound pause '%s' resource '%s' file '%s'" + , this->getName().c_str() + , m_resourceSound->getName().c_str() + , Helper::getResourceFilePath( m_resourceSound ).c_str() + ); + SOUND_SERVICE() ->pauseEmitter( m_soundIdentity ); - - EVENTABLE_METHOD( EVENT_ANIMATION_PAUSE ) - ->onAnimationPause( _enumerator ); } ////////////////////////////////////////////////////////////////////////// void SurfaceSound::_resume( UniqueId _enumerator, float _time ) { + MENGINE_UNUSED( _enumerator ); + MENGINE_UNUSED( _time ); + if( this->isCompile() == false ) { LOGGER_ERROR( "surface sound '%s' not compile" @@ -279,11 +296,14 @@ namespace Mengine return; } + LOGGER_INFO( "sound", "[surface] sound resume '%s' resource '%s' file '%s'" + , this->getName().c_str() + , m_resourceSound->getName().c_str() + , Helper::getResourceFilePath( m_resourceSound ).c_str() + ); + SOUND_SERVICE() ->resumeEmitter( m_soundIdentity ); - - EVENTABLE_METHOD( EVENT_ANIMATION_RESUME ) - ->onAnimationResume( _enumerator, _time ); } ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_stop( UniqueId _enumerator ) @@ -297,6 +317,12 @@ namespace Mengine return false; } + LOGGER_INFO( "sound", "[surface] sound stop '%s' resource '%s' file '%s'" + , this->getName().c_str() + , m_resourceSound->getName().c_str() + , Helper::getResourceFilePath( m_resourceSound ).c_str() + ); + if( m_soundIdentity != nullptr ) { SOUND_SERVICE() @@ -317,6 +343,12 @@ namespace Mengine // ->stopEmitter( m_soundEmitter ); //} + LOGGER_INFO( "sound", "[surface] sound end '%s' resource '%s' file '%s'" + , this->getName().c_str() + , m_resourceSound->getName().c_str() + , Helper::getResourceFilePath( m_resourceSound ).c_str() + ); + EVENTABLE_METHOD( EVENT_ANIMATION_END ) ->onAnimationEnd( _enumerator ); } @@ -450,7 +482,11 @@ namespace Mengine { MENGINE_UNUSED( _identity ); - // Empty + uint32_t id = this->getPlayId(); + float playTime = this->getPlayTime(); + + EVENTABLE_METHOD( EVENT_ANIMATION_PLAY ) + ->onAnimationPlay( id, playTime ); } ////////////////////////////////////////////////////////////////////////// void SurfaceSound::onSoundPause( const SoundIdentityInterfacePtr & _identity ) @@ -468,9 +504,10 @@ namespace Mengine MENGINE_UNUSED( _identity ); uint32_t id = this->getPlayId(); + float playTime = this->getPlayTime(); EVENTABLE_METHOD( EVENT_ANIMATION_RESUME ) - ->onAnimationResume( id, 0.f ); + ->onAnimationResume( id, playTime ); } ////////////////////////////////////////////////////////////////////////// void SurfaceSound::onSoundStop( const SoundIdentityInterfacePtr & _identity ) diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 1a6e9df3d8..e6727c6898 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -880,7 +880,7 @@ namespace Mengine if( this->playSoundBufferUpdate_( _identity ) == false ) { - LOGGER_MESSAGE( "invalid play sound buffer update" ); + LOGGER_ASSERTION( "invalid play sound buffer update" ); _identity->setState( ESS_END ); From 38fad8652abedc7c167bb12053a23fb9ee3d819f Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 18 Sep 2025 01:07:50 +0300 Subject: [PATCH 044/169] update android ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS --- gradle/androidx.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/androidx.gradle b/gradle/androidx.gradle index c8971359ca..d5c6c869fa 100644 --- a/gradle/androidx.gradle +++ b/gradle/androidx.gradle @@ -5,7 +5,7 @@ def ANDROID_APP_IMPLEMENTATION_ANDROIDX_PREFERENCE = Utils.getStringProperty("AN def ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT", "1.7.1") def ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW", "1.4.0") def ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS", "1.0.0") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS", "2.9.3") +def ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS", "2.9.4") dependencies { implementation "androidx.core:core:$ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE" From 59e65a25c0b6e76fb1af2c45179d563c08e8ba0c Mon Sep 17 00:00:00 2001 From: Yuriy Levchenko Date: Thu, 18 Sep 2025 10:50:25 +0300 Subject: [PATCH 045/169] Cache Google Play achievements state (#130) --- .../MengineGoogleGameSocialAchievement.java | 124 ++++++++++++++++++ .../MengineGoogleGameSocialPlugin.java | 113 +++++++++++++--- 2 files changed, 217 insertions(+), 20 deletions(-) create mode 100644 gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java new file mode 100644 index 0000000000..a609ef5a26 --- /dev/null +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java @@ -0,0 +1,124 @@ +package org.Mengine.Plugin.GoogleGameSocial; + +import androidx.annotation.NonNull; + +import com.google.android.gms.games.achievement.Achievement; + +import org.json.JSONException; +import org.json.JSONObject; + +public final class MengineGoogleGameSocialAchievement { + private final String m_id; + private String m_name; + private String m_description; + private int m_state; + private int m_type; + private long m_xpValue; + private long m_lastUpdatedTimestamp; + private int m_currentSteps; + private int m_totalSteps; + + public MengineGoogleGameSocialAchievement(@NonNull Achievement achievement) { + m_id = achievement.getAchievementId(); + + this.updateFromAchievement(achievement); + } + + private MengineGoogleGameSocialAchievement(@NonNull String achievementId) { + m_id = achievementId; + + m_name = ""; + m_description = ""; + m_state = Achievement.STATE_HIDDEN; + m_type = Achievement.TYPE_STANDARD; + m_xpValue = 0L; + m_lastUpdatedTimestamp = 0L; + m_currentSteps = 0; + m_totalSteps = 0; + } + + public static MengineGoogleGameSocialAchievement placeholder(@NonNull String achievementId) { + return new MengineGoogleGameSocialAchievement(achievementId); + } + + public void updateFromAchievement(@NonNull Achievement achievement) { + m_name = achievement.getName(); + m_description = achievement.getDescription(); + m_state = achievement.getState(); + m_type = achievement.getType(); + m_xpValue = achievement.getXpValue(); + m_lastUpdatedTimestamp = achievement.getLastUpdatedTimestamp(); + + if (achievement.getType() == Achievement.TYPE_INCREMENTAL) { + m_currentSteps = achievement.getCurrentSteps(); + m_totalSteps = achievement.getTotalSteps(); + } else { + m_currentSteps = 0; + m_totalSteps = 0; + } + } + + public boolean isUnlocked() { + return m_state == Achievement.STATE_UNLOCKED; + } + + public boolean isIncremental() { + return m_type == Achievement.TYPE_INCREMENTAL; + } + + public String getId() { + return m_id; + } + + public void markUnlocked(long timestamp) { + m_state = Achievement.STATE_UNLOCKED; + m_lastUpdatedTimestamp = timestamp; + + if (this.isIncremental()) { + m_currentSteps = m_totalSteps; + } + } + + public void markRevealed(long timestamp) { + if (m_state == Achievement.STATE_HIDDEN) { + m_state = Achievement.STATE_REVEALED; + } + + m_lastUpdatedTimestamp = timestamp; + } + + public void incrementSteps(int numSteps, long timestamp) { + if (this.isIncremental() == false) { + return; + } + + if (numSteps <= 0) { + return; + } + + m_currentSteps = Math.min(m_totalSteps, m_currentSteps + numSteps); + m_lastUpdatedTimestamp = timestamp; + + if (m_currentSteps >= m_totalSteps && m_totalSteps > 0) { + m_state = Achievement.STATE_UNLOCKED; + } + } + + public JSONObject toJSONObject() throws JSONException { + JSONObject achievementJSON = new JSONObject(); + + achievementJSON.put("achievementId", m_id); + achievementJSON.put("name", m_name); + achievementJSON.put("description", m_description); + achievementJSON.put("state", m_state); + achievementJSON.put("type", m_type); + achievementJSON.put("xpValue", m_xpValue); + achievementJSON.put("lastUpdatedTimestamp", m_lastUpdatedTimestamp); + achievementJSON.put("currentSteps", m_currentSteps); + achievementJSON.put("totalSteps", m_totalSteps); + achievementJSON.put("isUnlocked", this.isUnlocked()); + achievementJSON.put("isIncremental", this.isIncremental()); + + return achievementJSON; + } +} diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java index 71a9ecb133..a41db3c302 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java @@ -36,6 +36,7 @@ import org.json.JSONException; import org.json.JSONObject; +import java.util.HashMap; import java.util.Map; public class MengineGoogleGameSocialPlugin extends MengineService implements MengineListenerApplication, MengineListenerActivity { @@ -52,6 +53,8 @@ public class MengineGoogleGameSocialPlugin extends MengineService implements Men private EventsClient m_eventsClient; private boolean m_isAuthenticated = false; + private final Map m_cachedAchievements = new HashMap<>(); + private final Object m_cachedAchievementsLock = new Object(); @Override public boolean onAvailable(@NonNull MengineApplication application) { @@ -149,6 +152,10 @@ public void onDestroy(@NonNull MengineActivity activity) { m_achievementsClient = null; m_leaderboardsClient = null; m_eventsClient = null; + + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } } @Override @@ -187,6 +194,10 @@ private void signInSilently() { m_isAuthenticated = false; + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } + return; } @@ -197,6 +208,10 @@ private void signInSilently() { m_isAuthenticated = false; + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } + return; } @@ -265,6 +280,10 @@ public void signInIntent() { m_isAuthenticated = false; + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } + return; } @@ -306,32 +325,24 @@ public void requestAchievementsState() { } try { - int count = achievementBuffer.getCount(); - JSONArray achievementsJSON = new JSONArray(); - for (int index = 0; index < count; ++index) { - Achievement achievement = achievementBuffer.get(index).freeze(); + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); - JSONObject achievementJSON = new JSONObject(); + int count = achievementBuffer.getCount(); - achievementJSON.put("achievementId", achievement.getAchievementId()); - achievementJSON.put("name", achievement.getName()); - achievementJSON.put("description", achievement.getDescription()); - achievementJSON.put("state", achievement.getState()); - achievementJSON.put("type", achievement.getType()); - achievementJSON.put("xpValue", achievement.getXpValue()); - achievementJSON.put("lastUpdatedTimestamp", achievement.getLastUpdatedTimestamp()); + for (int index = 0; index < count; ++index) { + Achievement achievement = achievementBuffer.get(index).freeze(); - if (achievement.getType() == Achievement.TYPE_INCREMENTAL) { - achievementJSON.put("currentSteps", achievement.getCurrentSteps()); - achievementJSON.put("totalSteps", achievement.getTotalSteps()); - } else { - achievementJSON.put("currentSteps", 0); - achievementJSON.put("totalSteps", 0); - } + MengineGoogleGameSocialAchievement achievementInfo = new MengineGoogleGameSocialAchievement(achievement); + + m_cachedAchievements.put(achievementInfo.getId(), achievementInfo); - achievementsJSON.put(achievementJSON); + JSONObject achievementJSON = achievementInfo.toJSONObject(); + + achievementsJSON.put(achievementJSON); + } } this.logInfo("requestAchievementsState success %s", achievementsJSON); @@ -421,6 +432,22 @@ public void unlockAchievement(String achievementId) { return; } + boolean alreadyUnlocked; + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement cachedAchievement = m_cachedAchievements.get(achievementId); + + alreadyUnlocked = cachedAchievement != null && cachedAchievement.isUnlocked(); + } + + if (alreadyUnlocked) { + this.logInfo("unlockAchievement achievementId: %s already unlocked", achievementId); + + this.nativeCall("onGoogleGameSocialUnlockAchievementSuccess", achievementId); + + return; + } + this.logInfo("unlockAchievement achievementId: %s" , achievementId ); @@ -431,6 +458,20 @@ public void unlockAchievement(String achievementId) { , achievementId ); + long timestamp = System.currentTimeMillis(); + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement achievementInfo = m_cachedAchievements.get(achievementId); + + if (achievementInfo == null) { + achievementInfo = MengineGoogleGameSocialAchievement.placeholder(achievementId); + + m_cachedAchievements.put(achievementId, achievementInfo); + } + + achievementInfo.markUnlocked(timestamp); + } + MengineFragmentGame.INSTANCE.unlockAchievement(achievementId); this.nativeCall("onGoogleGameSocialUnlockAchievementSuccess", achievementId); @@ -484,6 +525,24 @@ public void incrementAchievement(String achievementId, int numSteps) { , numSteps ); + long timestamp = System.currentTimeMillis(); + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement achievementInfo = m_cachedAchievements.get(achievementId); + + if (achievementInfo == null) { + achievementInfo = MengineGoogleGameSocialAchievement.placeholder(achievementId); + + m_cachedAchievements.put(achievementId, achievementInfo); + } + + achievementInfo.incrementSteps(numSteps, timestamp); + + if (Boolean.TRUE.equals(aBoolean)) { + achievementInfo.markUnlocked(timestamp); + } + } + MengineFragmentGame.INSTANCE.incrementAchievement(achievementId, numSteps); this.nativeCall("onGoogleGameSocialIncrementAchievementSuccess", achievementId, numSteps); @@ -535,6 +594,20 @@ public void revealAchievement(String achievementId) { , achievementId ); + long timestamp = System.currentTimeMillis(); + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement achievementInfo = m_cachedAchievements.get(achievementId); + + if (achievementInfo == null) { + achievementInfo = MengineGoogleGameSocialAchievement.placeholder(achievementId); + + m_cachedAchievements.put(achievementId, achievementInfo); + } + + achievementInfo.markRevealed(timestamp); + } + MengineFragmentGame.INSTANCE.revealAchievement(achievementId); this.nativeCall("onGoogleGameSocialRevealAchievementSuccess", achievementId); From 4a50242f88e7d91d15adfa01205bc1fb53cb4479 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 18 Sep 2025 11:40:11 +0300 Subject: [PATCH 046/169] improve AccountService improve android MengineGoogleGameSocialAchievement --- .../MengineGoogleGameSocialAchievement.java | 1 - .../MengineGoogleGameSocialPlugin.java | 109 ++++++++++-------- src/Services/AccountService/Account.cpp | 1 - .../AccountService/AccountService.cpp | 8 ++ 4 files changed, 68 insertions(+), 51 deletions(-) diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java index a609ef5a26..765f2deca2 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java @@ -107,7 +107,6 @@ public void incrementSteps(int numSteps, long timestamp) { public JSONObject toJSONObject() throws JSONException { JSONObject achievementJSON = new JSONObject(); - achievementJSON.put("achievementId", m_id); achievementJSON.put("name", m_name); achievementJSON.put("description", m_description); achievementJSON.put("state", m_state); diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java index a41db3c302..50dcc1668b 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java @@ -53,7 +53,7 @@ public class MengineGoogleGameSocialPlugin extends MengineService implements Men private EventsClient m_eventsClient; private boolean m_isAuthenticated = false; - private final Map m_cachedAchievements = new HashMap<>(); + private Map m_cachedAchievements = new HashMap<>(); private final Object m_cachedAchievementsLock = new Object(); @Override @@ -325,24 +325,33 @@ public void requestAchievementsState() { } try { - JSONArray achievementsJSON = new JSONArray(); + Map cachedAchievements = new HashMap<>(); - synchronized (m_cachedAchievementsLock) { - m_cachedAchievements.clear(); + int count = achievementBuffer.getCount(); + + for (int index = 0; index < count; ++index) { + Achievement achievement = achievementBuffer.get(index).freeze(); - int count = achievementBuffer.getCount(); + MengineGoogleGameSocialAchievement achievementInfo = new MengineGoogleGameSocialAchievement(achievement); - for (int index = 0; index < count; ++index) { - Achievement achievement = achievementBuffer.get(index).freeze(); + String id = achievementInfo.getId(); - MengineGoogleGameSocialAchievement achievementInfo = new MengineGoogleGameSocialAchievement(achievement); + cachedAchievements.put(id, achievementInfo); + } - m_cachedAchievements.put(achievementInfo.getId(), achievementInfo); + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements = cachedAchievements; + } - JSONObject achievementJSON = achievementInfo.toJSONObject(); + JSONObject achievementsJSON = new JSONObject(); - achievementsJSON.put(achievementJSON); - } + for (Map.Entry entry : cachedAchievements.entrySet()) { + String id = entry.getKey(); + MengineGoogleGameSocialAchievement achievementInfo = entry.getValue(); + + JSONObject achievementJSON = achievementInfo.toJSONObject(); + + achievementsJSON.put(id, achievementJSON); } this.logInfo("requestAchievementsState success %s", achievementsJSON); @@ -411,6 +420,34 @@ public void showAchievements() { }); } + public boolean hasAchievementUnlock(String achievementId) { + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement cachedAchievement = m_cachedAchievements.get(achievementId); + + if (cachedAchievement == null) { + return false; + } + + boolean unlocked = cachedAchievement.isUnlocked(); + + return unlocked; + } + } + + private MengineGoogleGameSocialAchievement getCachedAchievement(String achievementId) { + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement cachedAchievement = m_cachedAchievements.get(achievementId); + + if (cachedAchievement == null) { + cachedAchievement = MengineGoogleGameSocialAchievement.placeholder(achievementId); + + m_cachedAchievements.put(achievementId, cachedAchievement); + } + + return cachedAchievement; + } + } + public void unlockAchievement(String achievementId) { if (MengineNetwork.isNetworkAvailable() == false) { this.logInfo("unlockAchievement achievementId: %s network not available" @@ -432,18 +469,10 @@ public void unlockAchievement(String achievementId) { return; } - boolean alreadyUnlocked; - - synchronized (m_cachedAchievementsLock) { - MengineGoogleGameSocialAchievement cachedAchievement = m_cachedAchievements.get(achievementId); - - alreadyUnlocked = cachedAchievement != null && cachedAchievement.isUnlocked(); - } - - if (alreadyUnlocked) { + if (this.hasAchievementUnlock(achievementId) == true) { this.logInfo("unlockAchievement achievementId: %s already unlocked", achievementId); - this.nativeCall("onGoogleGameSocialUnlockAchievementSuccess", achievementId); + this.nativeCall("onGoogleGameSocialUnlockAchievementError", achievementId, new RuntimeException("already unlocked")); return; } @@ -461,15 +490,9 @@ public void unlockAchievement(String achievementId) { long timestamp = System.currentTimeMillis(); synchronized (m_cachedAchievementsLock) { - MengineGoogleGameSocialAchievement achievementInfo = m_cachedAchievements.get(achievementId); - - if (achievementInfo == null) { - achievementInfo = MengineGoogleGameSocialAchievement.placeholder(achievementId); + MengineGoogleGameSocialAchievement cachedAchievement = this.getCachedAchievement(achievementId); - m_cachedAchievements.put(achievementId, achievementInfo); - } - - achievementInfo.markUnlocked(timestamp); + cachedAchievement.markUnlocked(timestamp); } MengineFragmentGame.INSTANCE.unlockAchievement(achievementId); @@ -519,7 +542,7 @@ public void incrementAchievement(String achievementId, int numSteps) { ); m_achievementsClient.incrementImmediate(achievementId, numSteps) - .addOnSuccessListener(aBoolean -> { + .addOnSuccessListener(unlock -> { this.logInfo("incrementAchievement complete achievementId: %s numSteps: %d" , achievementId , numSteps @@ -528,18 +551,12 @@ public void incrementAchievement(String achievementId, int numSteps) { long timestamp = System.currentTimeMillis(); synchronized (m_cachedAchievementsLock) { - MengineGoogleGameSocialAchievement achievementInfo = m_cachedAchievements.get(achievementId); - - if (achievementInfo == null) { - achievementInfo = MengineGoogleGameSocialAchievement.placeholder(achievementId); + MengineGoogleGameSocialAchievement cachedAchievement = this.getCachedAchievement(achievementId); - m_cachedAchievements.put(achievementId, achievementInfo); - } - - achievementInfo.incrementSteps(numSteps, timestamp); + cachedAchievement.incrementSteps(numSteps, timestamp); - if (Boolean.TRUE.equals(aBoolean)) { - achievementInfo.markUnlocked(timestamp); + if (Boolean.TRUE.equals(unlock)) { + cachedAchievement.markUnlocked(timestamp); } } @@ -597,15 +614,9 @@ public void revealAchievement(String achievementId) { long timestamp = System.currentTimeMillis(); synchronized (m_cachedAchievementsLock) { - MengineGoogleGameSocialAchievement achievementInfo = m_cachedAchievements.get(achievementId); - - if (achievementInfo == null) { - achievementInfo = MengineGoogleGameSocialAchievement.placeholder(achievementId); - - m_cachedAchievements.put(achievementId, achievementInfo); - } + MengineGoogleGameSocialAchievement cachedAchievement = this.getCachedAchievement(achievementId); - achievementInfo.markRevealed(timestamp); + cachedAchievement.markRevealed(timestamp); } MengineFragmentGame.INSTANCE.revealAchievement(achievementId); diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index 8a82c5ca91..bce739cbbf 100644 --- a/src/Services/AccountService/Account.cpp +++ b/src/Services/AccountService/Account.cpp @@ -317,7 +317,6 @@ namespace Mengine return config; } - LOGGER_ERROR( "account '%s' settings not found any config '%s' or '%s'" , m_accountId.c_str() , Helper::getContentFullPath( m_settingsJSONContent ).c_str() diff --git a/src/Services/AccountService/AccountService.cpp b/src/Services/AccountService/AccountService.cpp index d62ecee8fb..4cef310f5f 100644 --- a/src/Services/AccountService/AccountService.cpp +++ b/src/Services/AccountService/AccountService.cpp @@ -101,6 +101,8 @@ namespace Mengine m_currentAccountId = lastAccount; + m_invalidateAccounts = true; + this->saveAccounts(); } ////////////////////////////////////////////////////////////////////////// @@ -186,6 +188,8 @@ namespace Mengine m_accountProvider->onSelectAccount( _accountId ); } + m_invalidateAccounts = true; + return newAccount; } ////////////////////////////////////////////////////////////////////////// @@ -216,6 +220,8 @@ namespace Mengine newAccount->apply(); + m_invalidateAccounts = true; + return newAccount; } ////////////////////////////////////////////////////////////////////////// @@ -360,6 +366,8 @@ namespace Mengine m_invalidateAccounts = true; + this->saveAccounts(); + return true; } ////////////////////////////////////////////////////////////////////////// From f880820971825c8a3f9516bf3f1deb5e8bea30ee Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 18 Sep 2025 12:31:26 +0300 Subject: [PATCH 047/169] update ios AppLovin update ios Datadog --- .../AppleAppLovinApplicationDelegate.mm | 40 ++++++++++++++++--- .../AppleAppLovinPlugin/CMakeLists.txt | 6 +-- .../AppleDatadogApplicationDelegate.h | 2 +- .../AppleDatadogApplicationDelegate.mm | 3 ++ src/Plugins/AppleDatadogPlugin/CMakeLists.txt | 3 +- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm index 1016b8e30a..317c2f7ade 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm @@ -16,6 +16,10 @@ #include "Configuration/Configurations.h" +#if defined(MENGINE_DEBUG) +# import +#endif + #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_MEDIATION_META) # import #endif @@ -215,9 +219,39 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [advertisement setProvider:self]; + NSMutableArray * adUnitIdentifiers = [NSMutableArray array]; + +#if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_BANNER) + NSString * MengineAppleAppLovinPlugin_BannerAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdUnitId" withDefault:nil]; + + if (MengineAppleAppLovinPlugin_BannerAdUnitId != nil) { + [adUnitIdentifiers addObject:MengineAppleAppLovinPlugin_BannerAdUnitId]; + } +#endif + +#if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_INTERSTITIAL) + NSString * MengineAppleAppLovinPlugin_InterstitialAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"InterstitialAdUnitId" withDefault:nil]; + + if (MengineAppleAppLovinPlugin_InterstitialAdUnitId != nil) { + [adUnitIdentifiers addObject:MengineAppleAppLovinPlugin_InterstitialAdUnitId]; + } +#endif + +#if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_REWARDED) + NSString * MengineAppleAppLovinPlugin_RewardedAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"RewardedAdUnitId" withDefault:nil]; + + if (MengineAppleAppLovinPlugin_RewardedAdUnitId != nil) { + [adUnitIdentifiers addObject:MengineAppleAppLovinPlugin_RewardedAdUnitId]; + } +#endif + ALSdkInitializationConfiguration * initializationConfiguration = [ALSdkInitializationConfiguration configurationWithSdkKey:MengineAppleAppLovinPlugin_SdkKey builderBlock:^(ALSdkInitializationConfigurationBuilder * _Nonnull builder) { builder.pluginVersion = [@"Mengine-v" stringByAppendingString:@MENGINE_ENGINE_VERSION_STRING]; builder.mediationProvider = ALMediationProviderMAX; + builder.adUnitIdentifiers = adUnitIdentifiers; +#if defined(MENGINE_DEBUG) + builder.testDeviceAdvertisingIdentifiers = @[[ASIdentifierManager sharedManager].advertisingIdentifier.UUIDString]; +#endif }]; [[ALSdk shared] initializeWithConfiguration:initializationConfiguration completionHandler:^(ALSdkConfiguration *configuration) { @@ -255,8 +289,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #endif #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_BANNER) - NSString * MengineAppleAppLovinPlugin_BannerAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdUnitId" withDefault:nil]; - if (MengineAppleAppLovinPlugin_BannerAdUnitId != nil) { NSString * MengineAppleAppLovinPlugin_BannerPlacement = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerPlacement" withDefault:@"banner"]; @@ -269,8 +301,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #endif #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_INTERSTITIAL) - NSString * MengineAppleAppLovinPlugin_InterstitialAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"InterstitialAdUnitId" withDefault:nil]; - if (MengineAppleAppLovinPlugin_InterstitialAdUnitId != nil) { AppleAppLovinInterstitialDelegate * interstitialAd = [[AppleAppLovinInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_InterstitialAdUnitId]; @@ -279,8 +309,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #endif #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_REWARDED) - NSString * MengineAppleAppLovinPlugin_RewardedAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"RewardedAdUnitId" withDefault:nil]; - if (MengineAppleAppLovinPlugin_RewardedAdUnitId != nil) { AppleAppLovinRewardedDelegate * rewardedAd = [[AppleAppLovinRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_RewardedAdUnitId]; diff --git a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt index f9dc5538f2..0db9931cd9 100644 --- a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt @@ -90,7 +90,7 @@ if(MENGINE_PLUGIN_APPLE_APPLOVIN_CONSENT_FLOW) endif() ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("AppLovinSDK" "NO-GIT" "13.3.1") +ADD_MENGINE_COCOAPOD("AppLovinSDK" "NO-GIT" "13.4.0") macro(ADD_APPLOVIN_MEDIATION MEDIATION POD VERSION) if(MENGINE_PLUGIN_APPLE_APPLOVIN_MEDIATION_${MEDIATION}) @@ -98,14 +98,14 @@ macro(ADD_APPLOVIN_MEDIATION MEDIATION POD VERSION) endif() endmacro() -ADD_APPLOVIN_MEDIATION(ADMOB "AppLovinMediationGoogleAdapter" "12.9.0.0") +ADD_APPLOVIN_MEDIATION(ADMOB "AppLovinMediationGoogleAdapter" "12.11.0.0") ADD_APPLOVIN_MEDIATION(AMAZON "AppLovinMediationAmazonAdMarketplaceAdapter" "5.2.0.0") ADD_APPLOVIN_MEDIATION(BIDMACHINE "AppLovinMediationBidMachineAdapter" "3.3.0.0.0") ADD_APPLOVIN_MEDIATION(BIGO "AppLovinMediationBigoAdsAdapter" "4.7.0.2") ADD_APPLOVIN_MEDIATION(CHARTBOOST "AppLovinMediationChartboostAdapter" "9.9.0.0") ADD_APPLOVIN_MEDIATION(CSJ "AppLovinMediationCSJAdapter" "6.7.1.6.0") ADD_APPLOVIN_MEDIATION(DTEXCHANGE "AppLovinMediationFyberAdapter" "8.3.6.0") #DT Exchange -ADD_APPLOVIN_MEDIATION(GOOGLEADMANAGER "AppLovinMediationGoogleAdManagerAdapter" "12.9.0.0") +ADD_APPLOVIN_MEDIATION(GOOGLEADMANAGER "AppLovinMediationGoogleAdManagerAdapter" "12.11.0.0") ADD_APPLOVIN_MEDIATION(HYPRMX "AppLovinMediationHyprMXAdapter" "6.4.2.0.0") ADD_APPLOVIN_MEDIATION(INMOBI "AppLovinMediationInMobiAdapter" "10.8.3.1") ADD_APPLOVIN_MEDIATION(IRONSOURCE "AppLovinMediationIronSourceAdapter" "8.8.0.0.0") diff --git a/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.h b/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.h index 636e9ba198..eacfbd58cf 100644 --- a/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.h +++ b/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.h @@ -6,7 +6,7 @@ #import "Environment/iOS/iOSPluginLoggerDelegateInterface.h" #import "Environment/iOS/iOSPluginTransparencyConsentDelegateInterface.h" -@import DatadogObjc; +@class DDLogger; @interface AppleDatadogApplicationDelegate : NSObject diff --git a/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm b/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm index 95106bb047..179c44f0e0 100644 --- a/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm +++ b/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm @@ -6,6 +6,9 @@ #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" +@import DatadogCore; +@import DatadogLogs; + #define PLUGIN_BUNDLE_NAME "MengineAppleDatadogPlugin" @implementation AppleDatadogApplicationDelegate diff --git a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt index d378a63203..7e32d566c9 100644 --- a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt @@ -11,6 +11,7 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_DATADOG) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleDatadogApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("DatadogObjc" "NO-GIT" "2.30.0") +ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.0.0") +ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.0.0") target_compile_options(${PROJECT_NAME} PRIVATE -fcxx-modules) From 245d5282de642b406f0c336004666f6aabc05797 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 18 Sep 2025 18:55:09 +0300 Subject: [PATCH 048/169] fix android AppLovin --- .../AppOpenAd/MengineAppLovinAppOpenAd.java | 14 ++++++++++---- .../AppLovin/BannerAd/MengineAppLovinBannerAd.java | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java b/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java index 13de800526..707187a831 100644 --- a/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java +++ b/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java @@ -17,6 +17,8 @@ import org.Mengine.Base.MengineActivity; import org.Mengine.Base.MengineAdFormat; import org.Mengine.Base.MengineAdMediation; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; import org.Mengine.Base.MengineNetwork; import org.Mengine.Base.MengineServiceInvalidInitializeException; @@ -35,8 +37,8 @@ public class MengineAppLovinAppOpenAd extends MengineAppLovinBase implements Men protected MaxAppOpenAd m_appOpenAd; - public MengineAppLovinAppOpenAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.APP_OPEN); + public MengineAppLovinAppOpenAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.APP_OPEN); String MengineAppLovinPlugin_AppOpen_AdUnitId = plugin.getResourceString(METADATA_APPOPEN_ADUNITID); @@ -233,7 +235,9 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setAppOpenState("hidden." + placement + "." + ad.getNetworkName()); MengineUtils.performOnMainThread(() -> { - m_adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_APPOPEN, placement); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_APPOPEN, placement); this.loadAd(); }); @@ -285,7 +289,9 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setAppOpenState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); MengineUtils.performOnMainThread(() -> { - m_adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_APPOPEN, placement, errorCode); + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_APPLOVINMAX, MengineAdFormat.ADFORMAT_APPOPEN, placement, errorCode); this.loadAd(); }); diff --git a/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java b/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java index 80168c9067..0c5fef0dab 100644 --- a/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java +++ b/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java @@ -21,6 +21,7 @@ import com.applovin.sdk.AppLovinSdkUtils; import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineUtils; @@ -42,8 +43,8 @@ public class MengineAppLovinBannerAd extends MengineAppLovinBase implements Meng protected volatile boolean m_visible = false; protected volatile boolean m_loaded = false; - public MengineAppLovinBannerAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.BANNER); + public MengineAppLovinBannerAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.BANNER); String MengineAppLovinPlugin_Banner_AdUnitId = plugin.getResourceString(METADATA_BANNER_ADUNITID); From f002289207d78308000689b4420ed9c1445267a8 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 18 Sep 2025 18:58:30 +0300 Subject: [PATCH 049/169] fix android AppLovin --- .../Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java | 10 ++++++---- .../AppLovin/NativeAd/MengineAppLovinNativeAd.java | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java b/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java index bb1049e73a..5ddbc1cf5d 100644 --- a/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java +++ b/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java @@ -21,9 +21,11 @@ import com.applovin.sdk.AppLovinSdkUtils; import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; import org.Mengine.Base.MengineApplication; import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Base.MengineUtils; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinBase; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinMRECAdInterface; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinPluginInterface; @@ -41,8 +43,8 @@ public class MengineAppLovinMRECAd extends MengineAppLovinBase implements Mengin protected volatile boolean m_visible = false; protected volatile boolean m_loaded = false; - public MengineAppLovinMRECAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.MREC); + public MengineAppLovinMRECAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.MREC); String MengineAppLovinPlugin_MREC_AdUnitId = plugin.getResourceString(METADATA_MREC_ADUNITID); @@ -283,7 +285,7 @@ public boolean canYouShow() { } public void show(int leftMargin, int topMargin) { - MengineUtils.performOnMainThread("show", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == true) { return; } @@ -302,7 +304,7 @@ public void show(int leftMargin, int topMargin) { } public void hide() { - MengineUtils.performOnMainThread("hide", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == false) { return; } diff --git a/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java b/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java index af91674de5..c3cfbf8469 100644 --- a/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java +++ b/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java @@ -20,9 +20,11 @@ import com.applovin.mediation.nativeAds.MaxNativeAdViewBinder; import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Base.MengineUtils; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinBase; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinNativeAdInterface; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinPluginInterface; @@ -42,8 +44,8 @@ public class MengineAppLovinNativeAd extends MengineAppLovinBase implements Meng protected volatile boolean m_visible = false; protected volatile boolean m_loaded = false; - public MengineAppLovinNativeAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.NATIVE); + public MengineAppLovinNativeAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.NATIVE); String MengineAppLovinPlugin_Native_AdUnitId = plugin.getResourceString(METADATA_NATIVE_ADUNITID); @@ -312,7 +314,7 @@ public boolean canYouShow() { } public void show() { - MengineUtils.performOnMainThread("show", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == true) { return; } @@ -324,7 +326,7 @@ public void show() { } public void hide() { - MengineUtils.performOnMainThread("hide", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == false) { return; } From 9970168e1f1b9d5171653a0056df9d241951e982 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 19 Sep 2025 14:16:33 +0300 Subject: [PATCH 050/169] update android com.google.firebase:firebase-bom 34.3.0 --- .../java/org/Mengine/Base/MengineActivity.java | 15 +++++++++++++++ gradle/plugins/Amplitude/build.gradle | 2 +- gradle/plugins/Firebase/build.gradle | 2 +- gradle/plugins/FirebaseCrashlytics/build.gradle | 4 ++-- gradle/plugins/FirebaseInstallations/build.gradle | 2 +- .../MengineFirebaseMessagingPlugin.java | 2 +- .../FirebasePerformanceMonitoring/build.gradle | 2 +- gradle/plugins/FirebaseRemoteConfig/build.gradle | 2 +- .../MengineLocalNotificationsPlugin.java | 3 +-- .../Plugin/Vibrator/MengineVibratorPlugin.java | 15 ++++++--------- 10 files changed, 30 insertions(+), 19 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java index 299b031c60..e277a2130d 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineActivity.java @@ -1,5 +1,6 @@ package org.Mengine.Base; +import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; @@ -140,6 +141,20 @@ public void checkPermission(String permission, Runnable onSuccess, Runnable onFa this.checkPermissionRationale(permission, onSuccess, onFailure, null, null); } + public void checkPermissionPostNotifications(Runnable onSuccess, Runnable onFailure) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + this.checkPermission(Manifest.permission.POST_NOTIFICATIONS, onSuccess, onFailure); + } else { + if (onSuccess != null) { + onSuccess.run(); + } + } + } + + public void checkPermissionPostNotifications() { + this.checkPermissionPostNotifications(null, null); + } + public void checkPermissionRationale(String permission, Runnable onSuccess, Runnable onFailure, String title, String format, Object ... args) { if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) { MengineLog.logDebug(TAG, "checkPermission: %s already granted" diff --git a/gradle/plugins/Amplitude/build.gradle b/gradle/plugins/Amplitude/build.gradle index 2c67f1f112..ffba08509c 100644 --- a/gradle/plugins/Amplitude/build.gradle +++ b/gradle/plugins/Amplitude/build.gradle @@ -8,5 +8,5 @@ android { dependencies { implementation 'com.squareup.okhttp3:okhttp:5.1.0' - implementation 'com.amplitude:analytics-android:1.22.2' + implementation 'com.amplitude:analytics-android:1.22.3' } \ No newline at end of file diff --git a/gradle/plugins/Firebase/build.gradle b/gradle/plugins/Firebase/build.gradle index b8aed033df..c059046f3c 100644 --- a/gradle/plugins/Firebase/build.gradle +++ b/gradle/plugins/Firebase/build.gradle @@ -5,7 +5,7 @@ android { } dependencies { - api enforcedPlatform('com.google.firebase:firebase-bom:34.2.0') + api enforcedPlatform('com.google.firebase:firebase-bom:34.3.0') implementation 'com.google.firebase:firebase-common:22.0.1' } diff --git a/gradle/plugins/FirebaseCrashlytics/build.gradle b/gradle/plugins/FirebaseCrashlytics/build.gradle index fcd09785d2..56d78233af 100644 --- a/gradle/plugins/FirebaseCrashlytics/build.gradle +++ b/gradle/plugins/FirebaseCrashlytics/build.gradle @@ -10,8 +10,8 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-crashlytics:20.0.1' - implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.1' + implementation 'com.google.firebase:firebase-crashlytics:20.0.2' + implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.2' } android { diff --git a/gradle/plugins/FirebaseInstallations/build.gradle b/gradle/plugins/FirebaseInstallations/build.gradle index 8c7d0e447b..73e884304c 100644 --- a/gradle/plugins/FirebaseInstallations/build.gradle +++ b/gradle/plugins/FirebaseInstallations/build.gradle @@ -7,5 +7,5 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-installations:19.0.0' + implementation 'com.google.firebase:firebase-installations:19.0.1' } diff --git a/gradle/plugins/FirebaseMessaging/src/main/java/org/Mengine/Plugin/FirebaseMessaging/MengineFirebaseMessagingPlugin.java b/gradle/plugins/FirebaseMessaging/src/main/java/org/Mengine/Plugin/FirebaseMessaging/MengineFirebaseMessagingPlugin.java index b26e45b7b8..4ef4b5adb8 100644 --- a/gradle/plugins/FirebaseMessaging/src/main/java/org/Mengine/Plugin/FirebaseMessaging/MengineFirebaseMessagingPlugin.java +++ b/gradle/plugins/FirebaseMessaging/src/main/java/org/Mengine/Plugin/FirebaseMessaging/MengineFirebaseMessagingPlugin.java @@ -32,7 +32,7 @@ public boolean onAvailable(@NonNull MengineApplication application) { } public void askNotificationPermission(@NonNull MengineActivity activity) { - activity.checkPermission(Manifest.permission.POST_NOTIFICATIONS); + activity.checkPermissionPostNotifications(); } @Override diff --git a/gradle/plugins/FirebasePerformanceMonitoring/build.gradle b/gradle/plugins/FirebasePerformanceMonitoring/build.gradle index fae2f23018..7fed37c23a 100644 --- a/gradle/plugins/FirebasePerformanceMonitoring/build.gradle +++ b/gradle/plugins/FirebasePerformanceMonitoring/build.gradle @@ -8,5 +8,5 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-perf:22.0.1' + implementation 'com.google.firebase:firebase-perf:22.0.2' } \ No newline at end of file diff --git a/gradle/plugins/FirebaseRemoteConfig/build.gradle b/gradle/plugins/FirebaseRemoteConfig/build.gradle index 4666469607..b016717610 100644 --- a/gradle/plugins/FirebaseRemoteConfig/build.gradle +++ b/gradle/plugins/FirebaseRemoteConfig/build.gradle @@ -8,5 +8,5 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-config:23.0.0' + implementation 'com.google.firebase:firebase-config:23.0.1' } \ No newline at end of file diff --git a/gradle/plugins/LocalNotifications/src/main/java/org/Mengine/Plugin/LocalNotifications/MengineLocalNotificationsPlugin.java b/gradle/plugins/LocalNotifications/src/main/java/org/Mengine/Plugin/LocalNotifications/MengineLocalNotificationsPlugin.java index e7b9469d79..b6bcecfcfd 100644 --- a/gradle/plugins/LocalNotifications/src/main/java/org/Mengine/Plugin/LocalNotifications/MengineLocalNotificationsPlugin.java +++ b/gradle/plugins/LocalNotifications/src/main/java/org/Mengine/Plugin/LocalNotifications/MengineLocalNotificationsPlugin.java @@ -56,8 +56,7 @@ static class LocalNotificationDesc { @Override public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceState) { - activity.checkPermission(Manifest.permission.POST_NOTIFICATIONS - , () -> { + activity.checkPermissionPostNotifications(() -> { this.startLocalNotifications(activity); } , () -> {} diff --git a/gradle/plugins/Vibrator/src/main/java/org/Mengine/Plugin/Vibrator/MengineVibratorPlugin.java b/gradle/plugins/Vibrator/src/main/java/org/Mengine/Plugin/Vibrator/MengineVibratorPlugin.java index f4924e2127..d354601ba2 100644 --- a/gradle/plugins/Vibrator/src/main/java/org/Mengine/Plugin/Vibrator/MengineVibratorPlugin.java +++ b/gradle/plugins/Vibrator/src/main/java/org/Mengine/Plugin/Vibrator/MengineVibratorPlugin.java @@ -29,18 +29,15 @@ public class MengineVibratorPlugin extends MengineService implements MengineList @Override public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceState) { - activity.checkPermission(Manifest.permission.VIBRATE, () -> { - Vibrator vibrator = activity.getSystemService(Vibrator.class); + Vibrator vibrator = activity.getSystemService(Vibrator.class); - if (vibrator.hasVibrator() == false) { - this.logInfo("vibrator not found"); + if (vibrator.hasVibrator() == false) { + this.logInfo("vibrator not found"); - return; - } + return; + } - m_vibrator = vibrator; - }, () -> {} - ); + m_vibrator = vibrator; } @Override From f05700319853613edaf63a78b5ebd3199afb7fef Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 19 Sep 2025 16:36:37 +0300 Subject: [PATCH 051/169] wip cocoapods use_frameworks! :linkage => :static ref-in close file stream --- cmake/cocoapods_template.cmake | 6 +-- .../PythonFramework/HelperScriptEmbedding.cpp | 37 ++++++-------- src/Interface/AccountInterface.h | 5 +- src/Interface/ContentInterface.h | 4 +- src/Interface/FileGroupInterface.h | 8 +-- src/Interface/FileInputStreamInterface.h | 2 +- src/Interface/FileMappedInterface.h | 2 +- src/Interface/FileOutputStreamInterface.h | 2 +- src/Kernel/FileContent.cpp | 12 ++--- src/Kernel/FileContent.h | 4 +- src/Kernel/FileStreamHelper.cpp | 45 +++-------------- src/Kernel/FileStreamHelper.h | 4 +- src/Kernel/JSONHelper.cpp | 24 +++------ .../ParticleConverterPTCToPTZ.cpp | 13 ++--- .../DazzleEffectConverterDZBToDZZ.cpp | 13 ++--- .../HotspotImageConverterPNGToHIT.cpp | 9 +--- .../ImageConverterDDSToHTF.cpp | 10 +--- .../ImageConverterPNGToACF.cpp | 10 +--- .../ImageConverterPVRToHTF.cpp | 9 +--- src/Plugins/ZipPlugin/FileGroupZip.cpp | 16 ++---- src/Plugins/ZipPlugin/FileGroupZip.h | 8 +-- src/Services/AccountService/Account.cpp | 36 ++++++-------- src/Services/AccountService/Account.h | 5 +- .../AccountService/AccountService.cpp | 5 +- .../RenderService/RenderTextureService.cpp | 11 ++--- .../UserdataService/UserdataService.cpp | 14 ++---- .../AndroidAssetGroupDirectory.cpp | 28 +++-------- .../AndroidAssetGroupDirectory.h | 8 +-- .../AndroidAssetInputStream.cpp | 6 +-- .../AndroidAssetInputStream.h | 2 +- .../AndroidFileGroupDirectory.cpp | 34 +++---------- .../AndroidFileGroupDirectory.h | 8 +-- .../AndroidFileInputStream.cpp | 6 +-- .../AndroidFileInputStream.h | 2 +- .../AndroidFileOutputStream.cpp | 6 +-- .../AndroidFileOutputStream.h | 2 +- .../AndroidMutexAssetInputStream.cpp | 4 +- .../AndroidMutexAssetInputStream.h | 2 +- .../AndroidMutexFileInputStream.cpp | 4 +- .../AndroidMutexFileInputStream.h | 2 +- .../Win32FileGroupDirectory.cpp | 49 +++---------------- .../Win32FileSystem/Win32FileGroupDirectory.h | 8 +-- .../Win32FileSystem/Win32FileInputStream.cpp | 6 +-- .../Win32FileSystem/Win32FileInputStream.h | 2 +- .../Win32FileSystem/Win32FileMapped.cpp | 4 +- src/Systems/Win32FileSystem/Win32FileMapped.h | 2 +- .../Win32FileSystem/Win32FileOutputStream.cpp | 10 ++-- .../Win32FileSystem/Win32FileOutputStream.h | 2 +- .../Win32MutexFileInputStream.cpp | 4 +- .../Win32MutexFileInputStream.h | 2 +- 50 files changed, 155 insertions(+), 362 deletions(-) diff --git a/cmake/cocoapods_template.cmake b/cmake/cocoapods_template.cmake index a34079c1c6..452f6e7de3 100644 --- a/cmake/cocoapods_template.cmake +++ b/cmake/cocoapods_template.cmake @@ -5,7 +5,7 @@ ENDMACRO() MACRO(MENGINE_GENERATE_COCOAPODS) SET(PODFILE_BUFFER "") - STRING(APPEND PODFILE_BUFFER "source 'https://github.com/CocoaPods/Specs.git'\n") + STRING(APPEND PODFILE_BUFFER "source 'https://cdn.cocoapods.org/'\n") STRING(APPEND PODFILE_BUFFER "project '${MENGINE_PROJECT_NAME}.xcodeproj'\n") @@ -17,7 +17,7 @@ MACRO(MENGINE_GENERATE_COCOAPODS) STRING(APPEND PODFILE_BUFFER "platform :ios, '${CMAKE_OSX_DEPLOYMENT_TARGET}'\n") endif() - STRING(APPEND PODFILE_BUFFER "use_frameworks!\n") + STRING(APPEND PODFILE_BUFFER "use_frameworks! :linkage => :static\n") STRING(APPEND PODFILE_BUFFER "inhibit_all_warnings!\n") STRING(APPEND PODFILE_BUFFER "\n") @@ -100,7 +100,6 @@ MACRO(MENGINE_GENERATE_COCOAPODS) list(GET ${APPLICATION_APPLE_COCOAPODS_PROJECT} 0 COCOAPOD_PROJECT_NAME_0) STRING(APPEND PODFILE_BUFFER "target '" ${COCOAPOD_PROJECT_NAME_0} "' do\n") - STRING(APPEND PODFILE_BUFFER " use_frameworks!\n") foreach(INDEX RANGE 0 ${LENGTH_APPLICATION_APPLE_COCOAPODS_PROJECT} 5) SET(COCOAPOD_PROJECT_NAME) @@ -154,7 +153,6 @@ MACRO(MENGINE_GENERATE_COCOAPODS) endif() STRING(APPEND PODFILE_BUFFER "target '" ${PROJECT_NAME} "' do\n") - STRING(APPEND PODFILE_BUFFER " use_frameworks!\n") if(NOT ${LENGTH_APPLICATION_APPLE_GLOBAL_COCOAPODS} EQUAL -1) foreach(INDEX RANGE 0 ${LENGTH_APPLICATION_APPLE_GLOBAL_COCOAPODS} 5) diff --git a/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp index 06152103f8..1e0b835cf7 100644 --- a/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp @@ -2995,31 +2995,35 @@ namespace Mengine } //TODO create global data save - if( Helper::writeStreamArchiveMagic( stream, archivator, GET_MAGIC_NUMBER( MAGIC_ACCOUNT_DATA ), GET_MAGIC_VERSION( MAGIC_ACCOUNT_DATA ), true, memory_buffer, memory_size, EAC_NORMAL ) == false ) - { - LOGGER_ERROR( "invalid write file '%s'" - , filePath.c_str() - ); + bool successful = Helper::writeStreamArchiveMagic( stream, archivator, GET_MAGIC_NUMBER( MAGIC_ACCOUNT_DATA ), GET_MAGIC_VERSION( MAGIC_ACCOUNT_DATA ), true, memory_buffer, memory_size, EAC_NORMAL ); - return false; - } + Helper::closeOutputStreamFile( fileGroup, stream ); - if( Helper::closeOutputStreamFile( fileGroup, stream ) == false ) + if( successful == false ) { - LOGGER_ERROR( "invalid close file '%s'" + LOGGER_ERROR( "invalid write file '%s'" , filePath.c_str() ); return false; } - stream = nullptr; - return true; } ////////////////////////////////////////////////////////////////////////// PyObject * s_loadGlobalPickleFile( pybind::kernel_interface * _kernel, const WString & _filePath, PyObject * _pickleTypes ) { + ArchivatorInterfacePtr archivator = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "Archivator" ), STRINGIZE_STRING_LOCAL( "lz4" ) ); + + if( archivator == nullptr ) + { + LOGGER_ERROR( "invalid get archivator '%s'" + , "lz4" + ); + + return _kernel->ret_none(); + } + String utf8_filePath; if( Helper::unicodeToUtf8( _filePath, &utf8_filePath ) == false ) { @@ -3046,17 +3050,6 @@ namespace Mengine return _kernel->ret_none(); } - ArchivatorInterfacePtr archivator = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "Archivator" ), STRINGIZE_STRING_LOCAL( "lz4" ) ); - - if( archivator == nullptr ) - { - LOGGER_ERROR( "invalid get archivator '%s'" - , "lz4" - ); - - return _kernel->ret_none(); - } - MemoryInterfacePtr memory = Helper::readStreamArchiveMagic( stream, archivator, GET_MAGIC_NUMBER( MAGIC_ACCOUNT_DATA ), GET_MAGIC_VERSION( MAGIC_ACCOUNT_DATA ), MENGINE_DOCUMENT_FACTORABLE ); if( memory == nullptr ) diff --git a/src/Interface/AccountInterface.h b/src/Interface/AccountInterface.h index 6c606a6c2e..a0f4abccf2 100644 --- a/src/Interface/AccountInterface.h +++ b/src/Interface/AccountInterface.h @@ -43,9 +43,10 @@ namespace Mengine public: virtual InputStreamInterfacePtr openReadBinaryFile( const FilePath & _filePath ) = 0; + virtual void closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) = 0; + virtual OutputStreamInterfacePtr openWriteBinaryFile( const FilePath & _filePath ) = 0; - virtual bool closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) = 0; - virtual bool openWriteBinaryFile( const OutputStreamInterfacePtr & _stream ) = 0; + virtual void closeWriteBinaryFile( const OutputStreamInterfacePtr & _stream ) = 0; public: virtual MemoryInterfacePtr loadBinaryFile( const FilePath & _filePath ) = 0; diff --git a/src/Interface/ContentInterface.h b/src/Interface/ContentInterface.h index df13a48932..e635596f8a 100644 --- a/src/Interface/ContentInterface.h +++ b/src/Interface/ContentInterface.h @@ -49,10 +49,10 @@ namespace Mengine virtual MemoryInterfacePtr createMemoryFileString( bool _stream, bool _share, const DocumentInterfacePtr & _doc ) = 0; virtual InputStreamInterfacePtr openInputStreamFile( bool _streaming, bool _share, const DocumentInterfacePtr & _doc ) = 0; - virtual bool closeInputStreamFile( const InputStreamInterfacePtr & _stream ) = 0; + virtual void closeInputStreamFile( const InputStreamInterfacePtr & _stream ) = 0; virtual OutputStreamInterfacePtr openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) = 0; - virtual bool closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) = 0; + virtual void closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr ContentInterfacePtr; diff --git a/src/Interface/FileGroupInterface.h b/src/Interface/FileGroupInterface.h index 99c7650a10..f908b21907 100644 --- a/src/Interface/FileGroupInterface.h +++ b/src/Interface/FileGroupInterface.h @@ -63,17 +63,17 @@ namespace Mengine public: virtual InputStreamInterfacePtr createInputFile( const FilePath & _filePath, bool _streaming, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) = 0; virtual bool openInputFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size, bool _streaming, bool _share ) = 0; - virtual bool closeInputFile( const InputStreamInterfacePtr & _stream ) = 0; + virtual void closeInputFile( const InputStreamInterfacePtr & _stream ) = 0; public: virtual InputStreamInterfacePtr createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) = 0; virtual bool openInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size ) = 0; - virtual bool closeInputMutexFile( const InputStreamInterfacePtr & _stream ) = 0; + virtual void closeInputMutexFile( const InputStreamInterfacePtr & _stream ) = 0; public: virtual OutputStreamInterfacePtr createOutputFile( const DocumentInterfacePtr & _doc ) = 0; virtual bool openOutputFile( const FilePath & _filePath, const OutputStreamInterfacePtr & _stream, bool _withTemp ) = 0; - virtual bool closeOutputFile( const OutputStreamInterfacePtr & _stream ) = 0; + virtual void closeOutputFile( const OutputStreamInterfacePtr & _stream ) = 0; public: virtual bool isAvailableMappedFile() const = 0; @@ -81,7 +81,7 @@ namespace Mengine public: virtual MappedInterfacePtr createMappedFile( const FilePath & _filePath, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) = 0; virtual bool openMappedFile( const FilePath & _filePath, const MappedInterfacePtr & _stream, bool _shared ) = 0; - virtual bool closeMappedFile( const MappedInterfacePtr & _stream ) = 0; + virtual void closeMappedFile( const MappedInterfacePtr & _stream ) = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr FileGroupInterfacePtr; diff --git a/src/Interface/FileInputStreamInterface.h b/src/Interface/FileInputStreamInterface.h index 1ab59fada6..212cad4552 100644 --- a/src/Interface/FileInputStreamInterface.h +++ b/src/Interface/FileInputStreamInterface.h @@ -12,7 +12,7 @@ namespace Mengine { public: virtual bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) = 0; - virtual bool close() = 0; + virtual void close() = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr FileInputStreamInterfacePtr; diff --git a/src/Interface/FileMappedInterface.h b/src/Interface/FileMappedInterface.h index ff0de13999..ae29edd5c9 100644 --- a/src/Interface/FileMappedInterface.h +++ b/src/Interface/FileMappedInterface.h @@ -12,7 +12,7 @@ namespace Mengine { public: virtual bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _share ) = 0; - virtual bool close() = 0; + virtual void close() = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr FileMappedInterfacePtr; diff --git a/src/Interface/FileOutputStreamInterface.h b/src/Interface/FileOutputStreamInterface.h index f919b03cfd..c87531e531 100644 --- a/src/Interface/FileOutputStreamInterface.h +++ b/src/Interface/FileOutputStreamInterface.h @@ -12,7 +12,7 @@ namespace Mengine { public: virtual bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) = 0; - virtual bool close() = 0; + virtual void close() = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr FileOutputStreamInterfacePtr; diff --git a/src/Kernel/FileContent.cpp b/src/Kernel/FileContent.cpp index 67ced0ebbf..a49d4be46f 100644 --- a/src/Kernel/FileContent.cpp +++ b/src/Kernel/FileContent.cpp @@ -42,11 +42,9 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// - bool FileContent::closeInputStreamFile( const InputStreamInterfacePtr & _stream ) + void FileContent::closeInputStreamFile( const InputStreamInterfacePtr & _stream ) { - bool successful = Helper::closeInputStreamFile( m_fileGroup, _stream ); - - return successful; + Helper::closeInputStreamFile( m_fileGroup, _stream ); } ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr FileContent::openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) @@ -56,11 +54,9 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// - bool FileContent::closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) + void FileContent::closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) { - bool successful = Helper::closeOutputStreamFile( m_fileGroup, _stream ); - - return successful; + Helper::closeOutputStreamFile( m_fileGroup, _stream ); } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/FileContent.h b/src/Kernel/FileContent.h index 561c09882b..1c2691792e 100644 --- a/src/Kernel/FileContent.h +++ b/src/Kernel/FileContent.h @@ -23,10 +23,10 @@ namespace Mengine MemoryInterfacePtr createMemoryFileString( bool _stream, bool _share, const DocumentInterfacePtr & _doc ) override; InputStreamInterfacePtr openInputStreamFile( bool _streaming, bool _share, const DocumentInterfacePtr & _doc ) override; - bool closeInputStreamFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputStreamFile( const InputStreamInterfacePtr & _stream ) override; OutputStreamInterfacePtr openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) override; - bool closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) override; + void closeOutputStreamFile( const OutputStreamInterfacePtr & _stream ) override; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr FileContentPtr; diff --git a/src/Kernel/FileStreamHelper.cpp b/src/Kernel/FileStreamHelper.cpp index a0a1435a96..cbd5321b44 100644 --- a/src/Kernel/FileStreamHelper.cpp +++ b/src/Kernel/FileStreamHelper.cpp @@ -72,36 +72,14 @@ namespace Mengine return file; } ////////////////////////////////////////////////////////////////////////// - bool closeInputStreamFile( const FileGroupInterfacePtr & _fileGroup, const InputStreamInterfacePtr & _stream ) + void closeInputStreamFile( const FileGroupInterfacePtr & _fileGroup, const InputStreamInterfacePtr & _stream ) { - if( _fileGroup->closeInputFile( _stream ) == false ) - { - const FilePath & filePath = Helper::getDebugRelationPath( _stream ); - - LOGGER_ERROR( "invalid close input file '%s'" - , Helper::getFileGroupFullPath( _fileGroup, filePath ).c_str() - ); - - return false; - } - - return true; + _fileGroup->closeInputFile( _stream ); } ////////////////////////////////////////////////////////////////////////// - bool closeOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const OutputStreamInterfacePtr & _stream ) + void closeOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const OutputStreamInterfacePtr & _stream ) { - if( _fileGroup->closeOutputFile( _stream ) == false ) - { - const FilePath & filePath = Helper::getDebugFilePath( _stream ); - - LOGGER_ERROR( "invalid close output file '%s'" - , Helper::getFileGroupFullPath( _fileGroup, filePath ).c_str() - ); - - return false; - } - - return true; + _fileGroup->closeOutputFile( _stream ); } ////////////////////////////////////////////////////////////////////////// bool writeOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const FilePath & _filePath, bool _withTemp, const MemoryInterfacePtr & _memory, const DocumentInterfacePtr & _doc ) @@ -115,26 +93,19 @@ namespace Mengine const void * memory_buffer = _memory->getBuffer(); size_t memory_size = _memory->getSize(); - if( stream->write( memory_buffer, memory_size ) == false ) - { - LOGGER_ERROR( "invalid write output file '%s'" - , Helper::getFileGroupFullPath( _fileGroup, _filePath ).c_str() - ); + bool successful = stream->write( memory_buffer, memory_size ); - return false; - } + Helper::closeOutputStreamFile( _fileGroup, stream ); - if( Helper::closeOutputStreamFile( _fileGroup, stream ) == false ) + if( successful == false ) { - LOGGER_ERROR( "invalid close output file '%s'" + LOGGER_ERROR( "invalid write output file '%s'" , Helper::getFileGroupFullPath( _fileGroup, _filePath ).c_str() ); return false; } - stream = nullptr; - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Kernel/FileStreamHelper.h b/src/Kernel/FileStreamHelper.h index f3e89597bd..86418cf934 100644 --- a/src/Kernel/FileStreamHelper.h +++ b/src/Kernel/FileStreamHelper.h @@ -10,10 +10,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr openInputStreamFile( const FileGroupInterfacePtr & _fileGroup, const FilePath & _filePath, bool _streaming, bool _share, const DocumentInterfacePtr & _doc ); InputStreamInterfacePtr openInputStreamMutexFile( const FileGroupInterfacePtr & _fileGroup, const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, const DocumentInterfacePtr & _doc ); - bool closeInputStreamFile( const FileGroupInterfacePtr & _fileGroup, const InputStreamInterfacePtr & _stream ); + void closeInputStreamFile( const FileGroupInterfacePtr & _fileGroup, const InputStreamInterfacePtr & _stream ); ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr openOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const FilePath & _filePath, bool _withTemp, const DocumentInterfacePtr & _doc ); - bool closeOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const OutputStreamInterfacePtr & _stream ); + void closeOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const OutputStreamInterfacePtr & _stream ); bool writeOutputStreamFile( const FileGroupInterfacePtr & _fileGroup, const FilePath & _filePath, bool _withTemp, const MemoryInterfacePtr & _memory, const DocumentInterfacePtr & _doc ); ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/JSONHelper.cpp b/src/Kernel/JSONHelper.cpp index 824b5c863a..82425788bf 100644 --- a/src/Kernel/JSONHelper.cpp +++ b/src/Kernel/JSONHelper.cpp @@ -189,17 +189,11 @@ namespace Mengine return false; } - if( Helper::writeJSONStream( _j, stream ) == false ) - { - return false; - } + bool successful = Helper::writeJSONStream( _j, stream ); - if( Helper::closeOutputStreamFile( _fileGroup, stream ) == false ) - { - return false; - } + Helper::closeOutputStreamFile( _fileGroup, stream ); - return true; + return successful; } ////////////////////////////////////////////////////////////////////////// bool writeJSONFileCompact( const jpp::object & _j, const FileGroupInterfacePtr & _fileGroup, const FilePath & _filePath, bool _withTemp, const DocumentInterfacePtr & _doc ) @@ -211,17 +205,11 @@ namespace Mengine return false; } - if( Helper::writeJSONStreamCompact( _j, stream ) == false ) - { - return false; - } + bool successful = Helper::writeJSONStreamCompact( _j, stream ); - if( Helper::closeOutputStreamFile( _fileGroup, stream ) == false ) - { - return false; - } + Helper::closeOutputStreamFile( _fileGroup, stream ); - return true; + return successful; } ////////////////////////////////////////////////////////////////////////// bool writeJSONStream( const jpp::object & _j, const OutputStreamInterfacePtr & _stream ) diff --git a/src/Plugins/AstralaxPlugin/ParticleConverterPTCToPTZ.cpp b/src/Plugins/AstralaxPlugin/ParticleConverterPTCToPTZ.cpp index dd985f06db..770286cd11 100644 --- a/src/Plugins/AstralaxPlugin/ParticleConverterPTCToPTZ.cpp +++ b/src/Plugins/AstralaxPlugin/ParticleConverterPTCToPTZ.cpp @@ -79,7 +79,11 @@ namespace Mengine , full_outputFilePath.c_str() ); - if( Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_PTZ ), GET_MAGIC_VERSION( MAGIC_PTZ ), false, data_memory, data_size, EAC_BEST ) == false ) + bool successful = Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_PTZ ), GET_MAGIC_VERSION( MAGIC_PTZ ), false, data_memory, data_size, EAC_BEST ); + + Helper::closeOutputStreamFile( m_fileGroupDev, stream ); + + if( successful == false ) { LOGGER_ERROR( "invalid write '%s'" , full_outputFilePath.c_str() @@ -88,13 +92,6 @@ namespace Mengine return false; } - if( Helper::closeOutputStreamFile( m_fileGroupDev, stream ) == false ) - { - return false; - } - - stream = nullptr; - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Plugins/DazzlePlugin/DazzleEffectConverterDZBToDZZ.cpp b/src/Plugins/DazzlePlugin/DazzleEffectConverterDZBToDZZ.cpp index ba1dba549a..71b51e9f04 100644 --- a/src/Plugins/DazzlePlugin/DazzleEffectConverterDZBToDZZ.cpp +++ b/src/Plugins/DazzlePlugin/DazzleEffectConverterDZBToDZZ.cpp @@ -80,18 +80,13 @@ namespace Mengine , Helper::getContentFullPath( m_options.outputContent ).c_str() ); - if( Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_DZZ ), GET_MAGIC_VERSION( MAGIC_DZZ ), false, data_memory, data_size, EAC_BEST ) == false ) - { - LOGGER_ERROR( "dazzle converter invalid write '%s'" - , Helper::getContentFullPath( m_options.outputContent ).c_str() - ); + bool successful = Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_DZZ ), GET_MAGIC_VERSION( MAGIC_DZZ ), false, data_memory, data_size, EAC_BEST ); - return false; - } + Helper::closeOutputStreamFile( m_fileGroupDev, stream ); - if( Helper::closeOutputStreamFile( m_fileGroupDev, stream ) == false ) + if( successful == false ) { - LOGGER_ERROR( "dazzle converter invalid close '%s'" + LOGGER_ERROR( "dazzle converter invalid write '%s'" , Helper::getContentFullPath( m_options.outputContent ).c_str() ); diff --git a/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp b/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp index edfedc8a9a..eca34cff39 100644 --- a/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp @@ -175,14 +175,7 @@ namespace Mengine encoder->finalize(); - if( m_options.outputContent->closeOutputStreamFile( stream_output ) == false ) - { - LOGGER_ERROR( "HIT file '%s' invalid close" - , Helper::getContentFullPath( m_options.outputContent ).c_str() - ); - - return false; - } + m_options.outputContent->closeOutputStreamFile( stream_output ); if( encodeSize == 0 ) { diff --git a/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp b/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp index 25f917bdb5..3a3e5cce9b 100644 --- a/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/ImageConverterDDSToHTF.cpp @@ -164,15 +164,7 @@ namespace Mengine encoder->finalize(); - if( content_output->closeOutputStreamFile( stream_output ) == false ) - { - LOGGER_ERROR( "'%s' invalid close output '%s'" - , Helper::getContentFullPath( m_options.inputContent ).c_str() - , full_outputFilePath.c_str() - ); - - return false; - } + content_output->closeOutputStreamFile( stream_output ); if( encode_byte == 0 ) { diff --git a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp index 8f37df424b..4048680beb 100644 --- a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPNGToACF.cpp @@ -146,15 +146,7 @@ namespace Mengine encoder->finalize(); - if( content_output->closeOutputStreamFile( stream_output ) == false ) - { - LOGGER_ERROR( "%s invalid close output '%s'" - , Helper::getContentFullPath( m_options.inputContent ).c_str() - , Helper::getContentFullPath( m_options.outputContent ).c_str() - ); - - return false; - } + content_output->closeOutputStreamFile( stream_output ); if( encode_byte == 0 ) { diff --git a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp index e622793a3d..c9675c7347 100644 --- a/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp +++ b/src/Plugins/DevelopmentConverterPlugin/ImageConverterPVRToHTF.cpp @@ -163,14 +163,7 @@ namespace Mengine encoder->finalize(); - if( content_output->closeOutputStreamFile( stream_output ) == false ) - { - LOGGER_ERROR( "invalid close output '%s'" - , Helper::getContentFullPath( m_options.outputContent ).c_str() - ); - - return false; - } + content_output->closeOutputStreamFile( stream_output ); if( encode_byte == 0 ) { diff --git a/src/Plugins/ZipPlugin/FileGroupZip.cpp b/src/Plugins/ZipPlugin/FileGroupZip.cpp index 473aff244f..ead5e7a309 100644 --- a/src/Plugins/ZipPlugin/FileGroupZip.cpp +++ b/src/Plugins/ZipPlugin/FileGroupZip.cpp @@ -805,13 +805,11 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool FileGroupZip::closeInputFile( const InputStreamInterfacePtr & _stream ) + void FileGroupZip::closeInputFile( const InputStreamInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); //Empty - - return true; } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr FileGroupZip::createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) @@ -839,13 +837,11 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool FileGroupZip::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) + void FileGroupZip::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr FileGroupZip::createOutputFile( const DocumentInterfacePtr & _doc ) @@ -868,13 +864,11 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool FileGroupZip::closeOutputFile( const OutputStreamInterfacePtr & _stream ) + void FileGroupZip::closeOutputFile( const OutputStreamInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return true; } ////////////////////////////////////////////////////////////////////////// bool FileGroupZip::isAvailableMappedFile() const @@ -904,13 +898,11 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool FileGroupZip::closeMappedFile( const MappedInterfacePtr & _stream ) + void FileGroupZip::closeMappedFile( const MappedInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Plugins/ZipPlugin/FileGroupZip.h b/src/Plugins/ZipPlugin/FileGroupZip.h index 1f48160261..efc70266aa 100644 --- a/src/Plugins/ZipPlugin/FileGroupZip.h +++ b/src/Plugins/ZipPlugin/FileGroupZip.h @@ -47,17 +47,17 @@ namespace Mengine public: InputStreamInterfacePtr createInputFile( const FilePath & _filePath, bool _streaming, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool closeInputFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputFile( const InputStreamInterfacePtr & _stream ) override; public: InputStreamInterfacePtr createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size ) override; - bool closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; public: OutputStreamInterfacePtr createOutputFile( const DocumentInterfacePtr & _doc ) override; bool openOutputFile( const FilePath & _filePath, const OutputStreamInterfacePtr & _stream, bool _withTemp ) override; - bool closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; + void closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; public: bool isAvailableMappedFile() const override; @@ -65,7 +65,7 @@ namespace Mengine public: MappedInterfacePtr createMappedFile( const FilePath & _filePath, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openMappedFile( const FilePath & _filePath, const MappedInterfacePtr & _stream, bool _shared ) override; - bool closeMappedFile( const MappedInterfacePtr & _stream ) override; + void closeMappedFile( const MappedInterfacePtr & _stream ) override; protected: bool loadHeaders_(); diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index bce739cbbf..4549590b50 100644 --- a/src/Services/AccountService/Account.cpp +++ b/src/Services/AccountService/Account.cpp @@ -378,10 +378,7 @@ namespace Mengine return false; } - if( m_fileGroup->closeOutputFile( file ) == false ) - { - return false; - } + m_fileGroup->closeOutputFile( file ); return true; } @@ -424,6 +421,11 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// + void Account::closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) + { + m_fileGroup->closeInputFile( _stream ); + } + ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr Account::openWriteBinaryFile( const FilePath & _filePath ) { PathString path; @@ -447,18 +449,9 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// - bool Account::closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) - { - bool successful = m_fileGroup->closeInputFile( _stream ); - - return successful; - } - ////////////////////////////////////////////////////////////////////////// - bool Account::openWriteBinaryFile( const OutputStreamInterfacePtr & _stream ) + void Account::closeWriteBinaryFile( const OutputStreamInterfacePtr & _stream ) { - bool successful = m_fileGroup->closeOutputFile( _stream ); - - return successful; + m_fileGroup->closeOutputFile( _stream ); } ////////////////////////////////////////////////////////////////////////// MemoryInterfacePtr Account::loadBinaryFile( const FilePath & _filePath ) @@ -477,6 +470,8 @@ namespace Mengine MemoryInterfacePtr binaryBuffer = Helper::readStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_ACCOUNT_DATA ), GET_MAGIC_VERSION( MAGIC_ACCOUNT_DATA ), MENGINE_DOCUMENT_FACTORABLE ); + this->closeReadBinaryFile( stream ); + if( binaryBuffer == nullptr ) { LOGGER_ERROR( "account '%s' invalid load stream archive '%s'" @@ -517,7 +512,11 @@ namespace Mengine const void * data_memory = _data; size_t data_size = _size; - if( Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_ACCOUNT_DATA ), GET_MAGIC_VERSION( MAGIC_ACCOUNT_DATA ), true, data_memory, data_size, EAC_NORMAL ) == false ) + bool successful = Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_ACCOUNT_DATA ), GET_MAGIC_VERSION( MAGIC_ACCOUNT_DATA ), true, data_memory, data_size, EAC_NORMAL ); + + this->closeWriteBinaryFile( stream ); + + if( successful == false ) { LOGGER_ERROR( "account '%s' invalid write file '%s'" , m_accountId.c_str() @@ -527,11 +526,6 @@ namespace Mengine return false; } - if( m_fileGroup->closeOutputFile( stream ) == false ) - { - return false; - } - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/AccountService/Account.h b/src/Services/AccountService/Account.h index 0c56bff9ad..1096f6b135 100644 --- a/src/Services/AccountService/Account.h +++ b/src/Services/AccountService/Account.h @@ -50,9 +50,10 @@ namespace Mengine public: InputStreamInterfacePtr openReadBinaryFile( const FilePath & _filePath ) override; + void closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) override; + OutputStreamInterfacePtr openWriteBinaryFile( const FilePath & _filePath ) override; - bool closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) override; - bool openWriteBinaryFile( const OutputStreamInterfacePtr & _stream ) override; + void closeWriteBinaryFile( const OutputStreamInterfacePtr & _stream ) override; public: MemoryInterfacePtr loadBinaryFile( const FilePath & _filepath ) override; diff --git a/src/Services/AccountService/AccountService.cpp b/src/Services/AccountService/AccountService.cpp index 4cef310f5f..254d76308f 100644 --- a/src/Services/AccountService/AccountService.cpp +++ b/src/Services/AccountService/AccountService.cpp @@ -804,10 +804,7 @@ namespace Mengine return false; } - if( Helper::closeOutputStreamFile( m_fileGroup, stream ) == false ) - { - return false; - } + Helper::closeOutputStreamFile( m_fileGroup, stream ); for( const HashtableAccounts::value_type & value : m_accounts ) { diff --git a/src/Services/RenderService/RenderTextureService.cpp b/src/Services/RenderService/RenderTextureService.cpp index 1a784ee7d2..7f4c8bf7e2 100644 --- a/src/Services/RenderService/RenderTextureService.cpp +++ b/src/Services/RenderService/RenderTextureService.cpp @@ -156,6 +156,8 @@ namespace Mengine , Helper::getContentFullPath( _content ).c_str() ); + _content->closeOutputStreamFile( stream ); + return false; } @@ -199,14 +201,7 @@ namespace Mengine image->unlock( locked, 0, true ); - if( _content->closeOutputStreamFile( stream ) == false ) - { - LOGGER_ERROR( "can't close file '%s'" - , Helper::getContentFullPath( _content ).c_str() - ); - - return false; - } + _content->closeOutputStreamFile( stream ); if( bytesWritten == 0 ) { diff --git a/src/Services/UserdataService/UserdataService.cpp b/src/Services/UserdataService/UserdataService.cpp index 66bb97f9f3..6a616009b2 100644 --- a/src/Services/UserdataService/UserdataService.cpp +++ b/src/Services/UserdataService/UserdataService.cpp @@ -175,19 +175,13 @@ namespace Mengine const void * data_memory = _data; size_t data_size = _size; - if( Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_USER_DATA ), GET_MAGIC_VERSION( MAGIC_USER_DATA ), true, data_memory, data_size, EAC_NORMAL ) == false ) - { - LOGGER_ERROR( "data '%s' invalid write file '%s'" - , _name.c_str() - , Helper::getContentFullPath( desc.content ).c_str() - ); + bool successful = Helper::writeStreamArchiveMagic( stream, m_archivator, GET_MAGIC_NUMBER( MAGIC_USER_DATA ), GET_MAGIC_VERSION( MAGIC_USER_DATA ), true, data_memory, data_size, EAC_NORMAL ); - return false; - } + content->closeOutputStreamFile( stream ); - if( content->closeOutputStreamFile( stream ) == false ) + if( successful == false ) { - LOGGER_ERROR( "data '%s' invalid close file '%s'" + LOGGER_ERROR( "data '%s' invalid write file '%s'" , _name.c_str() , Helper::getContentFullPath( desc.content ).c_str() ); diff --git a/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp b/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp index 411a15a544..63ff3bcfc1 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp +++ b/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp @@ -179,19 +179,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool AndroidAssetGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) + void AndroidAssetGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = stdex::intrusive_get( _stream ); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr AndroidAssetGroupDirectory::createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) @@ -240,19 +234,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool AndroidAssetGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) + void AndroidAssetGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = stdex::intrusive_get( _stream ); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr AndroidAssetGroupDirectory::createOutputFile( const DocumentInterfacePtr & _doc ) @@ -275,13 +263,11 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool AndroidAssetGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) + void AndroidAssetGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// bool AndroidAssetGroupDirectory::isAvailableMappedFile() const @@ -311,13 +297,11 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool AndroidAssetGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) + void AndroidAssetGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.h b/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.h index 21e8ff6614..4a2fa32326 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.h +++ b/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.h @@ -42,17 +42,17 @@ namespace Mengine public: InputStreamInterfacePtr createInputFile( const FilePath & _filePath, bool _streaming, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool closeInputFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputFile( const InputStreamInterfacePtr & _stream ) override; public: InputStreamInterfacePtr createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size ) override; - bool closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; public: OutputStreamInterfacePtr createOutputFile( const DocumentInterfacePtr & _doc ) override; bool openOutputFile( const FilePath & _filePath, const OutputStreamInterfacePtr & _stream, bool _withTemp ) override; - bool closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; + void closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; public: bool isAvailableMappedFile() const override; @@ -60,7 +60,7 @@ namespace Mengine public: MappedInterfacePtr createMappedFile( const FilePath & _filePath, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openMappedFile( const FilePath & _filePath, const MappedInterfacePtr & _stream, bool _shared ) override; - bool closeMappedFile( const MappedInterfacePtr & _stream ) override; + void closeMappedFile( const MappedInterfacePtr & _stream ) override; protected: FactoryInterfacePtr m_factoryInputStreamFile; diff --git a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp index c9ae4cb144..e18d8eeadb 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp @@ -140,13 +140,13 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidAssetInputStream::close() + void AndroidAssetInputStream::close() { MENGINE_THREAD_GUARD_SCOPE( AndroidAssetInputStream, this ); if( m_asset == nullptr ) { - return true; + return; } #if defined(MENGINE_DEBUG) @@ -167,8 +167,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// size_t AndroidAssetInputStream::read( void * const _buf, size_t _count ) diff --git a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h index 07d0c718d4..99abbd8d8f 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.h @@ -26,7 +26,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _count ) override; diff --git a/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.cpp b/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.cpp index 68a9ebd7e5..15acbfe408 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.cpp @@ -245,19 +245,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) + void AndroidFileGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = stdex::intrusive_get( _stream ); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr AndroidFileGroupDirectory::createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) @@ -306,19 +300,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) + void AndroidFileGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = stdex::intrusive_get( _stream ); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr AndroidFileGroupDirectory::createOutputFile( const DocumentInterfacePtr & _doc ) @@ -346,19 +334,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) + void AndroidFileGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileOutputStreamInterface * file = stdex::intrusive_get( _stream ); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// bool AndroidFileGroupDirectory::isAvailableMappedFile() const @@ -388,13 +370,11 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) + void AndroidFileGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.h b/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.h index 3623d50c58..6c3a595352 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.h +++ b/src/Systems/AndroidFileSystem/AndroidFileGroupDirectory.h @@ -42,17 +42,17 @@ namespace Mengine public: InputStreamInterfacePtr createInputFile( const FilePath & _filePath, bool _streaming, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool closeInputFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputFile( const InputStreamInterfacePtr & _stream ) override; public: InputStreamInterfacePtr createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size ) override; - bool closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; public: OutputStreamInterfacePtr createOutputFile( const DocumentInterfacePtr & _doc ) override; bool openOutputFile( const FilePath & _filePath, const OutputStreamInterfacePtr & _stream, bool _withTemp ) override; - bool closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; + void closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; public: bool isAvailableMappedFile() const override; @@ -60,7 +60,7 @@ namespace Mengine public: MappedInterfacePtr createMappedFile( const FilePath & _filePath, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openMappedFile( const FilePath & _filePath, const MappedInterfacePtr & _stream, bool _shared ) override; - bool closeMappedFile( const MappedInterfacePtr & _stream ) override; + void closeMappedFile( const MappedInterfacePtr & _stream ) override; protected: FactoryInterfacePtr m_factoryInputStreamFile; diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp index 653304a404..c526801d26 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp @@ -140,11 +140,11 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileInputStream::close() + void AndroidFileInputStream::close() { if( m_file == nullptr ) { - return true; + return; } #if defined(MENGINE_DEBUG) @@ -165,8 +165,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// size_t AndroidFileInputStream::read( void * const _buf, size_t _count ) diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.h b/src/Systems/AndroidFileSystem/AndroidFileInputStream.h index 6d1483c174..ba094a9f26 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidFileInputStream.h @@ -24,7 +24,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _count ) override; diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp index fdf31c99b3..93c5862ba2 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp @@ -71,13 +71,13 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileOutputStream::close() + void AndroidFileOutputStream::close() { MENGINE_THREAD_GUARD_SCOPE( AndroidFileOutputStream, this ); if( m_file == nullptr ) { - return true; + return; } #if defined(MENGINE_DEBUG) @@ -98,8 +98,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// size_t AndroidFileOutputStream::write( const void * _data, size_t _size ) diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h index 9b615da74c..16d25d703d 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h @@ -20,7 +20,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) override; - bool close() override; + void close() override; public: size_t write( const void * _data, size_t _size ) override; diff --git a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp index 1a553d536b..dd76c3dc5f 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp @@ -84,7 +84,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidMutexAssetInputStream::close() + void AndroidMutexAssetInputStream::close() { m_stream = nullptr; m_mutex = nullptr; @@ -92,8 +92,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// size_t AndroidMutexAssetInputStream::read( void * const _buf, size_t _count ) diff --git a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h index a12b08e8f7..bcc72cdb9c 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.h @@ -26,7 +26,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _size ) override; diff --git a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp index 4129817c2e..d4da056b90 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp @@ -82,7 +82,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidMutexFileInputStream::close() + void AndroidMutexFileInputStream::close() { m_stream = nullptr; m_mutex = nullptr; @@ -90,8 +90,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// size_t AndroidMutexFileInputStream::read( void * const _buf, size_t _count ) diff --git a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h index dbe40c7a9d..4799b3bc61 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h @@ -26,7 +26,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _size ) override; diff --git a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp index e05ffbf885..82d90d5ce0 100644 --- a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp +++ b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp @@ -234,25 +234,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) + void Win32FileGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = _stream.getT(); - bool result = file->close(); - - if( result == false ) - { - return false; - } - - MENGINE_ASSERTION( result == true, "failed close file '%s%s'" - , m_relationPath.c_str() - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr Win32FileGroupDirectory::createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) @@ -299,20 +287,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) + void Win32FileGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = _stream.getT(); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s%s'" - , m_relationPath.c_str() - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr Win32FileGroupDirectory::createOutputFile( const DocumentInterfacePtr & _doc ) @@ -341,20 +322,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) + void Win32FileGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileOutputStreamInterface * file = _stream.getT(); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s%s'" - , m_relationPath.c_str() - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// bool Win32FileGroupDirectory::isAvailableMappedFile() const @@ -405,20 +379,13 @@ namespace Mengine return result; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) + void Win32FileGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileMappedInterface * mapped = _stream.getT(); - bool result = mapped->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s%s'" - , m_relationPath.c_str() - , m_folderPath.c_str() - ); - - return result; + mapped->close(); } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.h b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.h index b355dc8b0f..3ece56c004 100644 --- a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.h +++ b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.h @@ -40,17 +40,17 @@ namespace Mengine public: InputStreamInterfacePtr createInputFile( const FilePath & _filePath, bool _streaming, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool closeInputFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputFile( const InputStreamInterfacePtr & _stream ) override; public: InputStreamInterfacePtr createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size ) override; - bool closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; public: OutputStreamInterfacePtr createOutputFile( const DocumentInterfacePtr & _doc ) override; bool openOutputFile( const FilePath & _filePath, const OutputStreamInterfacePtr & _stream, bool _withTemp ) override; - bool closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; + void closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; public: bool isAvailableMappedFile() const override; @@ -58,7 +58,7 @@ namespace Mengine public: MappedInterfacePtr createMappedFile( const FilePath & _filePath, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openMappedFile( const FilePath & _filePath, const MappedInterfacePtr & _stream, bool _shared ) override; - bool closeMappedFile( const MappedInterfacePtr & _stream ) override; + void closeMappedFile( const MappedInterfacePtr & _stream ) override; protected: FactoryInterfacePtr m_factoryInputStreamFile; diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp index 4a976c68ba..4a5a6ba562 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.cpp @@ -125,11 +125,11 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileInputStream::close() + void Win32FileInputStream::close() { if( m_hFile == INVALID_HANDLE_VALUE ) { - return true; + return; } #if defined(MENGINE_DEBUG) @@ -156,8 +156,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// bool Win32FileInputStream::openFile_( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, WChar * const _fullPath ) diff --git a/src/Systems/Win32FileSystem/Win32FileInputStream.h b/src/Systems/Win32FileSystem/Win32FileInputStream.h index 161f21844c..119fc65384 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.h @@ -26,7 +26,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _count ) override; diff --git a/src/Systems/Win32FileSystem/Win32FileMapped.cpp b/src/Systems/Win32FileSystem/Win32FileMapped.cpp index 3b24d8fe46..efa28099c0 100644 --- a/src/Systems/Win32FileSystem/Win32FileMapped.cpp +++ b/src/Systems/Win32FileSystem/Win32FileMapped.cpp @@ -111,7 +111,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileMapped::close() + void Win32FileMapped::close() { if( m_hMapping != INVALID_HANDLE_VALUE ) { @@ -132,8 +132,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr Win32FileMapped::createInputStream( const DocumentInterfacePtr & _doc ) diff --git a/src/Systems/Win32FileSystem/Win32FileMapped.h b/src/Systems/Win32FileSystem/Win32FileMapped.h index 1a638cb7a8..237c3b9d2f 100644 --- a/src/Systems/Win32FileSystem/Win32FileMapped.h +++ b/src/Systems/Win32FileSystem/Win32FileMapped.h @@ -22,7 +22,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _share ) override; - bool close() override; + void close() override; public: InputStreamInterfacePtr createInputStream( const DocumentInterfacePtr & _doc ) override; diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp index 6e72fe3df9..549b800913 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp @@ -102,11 +102,11 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileOutputStream::close() + void Win32FileOutputStream::close() { if( m_hFile == INVALID_HANDLE_VALUE ) { - return true; + return; } #if defined(MENGINE_DEBUG) @@ -116,7 +116,7 @@ namespace Mengine } #endif - bool successful = this->flush(); + this->flush(); ::CloseHandle( m_hFile ); m_hFile = INVALID_HANDLE_VALUE; @@ -152,16 +152,12 @@ namespace Mengine , fullPathTemp , fullPath ); - - return false; } } #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return successful; } ////////////////////////////////////////////////////////////////////////// size_t Win32FileOutputStream::write( const void * _data, size_t _size ) diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.h b/src/Systems/Win32FileSystem/Win32FileOutputStream.h index d1846ada0e..08a6c50520 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.h @@ -20,7 +20,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) override; - bool close() override; + void close() override; public: size_t write( const void * _data, size_t _size ) override; diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp index 6780069925..c724926ada 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp @@ -91,7 +91,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool Win32MutexFileInputStream::close() + void Win32MutexFileInputStream::close() { m_stream = nullptr; m_mutex = nullptr; @@ -99,8 +99,6 @@ namespace Mengine #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// size_t Win32MutexFileInputStream::read( void * const _buf, size_t _count ) diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h index d4aaff3cd2..8688b1be34 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h @@ -26,7 +26,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _count ) override; From 7d08f4b6c57be87a5dcf18252ce863a7e23d1b14 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 19 Sep 2025 22:11:03 +0300 Subject: [PATCH 052/169] Fix iOS build --- cmake/xcode_ios_template.cmake | 2 +- src/Plugins/AppleDatadogPlugin/CMakeLists.txt | 4 +-- .../CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../AppleFirebasePlugin/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../AppleGameCenterApplicationDelegate.mm | 29 ++++++++++------ .../AppleStoreReviewApplicationDelegate.mm | 22 +++++------- .../ZipPlugin/ZipMemoryInputStream.cpp | 6 ++-- src/Plugins/ZipPlugin/ZipMemoryInputStream.h | 4 +-- .../AppleFileSystem/AppleFileGroupDirectory.h | 8 ++--- .../AppleFileGroupDirectory.mm | 34 ++++--------------- .../AppleFileSystem/AppleFileInputStream.h | 2 +- .../AppleFileSystem/AppleFileInputStream.mm | 34 +++++++++---------- src/Systems/AppleFileSystem/AppleFileMapped.h | 2 +- .../AppleFileSystem/AppleFileMapped.mm | 4 +-- .../AppleFileSystem/AppleFileOutputStream.h | 2 +- .../AppleFileSystem/AppleFileOutputStream.mm | 4 +-- .../AppleMutexFileInputStream.h | 2 +- .../AppleMutexFileInputStream.mm | 24 ++++++------- 22 files changed, 86 insertions(+), 109 deletions(-) diff --git a/cmake/xcode_ios_template.cmake b/cmake/xcode_ios_template.cmake index c4bae2997e..b033ad6faa 100644 --- a/cmake/xcode_ios_template.cmake +++ b/cmake/xcode_ios_template.cmake @@ -19,7 +19,7 @@ SET(XCODE_EMIT_EFFECTIVE_PLATFORM_NAME OFF) set(CMAKE_XCODE_GENERATE_SCHEME TRUE) -set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "CMAKE_OSX_DEPLOYMENT_TARGET" FORCE) +set(CMAKE_OSX_DEPLOYMENT_TARGET "15.0" CACHE STRING "CMAKE_OSX_DEPLOYMENT_TARGET" FORCE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $(inherited) -x objective-c") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $(inherited) -x objective-c++") diff --git a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt index 7e32d566c9..9a6c4efa29 100644 --- a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt @@ -11,7 +11,7 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_DATADOG) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleDatadogApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.0.0") -ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.0.0") +ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.1.0") +ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.1.0") target_compile_options(${PROJECT_NAME} PRIVATE -fcxx-modules) diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt index a15ac30e43..2013bfec7d 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt @@ -17,6 +17,6 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseAnalyticsApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseAnalytics" "NO-GIT" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebaseAnalytics" "NO-GIT" "12.3.0") TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) diff --git a/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt index 6a9eca60ec..34e35b5754 100644 --- a/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt @@ -18,7 +18,7 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseCrashlyticsApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseCrashlytics" "NO-GIT" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebaseCrashlytics" "NO-GIT" "12.3.0") ADD_MENGINE_SCRIPT_PHASE("Run Firebase Crashlytics" "($){PODS_ROOT}/FirebaseCrashlytics/run" "['($){DWARF_DSYM_FOLDER_PATH}/($){DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/($){TARGET_NAME}', '$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)']") diff --git a/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt index 1877aef422..2af3d3fdc0 100644 --- a/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt @@ -9,7 +9,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseMessaging" "NO-GIT" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebaseMessaging" "NO-GIT" "12.3.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseMessagingApplicationDelegate") diff --git a/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt b/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt index 574f8b3d51..91f80ab662 100644 --- a/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt @@ -11,6 +11,6 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebasePerformanceMonitoringApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebasePerformance" "NO-GIT" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebasePerformance" "NO-GIT" "12.3.0") TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) diff --git a/src/Plugins/AppleFirebasePlugin/CMakeLists.txt b/src/Plugins/AppleFirebasePlugin/CMakeLists.txt index 30befd828c..077844104d 100644 --- a/src/Plugins/AppleFirebasePlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebasePlugin/CMakeLists.txt @@ -9,7 +9,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseCore" "NO-GIT" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebaseCore" "NO-GIT" "12.3.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseApplicationDelegate") diff --git a/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt index 355c87269b..64c5fb35cf 100644 --- a/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt @@ -35,7 +35,7 @@ ADD_DEFINITIONS(-DMENGINE_FIREBASE_REMOTECONFIG_PLIST_NAME="${MENGINE_APPLICATIO ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseRemoteConfig" "NO-GIT" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebaseRemoteConfig" "NO-GIT" "12.3.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseRemoteConfigApplicationDelegate") diff --git a/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm b/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm index 6ae1934aa4..36284cf168 100644 --- a/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm +++ b/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm @@ -283,7 +283,7 @@ - (BOOL)reportScore:(NSString *)identifier score:(int64_t)score response:(void(^ ); if (self.m_authenticateSuccess == NO) { - IOS_LOGGER_ERROR( @"invalid report score '%@' value: %lld" + IOS_LOGGER_ERROR( @"invalid report score '%@' value: %lld [not authenticated]" , identifier , score ); @@ -291,19 +291,28 @@ - (BOOL)reportScore:(NSString *)identifier score:(int64_t)score response:(void(^ return NO; } - GKScore * scoreReporter = [[GKScore alloc] initWithLeaderboardIdentifier:identifier]; - scoreReporter.value = score; - scoreReporter.context = 0; + if ([GKLocalPlayer localPlayer].isAuthenticated == NO) { + IOS_LOGGER_ERROR( @"invalid report score '%@' value: %lld [local player not authenticated]" + , identifier + , score + ); + + return NO; + } - NSArray * scores = @[scoreReporter]; - [GKScore reportScores:scores withCompletionHandler:^(NSError * error) { + GKPlayer * player = [GKLocalPlayer localPlayer]; + + [GKLeaderboard submitScore:score + context:0 + player:player + leaderboardIDs:@[identifier] + completionHandler:^(NSError * _Nullable error) { if (error != nil) { - IOS_LOGGER_ERROR( @"response score '%@' value: %lld error: %@" + IOS_LOGGER_ERROR(@"response score '%@' value: %lld error: %@" , identifier , score - , [AppleDetail getMessageFromNSError:error] - ); - + , [AppleDetail getMessageFromNSError:error]); + [AppleDetail dispatchMainQueue:^{ handler(error); }]; diff --git a/src/Plugins/AppleStoreReviewPlugin/AppleStoreReviewApplicationDelegate.mm b/src/Plugins/AppleStoreReviewPlugin/AppleStoreReviewApplicationDelegate.mm index 5c07a09c5e..bfa41c7e16 100644 --- a/src/Plugins/AppleStoreReviewPlugin/AppleStoreReviewApplicationDelegate.mm +++ b/src/Plugins/AppleStoreReviewPlugin/AppleStoreReviewApplicationDelegate.mm @@ -22,20 +22,16 @@ + (instancetype) sharedInstance { - (void)launchTheInAppReview { IOS_LOGGER_MESSAGE( @"launch the InAppReview" ); - if (@available(iOS 14.5, *)) { - UIWindowScene * foregroundScene = nil; - - for (UIWindowScene * scene in UIApplication.sharedApplication.connectedScenes) { - if (scene.activationState == UISceneActivationStateForegroundActive) { - foregroundScene = scene; - } - } - - if (foregroundScene != nil) { - [SKStoreReviewController requestReviewInScene:foregroundScene]; + UIWindowScene * foregroundScene = nil; + + for (UIWindowScene * scene in UIApplication.sharedApplication.connectedScenes) { + if (scene.activationState == UISceneActivationStateForegroundActive) { + foregroundScene = scene; } - } else if (@available(iOS 10.3, *)) { - [SKStoreReviewController requestReview]; + } + + if (foregroundScene != nil) { + [SKStoreReviewController requestReviewInScene:foregroundScene]; } } diff --git a/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp index 7e09cb0d5f..21840ca5f8 100644 --- a/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp +++ b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp @@ -37,15 +37,13 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool ZipMemoryInputStream::close() + void ZipMemoryInputStream::close() { m_stream = nullptr; #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif - - return true; } ////////////////////////////////////////////////////////////////////////// Pointer ZipMemoryInputStream::newBuffer( size_t _size ) @@ -113,4 +111,4 @@ namespace Mengine return m_stream->memory( _memory, _size ); } ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file +} diff --git a/src/Plugins/ZipPlugin/ZipMemoryInputStream.h b/src/Plugins/ZipPlugin/ZipMemoryInputStream.h index 698c9671ba..72144c9ccb 100644 --- a/src/Plugins/ZipPlugin/ZipMemoryInputStream.h +++ b/src/Plugins/ZipPlugin/ZipMemoryInputStream.h @@ -23,7 +23,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath ); - bool close(); + void close(); public: Pointer newBuffer( size_t _size ) override; @@ -54,4 +54,4 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr ZipMemoryInputStreamPtr; ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file +} diff --git a/src/Systems/AppleFileSystem/AppleFileGroupDirectory.h b/src/Systems/AppleFileSystem/AppleFileGroupDirectory.h index f9be4119b3..e05ff64fa8 100644 --- a/src/Systems/AppleFileSystem/AppleFileGroupDirectory.h +++ b/src/Systems/AppleFileSystem/AppleFileGroupDirectory.h @@ -42,17 +42,17 @@ namespace Mengine public: InputStreamInterfacePtr createInputFile( const FilePath & _filePath, bool _streaming, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool closeInputFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputFile( const InputStreamInterfacePtr & _stream ) override; public: InputStreamInterfacePtr createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, size_t _offset, size_t _size ) override; - bool closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; + void closeInputMutexFile( const InputStreamInterfacePtr & _stream ) override; public: OutputStreamInterfacePtr createOutputFile( const DocumentInterfacePtr & _doc ) override; bool openOutputFile( const FilePath & _filePath, const OutputStreamInterfacePtr & _stream, bool _withTemp ) override; - bool closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; + void closeOutputFile( const OutputStreamInterfacePtr & _stream ) override; public: bool isAvailableMappedFile() const override; @@ -60,7 +60,7 @@ namespace Mengine public: MappedInterfacePtr createMappedFile( const FilePath & _filePath, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) override; bool openMappedFile( const FilePath & _filePath, const MappedInterfacePtr & _stream, bool _shared ) override; - bool closeMappedFile( const MappedInterfacePtr & _stream ) override; + void closeMappedFile( const MappedInterfacePtr & _stream ) override; protected: FactoryInterfacePtr m_factoryInputStreamFile; diff --git a/src/Systems/AppleFileSystem/AppleFileGroupDirectory.mm b/src/Systems/AppleFileSystem/AppleFileGroupDirectory.mm index ea0a285f4b..61144ca37d 100644 --- a/src/Systems/AppleFileSystem/AppleFileGroupDirectory.mm +++ b/src/Systems/AppleFileSystem/AppleFileGroupDirectory.mm @@ -243,19 +243,13 @@ return result; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) + void AppleFileGroupDirectory::closeInputFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = _stream.getT(); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr AppleFileGroupDirectory::createInputMutexFile( const FilePath & _filePath, const InputStreamInterfacePtr & _stream, const ThreadMutexInterfacePtr & _mutex, FileGroupInterface ** const _fileGroup, const DocumentInterfacePtr & _doc ) @@ -303,19 +297,13 @@ return result; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) + void AppleFileGroupDirectory::closeInputMutexFile( const InputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileInputStreamInterface * file = _stream.getT(); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr AppleFileGroupDirectory::createOutputFile( const DocumentInterfacePtr & _doc ) @@ -343,19 +331,13 @@ return result; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) + void AppleFileGroupDirectory::closeOutputFile( const OutputStreamInterfacePtr & _stream ) { MENGINE_ASSERTION_MEMORY_PANIC( _stream, "failed _stream == nullptr" ); FileOutputStreamInterface * file = _stream.getT(); - bool result = file->close(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , m_folderPath.c_str() - ); - - return result; + file->close(); } ////////////////////////////////////////////////////////////////////////// bool AppleFileGroupDirectory::isAvailableMappedFile() const @@ -385,13 +367,11 @@ return false; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) + void AppleFileGroupDirectory::closeMappedFile( const MappedInterfacePtr & _stream ) { MENGINE_UNUSED( _stream ); MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Systems/AppleFileSystem/AppleFileInputStream.h b/src/Systems/AppleFileSystem/AppleFileInputStream.h index f0186d0af5..e1bd64c9df 100644 --- a/src/Systems/AppleFileSystem/AppleFileInputStream.h +++ b/src/Systems/AppleFileSystem/AppleFileInputStream.h @@ -26,7 +26,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _count ) override; diff --git a/src/Systems/AppleFileSystem/AppleFileInputStream.mm b/src/Systems/AppleFileSystem/AppleFileInputStream.mm index 1b7090ae0e..f7053a7f16 100644 --- a/src/Systems/AppleFileSystem/AppleFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileInputStream.mm @@ -39,12 +39,6 @@ { MENGINE_THREAD_GUARD_SCOPE( AppleFileInputStream, this ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_streaming = _streaming; m_share = _share; @@ -115,6 +109,10 @@ return false; } } + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif return true; } @@ -154,18 +152,18 @@ return true; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileInputStream::close() -{ + void AppleFileInputStream::close() + { if( m_fileHandle == nullptr ) { - return true; + return; } #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, true, m_streaming ); } @@ -178,13 +176,13 @@ , Helper::getDebugFullPath( this ).c_str() , [[AppleDetail getMessageFromNSError:error] UTF8String] ); - - return false; } - + m_fileHandle = nil; - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// size_t AppleFileInputStream::read( void * const _buf, size_t _count ) @@ -396,9 +394,9 @@ bool AppleFileInputStream::time( uint64_t * const _time ) const { #if defined(MENGINE_DEBUG) - const FilePath & relationPath = this->getDebugRelationPath(); - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & relationPath = Helper::getDebugRelationPath( this ); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); Path fullPath = {'\0'}; if( Helper::concatenateFilePath( {relationPath, folderPath, filePath}, fullPath ) == false ) diff --git a/src/Systems/AppleFileSystem/AppleFileMapped.h b/src/Systems/AppleFileSystem/AppleFileMapped.h index cb81320b46..69599b3f7b 100644 --- a/src/Systems/AppleFileSystem/AppleFileMapped.h +++ b/src/Systems/AppleFileSystem/AppleFileMapped.h @@ -19,7 +19,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _share ) override; - bool close() override; + void close() override; public: InputStreamInterfacePtr createInputStream( const DocumentInterfacePtr & _doc ) override; diff --git a/src/Systems/AppleFileSystem/AppleFileMapped.mm b/src/Systems/AppleFileSystem/AppleFileMapped.mm index 0e543649eb..50b0201965 100644 --- a/src/Systems/AppleFileSystem/AppleFileMapped.mm +++ b/src/Systems/AppleFileSystem/AppleFileMapped.mm @@ -28,11 +28,9 @@ return false; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileMapped::close() + void AppleFileMapped::close() { MENGINE_ASSERTION_NOT_IMPLEMENTED(); - - return false; } ////////////////////////////////////////////////////////////////////////// InputStreamInterfacePtr AppleFileMapped::createInputStream( const DocumentInterfacePtr & _doc ) diff --git a/src/Systems/AppleFileSystem/AppleFileOutputStream.h b/src/Systems/AppleFileSystem/AppleFileOutputStream.h index 5c432ce1b8..afb4eb3412 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.h +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.h @@ -21,7 +21,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) override; - bool close() override; + void close() override; public: size_t write( const void * _data, size_t _size ) override; diff --git a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm index eefc76cfa8..ec3a76a293 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm @@ -97,7 +97,7 @@ return true; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileOutputStream::close() + void AppleFileOutputStream::close() { if( m_fileHandle == nullptr ) { @@ -108,8 +108,6 @@ m_fileHandle = nil; m_size = 0; - - return true; } ////////////////////////////////////////////////////////////////////////// size_t AppleFileOutputStream::write( const void * _data, size_t _size ) diff --git a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h index f8b7882910..8ca1a1a71f 100644 --- a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h +++ b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h @@ -25,7 +25,7 @@ namespace Mengine public: bool open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) override; - bool close() override; + void close() override; public: size_t read( void * const _buf, size_t _size ) override; diff --git a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm index 4115738dd9..2b0c078d54 100644 --- a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm @@ -46,12 +46,6 @@ MENGINE_UNUSED( _streaming ); MENGINE_UNUSED( _share ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - size_t size = m_stream->size(); if( _size != ~0U ) @@ -84,16 +78,22 @@ m_carriage = 0; m_capacity = 0; m_reading = 0; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif return true; } ////////////////////////////////////////////////////////////////////////// - bool AppleMutexFileInputStream::close() + void AppleMutexFileInputStream::close() { m_stream = nullptr; m_mutex = nullptr; - - return true; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// size_t AppleMutexFileInputStream::read( void * const _buf, size_t _count ) @@ -301,9 +301,9 @@ bool AppleMutexFileInputStream::time( uint64_t * const _time ) const { #if defined(MENGINE_DEBUG) - const FilePath & relationPath = this->getDebugRelationPath(); - const FilePath & folderPath = this->getDebugFolderPath(); - const FilePath & filePath = this->getDebugFilePath(); + const FilePath & relationPath = Helper::getDebugRelationPath( this ); + const FilePath & folderPath = Helper::getDebugFolderPath( this ); + const FilePath & filePath = Helper::getDebugFilePath( this ); Path fullPath = {'\0'}; if( Helper::concatenateFilePath( {relationPath, folderPath, filePath}, fullPath ) == false ) From 9f48fb7660243d5b7b1b86f4ee9be7375bc6be02 Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 21 Sep 2025 01:38:22 +0300 Subject: [PATCH 053/169] ref-in android AdService isShowingInterstitial&isShowingRewarded --- .../Base/MengineAdProviderInterface.java | 3 +- .../org/Mengine/Base/MengineAdService.java | 45 +++++++++---------- ...engineAppLovinInterstitialAdInterface.java | 2 +- .../MengineAppLovinRewardedAdInterface.java | 2 +- .../MengineAppLovinInterstitialAd.java | 13 +++++- .../RewardedAd/MengineAppLovinRewardedAd.java | 13 +++++- .../AppLovin/MengineAppLovinPlugin.java | 18 ++++++++ 7 files changed, 66 insertions(+), 30 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdProviderInterface.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdProviderInterface.java index ffa52f5ab6..2df8f475f7 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdProviderInterface.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdProviderInterface.java @@ -14,13 +14,14 @@ public interface MengineAdProviderInterface { boolean canYouShowInterstitial(String placement); boolean showInterstitial(String placement); + boolean isShowingInterstitial(); boolean hasRewarded(); boolean canOfferRewarded(String placement); boolean canYouShowRewarded(String placement); - boolean showRewarded(String placement); + boolean isShowingRewarded(); boolean hasAppOpen(); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java index d9a67bbb16..fc11b511b8 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java @@ -42,9 +42,6 @@ public class MengineAdService extends MengineService implements DefaultLifecycle protected long m_countShowRewarded = 0; protected long m_countShowAppOpen = 0; - protected boolean m_adInterstitialShowing = false; - protected boolean m_adRewardedShowing = false; - protected boolean m_optionNoAds = false; protected boolean m_noAds = false; @@ -339,22 +336,6 @@ public boolean getNoAds() { return false; } - public void setInterstitialAdShowing(boolean showing) { - m_adInterstitialShowing = showing; - } - - public boolean isInterstitialAdShowing() { - return m_adInterstitialShowing; - } - - public void setRewardedAdShowing(boolean showing) { - m_adRewardedShowing = showing; - } - - public boolean isRewardedAdShowing() { - return m_adRewardedShowing; - } - @Override public boolean hasBanner() { if (m_adProvider == null) { @@ -508,13 +489,25 @@ public boolean showInterstitial(String placement) { m_lastShowInterstitial = MengineUtils.getTimestamp(); m_countShowInterstitial += 1; - this.setInterstitialAdShowing(true); - adPoint.showAd(); return true; } + public boolean isShowingInterstitial() { + boolean noAds = this.getNoAds(); + + if (noAds == true) { + return false; + } + + if (m_adProvider.isShowingInterstitial() == false) { + return false; + } + + return true; + } + @Override public boolean hasRewarded() { if (m_adProvider == null) { @@ -603,13 +596,19 @@ public boolean showRewarded(String placement) { m_lastShowRewarded = MengineUtils.getTimestamp(); m_countShowRewarded += 1; - this.setRewardedAdShowing(true); - adPoint.showAd(); return true; } + public boolean isShowingRewarded() { + if (m_adProvider.isShowingRewarded() == false) { + return false; + } + + return true; + } + @Override public boolean hasAppOpen() { if (m_adProvider == null) { diff --git a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinInterstitialAdInterface.java b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinInterstitialAdInterface.java index e308196c9f..4084976ec6 100644 --- a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinInterstitialAdInterface.java +++ b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinInterstitialAdInterface.java @@ -6,6 +6,6 @@ public interface MengineAppLovinInterstitialAdInterface extends MengineAppLovinAdInterface { boolean canYouShowInterstitial(String placement); - boolean showInterstitial(@NonNull MengineActivity activity, String placement); + boolean isShowingInterstitial(); } diff --git a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinRewardedAdInterface.java b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinRewardedAdInterface.java index e3711c1523..861ac38a54 100644 --- a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinRewardedAdInterface.java +++ b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinRewardedAdInterface.java @@ -7,6 +7,6 @@ public interface MengineAppLovinRewardedAdInterface extends MengineAppLovinAdInterface { boolean canOfferRewarded(String placement); boolean canYouShowRewarded(String placement); - boolean showRewarded(@NonNull MengineActivity activity, String placement); + boolean isShowingRewarded(); } diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index 12a8974764..eb857f172e 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -34,6 +34,8 @@ public class MengineAppLovinInterstitialAd extends MengineAppLovinBase implement private MaxInterstitialAd m_interstitialAd; + private boolean m_showing = false; + public MengineAppLovinInterstitialAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.INTERSTITIAL); @@ -179,11 +181,18 @@ public boolean showInterstitial(@NonNull MengineActivity activity, String placem return false; } + m_showing = true; + m_interstitialAd.showAd(placement, activity); return true; } + @Override + public boolean isShowingInterstitial() { + return m_showing; + } + @Override public void onAdRequestStarted(@NonNull String adUnitId) { this.log("onAdRequestStarted"); @@ -234,7 +243,7 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setInterstitialState("hidden." + placement + "." + ad.getNetworkName()); - m_adService.setInterstitialAdShowing(false); + m_showing = false; MengineUtils.performOnMainThread(() -> { MengineAdResponseInterface adResponse = m_adService.getAdResponse(); @@ -292,7 +301,7 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setInterstitialState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); - m_adService.setInterstitialAdShowing(false); + m_showing = false; MengineUtils.performOnMainThread(() -> { MengineAdResponseInterface adResponse = m_adService.getAdResponse(); diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index 59c1838729..a17b4454f4 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -36,6 +36,8 @@ public class MengineAppLovinRewardedAd extends MengineAppLovinBase implements Me private MaxRewardedAd m_rewardedAd; + private boolean m_showing = false; + public MengineAppLovinRewardedAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.REWARDED); @@ -203,11 +205,18 @@ public boolean showRewarded(@NonNull MengineActivity activity, String placement) return false; } + m_showing = true; + m_rewardedAd.showAd(placement, activity); return true; } + @Override + public boolean isShowingRewarded() { + return m_showing; + } + @Override public void onAdRequestStarted(@NonNull String adUnitId) { this.log("onAdRequestStarted"); @@ -279,7 +288,7 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setRewardedState("hidden." + placement + "." + ad.getNetworkName()); - m_adService.setRewardedAdShowing(false); + m_showing = false; MengineUtils.performOnMainThread(() -> { MengineAdResponseInterface adResponse = m_adService.getAdResponse(); @@ -337,7 +346,7 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setRewardedState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); - m_adService.setRewardedAdShowing(false); + m_showing = false; MengineUtils.performOnMainThread(() -> { MengineAdResponseInterface adResponse = m_adService.getAdResponse(); diff --git a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java index a1dacffda8..8d6d0215cb 100644 --- a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java +++ b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java @@ -552,6 +552,15 @@ public boolean showInterstitial(String placement) { return true; } + @Override + public boolean isShowingInterstitial() { + if (m_interstitialAd == null) { + return false; + } + + return m_interstitialAd.isShowingInterstitial(); + } + @Override public boolean hasRewarded() { if (m_rewardedAd == null) { @@ -616,6 +625,15 @@ public boolean showRewarded(String placement) { return true; } + @Override + public boolean isShowingRewarded() { + if (m_rewardedAd == null) { + return false; + } + + return m_rewardedAd.isShowingRewarded(); + } + @Override public boolean hasAppOpen() { if (m_appOpenAd == null) { From 0ac83a6e1d9cf3e226134c4d55854714b437e6ab Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 21 Sep 2025 01:52:13 +0300 Subject: [PATCH 054/169] wip ios advertisement isShowingInterstitial&isShowingRewarded --- .../AppleAdvertisementApplicationDelegate.mm | 32 ++++++- .../AppleAdvertisementInterface.h | 5 + .../AppleAdvertisementScriptEmbedding.mm | 20 ++++ .../AppleAppLovinApplicationDelegate.mm | 93 +++++++++++++------ .../AppleAppLovinBannerDelegate.h | 5 +- .../AppleAppLovinBannerDelegate.mm | 9 +- .../AppleAppLovinBaseDelegate.h | 6 +- .../AppleAppLovinBaseDelegate.mm | 3 +- .../AppleAppLovinInterstitialDelegate.h | 5 +- .../AppleAppLovinInterstitialDelegate.mm | 16 +++- .../AppleAppLovinRewardedDelegate.h | 5 +- .../AppleAppLovinRewardedDelegate.mm | 18 +++- 12 files changed, 171 insertions(+), 46 deletions(-) diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm index 71f40936e3..0ac1c9807a 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm @@ -235,12 +235,30 @@ - (BOOL)showInterstitial:(NSString *)placement { self.m_lastShowInterstitial = [AppleDetail getTimestamp]; self.m_countShowInterstitial += 1; - + [adPoint showAd]; return YES; } +- (BOOL)isShowingInterstitial { + if (self.m_provider == nil) { + return NO; + } + + BOOL noAds = [self getNoAds]; + + if (noAds == YES) { + return NO; + } + + if ([self.m_provider isShowingInterstitial] == NO) { + return NO; + } + + return YES; +} + - (BOOL)hasRewarded { if (self.m_provider == nil) { return NO; @@ -326,6 +344,18 @@ - (BOOL)showRewarded:(NSString *)placement { return YES; } +- (BOOL)isShowingRewarded { + if (self.m_provider == nil) { + return NO; + } + + if ([self.m_provider isShowingRewarded] == NO) { + return NO; + } + + return YES; +} + #pragma mark - iOSPluginConfigDelegateInterface - (AppleAdvertisementInterstitialPoint *)getAdInterstitialPoint:(NSString *)placement { diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h index 096541535a..2a6d3d6afb 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h @@ -19,11 +19,13 @@ - (BOOL)hasInterstitial; - (BOOL)canYouShowInterstitial:(NSString *)placement; - (BOOL)showInterstitial:(NSString *)placement; +- (BOOL)isShowingInterstitial; - (BOOL)hasRewarded; - (BOOL)canOfferRewarded:(NSString *)placement; - (BOOL)canYouShowRewarded:(NSString *)placement; - (BOOL)showRewarded:(NSString *)placement; +- (BOOL)isShowingRewarded; @end @protocol AppleAdvertisementInterface @@ -34,6 +36,9 @@ - (void)readyAdProvider; +- (BOOL)isShowingInterstitial; +- (BOOL)isShowingRewarded; + - (void)setBannerCallback:(id)callback; - (id)getBannerCallback; diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementScriptEmbedding.mm b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementScriptEmbedding.mm index 168268e700..58e1ef656c 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementScriptEmbedding.mm +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementScriptEmbedding.mm @@ -282,6 +282,14 @@ static bool appleAdvertisement_showInterstitial( NSString * _placement ) { return true; } ////////////////////////////////////////////////////////////////////////// + static bool appleAdvertisement_isShowingInterstitial() { + if ([[AppleAdvertisementApplicationDelegate sharedInstance] isShowingInterstitial] == NO) { + return false; + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// static bool appleAdvertisement_hasRewarded() { if ([[AppleAdvertisementApplicationDelegate sharedInstance] hasRewarded] == NO) { return false; @@ -314,6 +322,14 @@ static bool appleAdvertisement_showRewarded( NSString * _placement ) { return true; } ////////////////////////////////////////////////////////////////////////// + static bool appleAdvertisement_isShowingRewarded() { + if ([[AppleAdvertisementApplicationDelegate sharedInstance] isShowingRewarded] == NO) { + return false; + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// } ////////////////////////////////////////////////////////////////////////// AppleAdvertisementScriptEmbedding::AppleAdvertisementScriptEmbedding() @@ -339,11 +355,13 @@ static bool appleAdvertisement_showRewarded( NSString * _placement ) { pybind::def_function( _kernel, "appleAdvertisementHasInterstitial", &Detail::appleAdvertisement_hasInterstitial ); pybind::def_function( _kernel, "appleAdvertisementCanYouShowInterstitial", &Detail::appleAdvertisement_canYouShowInterstitial ); pybind::def_function( _kernel, "appleAdvertisementShowInterstitial", &Detail::appleAdvertisement_showInterstitial ); + pybind::def_function( _kernel, "appleAdvertisementIsShowingInterstitial", &Detail::appleAdvertisement_isShowingInterstitial ); pybind::def_function( _kernel, "appleAdvertisementHasRewarded", &Detail::appleAdvertisement_hasRewarded ); pybind::def_function( _kernel, "appleAdvertisementCanOfferRewarded", &Detail::appleAdvertisement_canOfferRewarded ); pybind::def_function( _kernel, "appleAdvertisementCanYouShowRewarded", &Detail::appleAdvertisement_canYouShowRewarded ); pybind::def_function( _kernel, "appleAdvertisementShowRewarded", &Detail::appleAdvertisement_showRewarded ); + pybind::def_function( _kernel, "appleAdvertisementIsShowingRewarded", &Detail::appleAdvertisement_isShowingRewarded ); return true; } @@ -359,9 +377,11 @@ static bool appleAdvertisement_showRewarded( NSString * _placement ) { _kernel->remove_from_module( "appleAdvertisementGetBannerHeight", nullptr ); _kernel->remove_from_module( "appleAdvertisementCanYouShowInterstitial", nullptr ); _kernel->remove_from_module( "appleAdvertisementShowInterstitial", nullptr ); + _kernel->remove_from_module( "appleAdvertisementIsShowingInterstitial", nullptr ); _kernel->remove_from_module( "appleAdvertisementCanOfferRewarded", nullptr ); _kernel->remove_from_module( "appleAdvertisementCanYouShowRewarded", nullptr ); _kernel->remove_from_module( "appleAdvertisementShowRewarded", nullptr ); + _kernel->remove_from_module( "appleAdvertisementIsShowingRewarded", nullptr ); } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm index 317c2f7ade..0697adbf83 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm @@ -154,37 +154,23 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( IOS_LOGGER_MESSAGE(@"AppLovin: %@ [%lu]", ALSdk.version, ALSdk.versionCode); - NSString * MengineAppleAppLovinPlugin_CCPA = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"CCPA" withDefault:@"UNKNOWN"]; - - if ([MengineAppleAppLovinPlugin_CCPA caseInsensitiveCompare:@"YES"] == NSOrderedSame) { - [ALPrivacySettings setDoNotSell: YES]; - } else if ([MengineAppleAppLovinPlugin_CCPA caseInsensitiveCompare:@"NO"] == NSOrderedSame) { - [ALPrivacySettings setDoNotSell: NO]; - } else if ([MengineAppleAppLovinPlugin_CCPA caseInsensitiveCompare:@"UNKNOWN"] == NSOrderedSame) { - //Nothing - } else { - IOS_LOGGER_ERROR(@"[ERROR] AppLovin plugin invalid config [%@.CCPA] value %@ [YES|NO|UNKNOWN]", @PLUGIN_BUNDLE_NAME, MengineAppleAppLovinPlugin_CCPA); - - return NO; - } - - NSString * MengineAppleAppLovinPlugin_SdkKey = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"SdkKey" withDefault:nil]; - - if (MengineAppleAppLovinPlugin_SdkKey == nil) { - IOS_LOGGER_ERROR(@"[ERROR] AppLovin plugin missed required config [%@.SdkKey]", @PLUGIN_BUNDLE_NAME); - - return NO; - } - ALSdkSettings * settings = [ALSdk shared].settings; - BOOL MengineAppleAppLovinPlugin_Verbose = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"Verbose" withDefault:NO]; + BOOL MengineAppleAppLovinPlugin_VerboseLoggingEnabled = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"VerboseLoggingEnabled" withDefault:NO]; - if (MengineAppleAppLovinPlugin_Verbose == YES) { + if (MengineAppleAppLovinPlugin_VerboseLoggingEnabled == YES) { settings.verboseLoggingEnabled = YES; } else { settings.verboseLoggingEnabled = NO; } + + BOOL MengineAppleAppLovinPlugin_CreativeDebuggerEnabled = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"CreativeDebuggerEnabled" withDefault:NO]; + + if (MengineAppleAppLovinPlugin_CreativeDebuggerEnabled == YES) { + settings.creativeDebuggerEnabled = YES; + } else { + settings.creativeDebuggerEnabled = NO; + } NSString * userId = [iOSApplication.sharedInstance getUserId]; @@ -211,10 +197,25 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( settings.termsAndPrivacyPolicyFlowSettings.enabled = YES; settings.termsAndPrivacyPolicyFlowSettings.privacyPolicyURL = [NSURL URLWithString:MengineAppleAppLovinPlugin_PrivacyPolicyURL]; settings.termsAndPrivacyPolicyFlowSettings.termsOfServiceURL = [NSURL URLWithString:MengineAppleAppLovinPlugin_TermsOfServiceURL]; + settings.termsAndPrivacyPolicyFlowSettings.showTermsAndPrivacyPolicyAlertInGDPR = NO; } else { settings.termsAndPrivacyPolicyFlowSettings.enabled = NO; } + NSString * MengineAppleAppLovinPlugin_PrivacyDoNoSell = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"PrivacyDoNoSell" withDefault:@"UNKNOWN"]; + + if ([MengineAppleAppLovinPlugin_PrivacyDoNoSell caseInsensitiveCompare:@"YES"] == NSOrderedSame) { + [ALPrivacySettings setDoNotSell: YES]; + } else if ([MengineAppleAppLovinPlugin_PrivacyDoNoSell caseInsensitiveCompare:@"NO"] == NSOrderedSame) { + [ALPrivacySettings setDoNotSell: NO]; + } else if ([MengineAppleAppLovinPlugin_PrivacyDoNoSell caseInsensitiveCompare:@"UNKNOWN"] == NSOrderedSame) { + //Nothing + } else { + IOS_LOGGER_ERROR(@"[ERROR] AppLovin plugin invalid config [%@.PrivacyDoNoSell] value %@ [YES|NO|UNKNOWN]", @PLUGIN_BUNDLE_NAME, MengineAppleAppLovinPlugin_PrivacyDoNoSell); + + return NO; + } + id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; [advertisement setProvider:self]; @@ -245,12 +246,22 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( } #endif + NSString * MengineAppleAppLovinPlugin_SdkKey = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"SdkKey" withDefault:nil]; + + if (MengineAppleAppLovinPlugin_SdkKey == nil) { + IOS_LOGGER_ERROR(@"[ERROR] AppLovin plugin missed required config [%@.SdkKey]", @PLUGIN_BUNDLE_NAME); + + return NO; + } + ALSdkInitializationConfiguration * initializationConfiguration = [ALSdkInitializationConfiguration configurationWithSdkKey:MengineAppleAppLovinPlugin_SdkKey builderBlock:^(ALSdkInitializationConfigurationBuilder * _Nonnull builder) { builder.pluginVersion = [@"Mengine-v" stringByAppendingString:@MENGINE_ENGINE_VERSION_STRING]; builder.mediationProvider = ALMediationProviderMAX; builder.adUnitIdentifiers = adUnitIdentifiers; #if defined(MENGINE_DEBUG) - builder.testDeviceAdvertisingIdentifiers = @[[ASIdentifierManager sharedManager].advertisingIdentifier.UUIDString]; + if ([AppleDetail hasOption:@"applovin.test_device_advertising"] == YES) { + builder.testDeviceAdvertisingIdentifiers = @[[ASIdentifierManager sharedManager].advertisingIdentifier.UUIDString]; + } #endif }]; @@ -294,7 +305,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( BOOL MengineAppleAppLovinPlugin_BannerAdaptive = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdaptive" withDefault:YES]; - AppleAppLovinBannerDelegate * bannerAd = [[AppleAppLovinBannerDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_BannerAdUnitId placement:MengineAppleAppLovinPlugin_BannerPlacement adaptive:MengineAppleAppLovinPlugin_BannerAdaptive]; + AppleAppLovinBannerDelegate * bannerAd = [[AppleAppLovinBannerDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_BannerAdUnitId advertisement:advertisement placement:MengineAppleAppLovinPlugin_BannerPlacement adaptive:MengineAppleAppLovinPlugin_BannerAdaptive]; self.m_bannerAd = bannerAd; } @@ -302,7 +313,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_INTERSTITIAL) if (MengineAppleAppLovinPlugin_InterstitialAdUnitId != nil) { - AppleAppLovinInterstitialDelegate * interstitialAd = [[AppleAppLovinInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_InterstitialAdUnitId]; + AppleAppLovinInterstitialDelegate * interstitialAd = [[AppleAppLovinInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_InterstitialAdUnitId advertisement:advertisement]; self.m_interstitialAd = interstitialAd; } @@ -310,7 +321,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_REWARDED) if (MengineAppleAppLovinPlugin_RewardedAdUnitId != nil) { - AppleAppLovinRewardedDelegate * rewardedAd = [[AppleAppLovinRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_RewardedAdUnitId]; + AppleAppLovinRewardedDelegate * rewardedAd = [[AppleAppLovinRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_RewardedAdUnitId advertisement:advertisement]; self.m_rewardedAd = rewardedAd; } @@ -407,6 +418,18 @@ - (BOOL)showInterstitial:(NSString *)placement { return YES; } +- (BOOL)isShowingInterstitial { + if (self.m_interstitialAd == nil) { + return NO; + } + + if ([self.m_interstitialAd isShowing] == NO) { + return NO; + } + + return YES; +} + - (BOOL)hasRewarded { if (self.m_rewardedAd == nil) { return NO; @@ -463,4 +486,18 @@ - (BOOL)showRewarded:(NSString *)placement { return YES; } +- (BOOL)isShowingRewarded { + if (self.m_rewardedAd == nil) { + return NO; + } + + if ([self.m_rewardedAd isShowing] == NO) { + return NO; + } + + return YES; +} + + + @end diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.h b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.h index c6e3647104..4bcf00ec60 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.h +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.h @@ -15,8 +15,9 @@ @interface AppleAppLovinBannerDelegate : AppleAppLovinBaseDelegate - (instancetype _Nullable)initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId - placement:(NSString * _Nonnull) placement - adaptive:(BOOL) adaptive; + advertisement:(id _Nonnull)advertisement + placement:(NSString * _Nonnull) placement + adaptive:(BOOL) adaptive; - (void)show; - (void)hide; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.mm index f921f4166d..9bfd98399c 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBannerDelegate.mm @@ -11,10 +11,11 @@ @implementation AppleAppLovinBannerDelegate -- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId - placement:(NSString * _Nonnull) placement - adaptive:(BOOL) adaptive { - self = [super initWithAdUnitIdentifier:adUnitId adFormat:MAAdFormat.banner]; +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId + advertisement:(id _Nonnull)advertisement + placement:(NSString * _Nonnull)placement + adaptive:(BOOL)adaptive { + self = [super initWithAdUnitIdentifier:adUnitId adFormat:MAAdFormat.banner advertisement:advertisement]; self.m_bannerAdaptive = adaptive; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.h b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.h index cfef70c8ea..944c9930e9 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.h +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.h @@ -4,12 +4,15 @@ #import "Environment/Apple/AppleIncluder.h" +#import "Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h" + #import @interface AppleAppLovinBaseDelegate : NSObject - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId - adFormat:(MAAdFormat * _Nonnull) adFormat; + adFormat:(MAAdFormat * _Nonnull) adFormat + advertisement:(id _Nonnull)advertisement; - (void) loadAd; - (void) retryLoadAd; @@ -31,6 +34,7 @@ - (void) eventRevenue:(MAAd * _Nonnull) ad; @property (nonatomic, strong) NSString * _Nonnull m_adUnitId; +@property (nonatomic, strong) id _Nonnull m_advertisement; @property (nonatomic, strong) MAAdFormat * _Nonnull m_adFormat; @property (nonatomic, assign) NSInteger m_enumeratorRequest; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm index 6c0f49e680..44cd3a3ffa 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm @@ -9,7 +9,8 @@ @implementation AppleAppLovinBaseDelegate - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId - adFormat:(MAAdFormat * _Nonnull) adFormat { + adFormat:(MAAdFormat * _Nonnull) adFormat + advertisement:(id _Nonnull)advertisement{ self = [super init]; self.m_adUnitId = adUnitId; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.h b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.h index a8b3da87ca..dc1a5ed324 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.h +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.h @@ -14,15 +14,18 @@ @interface AppleAppLovinInterstitialDelegate : AppleAppLovinBaseDelegate -- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId; +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId advertisement:(id _Nonnull)advertisement; - (BOOL) canYouShow:(NSString * _Nonnull) placement; - (BOOL) show:(NSString * _Nonnull) placement; +- (BOOL) isShowing; - (void) loadAd; @property (nonatomic, strong) MAInterstitialAd * _Nullable m_interstitialAd; +@property (atomic, assign) BOOL m_showing; + #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_MEDIATION_AMAZON) @property (nonatomic, strong) AppleAppLovinInterstitialAmazonLoader * _Nullable m_amazonLoader; #endif diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm index 9f37e13c1a..755628f109 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm @@ -11,8 +11,8 @@ @implementation AppleAppLovinInterstitialDelegate -- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId { - self = [super initWithAdUnitIdentifier:adUnitId adFormat:MAAdFormat.interstitial]; +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId advertisement:(id _Nonnull)advertisement { + self = [super initWithAdUnitIdentifier:adUnitId adFormat:MAAdFormat.interstitial advertisement:advertisement]; MAInterstitialAd * interstitialAd; @@ -36,6 +36,8 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI self.m_interstitialAd = interstitialAd; + self.m_showing = NO; + #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_MEDIATION_AMAZON) self.m_amazonLoader = [[AppleAppLovinInterstitialAmazonLoader alloc] initWithSlotId:amazonSlotId interstitialAd:self.m_interstitialAd]; #else @@ -107,11 +109,17 @@ - (BOOL) show:(NSString * _Nonnull)placement { return NO; } + self.m_showing = YES; + [self.m_interstitialAd showAdForPlacement:placement]; return YES; } +- (BOOL) isShowing { + return self.m_showing; +} + - (void) loadAd { if( self.m_interstitialAd == nil ) { return; @@ -183,6 +191,8 @@ - (void) didHideAd:(MAAd *)ad { @"ad": [self getMAAdParams:ad] }]; + self.m_showing = NO; + id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; if (callback != nil) { @@ -202,6 +212,8 @@ - (void) didFailToDisplayAd:(MAAd *)ad withError:(MAError *)error { @"ad": [self getMAAdParams:ad] }]; + self.m_showing = NO; + id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; if (callback != nil) { diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.h b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.h index 00d5d587b6..48c6afbdb8 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.h +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.h @@ -14,16 +14,19 @@ @interface AppleAppLovinRewardedDelegate : AppleAppLovinBaseDelegate -- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId; +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId advertisement:(id _Nonnull)advertisement; - (BOOL) canOffer:(NSString * _Nonnull)placement; - (BOOL) canYouShow:(NSString * _Nonnull)placement; - (BOOL) show:(NSString * _Nonnull)placement; +- (BOOL) isShowing; - (void) loadAd; @property (nonatomic, strong) MARewardedAd * _Nullable m_rewardedAd; +@property (atomic, assign) BOOL m_showing; + #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_MEDIATION_AMAZON) @property (nonatomic, strong) AppleAppLovinRewardedAmazonLoader * _Nullable m_amazonLoader; #endif diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm index e9ca7bfe8e..b48fdf7f90 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm @@ -10,8 +10,8 @@ @implementation AppleAppLovinRewardedDelegate -- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId { - self = [super initWithAdUnitIdentifier:adUnitId adFormat:MAAdFormat.rewarded]; +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId advertisement:(id _Nonnull)advertisement { + self = [super initWithAdUnitIdentifier:adUnitId adFormat:MAAdFormat.rewarded advertisement:advertisement]; MARewardedAd * rewardedAd; @@ -35,9 +35,7 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI self.m_rewardedAd = rewardedAd; - self.m_requestAttempt = 0; - self.m_enumeratorRequest = 0; - self.m_requestId = 0; + self.m_showing = NO; #if defined(MENGINE_PLUGIN_APPLE_APPLOVIN_MEDIATION_AMAZON) self.m_amazonLoader = [[AppleAppLovinRewardedAmazonLoader alloc] initWithSlotId:amazonSlotId rewardedAd:self.m_rewardedAd]; @@ -127,11 +125,17 @@ - (BOOL) show:(NSString * _Nonnull)placement { return NO; } + self.m_showing = YES; + [self.m_rewardedAd showAdForPlacement:placement]; return YES; } +- (BOOL) isShowing { + return self.m_showing; +} + - (void) loadAd { if (self.m_rewardedAd == nil) { return; @@ -203,6 +207,8 @@ - (void) didHideAd:(MAAd *)ad { @"placement": ad.placement, @"ad": [self getMAAdParams:ad] }]; + + self.m_showing = NO; id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; @@ -222,6 +228,8 @@ - (void) didFailToDisplayAd:(MAAd *)ad withError:(MAError *)error { @"error_code": @(error.code), @"ad": [self getMAAdParams:ad] }]; + + self.m_showing = NO; id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; From e3cd4ff71c3813225a11cd8e025f0281a7dd9c0e Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 21 Sep 2025 17:37:32 +0300 Subject: [PATCH 055/169] add freezePlatform&unfreezePlatform --- .../java/org/Mengine/Base/MengineNative.java | 2 + .../MengineAppLovinInterstitialAd.java | 5 + .../RewardedAd/MengineAppLovinRewardedAd.java | 5 + ...AndroidPlatformServiceExtensionInterface.h | 2 + src/Interface/PlatformServiceInterface.h | 3 + .../AndroidPlatformService.cpp | 117 +++++++++++++++++- .../AndroidPlatform/AndroidPlatformService.h | 25 ++++ .../Win32Platform/Win32PlatformService.cpp | 34 ++++- .../Win32Platform/Win32PlatformService.h | 4 + 9 files changed, 191 insertions(+), 6 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java index b94ff5c7a3..a1331b7531 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java @@ -43,6 +43,8 @@ public class MengineNative { public static native void AndroidPlatform_startEvent(); public static native void AndroidPlatform_restartEvent(); public static native void AndroidPlatform_destroyEvent(); + public static native void AndroidPlatform_freezeEvent( boolean tick, boolean render ); + public static native void AndroidPlatform_unfreezeEvent( boolean tick, boolean render ); public static native void AndroidPlatform_clipboardChangedEvent(); public static native void AndroidPlatform_windowFocusChangedEvent(boolean focus); public static native void AndroidPlatform_quitEvent(); diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index eb857f172e..039eee3fef 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -20,6 +20,7 @@ import org.Mengine.Base.MengineAdResponseInterface; import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineNative; import org.Mengine.Base.MengineNetwork; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineUtils; @@ -228,6 +229,8 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setInterstitialState("displayed." + placement + "." + ad.getNetworkName()); + + MengineNative.AndroidPlatform_freezeEvent( true, true ); } @Override @@ -243,6 +246,8 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setInterstitialState("hidden." + placement + "." + ad.getNetworkName()); + MengineNative.AndroidPlatform_unfreezeEvent( false, false ); + m_showing = false; MengineUtils.performOnMainThread(() -> { diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index a17b4454f4..9c2a3b3a9d 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -21,6 +21,7 @@ import org.Mengine.Base.MengineAdResponseInterface; import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineNative; import org.Mengine.Base.MengineNetwork; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineUtils; @@ -273,6 +274,8 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setRewardedState("displayed." + placement + "." + ad.getNetworkName()); + + MengineNative.AndroidPlatform_freezeEvent( true, true ); } @Override @@ -288,6 +291,8 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setRewardedState("hidden." + placement + "." + ad.getNetworkName()); + MengineNative.AndroidPlatform_unfreezeEvent( false, false ); + m_showing = false; MengineUtils.performOnMainThread(() -> { diff --git a/src/Environment/Android/AndroidPlatformServiceExtensionInterface.h b/src/Environment/Android/AndroidPlatformServiceExtensionInterface.h index 5ad908d2d5..8b670628b3 100644 --- a/src/Environment/Android/AndroidPlatformServiceExtensionInterface.h +++ b/src/Environment/Android/AndroidPlatformServiceExtensionInterface.h @@ -28,6 +28,8 @@ namespace Mengine virtual void androidNativeStartEvent() = 0; virtual void androidNativeRestartEvent() = 0; virtual void androidNativeDestroyEvent() = 0; + virtual void androidNativeFreezeEvent( bool _tick, bool _render ) = 0; + virtual void androidNativeUnfreezeEvent( bool _tick, bool _render ) = 0; virtual void androidNativeClipboardChangedEvent() = 0; virtual void androidNativeWindowFocusChangedEvent( jboolean _focus ) = 0; diff --git a/src/Interface/PlatformServiceInterface.h b/src/Interface/PlatformServiceInterface.h index 233fb7e5ed..c5923b6b43 100644 --- a/src/Interface/PlatformServiceInterface.h +++ b/src/Interface/PlatformServiceInterface.h @@ -42,6 +42,9 @@ namespace Mengine virtual bool updatePlatform() = 0; virtual void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) = 0; virtual void stopPlatform() = 0; + virtual void freezePlatform( bool _tick, bool _render ) = 0; + virtual void unfreezePlatform( bool _tick, bool _render ) = 0; + public: virtual void setSleepMode( bool _sleepMode ) = 0; diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index ed055823c8..7f789969ce 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -86,7 +86,7 @@ extern "C" { ////////////////////////////////////////////////////////////////////////// - static volatile bool g_androidPlatformActived = true; + static volatile bool g_androidPlatformActived = false; ////////////////////////////////////////////////////////////////////////// static bool AndroidWriteMemory( JNIEnv * env, const Mengine::MemoryInterfacePtr & _memory, jobject _writer ) { @@ -431,6 +431,32 @@ extern "C" platformExtension->androidNativeDestroyEvent(); } /////////////////////////////////////////////////////////////////////// + JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidPlatform_1freezeEvent )(JNIEnv * env, jclass cls, jboolean tick, jboolean render) + { + if( g_androidPlatformActived == false ) + { + return; + } + + Mengine::AndroidPlatformServiceExtensionInterface * platformExtension = PLATFORM_SERVICE() + ->getUnknown(); + + platformExtension->androidNativeFreezeEvent( tick, render ); + } + /////////////////////////////////////////////////////////////////////// + JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidPlatform_1unfreezeEvent )(JNIEnv * env, jclass cls, jboolean tick, jboolean render) + { + if( g_androidPlatformActived == false ) + { + return; + } + + Mengine::AndroidPlatformServiceExtensionInterface * platformExtension = PLATFORM_SERVICE() + ->getUnknown(); + + platformExtension->androidNativeUnfreezeEvent( tick, render ); + } + /////////////////////////////////////////////////////////////////////// JNIEXPORT void JNICALL MENGINE_JAVA_INTERFACE( AndroidPlatform_1clipboardChangedEvent )(JNIEnv * env, jclass cls) { if( g_androidPlatformActived == false ) @@ -553,6 +579,8 @@ namespace Mengine , m_prevTime( 0.0 ) , m_pauseUpdatingTime( -1.f ) , m_active( false ) + , m_freezedTick( 0 ) + , m_freezedRender( 0 ) , m_desktop( false ) , m_touchpad( false ) { @@ -754,6 +782,8 @@ namespace Mengine NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_BOOTSTRAPPER_INITIALIZE_BASE_SERVICES, &AndroidPlatformService::notifyBootstrapperInitializeBaseServices_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_BOOTSTRAPPER_CREATE_APPLICATION, &AndroidPlatformService::notifyBootstrapperCreateApplication_, MENGINE_DOCUMENT_FACTORABLE ); + g_androidPlatformActived = true; + return true; } ////////////////////////////////////////////////////////////////////////// @@ -864,7 +894,7 @@ namespace Mengine bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); - if( updating == true ) + if(m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { @@ -889,7 +919,7 @@ namespace Mengine return; } - if( _render == false ) + if( m_freezedRender != 0 || _render == false ) { return; } @@ -1051,6 +1081,32 @@ namespace Mengine this->pushQuitEvent_(); } ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::freezePlatform( bool _tick, bool _render ) + { + if( _tick == true ) + { + ++m_freezedTick; + } + + if( _render == true ) + { + ++m_freezedRender; + } + } + ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::unfreezePlatform( bool _tick, bool _render ) + { + if( _tick == true ) + { + --m_freezedTick; + } + + if( _render == true ) + { + --m_freezedRender; + } + } + ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::setSleepMode( bool _sleepMode ) { MENGINE_UNUSED( _sleepMode ); @@ -1535,6 +1591,14 @@ namespace Mengine { this->destroyEvent_( ev.data.destroy ); }break; + case PlatformUnionEvent::PET_FREEZE: + { + this->freezeEvent_( ev.data.freeze ); + }break; + case PlatformUnionEvent::PET_UNFREEZE: + { + this->unfreezeEvent_( ev.data.unfreeze ); + }break; case PlatformUnionEvent::PET_SURFACE_CREATE: { this->surfaceCreateEvent_( ev.data.surfaceCreate ); @@ -2331,6 +2395,37 @@ namespace Mengine this->pushEvent( event ); } ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::androidNativeFreezeEvent( bool _tick, bool _render ) + { + PlatformUnionEvent event; + event.type = PlatformUnionEvent::PET_FREEZE; + event.data.freeze.tick = _tick; + event.data.freeze.render = _render; + + LOGGER_INFO( "platform", "freeze event: tick %d render %d" + , _tick + , _render + ); + + this->pushEvent( event ); + } + + ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::androidNativeUnfreezeEvent( bool _tick, bool _render ) + { + PlatformUnionEvent event; + event.type = PlatformUnionEvent::PET_UNFREEZE; + event.data.unfreeze.tick = _tick; + event.data.unfreeze.render = _render; + + LOGGER_INFO( "platform", "unfreeze event: tick %d render %d" + , _tick + , _render + ); + + this->pushEvent( event ); + } + ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::androidNativeClipboardChangedEvent() { PlatformUnionEvent event; @@ -2447,6 +2542,22 @@ namespace Mengine //ToDo } ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::freezeEvent_( const PlatformUnionEvent::PlatformFreezeEvent & _event ) + { + bool tick = _event.tick; + bool render = _event.render; + + this->freezePlatform( tick, render ); + } + ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::unfreezeEvent_( const PlatformUnionEvent::PlatformUnfreezeEvent & _event ) + { + bool tick = _event.tick; + bool render = _event.render; + + this->unfreezePlatform( tick, render ); + } + ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::surfaceCreateEvent_( const PlatformUnionEvent::PlatformSurfaceCreateEvent & _event ) { MENGINE_ASSERTION_FATAL( m_eglDisplay != nullptr, "display not created" ); diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.h b/src/Platforms/AndroidPlatform/AndroidPlatformService.h index 6f082fc218..c861c25823 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.h +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.h @@ -60,6 +60,8 @@ namespace Mengine bool updatePlatform() override; void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; + void freezePlatform( bool _tick, bool _render ) override; + void unfreezePlatform( bool _tick, bool _render ) override; public: void setSleepMode( bool _sleepMode ) override; @@ -182,6 +184,8 @@ namespace Mengine void androidNativeStartEvent() override; void androidNativeRestartEvent() override; void androidNativeDestroyEvent() override; + void androidNativeFreezeEvent( bool _tick, bool _render ) override; + void androidNativeUnfreezeEvent( bool _tick, bool _render ) override; void androidNativeClipboardChangedEvent() override; void androidNativeWindowFocusChangedEvent( jboolean _focus ) override; void androidNativeQuitEvent() override; @@ -215,6 +219,8 @@ namespace Mengine PET_START, PET_RESTART, PET_DESTROY, + PET_FREEZE, + PET_UNFREEZE, PET_SURFACE_CREATE, PET_SURFACE_DESTROY, PET_SURFACE_CHANGED, @@ -262,6 +268,18 @@ namespace Mengine int32_t dummy; }; + struct PlatformFreezeEvent + { + bool tick; + bool render; + }; + + struct PlatformUnfreezeEvent + { + bool tick; + bool render; + }; + struct PlatformSurfaceCreateEvent { ANativeWindow * nativeWindow; @@ -316,6 +334,8 @@ namespace Mengine PlatformStartEvent start; PlatformRestartEvent restart; PlatformDestroyEvent destroy; + PlatformFreezeEvent freeze; + PlatformUnfreezeEvent unfreeze; PlatformSurfaceCreateEvent surfaceCreate; PlatformSurfaceDestroyEvent surfaceDestroy; PlatformSurfaceChangedEvent surfaceChanged; @@ -334,6 +354,8 @@ namespace Mengine void startEvent_( const PlatformUnionEvent::PlatformStartEvent & _event ); void restartEvent_( const PlatformUnionEvent::PlatformRestartEvent & _event ); void destroyEvent_( const PlatformUnionEvent::PlatformDestroyEvent & _event ); + void freezeEvent_( const PlatformUnionEvent::PlatformFreezeEvent & _event ); + void unfreezeEvent_( const PlatformUnionEvent::PlatformUnfreezeEvent & _event ); void surfaceCreateEvent_( const PlatformUnionEvent::PlatformSurfaceCreateEvent & _event ); void surfaceDestroyEvent_( const PlatformUnionEvent::PlatformSurfaceDestroyEvent & _event ); void surfaceChangedEvent_( const PlatformUnionEvent::PlatformSurfaceChangedEvent & _event ); @@ -369,6 +391,7 @@ namespace Mengine EAS_PAUSE, EAS_STOP, EAS_RESTART, + EAS_FREEZE, EAS_DESTROY }; @@ -399,6 +422,8 @@ namespace Mengine float m_pauseUpdatingTime; bool m_active; + int32_t m_freezedTick; + int32_t m_freezedRender; bool m_desktop; bool m_touchpad; diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index 055af0fa38..bd59d6674f 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -106,6 +106,8 @@ namespace Mengine , m_performanceFrequency{0} , m_performanceSupport( false ) , m_active( false ) + , m_freezedTick( 0 ) + , m_freezedRender( 0 ) , m_hIcon( NULL ) , m_close( false ) , m_sleepMode( true ) @@ -661,7 +663,7 @@ namespace Mengine bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); - if( updating == true ) + if( m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { @@ -676,7 +678,7 @@ namespace Mengine APPLICATION_SERVICE() ->endUpdate(); - if( this->isNeedWindowRender() == true && _render == true ) + if( m_freezedRender == false && this->isNeedWindowRender() == true && _render == true ) { bool sucessful = APPLICATION_SERVICE() ->render(); @@ -699,7 +701,7 @@ namespace Mengine m_pauseUpdatingTime = _frameTime; } - if( m_sleepMode == true ) + if( m_freezedTick != 0 || m_freezedRender != 0 || m_sleepMode == true ) { ::Sleep( 100 ); } @@ -777,6 +779,32 @@ namespace Mengine MENGINE_PROFILER_END_APPLICATION(); } ////////////////////////////////////////////////////////////////////////// + void Win32PlatformService::freezePlatform( bool _tick, bool _render ) + { + if( _tick == true ) + { + ++m_freezedTick; + } + + if( _render == true ) + { + ++m_freezedRender; + } + } + ////////////////////////////////////////////////////////////////////////// + void Win32PlatformService::unfreezePlatform( bool _tick, bool _render ) + { + if( _tick == true ) + { + --m_freezedTick; + } + + if( _render == true ) + { + --m_freezedRender; + } + } + ////////////////////////////////////////////////////////////////////////// bool Win32PlatformService::setHWNDIcon( const WChar * _iconResource ) { HINSTANCE hInstance = ::GetModuleHandle( NULL ); diff --git a/src/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index b639e6f39d..9893137b67 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.h +++ b/src/Platforms/Win32Platform/Win32PlatformService.h @@ -49,6 +49,8 @@ namespace Mengine bool updatePlatform() override; void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; + void freezePlatform( bool _tick, bool _render ) override; + void unfreezePlatform( bool _tick, bool _render ) override; public: bool setHWNDIcon( const WChar * _iconResource ) override; @@ -236,6 +238,8 @@ namespace Mengine bool m_fullscreen; bool m_active; + int32_t m_freezedTick; + int32_t m_freezedRender; bool m_close; bool m_sleepMode; From 7bfc73e65b167721ba9b6d741d4ae72ff0489e5d Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 21 Sep 2025 18:38:57 +0300 Subject: [PATCH 056/169] improve ios platform freeze&unfreeze --- .../iOSPlatform/iOSPlatformService.h | 5 +++ .../iOSPlatform/iOSPlatformService.mm | 38 ++++++++++++++++--- .../AppleAppLovinInterstitialDelegate.mm | 12 ++++-- .../AppleAppLovinRewardedDelegate.mm | 10 ++++- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.h b/src/Platforms/iOSPlatform/iOSPlatformService.h index d25d7f5fbc..24599d6254 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.h +++ b/src/Platforms/iOSPlatform/iOSPlatformService.h @@ -61,6 +61,8 @@ namespace Mengine bool updatePlatform() override; void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; + void freezePlatform( bool _tick, bool _render ) override; + void unfreezePlatform( bool _tick, bool _render ) override; public: void setSleepMode( bool _sleepMode ) override; @@ -222,6 +224,9 @@ namespace Mengine bool m_active; bool m_sleepMode; + + int32_t m_freezedTick; + int32_t m_freezedRender; bool m_desktop; bool m_touchpad; diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index dc2c75ce88..6ce7894edc 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -90,6 +90,8 @@ , m_pauseUpdatingTime( -1.f ) , m_active( false ) , m_sleepMode( true ) + , m_freezedTick( 0 ) + , m_freezedRender( 0 ) , m_desktop( false ) , m_touchpad( false ) , m_glContext( nullptr ) @@ -790,7 +792,7 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); - if( updating == true ) + if( m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { @@ -801,8 +803,11 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit APPLICATION_SERVICE() ->tick( _frameTime ); } + + APPLICATION_SERVICE() + ->endUpdate(); - if( this->isNeedWindowRender() == true && _render == true ) + if( m_freezedRender == 0 && this->isNeedWindowRender() == true && _render == true ) { bool sucessful = APPLICATION_SERVICE() ->render(); @@ -823,9 +828,6 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit } } } - - APPLICATION_SERVICE() - ->endUpdate(); } ////////////////////////////////////////////////////////////////////////// void iOSPlatformService::loopPlatform() @@ -968,6 +970,32 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit this->pushQuitEvent_(); } ////////////////////////////////////////////////////////////////////////// + void iOSPlatformService::freezePlatform( bool _tick, bool _render ) + { + if( _tick == true ) + { + ++m_freezedTick; + } + + if( _render == true ) + { + ++m_freezedRender; + } + } + ////////////////////////////////////////////////////////////////////////// + void iOSPlatformService::unfreezePlatform( bool _tick, bool _render ) + { + if( _tick == true ) + { + --m_freezedTick; + } + + if( _render == true ) + { + --m_freezedRender; + } + } + ////////////////////////////////////////////////////////////////////////// void iOSPlatformService::setSleepMode( bool _sleepMode ) { m_sleepMode = _sleepMode; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm index 755628f109..fb0482261d 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm @@ -1,13 +1,13 @@ #import "AppleAppLovinInterstitialDelegate.h" +#include "Interface/PlatformServiceInterface.h" + #import "Environment/Apple/AppleDetail.h" #import "Environment/Apple/AppleString.h" #import "Environment/iOS/iOSLog.h" -#include "AppleAppLovinApplicationDelegate.h" - -#include "Kernel/AnalyticsHelper.h" +#import "AppleAppLovinApplicationDelegate.h" @implementation AppleAppLovinInterstitialDelegate @@ -172,6 +172,9 @@ - (void) didDisplayAd:(MAAd *)ad { @"placement": ad.placement, @"ad": [self getMAAdParams:ad] }]; + + PLATFORM_SERVICE() + ->freezePlatform( true, true ); } - (void) didClickAd:(MAAd *)ad { @@ -191,6 +194,9 @@ - (void) didHideAd:(MAAd *)ad { @"ad": [self getMAAdParams:ad] }]; + PLATFORM_SERVICE() + ->unfreezePlatform( true, true ); + self.m_showing = NO; id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm index b48fdf7f90..951147370a 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm @@ -1,12 +1,14 @@ #import "AppleAppLovinRewardedDelegate.h" +#include "Interface/PlatformServiceInterface.h" + #import "Environment/Apple/AppleDetail.h" #import "Environment/Apple/AppleString.h" #import "Environment/iOS/iOSLog.h" #import "Environment/iOS/iOSNetwork.h" -#include "AppleAppLovinApplicationDelegate.h" +#import "AppleAppLovinApplicationDelegate.h" @implementation AppleAppLovinRewardedDelegate @@ -189,6 +191,9 @@ - (void) didDisplayAd:(MAAd *)ad { @"placement": ad.placement, @"ad": [self getMAAdParams:ad] }]; + + PLATFORM_SERVICE() + ->freezePlatform( true, true ); } - (void) didClickAd:(MAAd *)ad { @@ -208,6 +213,9 @@ - (void) didHideAd:(MAAd *)ad { @"ad": [self getMAAdParams:ad] }]; + PLATFORM_SERVICE() + ->unfreezePlatform( true, true ); + self.m_showing = NO; id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; From 307b60658a073c44320c042ad88434a0616a521c Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 21 Sep 2025 21:10:10 +0300 Subject: [PATCH 057/169] Fix code --- .../AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java | 1 - .../Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java | 2 +- src/Platforms/Win32Platform/Win32PlatformService.cpp | 2 +- src/Platforms/Win32Platform/Win32PlatformService.h | 3 ++- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index 039eee3fef..e1e7c98431 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -45,7 +45,6 @@ public MengineAppLovinInterstitialAd(@NonNull MengineAdService adService, @NonNu if (MengineAppLovinPlugin_Interstitial_AdUnitId.isEmpty() == true) { this.invalidInitialize("meta %s is empty" , plugin.getResourceName(METADATA_INTERSTITIAL_ADUNITID) - , MengineAppLovinPlugin_Interstitial_AdUnitId ); } diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index 9c2a3b3a9d..e3250169b4 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -46,7 +46,7 @@ public MengineAppLovinRewardedAd(@NonNull MengineAdService adService, @NonNull M if (MengineAppLovinPlugin_Rewarded_AdUnitId.isEmpty() == true) { this.invalidInitialize("meta %s is empty" - , METADATA_REWARDED_ADUNITID + , plugin.getResourceName(METADATA_REWARDED_ADUNITID) ); } diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index bd59d6674f..cdd45c7458 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -106,10 +106,10 @@ namespace Mengine , m_performanceFrequency{0} , m_performanceSupport( false ) , m_active( false ) + , m_close( false ) , m_freezedTick( 0 ) , m_freezedRender( 0 ) , m_hIcon( NULL ) - , m_close( false ) , m_sleepMode( true ) , m_windowExposed( false ) , m_pauseUpdatingTime( -1.f ) diff --git a/src/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index 9893137b67..331442c156 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.h +++ b/src/Platforms/Win32Platform/Win32PlatformService.h @@ -238,9 +238,10 @@ namespace Mengine bool m_fullscreen; bool m_active; + bool m_close; + int32_t m_freezedTick; int32_t m_freezedRender; - bool m_close; bool m_sleepMode; bool m_windowExposed; From 61f22c34e96512147157d95e23723181f0c5916c Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 22 Sep 2025 13:02:27 +0300 Subject: [PATCH 058/169] update README.md --- README.md | 5 +++++ src/Platforms/AndroidPlatform/AndroidPlatformService.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 571ef2ad72..59dbe132d6 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,11 @@ Games that are being developed or have been released on this engine Mobile ------- +[NY: Hidden Crimes](https://www.youtube.com/watch?v=zgBkBY-GCBI) + +From now on all New York secrets are in your hands! A new "hidden objects" game will let you explore the most remote and mysterious corners of the legendary city, enjoying the atmosphere of detective adventures. +Try on the role of a famous criminal blogger and take part into the most puzzling criminal investigations. Use your skills of searching objects to find evidence, leading to the trails of mysterious criminals. The police of the Big Apple awaits for your help since you're the one who can guide them through the world of mysteries and secrets! + [Numberphile](https://www.wonderland-games.com/projects/numberphile) [![Android](https://raw.githubusercontent.com/irov/badgets/master/half/GetItOnGooglePlay_Badge_Web_color_English.png)](https://play.google.com/store/apps/details?id=com.wonderland.numberphile) diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index 7f789969ce..873c3156ae 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -894,7 +894,7 @@ namespace Mengine bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); - if(m_freezedTick == 0 && updating == true ) + if( m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { From ffce2e8b9e5f2e81bef428fa4d646c0134b06b1d Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 22 Sep 2025 23:19:25 +0300 Subject: [PATCH 059/169] improve android file system improve imGUI save settings use size_t --- .../AndroidApplication/AndroidApplication.cpp | 6 +- src/Config/Config.h | 8 +- src/Config/UniqueId.h | 1 - src/Engine/TextField.cpp | 6 +- .../Android/AndroidAssetService.cpp | 12 +-- src/Environment/Android/AndroidAssetService.h | 2 +- .../Android}/AndroidAssetServiceInterface.h | 0 src/Environment/Android/CMakeLists.txt | 2 + .../Apple}/AppleKernelServiceInterface.h | 0 src/Environment/Apple/CMakeLists.txt | 16 ++-- .../Windows/Win32ConsoleLogger.cpp | 6 +- src/Environment/iOS/CMakeLists.txt | 2 + .../iOS}/iOSKernelServiceInterface.h | 0 src/Interface/CMakeLists.txt | 3 - src/Kernel/ArrayTString.h | 4 +- src/Kernel/ConstStringHolder.h | 2 +- src/Kernel/Hashtable.h | 20 ++--- src/Kernel/Hashtable2.h | 20 ++--- src/Kernel/Polygon.h | 2 +- src/Kernel/PolygonHelper.cpp | 52 ++++++------ src/Kernel/SHA1.cpp | 38 +++++---- src/Kernel/StringFormat.cpp | 3 +- .../Win32Platform/Win32PlatformService.cpp | 6 +- src/Plugins/ImGUIPlugin/ImGUIService.cpp | 21 +++-- src/Services/AccountService/Account.cpp | 25 ++---- .../AccountService/AccountService.cpp | 4 + src/Services/MemoryService/MemoryService.cpp | 2 +- .../AndroidAssetGroupDirectory.cpp | 2 +- .../AndroidAssetInputStream.cpp | 5 +- .../AndroidFileInputStream.cpp | 71 +++++++++++++--- .../AndroidFileOutputStream.cpp | 80 ++++++++++++++----- .../AndroidFileOutputStream.h | 6 ++ .../AndroidFileSystem/AndroidFileSystem.cpp | 18 ++++- .../AndroidMutexAssetInputStream.cpp | 5 +- .../AndroidMutexFileInputStream.cpp | 6 +- .../AppleFileSystem/AppleFileInputStream.mm | 2 +- .../AppleFileSystem/AppleFileOutputStream.mm | 43 +++++++--- .../AppleMutexFileInputStream.mm | 5 +- .../SDL2FileSystem/SDL2FileInputStream.cpp | 2 +- .../SDL2MutexFileInputStream.cpp | 2 +- .../Win32FileSystem/Win32FileOutputStream.cpp | 5 ++ .../Win32MutexFileInputStream.cpp | 4 +- 42 files changed, 339 insertions(+), 180 deletions(-) rename src/{Interface => Environment/Android}/AndroidAssetServiceInterface.h (100%) rename src/{Interface => Environment/Apple}/AppleKernelServiceInterface.h (100%) rename src/{Interface => Environment/iOS}/iOSKernelServiceInterface.h (100%) diff --git a/src/Applications/AndroidApplication/AndroidApplication.cpp b/src/Applications/AndroidApplication/AndroidApplication.cpp index a015106fb9..ade4a0af0f 100644 --- a/src/Applications/AndroidApplication/AndroidApplication.cpp +++ b/src/Applications/AndroidApplication/AndroidApplication.cpp @@ -68,7 +68,7 @@ namespace Mengine LoggerInterfacePtr loggerAndroid = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FUNCTION ); - loggerAndroid->setWriteHistory(true ); + loggerAndroid->setWriteHistory( true ); if(LOGGER_SERVICE() ->registerLogger(loggerAndroid ) == true ) @@ -81,10 +81,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidApplication::finalizeLoggerService_() { - if(m_loggerAndroid != nullptr ) + if( m_loggerAndroid != nullptr ) { LOGGER_SERVICE() - ->unregisterLogger(m_loggerAndroid ); + ->unregisterLogger( m_loggerAndroid ); m_loggerAndroid = nullptr; } diff --git a/src/Config/Config.h b/src/Config/Config.h index 79c59edbce..444c2e5497 100644 --- a/src/Config/Config.h +++ b/src/Config/Config.h @@ -351,15 +351,15 @@ #endif #ifndef MENGINE_UNKNOWN_SIZE -#define MENGINE_UNKNOWN_SIZE (~0U) +#define MENGINE_UNKNOWN_SIZE ((size_t)-1) #endif -#ifndef MENGINE_UNKNOWN_HASH -#define MENGINE_UNKNOWN_HASH (-1) +#ifndef MENGINE_UNKNOWN_COUNT +#define MENGINE_UNKNOWN_COUNT ((uint32_t)-1) #endif #ifndef MENGINE_PATH_INVALID_LENGTH -#define MENGINE_PATH_INVALID_LENGTH (~0U) +#define MENGINE_PATH_INVALID_LENGTH ((size_t)-1) #endif #if defined(MENGINE_PLATFORM_MACOS) diff --git a/src/Config/UniqueId.h b/src/Config/UniqueId.h index 6db27ca49c..38ea7cffaa 100644 --- a/src/Config/UniqueId.h +++ b/src/Config/UniqueId.h @@ -7,5 +7,4 @@ namespace Mengine typedef uint32_t UniqueId; static constexpr UniqueId INVALID_UNIQUE_ID = 0U; - static constexpr UniqueId REMOVE_UNIQUE_ID = ~0U; } \ No newline at end of file diff --git a/src/Engine/TextField.cpp b/src/Engine/TextField.cpp index 80b81aea91..9d413139e6 100644 --- a/src/Engine/TextField.cpp +++ b/src/Engine/TextField.cpp @@ -43,7 +43,7 @@ namespace Mengine , m_charOffset( 0.f ) , m_anchorPercent( 0.f, 0.f ) , m_textParams( EFP_NONE ) - , m_maxCharCount( MENGINE_UNKNOWN_SIZE ) + , m_maxCharCount( MENGINE_UNKNOWN_COUNT ) , m_cacheCharCount( 0 ) , m_cacheLayoutCount( 0 ) , m_cacheTextSize( 0.f, 0.f ) @@ -1125,7 +1125,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void TextField::updateTextLinesMaxCount_( VectorTextLineChunks2 * const _textLines ) const { - if( m_maxCharCount == MENGINE_UNKNOWN_SIZE ) + if( m_maxCharCount == MENGINE_UNKNOWN_COUNT ) { return; } @@ -1371,7 +1371,7 @@ namespace Mengine bool autoScale = this->calcAutoScale(); - MENGINE_ASSERTION( !(autoScale == true && (m_wrap == true || m_maxCharCount != MENGINE_UNKNOWN_SIZE)), "text '%s' invalid enable together attributes 'wrap' and 'autoScale'" + MENGINE_ASSERTION( !(autoScale == true && (m_wrap == true || m_maxCharCount != MENGINE_UNKNOWN_COUNT)), "text '%s' invalid enable together attributes 'wrap' and 'autoScale'" , this->getName().c_str() ); diff --git a/src/Environment/Android/AndroidAssetService.cpp b/src/Environment/Android/AndroidAssetService.cpp index 1d5fd6b4e7..28bccbd5e2 100644 --- a/src/Environment/Android/AndroidAssetService.cpp +++ b/src/Environment/Android/AndroidAssetService.cpp @@ -97,23 +97,23 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// size_t AndroidAssetService::read( AAsset * _asset, void * _buffer, size_t _size ) const { - size_t read = AAsset_read( _asset, _buffer, _size ); + int read = AAsset_read( _asset, _buffer, _size ); - return read; + return (size_t)read; } ////////////////////////////////////////////////////////////////////////// int64_t AndroidAssetService::size( AAsset * _asset ) const { - int64_t size = AAsset_getLength64( _asset ); + off64_t size = AAsset_getLength64( _asset ); - return size; + return (int64_t)size; } ////////////////////////////////////////////////////////////////////////// int64_t AndroidAssetService::seek( AAsset * _asset, int64_t _offset, int _whence ) const { - int64_t seek = AAsset_seek64( _asset, _offset, _whence ); + off64_t seek = AAsset_seek64( _asset, _offset, _whence ); - return seek; + return (int64_t)seek; } ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Environment/Android/AndroidAssetService.h b/src/Environment/Android/AndroidAssetService.h index 8cc847c114..a9f137ded7 100644 --- a/src/Environment/Android/AndroidAssetService.h +++ b/src/Environment/Android/AndroidAssetService.h @@ -1,6 +1,6 @@ #pragma once -#include "Interface/AndroidAssetServiceInterface.h" +#include "Environment/Android/AndroidAssetServiceInterface.h" #include "Kernel/ServiceBase.h" diff --git a/src/Interface/AndroidAssetServiceInterface.h b/src/Environment/Android/AndroidAssetServiceInterface.h similarity index 100% rename from src/Interface/AndroidAssetServiceInterface.h rename to src/Environment/Android/AndroidAssetServiceInterface.h diff --git a/src/Environment/Android/CMakeLists.txt b/src/Environment/Android/CMakeLists.txt index 9886f50e58..4fe9adae43 100644 --- a/src/Environment/Android/CMakeLists.txt +++ b/src/Environment/Android/CMakeLists.txt @@ -13,6 +13,8 @@ src AndroidHelper.h AndroidHelper.cpp + AndroidAssetServiceInterface.h + AndroidKernelServiceInterface.h AndroidKernelService.h diff --git a/src/Interface/AppleKernelServiceInterface.h b/src/Environment/Apple/AppleKernelServiceInterface.h similarity index 100% rename from src/Interface/AppleKernelServiceInterface.h rename to src/Environment/Apple/AppleKernelServiceInterface.h diff --git a/src/Environment/Apple/CMakeLists.txt b/src/Environment/Apple/CMakeLists.txt index b45536b54c..75678bc216 100644 --- a/src/Environment/Apple/CMakeLists.txt +++ b/src/Environment/Apple/CMakeLists.txt @@ -2,12 +2,12 @@ MENGINE_PROJECT(Apple) ADD_FILTER( src - AppleIncluder.h - + AppleIncluder.h + AppleLog.h AppleLog.mm - AppleLogRecordParam.h - AppleLogRecordParam.mm + AppleLogRecordParam.h + AppleLogRecordParam.mm AppleDetail.h AppleDetail.mm AppleBundle.h @@ -17,9 +17,9 @@ src AppleEvent.h AppleEvent.mm - - AppleISO8601Date.h - AppleISO8601Date.mm + + AppleISO8601Date.h + AppleISO8601Date.mm AppleUserDefaults.h AppleUserDefaults.mm @@ -34,6 +34,8 @@ src AppleSemaphoreService.h AppleSemaphoreService.mm + AppleKernelServiceInterface.h + AppleKernelService.h AppleKernelService.mm diff --git a/src/Environment/Windows/Win32ConsoleLogger.cpp b/src/Environment/Windows/Win32ConsoleLogger.cpp index 057779e6b0..f6d4151c9a 100644 --- a/src/Environment/Windows/Win32ConsoleLogger.cpp +++ b/src/Environment/Windows/Win32ConsoleLogger.cpp @@ -116,10 +116,10 @@ namespace Mengine m_CONOUT = ::freopen( "CONOUT$", "w", stdout ); m_CONERR = ::freopen( "CONOUT$", "w", stderr ); - uint32_t OPTION_consolex = GET_OPTION_VALUE_UINT32( "consolex", MENGINE_UNKNOWN_SIZE ); - uint32_t OPTION_consoley = GET_OPTION_VALUE_UINT32( "consoley", MENGINE_UNKNOWN_SIZE ); + uint32_t OPTION_consolex = GET_OPTION_VALUE_UINT32( "consolex", MENGINE_UNKNOWN_COUNT ); + uint32_t OPTION_consoley = GET_OPTION_VALUE_UINT32( "consoley", MENGINE_UNKNOWN_COUNT ); - if( OPTION_consolex != MENGINE_UNKNOWN_SIZE && OPTION_consoley != MENGINE_UNKNOWN_SIZE ) + if( OPTION_consolex != MENGINE_UNKNOWN_COUNT && OPTION_consoley != MENGINE_UNKNOWN_COUNT ) { HWND hWnd = ::GetConsoleWindow(); RECT rect; diff --git a/src/Environment/iOS/CMakeLists.txt b/src/Environment/iOS/CMakeLists.txt index 3f22c11ca6..75c76cdd43 100644 --- a/src/Environment/iOS/CMakeLists.txt +++ b/src/Environment/iOS/CMakeLists.txt @@ -10,6 +10,8 @@ src iOSApplication.h iOSApplication.mm + + iOSKernelServiceInterface.h iOSKernelService.h iOSKernelService.mm diff --git a/src/Interface/iOSKernelServiceInterface.h b/src/Environment/iOS/iOSKernelServiceInterface.h similarity index 100% rename from src/Interface/iOSKernelServiceInterface.h rename to src/Environment/iOS/iOSKernelServiceInterface.h diff --git a/src/Interface/CMakeLists.txt b/src/Interface/CMakeLists.txt index 8efa5c522e..5c4ed7a941 100644 --- a/src/Interface/CMakeLists.txt +++ b/src/Interface/CMakeLists.txt @@ -138,9 +138,6 @@ Common HttpRequestInterface.h HttpReceiverInterface.h EnvironmentServiceInterface.h - AndroidAssetServiceInterface.h - AppleKernelServiceInterface.h - iOSKernelServiceInterface.h Win32KernelServiceInterface.h ArrowServiceInterface.h AmplifierServiceInterface.h diff --git a/src/Kernel/ArrayTString.h b/src/Kernel/ArrayTString.h index 907153c749..bc39492385 100644 --- a/src/Kernel/ArrayTString.h +++ b/src/Kernel/ArrayTString.h @@ -8,12 +8,12 @@ namespace Mengine { - template + template class ArrayTString { public: typedef T value_type; - typedef uint32_t size_type; + typedef size_t size_type; public: ArrayTString() diff --git a/src/Kernel/ConstStringHolder.h b/src/Kernel/ConstStringHolder.h index 12f9b40247..bcf90015d2 100644 --- a/src/Kernel/ConstStringHolder.h +++ b/src/Kernel/ConstStringHolder.h @@ -22,7 +22,7 @@ namespace Mengine ConstStringHolder & operator = ( const ConstStringHolder & _holder ); public: - typedef uint32_t size_type; + typedef size_t size_type; typedef HashType hash_type; typedef Char value_type; diff --git a/src/Kernel/Hashtable.h b/src/Kernel/Hashtable.h index a6cd78c885..6bf2119164 100644 --- a/src/Kernel/Hashtable.h +++ b/src/Kernel/Hashtable.h @@ -20,7 +20,7 @@ namespace Mengine class Hashtable { public: - typedef uint32_t size_type; + typedef size_t size_type; typedef HashType hash_type; typedef K key_type; typedef T element_type_ptr; @@ -148,7 +148,7 @@ namespace Mengine } public: - void reserve( uint32_t _capacity ) + void reserve( size_type _capacity ) { if( m_capacity > _capacity ) { @@ -171,7 +171,7 @@ namespace Mengine return m_size == 0; } - uint32_t size() const + size_type size() const { return m_size; } @@ -640,7 +640,7 @@ namespace Mengine class Hashtable { public: - typedef uint32_t size_type; + typedef size_t size_type; typedef HashType hash_type; typedef K key_type; typedef T * element_type_ptr; @@ -679,8 +679,8 @@ namespace Mengine { MENGINE_ASSERTION_MEMORY_PANIC( _element, "invalid emplace element" ); - uint32_t test_size = (m_size + m_dummy) * 3 + 1; - uint32_t test_capacity = m_capacity * 2; + size_type test_size = (m_size + m_dummy) * 3 + 1; + size_type test_capacity = m_capacity * 2; if( test_size > test_capacity ) { this->increase_(); @@ -697,8 +697,8 @@ namespace Mengine { MENGINE_ASSERTION_MEMORY_PANIC( _element, "invalid change element" ); - uint32_t test_size = (m_size + m_dummy) * 3 + 1; - uint32_t test_capacity = m_capacity * 2; + size_type test_size = (m_size + m_dummy) * 3 + 1; + size_type test_capacity = m_capacity * 2; if( test_size > test_capacity ) { this->increase_(); @@ -766,7 +766,7 @@ namespace Mengine } public: - void reserve( uint32_t _capacity ) + void reserve( size_type _capacity ) { if( m_capacity > _capacity ) { @@ -789,7 +789,7 @@ namespace Mengine return m_size == 0; } - uint32_t size() const + size_type size() const { return m_size; } diff --git a/src/Kernel/Hashtable2.h b/src/Kernel/Hashtable2.h index 36acae9d0b..baed083756 100644 --- a/src/Kernel/Hashtable2.h +++ b/src/Kernel/Hashtable2.h @@ -20,7 +20,7 @@ namespace Mengine class Hashtable2 { public: - typedef uint32_t size_type; + typedef size_t size_type; typedef HashType hash_type; typedef K1 key_type1; typedef K2 key_type2; @@ -161,7 +161,7 @@ namespace Mengine } public: - void reserve( uint32_t _capacity ) + void reserve( size_type _capacity ) { if( m_capacity > _capacity ) { @@ -184,7 +184,7 @@ namespace Mengine return m_size == 0; } - uint32_t size() const + size_type size() const { return m_size; } @@ -656,7 +656,7 @@ namespace Mengine class Hashtable2 { public: - typedef uint32_t size_type; + typedef size_t size_type; typedef HashType hash_type; typedef K1 key_type1; typedef K2 key_type2; @@ -708,8 +708,8 @@ namespace Mengine { MENGINE_ASSERTION_MEMORY_PANIC( _element, "invalid emplace element" ); - uint32_t test_size = (m_size + m_dummy) * 3 + 1; - uint32_t test_capacity = m_capacity * 2; + size_type test_size = (m_size + m_dummy) * 3 + 1; + size_type test_capacity = m_capacity * 2; if( test_size > test_capacity ) { @@ -727,8 +727,8 @@ namespace Mengine { MENGINE_ASSERTION_MEMORY_PANIC( _element, "invalid change element" ); - uint32_t test_size = (m_size + m_dummy) * 3 + 1; - uint32_t test_capacity = m_capacity * 2; + size_type test_size = (m_size + m_dummy) * 3 + 1; + size_type test_capacity = m_capacity * 2; if( test_size > test_capacity ) { @@ -797,7 +797,7 @@ namespace Mengine } public: - void reserve( uint32_t _capacity ) + void reserve( size_type _capacity ) { if( m_capacity > _capacity ) { @@ -820,7 +820,7 @@ namespace Mengine return m_size == 0; } - uint32_t size() const + size_type size() const { return m_size; } diff --git a/src/Kernel/Polygon.h b/src/Kernel/Polygon.h index af7775162d..e7e65a10bf 100644 --- a/src/Kernel/Polygon.h +++ b/src/Kernel/Polygon.h @@ -24,7 +24,7 @@ namespace Mengine Polygon( Polygon && _polygon ); public: - typedef uint32_t size_type; + typedef VectorPoints::size_type size_type; typedef VectorPoints::iterator iterator; typedef VectorPoints::const_iterator const_iterator; diff --git a/src/Kernel/PolygonHelper.cpp b/src/Kernel/PolygonHelper.cpp index b07524cfe8..e951c9f1ff 100644 --- a/src/Kernel/PolygonHelper.cpp +++ b/src/Kernel/PolygonHelper.cpp @@ -213,7 +213,7 @@ namespace Mengine bool triangulate( const Polygon & _polygon, VectorPoints * const _result ) { const VectorPoints & polygon_points = _polygon.getPoints(); - uint32_t polygon_size = _polygon.size(); + VectorPoints::size_type polygon_size = _polygon.size(); --polygon_size; @@ -222,29 +222,29 @@ namespace Mengine return false; } - uint32_t * V = Helper::allocateArrayT( polygon_size ); /* we want a counter-clockwise polygon in V */ + VectorPoints::size_type * V = Helper::allocateArrayT( polygon_size ); /* we want a counter-clockwise polygon in V */ float polygon_area = _polygon.area(); if( polygon_area < 0.f ) { - for( uint32_t v = 0; v != polygon_size; ++v ) + for( VectorPoints::size_type v = 0; v != polygon_size; ++v ) { V[v] = v; } } else { - for( uint32_t v = 0; v != polygon_size; ++v ) + for( VectorPoints::size_type v = 0; v != polygon_size; ++v ) { V[v] = (polygon_size - 1) - v; } } - uint32_t nv = polygon_size; - uint32_t count = 2 * nv; + VectorPoints::size_type nv = polygon_size; + VectorPoints::size_type count = 2 * nv; - for( uint32_t v = nv - 1; nv > 2; ) + for( VectorPoints::size_type v = nv - 1; nv > 2; ) { if( 0 == (count--) ) { @@ -253,7 +253,7 @@ namespace Mengine return false; } - uint32_t u = v; + VectorPoints::size_type u = v; if( nv <= u ) { @@ -267,7 +267,7 @@ namespace Mengine v = 0; } - uint32_t w = v + 1; + VectorPoints::size_type w = v + 1; if( nv <= w ) { @@ -276,9 +276,9 @@ namespace Mengine if( Detail::snip( polygon_points, u, v, w, nv, V ) == true ) { - uint32_t a = V[u]; - uint32_t b = V[v]; - uint32_t c = V[w]; + VectorPoints::size_type a = V[u]; + VectorPoints::size_type b = V[v]; + VectorPoints::size_type c = V[w]; const mt::vec2f & Ca = polygon_points[a]; const mt::vec2f & Cb = polygon_points[b]; @@ -288,7 +288,7 @@ namespace Mengine _result->emplace_back( Cb ); _result->emplace_back( Cc ); - for( uint32_t s = v, t = v + 1; t < nv; s++, t++ ) + for( VectorPoints::size_type s = v, t = v + 1; t < nv; s++, t++ ) { V[s] = V[t]; } @@ -307,7 +307,7 @@ namespace Mengine bool triangulate_indices( const Polygon & _polygon, VectorPolygonIndices * const _result ) { const VectorPoints & polygon_points = _polygon.getPoints(); - uint32_t n = _polygon.size(); + VectorPoints::size_type n = _polygon.size(); --n; @@ -316,29 +316,29 @@ namespace Mengine return false; } - uint32_t * V = Helper::allocateArrayT( n ); + VectorPoints::size_type * V = Helper::allocateArrayT( n ); float polygon_area = _polygon.area(); if( polygon_area < 0.f ) { - for( uint32_t v = 0; v < n; v++ ) + for( VectorPoints::size_type v = 0; v < n; v++ ) { V[v] = v; } } else { - for( uint32_t v = 0; v < n; v++ ) + for( VectorPoints::size_type v = 0; v < n; v++ ) { V[v] = (n - 1) - v; } } - uint32_t nv = n; - uint32_t count = 2 * nv; + VectorPoints::size_type nv = n; + VectorPoints::size_type count = 2 * nv; - for( uint32_t v = nv - 1; nv > 2; ) + for( VectorPoints::size_type v = nv - 1; nv > 2; ) { if( 0 == (count--) ) { @@ -347,7 +347,7 @@ namespace Mengine return false; } - uint32_t u = v; + VectorPoints::size_type u = v; if( nv <= u ) { @@ -361,7 +361,7 @@ namespace Mengine v = 0; } - uint32_t w = v + 1; + VectorPoints::size_type w = v + 1; if( nv <= w ) { @@ -370,15 +370,15 @@ namespace Mengine if( Detail::snip( polygon_points, u, v, w, nv, V ) == true ) { - uint32_t a = V[u]; - uint32_t b = V[v]; - uint32_t c = V[w]; + VectorPoints::size_type a = V[u]; + VectorPoints::size_type b = V[v]; + VectorPoints::size_type c = V[w]; _result->emplace_back( a ); _result->emplace_back( b ); _result->emplace_back( c ); - for( uint32_t s = v, t = v + 1; t < nv; s++, t++ ) + for( VectorPoints::size_type s = v, t = v + 1; t < nv; s++, t++ ) { V[s] = V[t]; } diff --git a/src/Kernel/SHA1.cpp b/src/Kernel/SHA1.cpp index a05a5f27a8..faefc6e6dd 100644 --- a/src/Kernel/SHA1.cpp +++ b/src/Kernel/SHA1.cpp @@ -28,8 +28,8 @@ namespace Mengine struct SHA1_CTX { uint32_t state[5]; - size_t count[2]; - uint8_t buffer[64]; + uint32_t count[2]; + uint8_t buffer[64]; }; ////////////////////////////////////////////////////////////////////////// MENGINE_CONSTEXPR uint32_t SHA1_rotl32( uint32_t var, uint32_t hops ) @@ -37,7 +37,7 @@ namespace Mengine return (var << hops) | (var >> (32 - hops)); } ////////////////////////////////////////////////////////////////////////// - MENGINE_CONSTEXPR void SHA1_Transform( uint32_t state[5], const uint8_t buffer[64] ) + MENGINE_CONSTEXPR void SHA1_Transform( uint32_t * const state, const uint8_t * buffer ) { typedef union { @@ -45,7 +45,13 @@ namespace Mengine uint32_t l[16]; } CHAR64LONG16; - CHAR64LONG16 * block = (CHAR64LONG16 *)buffer; + CHAR64LONG16 blk = {}; + for( size_t i = 0; i != 64; ++i ) + { + blk.c[i] = buffer[i]; + } + + CHAR64LONG16 * block = &blk; uint32_t a = state[0]; uint32_t b = state[1]; @@ -81,7 +87,7 @@ namespace Mengine state[4] += e; } ////////////////////////////////////////////////////////////////////////// - MENGINE_INLINE void SHA1_Init( SHA1_CTX * context ) + MENGINE_INLINE void SHA1_Init( SHA1_CTX * const context ) { context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; @@ -92,9 +98,9 @@ namespace Mengine context->count[1] = 0; } ////////////////////////////////////////////////////////////////////////// - MENGINE_INLINE void SHA1_Update( SHA1_CTX * context, const uint8_t * data, size_t len ) + MENGINE_INLINE void SHA1_Update( SHA1_CTX * const context, const uint8_t * data, size_t len ) { - size_t j = (context->count[0] >> 3) & 63; + uint32_t j = (context->count[0] >> 3) & 63; if( (context->count[0] += len << 3) < (len << 3) ) { @@ -126,20 +132,22 @@ namespace Mengine stdex::memorycopy( context->buffer, j, &data[i], (len - i) * sizeof( uint8_t ) ); } ////////////////////////////////////////////////////////////////////////// - MENGINE_INLINE void SHA1_Final( SHA1_CTX * context, uint8_t * const digest, size_t _size ) + MENGINE_INLINE void SHA1_Final( SHA1_CTX * const context, uint8_t * const digest, size_t _size ) { uint8_t finalcount[8]; for( size_t i = 0; i != 8; i++ ) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); + finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); } - SHA1_Update( context, (uint8_t *)"\200", 1 ); + uint8_t pad[] = {0x80}; + SHA1_Update( context, pad, 1 ); while( (context->count[0] & 504) != 448 ) { - SHA1_Update( context, (uint8_t *)"\0", 1 ); + uint8_t zero[] = {0x00}; + SHA1_Update( context, zero, 1 ); } SHA1_Update( context, finalcount, 8 ); @@ -151,7 +159,7 @@ namespace Mengine StdString::memset( context->buffer, 0, 64 * sizeof( uint8_t ) ); StdString::memset( context->state, 0, 5 * sizeof( uint32_t ) ); - StdString::memset( context->count, 0, 2 * sizeof( size_t ) ); + StdString::memset( context->count, 0, 2 * sizeof( uint32_t ) ); StdString::memset( finalcount, 0, 8 ); } ////////////////////////////////////////////////////////////////////////// @@ -162,7 +170,7 @@ namespace Mengine Detail::SHA1_CTX context; Detail::SHA1_Init( &context ); - Detail::SHA1_Update( &context, (uint8_t *)_buffer, _size ); + Detail::SHA1_Update( &context, (const uint8_t *)_buffer, _size ); Detail::SHA1_Final( &context, _sha1, _digestSize ); } ////////////////////////////////////////////////////////////////////////// @@ -171,7 +179,7 @@ namespace Mengine uint8_t sha1[MENGINE_SHA1_UINT8_COUNT]; Helper::makeSHA1( _buffer, _size, sha1, MENGINE_SHA1_UINT8_COUNT ); - Helper::encodeHexadecimal( sha1, sizeof( sha1 ), _hex, ~0U, _lowercase, nullptr ); + Helper::encodeHexadecimal( sha1, sizeof( sha1 ), _hex, MENGINE_UNKNOWN_SIZE, _lowercase, nullptr ); } ////////////////////////////////////////////////////////////////////////// void makeSHA1String( const Char * _string, Char * const _hex, bool _lowercase ) @@ -181,7 +189,7 @@ namespace Mengine uint8_t sha1[MENGINE_SHA1_UINT8_COUNT]; Helper::makeSHA1( _string, len, sha1, MENGINE_SHA1_UINT8_COUNT ); - Helper::encodeHexadecimal( sha1, sizeof( sha1 ), _hex, ~0U, _lowercase, nullptr ); + Helper::encodeHexadecimal( sha1, sizeof( sha1 ), _hex, MENGINE_UNKNOWN_SIZE, _lowercase, nullptr ); } ////////////////////////////////////////////////////////////////////////// void makeSHA1Base64( const void * _buffer, size_t _size, Char * const _base64 ) diff --git a/src/Kernel/StringFormat.cpp b/src/Kernel/StringFormat.cpp index 26106119eb..2b64ca1a3c 100644 --- a/src/Kernel/StringFormat.cpp +++ b/src/Kernel/StringFormat.cpp @@ -27,6 +27,7 @@ namespace Mengine ++index; const Char ch1 = _format[index]; + switch( ch1 ) { case '%': @@ -38,7 +39,7 @@ namespace Mengine }break; default: { - return MENGINE_UNKNOWN_SIZE; + return MENGINE_UNKNOWN_COUNT; }break; } }break; diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index cdd45c7458..3afaebf319 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -2677,10 +2677,10 @@ namespace Mengine if( _fullsreen == false ) { - uint32_t OPTION_winx = GET_OPTION_VALUE_UINT32( "winx", MENGINE_UNKNOWN_SIZE ); - uint32_t OPTION_winy = GET_OPTION_VALUE_UINT32( "winy", MENGINE_UNKNOWN_SIZE ); + uint32_t OPTION_winx = GET_OPTION_VALUE_UINT32( "winx", MENGINE_UNKNOWN_COUNT ); + uint32_t OPTION_winy = GET_OPTION_VALUE_UINT32( "winy", MENGINE_UNKNOWN_COUNT ); - if( OPTION_winx != MENGINE_UNKNOWN_SIZE && OPTION_winy != MENGINE_UNKNOWN_SIZE ) + if( OPTION_winx != MENGINE_UNKNOWN_COUNT && OPTION_winy != MENGINE_UNKNOWN_COUNT ) { uint32_t width = rc.right - rc.left; uint32_t height = rc.bottom - rc.top; diff --git a/src/Plugins/ImGUIPlugin/ImGUIService.cpp b/src/Plugins/ImGUIPlugin/ImGUIService.cpp index 032f060b1e..7a0d36412b 100644 --- a/src/Plugins/ImGUIPlugin/ImGUIService.cpp +++ b/src/Plugins/ImGUIPlugin/ImGUIService.cpp @@ -189,18 +189,25 @@ namespace Mengine } #endif + size_t imIniSettingsSize = 0; + const char * imIniSettings = ImGui::SaveIniSettingsToMemory( &imIniSettingsSize ); + const FileGroupInterfacePtr & userFileGroup = FILE_SERVICE() ->getFileGroup( STRINGIZE_STRING_LOCAL( "user" ) ); - OutputStreamInterfacePtr stream = Helper::openOutputStreamFile( userFileGroup, STRINGIZE_FILEPATH_LOCAL( "imgui.ini" ), true, MENGINE_DOCUMENT_FACTORABLE ); - - size_t imIniSettingsSize; - const char * imIniSettings = ImGui::SaveIniSettingsToMemory( &imIniSettingsSize ); + if( imIniSettingsSize != 0 ) + { + OutputStreamInterfacePtr stream = Helper::openOutputStreamFile( userFileGroup, STRINGIZE_FILEPATH_LOCAL( MENGINE_IMGUI_INI_FILE ), true, MENGINE_DOCUMENT_FACTORABLE ); - stream->write( imIniSettings, imIniSettingsSize ); - stream->flush(); + stream->write( imIniSettings, imIniSettingsSize ); + stream->flush(); - Helper::closeOutputStreamFile( userFileGroup, stream ); + Helper::closeOutputStreamFile( userFileGroup, stream ); + } + else + { + userFileGroup->removeFile( STRINGIZE_FILEPATH_LOCAL( MENGINE_IMGUI_INI_FILE ) ); + } #if defined(MENGINE_ENVIRONMENT_PLATFORM_SDL2) ImGui_ImplSDL2_Shutdown(); diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index 4549590b50..6f0d3c0a89 100644 --- a/src/Services/AccountService/Account.cpp +++ b/src/Services/AccountService/Account.cpp @@ -328,20 +328,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Account::save() { - const FilePath & settingsJSONPath = m_settingsJSONContent->getFilePath(); - - OutputStreamInterfacePtr file = Helper::openOutputStreamFile( m_fileGroup, settingsJSONPath, true, MENGINE_DOCUMENT_FACTORABLE ); - - if( file == nullptr ) - { - LOGGER_ERROR( "can't open file for writing. Account '%s' settings not saved '%s'" - , m_accountId.c_str() - , Helper::getContentFullPath( m_settingsJSONContent ).c_str() - ); - - return false; - } - jpp::object j_root = jpp::make_object(); jpp::object j_account = jpp::make_object(); @@ -373,13 +359,18 @@ namespace Mengine j_root.set( "ACCOUNT", j_account ); j_root.set( "SETTINGS", j_settings ); - if( Helper::writeJSONStream( j_root, file ) == false ) + const FilePath & settingsJSONPath = m_settingsJSONContent->getFilePath(); + + if( Helper::writeJSONFileCompact( j_root, m_fileGroup, settingsJSONPath, true, MENGINE_DOCUMENT_FACTORABLE ) == false ) { + LOGGER_ERROR( "account '%s' invalid write json to file '%s'" + , m_accountId.c_str() + , Helper::getContentFullPath( m_settingsJSONContent ).c_str() + ); + return false; } - m_fileGroup->closeOutputFile( file ); - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/AccountService/AccountService.cpp b/src/Services/AccountService/AccountService.cpp index 254d76308f..4ef4525347 100644 --- a/src/Services/AccountService/AccountService.cpp +++ b/src/Services/AccountService/AccountService.cpp @@ -801,6 +801,10 @@ namespace Mengine if( Helper::writeJSONStream( j_root, stream ) == false ) { + LOGGER_ERROR( "invalid write accounts '%s'" + , Game_AccountsPath.c_str() + ); + return false; } diff --git a/src/Services/MemoryService/MemoryService.cpp b/src/Services/MemoryService/MemoryService.cpp index cc0b62c0af..f907ebc116 100644 --- a/src/Services/MemoryService/MemoryService.cpp +++ b/src/Services/MemoryService/MemoryService.cpp @@ -83,7 +83,7 @@ namespace Mengine { MENGINE_UNUSED( _doc ); - size_t minSize = 0U; + size_t minSize = 0; size_t maxSize = MENGINE_UNKNOWN_SIZE; const VectorCacheBufferMemory::size_type invalidIndex = MENGINE_UNKNOWN_SIZE; diff --git a/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp b/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp index 63ff3bcfc1..d912f61909 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp +++ b/src/Systems/AndroidFileSystem/AndroidAssetGroupDirectory.cpp @@ -2,10 +2,10 @@ #include "Interface/UnicodeSystemInterface.h" #include "Interface/PlatformServiceInterface.h" -#include "Interface/AndroidAssetServiceInterface.h" #include "Environment/Android/AndroidEnv.h" #include "Environment/Android/AndroidActivityHelper.h" +#include "Environment/Android/AndroidAssetServiceInterface.h" #include "AndroidAssetInputStream.h" #include "AndroidMutexAssetInputStream.h" diff --git a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp index e18d8eeadb..f59b8f4069 100644 --- a/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidAssetInputStream.cpp @@ -2,7 +2,8 @@ #include "Interface/UnicodeSystemInterface.h" #include "Interface/PlatformServiceInterface.h" -#include "Interface/AndroidAssetServiceInterface.h" + +#include "Environment/Android/AndroidAssetServiceInterface.h" #include "Kernel/Logger.h" #include "Kernel/ThreadGuardScope.h" @@ -52,7 +53,7 @@ namespace Mengine int64_t size = ANDROID_ASSET_SERVICE() ->size( m_asset ); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > (size_t)size ) { diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp index c526801d26..d4d60cc2f2 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileInputStream.cpp @@ -14,6 +14,7 @@ #include "stdex/memorycopy.h" #include +#include namespace Mengine { @@ -49,11 +50,31 @@ namespace Mengine return false; } - ::fseek( m_file, 0, SEEK_END ); - int64_t size = ::ftell( m_file ); + int32_t result = ::fseeko( m_file, 0, SEEK_END ); + + if( result < 0 ) + { + LOGGER_ERROR( "invalid file '%s' seek end" + , fullPath + ); + + return false; + } + + off_t size = ::ftello( m_file ); + + if( size < 0 ) + { + LOGGER_ERROR( "invalid file '%s' tell" + , fullPath + ); + + return false; + } + ::rewind( m_file ); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > (size_t)size ) { @@ -82,9 +103,9 @@ namespace Mengine if( m_offset != 0 ) { - int64_t result = ::fseek( m_file, m_offset, SEEK_SET ); + int32_t result_set = ::fseeko( m_file, m_offset, SEEK_SET ); - if( result <= 0 ) + if( result_set < 0 ) { LOGGER_ERROR( "invalid file '%s' seek offset %zu size %zu" , fullPath @@ -254,6 +275,20 @@ namespace Mengine if( bytesRead == 0 ) { + int ferr = ::ferror( m_file ); + + if( ferr != 0 ) + { + LOGGER_ERROR( "file '%s:%s' invalid read size: %zu error: %d" + , Helper::getDebugFolderPath( this ).c_str() + , Helper::getDebugFilePath( this ).c_str() + , _size + , ferr + ); + + return false; + } + *_read = 0; return true; @@ -299,7 +334,7 @@ namespace Mengine { int64_t seek_pos = m_offset + _pos; - int64_t result = ::fseek( m_file, seek_pos, SEEK_SET ); + int32_t result = ::fseeko( m_file, seek_pos, SEEK_SET ); if( result < 0 ) { @@ -316,7 +351,19 @@ namespace Mengine m_carriage = 0; m_capacity = 0; - m_reading = static_cast(result) - m_offset; + off_t pos = ::ftello( m_file ); + + if( pos < 0 ) + { + LOGGER_ERROR( "file '%s:%s' invalid tell" + , Helper::getDebugFolderPath( this ).c_str() + , Helper::getDebugFilePath( this ).c_str() + ); + + return false; + } + + m_reading = static_cast(pos) - m_offset; } return true; @@ -360,8 +407,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidFileInputStream::time( uint64_t * const _time ) const { - MENGINE_UNUSED( _time ); - +#if defined(MENGINE_DEBUG) int fd = ::fileno( m_file ); struct stat fi; @@ -377,7 +423,12 @@ namespace Mengine *_time = (uint64_t)fi.st_mtime; + return true; +#else + MENGINE_UNUSED( _time ); + return false; +#endif } ////////////////////////////////////////////////////////////////////////// bool AndroidFileInputStream::memory( void ** const _memory, size_t * const _size ) @@ -393,4 +444,4 @@ namespace Mengine return m_file; } ////////////////////////////////////////////////////////////////////////// -} +} \ No newline at end of file diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp index 93c5862ba2..235209e61e 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp @@ -1,13 +1,16 @@ #include "AndroidFileOutputStream.h" #include "Interface/PlatformServiceInterface.h" -#include "Interface/AndroidAssetServiceInterface.h" +#include "Interface/FileSystemInterface.h" + +#include "Environment/Android/AndroidAssetServiceInterface.h" #include "Kernel/Logger.h" #include "Kernel/DebugFileHelper.h" #include "Kernel/ThreadGuardScope.h" #include "Kernel/NotificationHelper.h" #include "Kernel/DocumentHelper.h" +#include "Kernel/FilePathHelper.h" #include "Config/Path.h" @@ -17,6 +20,7 @@ namespace Mengine AndroidFileOutputStream::AndroidFileOutputStream() : m_file( nullptr ) , m_size( 0 ) + , m_withTemp( false ) { } ////////////////////////////////////////////////////////////////////////// @@ -27,19 +31,38 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidFileOutputStream::open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, bool _withTemp ) { - MENGINE_UNUSED( _withTemp ); - MENGINE_THREAD_GUARD_SCOPE( AndroidFileOutputStream, this ); + m_relationPath = _relationPath; + m_folderPath = _folderPath; + m_filePath = _filePath; + + m_withTemp = _withTemp; + Path fullPath = {'\0'}; - if( Helper::concatenateFilePath( {_relationPath, _folderPath, _filePath}, fullPath ) == false ) + if( m_withTemp == true ) { - LOGGER_ERROR( "invalid concatenate filePath '%s:%s'" - , _folderPath.c_str() - , _filePath.c_str() - ); - - return false; + if( Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath, STRINGIZE_FILEPATH_LOCAL( ".~tmp" )}, fullPath ) == false ) + { + LOGGER_ERROR( "invalid concatenate filePath '%s:%s' [temp]" + , m_folderPath.c_str() + , m_filePath.c_str() + ); + + return false; + } + } + else + { + if( Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath}, fullPath ) == false ) + { + LOGGER_ERROR( "invalid concatenate filePath '%s:%s'" + , m_folderPath.c_str() + , m_filePath.c_str() + ); + + return false; + } } FILE * file = ::fopen( fullPath, "wb" ); @@ -60,12 +83,12 @@ namespace Mengine #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, _folderPath, _filePath, false, false ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_OPEN_FILE, m_folderPath, m_filePath, false, false ); } #endif #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) - Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); + Helper::addDebugFilePath( this, m_relationPath, m_folderPath, m_filePath, MENGINE_DOCUMENT_FACTORABLE ); #endif return true; @@ -80,13 +103,15 @@ namespace Mengine return; } + MENGINE_ASSERTION_FATAL( m_size != 0, "file '%s:%s' is empty" + , m_folderPath.c_str() + , m_filePath.c_str() + ); + #if defined(MENGINE_DEBUG) if( SERVICE_IS_INITIALIZE( NotificationServiceInterface ) == true ) { - const FilePath & folderPath = Helper::getDebugFolderPath( this ); - const FilePath & filePath = Helper::getDebugFilePath( this ); - - NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, folderPath, filePath, false, false ); + NOTIFICATION_NOTIFY( NOTIFICATOR_DEBUG_CLOSE_FILE, m_folderPath, m_filePath, false, false ); } #endif @@ -95,6 +120,24 @@ namespace Mengine m_size = 0; + if( m_withTemp == true ) + { + Path fullPathTemp = {'\0'}; + Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath, STRINGIZE_FILEPATH_LOCAL( ".~tmp" )}, fullPathTemp ); + + Path fullPath = {'\0'}; + Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath}, fullPath ); + + if( FILE_SYSTEM() + ->moveFile( fullPathTemp, fullPath ) == false ) + { + LOGGER_ERROR( "invalid move close file from '%s' to '%s'" + , fullPathTemp + , fullPath + ); + } + } + #if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) Helper::removeDebugFilePath( this ); #endif @@ -106,8 +149,9 @@ namespace Mengine if( written != _size ) { - LOGGER_ERROR( "invalid write file '%s' size: %zu error: %d" - , Helper::getDebugFullPath( this ).c_str() + LOGGER_ERROR( "invalid write file '%s:%s' size: %zu error: %d" + , m_folderPath.c_str() + , m_filePath.c_str() , _size , errno ); diff --git a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h index 16d25d703d..c9f8be3f3a 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.h @@ -34,6 +34,12 @@ namespace Mengine size_t m_size; + FilePath m_relationPath; + FilePath m_folderPath; + FilePath m_filePath; + + bool m_withTemp; + MENGINE_THREAD_GUARD_INIT( AndroidFileOutputStream ); }; ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/AndroidFileSystem/AndroidFileSystem.cpp b/src/Systems/AndroidFileSystem/AndroidFileSystem.cpp index 3e2d38f755..05f39b543a 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileSystem.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileSystem.cpp @@ -136,6 +136,11 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidFileSystem::createDirectory( const Char * _basePath, const Char * _directory ) { + LOGGER_INFO( "file", "create directory path '%s' directory '%s'" + , _basePath + , _directory + ); + Path correctBasePath = {'\0'}; Helper::pathCorrectBackslashToA( correctBasePath, _basePath ); @@ -211,6 +216,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidFileSystem::removeFile( const Char * _filePath ) { + LOGGER_INFO( "file", "remove file '%s'" + , _filePath + ); + Path pathCorrect = {'\0'}; Helper::pathCorrectBackslashToA( pathCorrect, _filePath ); @@ -226,6 +235,11 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool AndroidFileSystem::moveFile( const Char * _oldFilePath, const Char * _newFilePath ) { + LOGGER_INFO( "file", "move file from '%s' to '%s'" + , _oldFilePath + , _newFilePath + ); + Path oldPathCorrect = {'\0'}; Helper::pathCorrectBackslashToA( oldPathCorrect, _oldFilePath ); @@ -233,7 +247,7 @@ namespace Mengine Helper::pathCorrectBackslashToA( newPathCorrect, _newFilePath ); struct stat sb; - if( stat( newPathCorrect, &sb ) == 0 && ((sb.st_mode) & S_IFMT) != S_IFDIR ) + if( ::stat( newPathCorrect, &sb ) == 0 && ((sb.st_mode) & S_IFMT) != S_IFDIR ) { int result_remove = ::remove( newPathCorrect ); @@ -284,7 +298,7 @@ namespace Mengine uint64_t AndroidFileSystem::getFileTime( const Char * _filePath ) const { struct stat fs; - if( stat( _filePath, &fs ) != 0 ) + if( ::stat( _filePath, &fs ) != 0 ) { return 0U; } diff --git a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp index dd76c3dc5f..234f48d764 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp @@ -2,7 +2,8 @@ #include "Interface/UnicodeSystemInterface.h" #include "Interface/ThreadServiceInterface.h" -#include "Interface/AndroidAssetServiceInterface.h" + +#include "Environment/Android/AndroidAssetServiceInterface.h" #include "Kernel/Logger.h" #include "Kernel/ThreadMutexScope.h" @@ -46,7 +47,7 @@ namespace Mengine size_t size = m_stream->size(); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { diff --git a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp index d4da056b90..ffd5802662 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp @@ -44,7 +44,7 @@ namespace Mengine size_t size = m_stream->size(); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { @@ -179,9 +179,9 @@ namespace Mengine size_t pos = m_offset + current; - int64_t result = ::fseek( file, pos, SEEK_SET ); + int32_t result = ::fseeko( file, pos, SEEK_SET ); - if( result <= 0 ) + if( result < 0 ) { LOGGER_ERROR( "invalid seek pos: %zu size: %zu" , pos diff --git a/src/Systems/AppleFileSystem/AppleFileInputStream.mm b/src/Systems/AppleFileSystem/AppleFileInputStream.mm index f7053a7f16..42b15a42af 100644 --- a/src/Systems/AppleFileSystem/AppleFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileInputStream.mm @@ -67,7 +67,7 @@ size_t size = attribute_filesize.unsignedLongLongValue; - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > (size_t)size ) { diff --git a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm index ec3a76a293..122d2dd513 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm @@ -35,7 +35,6 @@ Path concatenatePath = {'\0'}; -#if defined(MENGINE_PLATFORM_WINDOWS) && !defined(MENGINE_PLATFORM_UWP) if( m_withTemp == true ) { if( Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath, STRINGIZE_FILEPATH_LOCAL( ".~tmp" )}, concatenatePath ) == false ) @@ -60,17 +59,6 @@ return false; } } -#else - if( Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath}, concatenatePath ) == false ) - { - LOGGER_ERROR( "invalid concatenate filePath '%s:%s'" - , m_folderPath.c_str() - , m_filePath.c_str() - ); - - return false; - } -#endif NSFileHandle * fileHandle = [NSFileHandle fileHandleForWritingAtPath:@(concatenatePath)]; @@ -93,6 +81,10 @@ m_fileHandle = fileHandle; m_size = 0; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, m_relationPath, m_folderPath, m_filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif return true; } @@ -103,11 +95,38 @@ { return true; } + + MENGINE_ASSERTION_FATAL( m_size != 0, "file '%s:%s' is empty" + , m_folderPath.c_str() + , m_filePath.c_str() + ); [m_fileHandle closeFile]; m_fileHandle = nil; m_size = 0; + + if( m_withTemp == true ) + { + Path fullPathTemp = {'\0'}; + Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath, STRINGIZE_FILEPATH_LOCAL( ".~tmp" )}, fullPath ); + + Path fullPath = {'\0'}; + Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath}, fullPath ); + + if( FILE_SYSTEM() + ->moveFile( fullPathTemp, fullPath ) == false ) + { + LOGGER_ERROR( "invalid move close file from '%s' to '%s'" + , fullPathTemp + , fullPath + ); + } + } + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// size_t AppleFileOutputStream::write( const void * _data, size_t _size ) diff --git a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm index 2b0c078d54..3456b85962 100644 --- a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm @@ -43,12 +43,15 @@ ////////////////////////////////////////////////////////////////////////// bool AppleMutexFileInputStream::open( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, size_t _offset, size_t _size, bool _streaming, bool _share ) { + MENGINE_UNUSED( _relationPath ); + MENGINE_UNUSED( _folderPath ); + MENGINE_UNUSED( _filePath ); MENGINE_UNUSED( _streaming ); MENGINE_UNUSED( _share ); size_t size = m_stream->size(); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { diff --git a/src/Systems/SDL2FileSystem/SDL2FileInputStream.cpp b/src/Systems/SDL2FileSystem/SDL2FileInputStream.cpp index 50f9716acf..5980d6139a 100644 --- a/src/Systems/SDL2FileSystem/SDL2FileInputStream.cpp +++ b/src/Systems/SDL2FileSystem/SDL2FileInputStream.cpp @@ -64,7 +64,7 @@ namespace Mengine return false; } - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > (size_t)size ) { diff --git a/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.cpp b/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.cpp index 8fb37d05c6..07fff67a92 100644 --- a/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.cpp +++ b/src/Systems/SDL2FileSystem/SDL2MutexFileInputStream.cpp @@ -53,7 +53,7 @@ namespace Mengine size_t size = m_stream->size(); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { diff --git a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp index 549b800913..bd7597a516 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.cpp @@ -116,6 +116,11 @@ namespace Mengine } #endif + MENGINE_ASSERTION_FATAL( m_size != 0, "file '%s:%s' is empty" + , m_folderPath.c_str() + , m_filePath.c_str() + ); + this->flush(); ::CloseHandle( m_hFile ); diff --git a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp index c724926ada..6cf8ec1230 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.cpp @@ -59,7 +59,9 @@ namespace Mengine { if( _offset + _size > size ) { - LOGGER_ERROR( "invalid file '%s' range %zu:%zu size %zu" + LOGGER_ERROR( "invalid relation '%s' folder '%s' file '%s' range %zu:%zu size %zu" + , _relationPath.c_str() + , _folderPath.c_str() , _filePath.c_str() , _offset , _size From e4965c1f4727f3546ab737e708826ba56cd4e84c Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 22 Sep 2025 23:53:46 +0300 Subject: [PATCH 060/169] fix ios --- src/Environment/Apple/AppleKernelService.h | 2 +- src/Environment/iOS/iOSKernelService.h | 3 +-- src/Interface/RenderServiceInterface.h | 4 ++-- src/Kernel/AllocatorHelper.h | 6 +++--- src/Platforms/iOSPlatform/iOSPlatformService.mm | 2 +- .../AppleUserNotificationCenterApplicationDelegate.h | 2 +- .../AppleUserNotificationCenterApplicationDelegate.mm | 9 +++++++-- .../HotSpotPolygonDebugRender.cpp | 10 +++++----- .../NodeDebugRenderPlugin/NodeDebugRenderHelper.cpp | 6 +++--- src/Services/RenderService/RenderService.cpp | 4 ++-- src/Services/RenderService/RenderService.h | 4 ++-- src/Systems/AppleFileSystem/AppleFileOutputStream.mm | 3 ++- 12 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/Environment/Apple/AppleKernelService.h b/src/Environment/Apple/AppleKernelService.h index 0a87fcc56a..926330bbc4 100644 --- a/src/Environment/Apple/AppleKernelService.h +++ b/src/Environment/Apple/AppleKernelService.h @@ -1,6 +1,6 @@ #pragma once -#include "Interface/AppleKernelServiceInterface.h" +#import "Environment/Apple/AppleKernelServiceInterface.h" #include "Kernel/ServiceBase.h" diff --git a/src/Environment/iOS/iOSKernelService.h b/src/Environment/iOS/iOSKernelService.h index f46917e512..36a48b08a2 100644 --- a/src/Environment/iOS/iOSKernelService.h +++ b/src/Environment/iOS/iOSKernelService.h @@ -1,7 +1,6 @@ #pragma once -#include "Interface/iOSKernelServiceInterface.h" -#include "Interface/LoggerInterface.h" +#import "Environment/iOS/iOSKernelServiceInterface.h" #include "Kernel/ServiceBase.h" diff --git a/src/Interface/RenderServiceInterface.h b/src/Interface/RenderServiceInterface.h index 79e82f414c..1a6377def1 100644 --- a/src/Interface/RenderServiceInterface.h +++ b/src/Interface/RenderServiceInterface.h @@ -51,8 +51,8 @@ namespace Mengine SERVICE_DECLARE( "RenderService" ) public: - virtual VectorRenderVertex2D & getDebugRenderVertex2D( uint32_t _count ) = 0; - virtual VectorRenderIndex & getDebugRenderIndex( uint32_t _count ) = 0; + virtual VectorRenderVertex2D & getDebugRenderVertex2D( size_t _count ) = 0; + virtual VectorRenderIndex & getDebugRenderIndex( size_t _count ) = 0; public: virtual bool createRenderWindow( const Resolution & _windowResolution, const Viewport & _renderViewport, bool _vsync, uint32_t _bits, bool _fullscreen, int32_t _FSAAType, int32_t _FSAAQuality ) = 0; diff --git a/src/Kernel/AllocatorHelper.h b/src/Kernel/AllocatorHelper.h index 9e8ac9867d..f3245c0917 100644 --- a/src/Kernel/AllocatorHelper.h +++ b/src/Kernel/AllocatorHelper.h @@ -26,7 +26,7 @@ namespace Mengine } ////////////////////////////////////////////////////////////////////////// template - T * allocateMemoryNT( uint32_t _count, const Char * _doc ) + T * allocateMemoryNT( size_t _count, const Char * _doc ) { const size_t element_size = sizeof( T ); const size_t memory_size = element_size * _count; @@ -36,7 +36,7 @@ namespace Mengine } ////////////////////////////////////////////////////////////////////////// template - T * callocateMemoryNT( uint32_t _count, const Char * _doc ) + T * callocateMemoryNT( size_t _count, const Char * _doc ) { const size_t element_size = sizeof( T ); void * ptr = Helper::callocateMemory( _count, element_size, _doc ); @@ -64,4 +64,4 @@ namespace Mengine } ////////////////////////////////////////////////////////////////////////// } -} \ No newline at end of file +} diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index 6ce7894edc..ac29b3ad4b 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -12,7 +12,6 @@ #include "Interface/DateTimeSystemInterface.h" #include "Interface/ThreadServiceInterface.h" #include "Interface/EnvironmentServiceInterface.h" -#include "Interface/iOSKernelServiceInterface.h" #include "Interface/AccountServiceInterface.h" #include "Interface/AnalyticsServiceInterface.h" @@ -20,6 +19,7 @@ #import "Environment/iOS/iOSApplication.h" #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSKernelServiceInterface.h" #include "iOSAnalyticsEventProvider.h" diff --git a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.h b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.h index 59f7b620f2..8325ee405e 100644 --- a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.h +++ b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.h @@ -8,7 +8,7 @@ + (instancetype)sharedInstance; -- (void)scheduleNotification:(NSNumber *)badge withTitle:(NSString *)title withBody:(NSString *)body withDelay:(NSTimeInterval)delay; +- (void)scheduleNotification:(NSNumber *)badge withTitle:(NSString *)title withBody:(NSString *)body withDelay:(NSTimeInterval)delay relevanceScore:(double)relevanceScore; @property (nonatomic, assign) BOOL m_notificationPermissionGranted; diff --git a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm index 0bf457915f..e65c2de75a 100644 --- a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm +++ b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm @@ -16,12 +16,17 @@ + (instancetype)sharedInstance { return sharedInstance; } -- (void)scheduleNotification:(NSNumber *)badge withTitle:(NSString *)title withBody:(NSString *)body withDelay:(NSTimeInterval)delay { +- (void)scheduleNotification:(NSNumber *)badge withTitle:(NSString *)title withBody:(NSString *)body withDelay:(NSTimeInterval)delay relevanceScore:(double)relevanceScore { UNMutableNotificationContent * content = [[UNMutableNotificationContent alloc] init]; content.title = title; content.body = body; content.sound = [UNNotificationSound defaultSound]; content.badge = badge; + + if (@available(iOS 15.0, *)) { + content.interruptionLevel = UNNotificationInterruptionLevelTimeSensitive; + content.relevanceScore = relevanceScore; // от 0.0 до 1.0 + } UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:delay repeats:NO]; @@ -81,7 +86,7 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNot , notification.request.content.body ); - completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge); + completionHandler(UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionList | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge); } - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) API_UNAVAILABLE(tvos) { diff --git a/src/Plugins/NodeDebugRenderPlugin/HotSpotPolygonDebugRender.cpp b/src/Plugins/NodeDebugRenderPlugin/HotSpotPolygonDebugRender.cpp index 5d235aa94a..9e95a7e301 100644 --- a/src/Plugins/NodeDebugRenderPlugin/HotSpotPolygonDebugRender.cpp +++ b/src/Plugins/NodeDebugRenderPlugin/HotSpotPolygonDebugRender.cpp @@ -23,14 +23,14 @@ namespace Mengine const Polygon & polygon = _node->getPolygon(); - uint32_t numpoints = polygon.size(); + Polygon::size_type numpoints = polygon.size(); if( numpoints == 0 ) { return; } - uint32_t vertexCount = numpoints * 2; + Polygon::size_type vertexCount = numpoints * 2; VectorRenderVertex2D & vertices = RENDER_SERVICE() ->getDebugRenderVertex2D( vertexCount ); @@ -50,9 +50,9 @@ namespace Mengine const VectorPoints & ring = polygon.getPoints(); - for( uint32_t i = 0; i != numpoints; ++i ) + for( Polygon::size_type i = 0; i != numpoints; ++i ) { - uint32_t j = (i + 1) % numpoints; + Polygon::size_type j = (i + 1) % numpoints; mt::vec3f trP0; mt::mul_v3_v2_m4( &trP0, ring[i], wm ); @@ -88,4 +88,4 @@ namespace Mengine Helper::nodeDebugRenderLine( _renderPipeline, _context, vertices, MENGINE_DOCUMENT_FORWARD ); } ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file +} diff --git a/src/Plugins/NodeDebugRenderPlugin/NodeDebugRenderHelper.cpp b/src/Plugins/NodeDebugRenderPlugin/NodeDebugRenderHelper.cpp index 0752afd60d..64311e413a 100644 --- a/src/Plugins/NodeDebugRenderPlugin/NodeDebugRenderHelper.cpp +++ b/src/Plugins/NodeDebugRenderPlugin/NodeDebugRenderHelper.cpp @@ -100,14 +100,14 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void nodeDebugRenderPolygon( const RenderPipelineInterfacePtr & _renderPipeline, const RenderContext * _context, const mt::mat4f & _wm, const Polygon & _polygon, ColorValue_ARGB _color, const DocumentInterfacePtr & _doc ) { - uint32_t numpoints = _polygon.size(); + Polygon::size_type numpoints = _polygon.size(); if( numpoints == 0 ) { return; } - uint32_t vertexCount = numpoints * 2; + Polygon::size_type vertexCount = numpoints * 2; VectorRenderVertex2D & vertices = RENDER_SERVICE() ->getDebugRenderVertex2D( vertexCount ); @@ -185,4 +185,4 @@ namespace Mengine } ////////////////////////////////////////////////////////////////////////// } -} \ No newline at end of file +} diff --git a/src/Services/RenderService/RenderService.cpp b/src/Services/RenderService/RenderService.cpp index ad03ae8989..a62788c2d6 100644 --- a/src/Services/RenderService/RenderService.cpp +++ b/src/Services/RenderService/RenderService.cpp @@ -1128,7 +1128,7 @@ namespace Mengine return batch; } ////////////////////////////////////////////////////////////////////////// - VectorRenderVertex2D & RenderService::getDebugRenderVertex2D( uint32_t _count ) + VectorRenderVertex2D & RenderService::getDebugRenderVertex2D( size_t _count ) { m_debugRenderVertices.emplace_back( VectorRenderVertex2D() ); VectorRenderVertex2D & vertices_array = m_debugRenderVertices.back(); @@ -1137,7 +1137,7 @@ namespace Mengine return vertices_array; } ////////////////////////////////////////////////////////////////////////// - VectorRenderIndex & RenderService::getDebugRenderIndex( uint32_t _count ) + VectorRenderIndex & RenderService::getDebugRenderIndex( size_t _count ) { m_debugRenderIndices.emplace_back( VectorRenderIndex() ); VectorRenderIndex & indices_array = m_debugRenderIndices.back(); diff --git a/src/Services/RenderService/RenderService.h b/src/Services/RenderService/RenderService.h index 971f44cab6..59db610c37 100644 --- a/src/Services/RenderService/RenderService.h +++ b/src/Services/RenderService/RenderService.h @@ -51,8 +51,8 @@ namespace Mengine const RenderBatchInterfacePtr & requestRenderBatch( const RenderVertexAttributeInterfacePtr & _vertexAttribute, uint32_t _vertexCount, uint32_t _indexCount, const DocumentInterfacePtr & _doc ) override; public: - VectorRenderVertex2D & getDebugRenderVertex2D( uint32_t _count ) override; - VectorRenderIndex & getDebugRenderIndex( uint32_t _count ) override; + VectorRenderVertex2D & getDebugRenderVertex2D( size_t _count ) override; + VectorRenderIndex & getDebugRenderIndex( size_t _count ) override; public: bool beginScene( const RenderPipelineInterfacePtr & _pipeline ) override; diff --git a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm index 122d2dd513..41ce037996 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm @@ -1,6 +1,7 @@ #include "AppleFileOutputStream.h" #include "Interface/PlatformServiceInterface.h" +#include "Interface/FileSystemInterface.h" #import "Environment/Apple/AppleDetail.h" @@ -109,7 +110,7 @@ if( m_withTemp == true ) { Path fullPathTemp = {'\0'}; - Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath, STRINGIZE_FILEPATH_LOCAL( ".~tmp" )}, fullPath ); + Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath, STRINGIZE_FILEPATH_LOCAL( ".~tmp" )}, fullPathTemp ); Path fullPath = {'\0'}; Helper::concatenateFilePath( {m_relationPath, m_folderPath, m_filePath}, fullPath ); From a8e469ce9daf7a454dbb7d410d701d453dbe9c81 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 23 Sep 2025 18:59:02 +0300 Subject: [PATCH 061/169] fix DebugAllocatorSystem --- src/Environment/Apple/AppleDetail.mm | 2 +- .../AppleFileSystem/AppleFileInputStream.mm | 70 +++++------ .../AppleFileSystem/AppleFileOutputStream.mm | 1 + .../AppleMutexFileInputStream.mm | 112 +++++++++--------- .../DebugAllocatorSystem.cpp | 50 ++++---- 5 files changed, 120 insertions(+), 115 deletions(-) diff --git a/src/Environment/Apple/AppleDetail.mm b/src/Environment/Apple/AppleDetail.mm index a5f2ca29e5..9120656c42 100644 --- a/src/Environment/Apple/AppleDetail.mm +++ b/src/Environment/Apple/AppleDetail.mm @@ -136,7 +136,7 @@ + (BOOL)getParamsFromJSON:(NSString * _Nonnull)_in outParams:(Mengine::Params * return YES; } -+ (void)getParamsFromNSDictionary:(NSDictionary *) _in outParams:(Mengine::Params * const) _out { ++ (void)getParamsFromNSDictionary:(NSDictionary *)_in outParams:(Mengine::Params * const)_out { if (_in == nil) { return; } diff --git a/src/Systems/AppleFileSystem/AppleFileInputStream.mm b/src/Systems/AppleFileSystem/AppleFileInputStream.mm index 42b15a42af..125e7f2243 100644 --- a/src/Systems/AppleFileSystem/AppleFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileInputStream.mm @@ -259,43 +259,45 @@ ////////////////////////////////////////////////////////////////////////// bool AppleFileInputStream::read_( void * const _buf, size_t _offset, size_t _size, size_t * const _read ) { - if( _size == 0 ) - { - *_read = 0; - - return true; - } - - uint8_t * buf_offset = MENGINE_PVOID_OFFSET( _buf, _offset ); - - NSError * error = nil; - NSData * data = [m_fileHandle readDataUpToLength:_size error:&error]; - - if( error != nil ) - { - LOGGER_ERROR( "read file '%s' offset %zu size %zu:%zu get error %s" - , Helper::getDebugFullPath( this ).c_str() - , _offset - , _size - , m_size - , [[AppleDetail getMessageFromNSError:error] UTF8String] - ); + @autoreleasepool { + if( _size == 0 ) + { + *_read = 0; + + return true; + } + + uint8_t * buf_offset = MENGINE_PVOID_OFFSET( _buf, _offset ); + + NSError * error = nil; + NSData * data = [m_fileHandle readDataUpToLength:_size error:&error]; + + if( data == nil ) + { + LOGGER_ERROR( "read file '%s' offset %zu size %zu:%zu get error %s" + , Helper::getDebugFullPath( this ).c_str() + , _offset + , _size + , m_size + , [[AppleDetail getMessageFromNSError:error] UTF8String] + ); + + return false; + } + + if( data.length == 0 ) + { + *_read = 0; + + return true; + } + + stdex::memorycopy( buf_offset, 0, data.bytes, data.length ); + + *_read = data.length; - return false; - } - - if( data.length == 0 ) - { - *_read = 0; - return true; } - - stdex::memorycopy( buf_offset, 0, data.bytes, data.length ); - - *_read = data.length; - - return true; } ////////////////////////////////////////////////////////////////////////// bool AppleFileInputStream::seek( size_t _pos ) diff --git a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm index 41ce037996..9ed572806f 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm @@ -8,6 +8,7 @@ #include "Kernel/Logger.h" #include "Kernel/PathHelper.h" #include "Kernel/FilePathHelper.h" +#include "Kernel/DebugFileHelper.h" #include "Config/Path.h" diff --git a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm index 3456b85962..0906acb5a1 100644 --- a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm @@ -171,64 +171,66 @@ ////////////////////////////////////////////////////////////////////////// bool AppleMutexFileInputStream::read_( void * const _buf, size_t _offset, size_t _size, size_t * const _read ) { - if( _size == 0 ) - { - *_read = 0; - - return true; - } - - MENGINE_THREAD_MUTEX_SCOPE( m_mutex ); - - NSFileHandle * fileHandle = m_stream->getFileHandle(); - - size_t current = m_reading - m_capacity + m_carriage; - - size_t seek_pos = m_offset + current; - - NSError * seek_error = nil; - if( [fileHandle seekToOffset:seek_pos error:&seek_error] == NO ) - { - LOGGER_ERROR( "file '%s' seek %zu:%zu get [error: %s]" - , Helper::getDebugFullPath( m_stream ).c_str() - , seek_pos - , m_size - , [[AppleDetail getMessageFromNSError:seek_error] UTF8String] - ); - - return false; - } - - uint8_t * buf_offset = MENGINE_PVOID_OFFSET( _buf, _offset ); - - NSError * read_error = nil; - NSData * data = [fileHandle readDataUpToLength:_size error:&read_error]; - - if( read_error != nil ) - { - LOGGER_ERROR( "read file '%s' offset %zu size %zu:%zu get error %s" - , Helper::getDebugFullPath( m_stream ).c_str() - , _offset - , _size - , m_size - , [[AppleDetail getMessageFromNSError:read_error] UTF8String] - ); + @autoreleasepool { + if( _size == 0 ) + { + *_read = 0; + + return true; + } + + MENGINE_THREAD_MUTEX_SCOPE( m_mutex ); + + NSFileHandle * fileHandle = m_stream->getFileHandle(); + + size_t current = m_reading - m_capacity + m_carriage; + + size_t seek_pos = m_offset + current; + + NSError * seek_error = nil; + if( [fileHandle seekToOffset:seek_pos error:&seek_error] == NO ) + { + LOGGER_ERROR( "file '%s' seek %zu:%zu get [error: %s]" + , Helper::getDebugFullPath( m_stream ).c_str() + , seek_pos + , m_size + , [[AppleDetail getMessageFromNSError:seek_error] UTF8String] + ); + + return false; + } + + uint8_t * buf_offset = MENGINE_PVOID_OFFSET( _buf, _offset ); + + NSError * read_error = nil; + NSData * data = [fileHandle readDataUpToLength:_size error:&read_error]; + + if( data == nil ) + { + LOGGER_ERROR( "read file '%s' offset %zu size %zu:%zu get error %s" + , Helper::getDebugFullPath( m_stream ).c_str() + , _offset + , _size + , m_size + , [[AppleDetail getMessageFromNSError:read_error] UTF8String] + ); + + return false; + } + + if( data.length == 0 ) + { + *_read = 0; + + return true; + } + + stdex::memorycopy( buf_offset, 0, data.bytes, data.length ); + + *_read = data.length; - return false; - } - - if( data.length == 0 ) - { - *_read = 0; - return true; } - - stdex::memorycopy( buf_offset, 0, data.bytes, data.length ); - - *_read = data.length; - - return true; } ////////////////////////////////////////////////////////////////////////// bool AppleMutexFileInputStream::seek( size_t _pos ) diff --git a/src/Systems/DebugAllocatorSystem/DebugAllocatorSystem.cpp b/src/Systems/DebugAllocatorSystem/DebugAllocatorSystem.cpp index 60b8e079fd..5eaf2e28a2 100644 --- a/src/Systems/DebugAllocatorSystem/DebugAllocatorSystem.cpp +++ b/src/Systems/DebugAllocatorSystem/DebugAllocatorSystem.cpp @@ -16,7 +16,7 @@ #include "Config/StdLib.h" #if !defined(MENGINE_DEBUG_ALLOCATOR_REPORT) -# ifdef MENGINE_PLATFORM_WINDOWS +# ifdef MENGINE_DEBUG # define MENGINE_DEBUG_ALLOCATOR_REPORT 1 # else # define MENGINE_DEBUG_ALLOCATOR_REPORT 0 @@ -28,7 +28,7 @@ #endif #if !defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION) -# ifdef MENGINE_PLATFORM_WINDOWS +# ifdef MENGINE_DEBUG # define MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION 1 # else # define MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION 0 @@ -60,7 +60,7 @@ namespace Mengine //////////////////////////////////////////////////////////////////////// static void setMemoryOverrideCorruptionTrap( void * _p, size_t _size ) { - uint8_t * b = MENGINE_PVOID_OFFSET( _p, _size ); + uint8_t * b = MENGINE_PVOID_OFFSET( _p, _size - MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE ); StdString::memset( b, 0xEF, MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE ); } @@ -138,15 +138,15 @@ namespace Mengine ); StdString::memset( new_mem, 0xDB, _size ); + + size_t usage_size = MENGINE_MALLOC_SIZE( new_mem ); + + MENGINE_ASSERTION_FATAL( usage_size != (size_t)-1, "invalid get memory size" ); #if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 - Detail::setMemoryOverrideCorruptionTrap( new_mem, _size ); + Detail::setMemoryOverrideCorruptionTrap( new_mem, usage_size ); #endif - size_t usage_size = MENGINE_MALLOC_SIZE( new_mem ); - - MENGINE_ASSERTION_FATAL( usage_size != (size_t)-1, "invalid get memory size" ); - #if defined(MENGINE_DEBUG_ALLOCATOR_REPORT_ENABLE) this->report( _doc, usage_size, 0 ); #endif @@ -210,15 +210,15 @@ namespace Mengine ); StdString::memset( new_mem, 0x00, calloc_size ); - -#if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 - Detail::setMemoryOverrideCorruptionTrap( new_mem, calloc_size ); -#endif - + size_t usage_size = MENGINE_MALLOC_SIZE( new_mem ); MENGINE_ASSERTION_FATAL( usage_size != (size_t)-1, "invalid get memory size" ); +#if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 + Detail::setMemoryOverrideCorruptionTrap( new_mem, usage_size ); +#endif + #if defined(MENGINE_DEBUG_ALLOCATOR_REPORT_ENABLE) this->report( _doc, usage_size, 0 ); #endif @@ -248,15 +248,15 @@ namespace Mengine ); StdString::memset( new_mem, 0xDB, _size ); - -#if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 - Detail::setMemoryOverrideCorruptionTrap( new_mem, _size ); -#endif - + size_t usage_size = MENGINE_MALLOC_SIZE( new_mem ); MENGINE_ASSERTION_FATAL( usage_size != (size_t)-1, "invalid get memory size" ); +#if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 + Detail::setMemoryOverrideCorruptionTrap( new_mem, usage_size ); +#endif + #if defined(MENGINE_DEBUG_ALLOCATOR_REPORT_ENABLE) this->report( _doc, usage_size, 0 ); #endif @@ -288,23 +288,23 @@ namespace Mengine , _mem , _doc ); - -#if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 - Detail::setMemoryOverrideCorruptionTrap( new_mem, _size ); -#endif - + size_t usage_size = MENGINE_MALLOC_SIZE( new_mem ); MENGINE_ASSERTION_FATAL( usage_size != (size_t)-1, "invalid get memory size" ); +#if defined(MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_ENABLE) && MENGINE_DEBUG_ALLOCATOR_MEMORY_OVERRIDE_CORRUPTION_SIZE > 0 + Detail::setMemoryOverrideCorruptionTrap( new_mem, usage_size ); +#endif + #if defined(MENGINE_DEBUG_ALLOCATOR_REPORT_ENABLE) this->report( _doc, usage_size, old_size ); #endif STATISTIC_ADD_INTEGER( STATISTIC_ALLOCATOR_NEW, usage_size ); - STATISTIC_ADD_INTEGER( STATISTIC_ALLOCATOR_SIZE, usage_size ); - STATISTIC_ADD_INTEGER( STATISTIC_ALLOCATOR_FREE, old_size ); + + STATISTIC_ADD_INTEGER( STATISTIC_ALLOCATOR_SIZE, usage_size ); STATISTIC_DEL_INTEGER( STATISTIC_ALLOCATOR_SIZE, old_size ); return new_mem; From 88b0e27a032b8a93b825588fb521f5c93c7532f9 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 24 Sep 2025 00:44:16 +0300 Subject: [PATCH 062/169] improve logs --- .../PythonFramework/EngineScriptEmbedding.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index f9e3f3c95d..026a025432 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -130,6 +130,7 @@ #include "Kernel/ContentHelper.h" #include "Kernel/PrototypeHelper.h" #include "Kernel/NodeScreenPosition.h" +#include "Kernel/TagsHelper.h" #include "Config/StdString.h" #include "Config/Lambda.h" @@ -4201,6 +4202,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void s_incrementResources( const ConstString & _groupName ) { + LOGGER_INFO( "resource", "increment resources group: %s" + , _groupName.c_str() + ); + RESOURCE_SERVICE() ->foreachGroupResources( _groupName, []( const ResourcePtr & _resource ) { @@ -4217,6 +4222,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void s_decrementResources( const ConstString & _groupName ) { + LOGGER_INFO( "resource", "decrement resources group: %s" + , _groupName.c_str() + ); + RESOURCE_SERVICE() ->foreachGroupResources( _groupName, []( const ResourcePtr & _resource ) { @@ -4226,6 +4235,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void s_incrementResourcesTags( const Tags & _tags ) { + LOGGER_INFO( "resource", "increment resources tags: %s" + , Helper::tagsToString( _tags ).c_str() + ); + RESOURCE_SERVICE() ->foreachTagsResources( _tags, []( const ResourcePtr & _resource ) { @@ -4242,6 +4255,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void s_decrementResourcesTags( const Tags & _tags ) { + LOGGER_INFO( "resource", "decrement resources tags: %s" + , Helper::tagsToString( _tags ).c_str() + ); + RESOURCE_SERVICE() ->foreachTagsResources( _tags, []( const ResourcePtr & _resource ) { From 37a8fcc1ce5f5379e344aaef9ef98972e926a34e Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 24 Sep 2025 21:01:31 +0300 Subject: [PATCH 063/169] fix android AndroidPlatform_unfreezeEvent update android com.datadoghq:dd-sdk-android-logs --- gradle/gradle/wrapper/gradle-wrapper.properties | 4 ++-- .../InterstitialAd/MengineAppLovinInterstitialAd.java | 2 +- .../Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java | 2 +- gradle/plugins/DataDog/build.gradle | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index f8bf34ad13..737a1463ee 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Jul 03 22:32:42 EEST 2025 +#Wed Sep 24 12:58:29 EEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index e1e7c98431..fa5b7c5797 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -245,7 +245,7 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setInterstitialState("hidden." + placement + "." + ad.getNetworkName()); - MengineNative.AndroidPlatform_unfreezeEvent( false, false ); + MengineNative.AndroidPlatform_unfreezeEvent( true, true ); m_showing = false; diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index e3250169b4..8bf5395e70 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -291,7 +291,7 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setRewardedState("hidden." + placement + "." + ad.getNetworkName()); - MengineNative.AndroidPlatform_unfreezeEvent( false, false ); + MengineNative.AndroidPlatform_unfreezeEvent( true, true ); m_showing = false; diff --git a/gradle/plugins/DataDog/build.gradle b/gradle/plugins/DataDog/build.gradle index 51667baa00..e9cf6059f3 100644 --- a/gradle/plugins/DataDog/build.gradle +++ b/gradle/plugins/DataDog/build.gradle @@ -15,5 +15,5 @@ android { } dependencies { - implementation 'com.datadoghq:dd-sdk-android-logs:3.0.0' + implementation 'com.datadoghq:dd-sdk-android-logs:3.1.0' } \ No newline at end of file From f998f0ec389b370b59ab4447dd4bfb5dba64b980 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 25 Sep 2025 20:31:35 +0300 Subject: [PATCH 064/169] fix SurfaceSound --- .../PythonFramework/SoundScriptEmbedding.cpp | 13 +++++++++++-- src/Kernel/SurfaceSound.cpp | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index 366657cca9..c4968feec8 100644 --- a/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp @@ -22,6 +22,7 @@ #include "Kernel/ResourceHelper.h" #include "Kernel/ResourceSound.h" #include "Kernel/VocabularyHelper.h" +#include "Kernel/DebugFileHelper.h" #include "Config/Lambda.h" @@ -562,6 +563,12 @@ namespace Mengine return false; } + LOGGER_INFO( "sound", "[script] sound fade out to '%f' in time '%f' file '%s'" + , _to + , _time + , Helper::getDebugFullPath( _identity->getSoundSource()->getSoundBuffer()->getDecoder()->getStream() ).c_str() + ); + PythonSoundAffectorCallbackPtr callback = createSoundAffectorCallback( _identity, _cb, _args ); EasingInterfacePtr easing = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "Easing" ), _easingType ); @@ -598,8 +605,9 @@ namespace Mengine if( soundIdentity == nullptr ) { - LOGGER_ERROR( "invalid create sound source '%s'" + LOGGER_ERROR( "invalid create sound source resource '%s' file '%s'" , _resourceName.c_str() + , Helper::getResourceFilePathByName( _resourceName ).c_str() ); return nullptr; @@ -608,8 +616,9 @@ namespace Mengine if( SOUND_SERVICE() ->playEmitter( soundIdentity ) == false ) { - LOGGER_WARNING( "resource sound '%s' invalid play" + LOGGER_WARNING( "invalid play emitter resource '%s' file '%s'" , _resourceName.c_str() + , Helper::getResourceFilePathByName( _resourceName ).c_str() ); SOUND_SERVICE() diff --git a/src/Kernel/SurfaceSound.cpp b/src/Kernel/SurfaceSound.cpp index 0adfc6241e..633cb51b62 100644 --- a/src/Kernel/SurfaceSound.cpp +++ b/src/Kernel/SurfaceSound.cpp @@ -221,7 +221,7 @@ namespace Mengine if( SOUND_SERVICE() ->playEmitter( m_soundIdentity ) == false ) { - LOGGER_WARNING( "surface sound '%s' invalid play [%u] resource '%s'" + LOGGER_WARNING( "surface sound '%s' invalid play identity [%u] resource: '%s'" , this->getName().c_str() , m_soundIdentity->getUniqueIdentity() , m_resourceSound->getName().c_str() @@ -329,7 +329,7 @@ namespace Mengine ->stopEmitter( m_soundIdentity ); } - EVENTABLE_METHOD( EVENT_ANIMATION_END ) + EVENTABLE_METHOD( EVENT_ANIMATION_STOP ) ->onAnimationStop( _enumerator ); return true; From ec9b16aa8739b920fedd0bdbc624df2a476457f6 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 25 Sep 2025 21:29:57 +0300 Subject: [PATCH 065/169] fix SoundService --- src/Services/SoundService/SoundService.cpp | 35 ++++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index e6727c6898..96316c63df 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -249,9 +249,11 @@ namespace Mengine { if( source->resume() == false ) { - LOGGER_ASSERTION( "invalid resume (play)" ); + LOGGER_ASSERTION( "invalid resume (play) identity [%u]" + , identity->getUniqueIdentity() + ); - identity->setState( ESS_END ); + identity->setState( ESS_STOP ); continue; } @@ -269,9 +271,11 @@ namespace Mengine if( this->playSoundBufferUpdate_( identity ) == false ) { - LOGGER_MESSAGE( "invalid play sound buffer update" ); + LOGGER_MESSAGE( "invalid play sound buffer update identity [%u]" + , identity->getUniqueIdentity() + ); - identity->setState( ESS_END ); + identity->setState( ESS_STOP ); continue; } @@ -692,12 +696,7 @@ namespace Mengine continue; } - if( state == ESS_STOP ) - { - continue; - } - - if( state == ESS_END ) + if( state == ESS_STOP || state == ESS_END ) { m_soundIdentitiesEndAux.emplace_back( identity ); @@ -737,7 +736,7 @@ namespace Mengine { if( worker->isDone() == true ) { - identity->setState( ESS_END ); + identity->setState( ESS_STOP ); m_soundIdentitiesEndAux.emplace_back( identity ); } @@ -757,7 +756,7 @@ namespace Mengine { if( time_new <= 0.f ) { - identity->setState( ESS_END ); + identity->setState( ESS_STOP ); m_soundIdentitiesEndAux.emplace_back( identity ); } @@ -882,7 +881,7 @@ namespace Mengine { LOGGER_ASSERTION( "invalid play sound buffer update" ); - _identity->setState( ESS_END ); + _identity->setState( ESS_STOP ); return false; } @@ -919,7 +918,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_END ); + _identity->setState( ESS_STOP ); return false; } @@ -1056,7 +1055,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_END ); + _identity->setState( ESS_STOP ); return false; } @@ -1351,10 +1350,6 @@ namespace Mengine LOGGER_ASSERTION( "invalid set position identity: %u" , _identity->getUniqueIdentity() ); - - _identity->setState( ESS_END ); - - return false; } if( hasBufferUpdate == true && playing == true && pausing == false ) @@ -1365,7 +1360,7 @@ namespace Mengine , _identity->getUniqueIdentity() ); - _identity->setState( ESS_END ); + _identity->setState( ESS_STOP ); return false; } From a73b215706bcbf35a5854f09ed0009ab2dca0b18 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 25 Sep 2025 21:38:24 +0300 Subject: [PATCH 066/169] fix SoundService --- src/Services/SoundService/SoundService.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 96316c63df..4d2b8bcc12 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -1136,6 +1136,10 @@ namespace Mengine keep_listener->onSoundStop( _identity ); } }break; + case ESS_STOP: + { + //Empty + }break; default: { #if defined(MENGINE_DEBUG) From d709cb3d432bafa202077053aeed4473cfb5eeda Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 27 Sep 2025 18:33:56 +0300 Subject: [PATCH 067/169] improve android is_publish&is_debug fix android Amplitude properties fix ImGUIService --- .../java/org/Mengine/Base/MengineApplication.java | 5 ++++- .../Plugin/Amplitude/MengineAmplitudePlugin.java | 15 +++++++++------ .../Plugin/AppLovin/MengineAppLovinPlugin.java | 2 +- .../Plugin/DataDog/MengineDataDogPlugin.java | 4 ++-- .../MengineFirebaseAnalyticsPlugin.java | 5 ++++- .../MengineFirebaseCrashlyticsPlugin.java | 7 ++++--- .../AppleFirebaseAnalyticsApplicationDelegate.mm | 3 ++- src/Plugins/ImGUIPlugin/ImGUIService.cpp | 5 ++++- 8 files changed, 30 insertions(+), 16 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java index f1fcfc2860..5dc6805355 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java @@ -753,7 +753,10 @@ public void onCreate() { MengineStatistic.load(this); - MengineAnalytics.addContextParameterBoolean("is_dev", BuildConfig.DEBUG); + boolean is_publish = this.isBuildPublish(); + + MengineAnalytics.addContextParameterBoolean("is_publish", is_publish); + MengineAnalytics.addContextParameterBoolean("is_debug", BuildConfig.DEBUG); MengineAnalytics.addContextParameterString("install_id", m_installId); MengineAnalytics.addContextParameterLong("install_timestamp", m_installTimestamp); MengineAnalytics.addContextParameterString("install_version", m_installVersion); diff --git a/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java b/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java index 7730ffe57d..b083e916ca 100644 --- a/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java +++ b/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java @@ -56,13 +56,16 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS long sessionIndex = application.getSessionIndex(); long sessionTimestamp = application.getSessionTimestamp(); - identify.set("is_dev", String.valueOf(BuildConfig.DEBUG)); + boolean is_publish = application.isBuildPublish(); + + identify.set("is_publish", is_publish); + identify.set("is_debug", BuildConfig.DEBUG); identify.set("install_id", installId); - identify.set("install_timestamp", String.valueOf(installTimestamp)); + identify.set("install_timestamp", installTimestamp); identify.set("install_version", installVersion); - identify.set("install_rnd", String.valueOf(installRND)); - identify.set("session_index", String.valueOf(sessionIndex)); - identify.set("session_timestamp", String.valueOf(sessionTimestamp)); + identify.set("install_rnd", installRND); + identify.set("session_index", sessionIndex); + identify.set("session_timestamp", sessionTimestamp); String acquisitionNetwork = application.getAcquisitionNetwork(); String acquisitionCampaign = application.getAcquisitionCampaign(); @@ -73,7 +76,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS long currentTimestamp = MengineUtils.getTimestamp(); long lifeTime = currentTimestamp - installTimestamp; - identify.set("life_time", String.valueOf(lifeTime)); + identify.set("life_time", lifeTime); amplitude.identify(identify); diff --git a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java index 8d6d0215cb..358888f510 100644 --- a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java +++ b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java @@ -85,7 +85,7 @@ protected AppLovinSdk getAppLovinSdkInstance() { } @SuppressWarnings("unchecked") - protected T createAd(@NonNull MengineAdService adService, @NonNull List adUnitIds, @NonNull String className) throws MengineServiceInvalidInitializeException { + protected T createAd(@NonNull MengineAdService adService, @NonNull List adUnitIds, @NonNull String className) throws MengineServiceInvalidInitializeException { T ad = (T)this.newInstance(className, true, adService, this); if (ad == null) { diff --git a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java index 15111d5c04..629d71cbb8 100644 --- a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java +++ b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java @@ -110,10 +110,10 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine boolean crashReportsEnabled = false; - boolean isBuildPublish = application.isBuildPublish(); + boolean is_publish = application.isBuildPublish(); String clientToken = MengineDataDogPlugin_ClientToken; - String envName = (isBuildPublish == true) ? "dev" : "prod"; + String envName = (is_publish == true) ? "dev" : "prod"; String variant = ""; Configuration config = new Configuration.Builder(clientToken, envName, variant) diff --git a/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java b/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java index a704815b9e..a1182ab508 100644 --- a/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java +++ b/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java @@ -49,7 +49,10 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine long sessionIndex = application.getSessionIndex(); long sessionTimestamp = application.getSessionTimestamp(); - firebaseAnalytics.setUserProperty("is_dev", String.valueOf(BuildConfig.DEBUG)); + boolean is_publish = application.isBuildPublish(); + + firebaseAnalytics.setUserProperty("is_publish", String.valueOf(is_publish)); + firebaseAnalytics.setUserProperty("is_debug", String.valueOf(BuildConfig.DEBUG)); firebaseAnalytics.setUserProperty("install_id", installId); firebaseAnalytics.setUserProperty("install_timestamp", String.valueOf(installTimestamp)); firebaseAnalytics.setUserProperty("install_version", installVersion); diff --git a/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java b/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java index f6b43a757f..761fc1af80 100644 --- a/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java +++ b/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java @@ -35,12 +35,13 @@ public class MengineFirebaseCrashlyticsPlugin extends MengineService implements @Override public void onAppInit(@NonNull MengineApplication application, boolean isMainProcess) throws MengineServiceInvalidInitializeException { - FirebaseCrashlytics.getInstance().setCustomKey("is_dev", BuildConfig.DEBUG); + boolean is_publish = application.isBuildPublish(); + FirebaseCrashlytics.getInstance().setCustomKey("is_publish", is_publish); + FirebaseCrashlytics.getInstance().setCustomKey("is_debug", BuildConfig.DEBUG); - boolean isBuildPublish = application.isBuildPublish(); boolean isDebuggerConnected = MengineUtils.isDebuggerConnected(); - if (isBuildPublish == false && isDebuggerConnected == false) { + if (is_publish == false && isDebuggerConnected == false) { FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false); } } diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm index 72723dfb02..00b1751363 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm @@ -39,7 +39,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSInteger sessionIndex = [iOSApplication.sharedInstance getSessionIndex]; NSInteger sessionTimestamp = [iOSApplication.sharedInstance getSessionTimestamp]; - [FIRAnalytics setUserPropertyString:MENGINE_DEBUG_VALUE(@"true", @"false") forName:@"is_dev"]; + [FIRAnalytics setUserPropertyString:MENGINE_PUBLISH_VALUE(@"true", @"false") forName:@"is_publish"]; + [FIRAnalytics setUserPropertyString:MENGINE_DEBUG_VALUE(@"true", @"false") forName:@"is_debug"]; [FIRAnalytics setUserPropertyString:installId forName:@"install_id"]; [FIRAnalytics setUserPropertyString:[NSString stringWithFormat:@"%ld", (long)installTimestamp] forName:@"install_timestamp"]; [FIRAnalytics setUserPropertyString:intstallVersion forName:@"install_version"]; diff --git a/src/Plugins/ImGUIPlugin/ImGUIService.cpp b/src/Plugins/ImGUIPlugin/ImGUIService.cpp index 7a0d36412b..879d4901de 100644 --- a/src/Plugins/ImGUIPlugin/ImGUIService.cpp +++ b/src/Plugins/ImGUIPlugin/ImGUIService.cpp @@ -206,7 +206,10 @@ namespace Mengine } else { - userFileGroup->removeFile( STRINGIZE_FILEPATH_LOCAL( MENGINE_IMGUI_INI_FILE ) ); + if( userFileGroup->existFile( STRINGIZE_FILEPATH_LOCAL( MENGINE_IMGUI_INI_FILE ), false ) == true ) + { + userFileGroup->removeFile( STRINGIZE_FILEPATH_LOCAL( MENGINE_IMGUI_INI_FILE ) ); + } } #if defined(MENGINE_ENVIRONMENT_PLATFORM_SDL2) From 309add9926b6acdf0882628c7a7bfebb1b58e850 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 30 Sep 2025 15:51:07 +0300 Subject: [PATCH 068/169] add android AppLovin MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID [SELF] improve android MengineGoogleAdvertisingPlugin --- .../Base/MengineFragmentAdvertisingId.java | 14 +++++ .../AppLovin/MengineAppLovinPlugin.java | 17 +++++- .../MengineGoogleAdvertisingPlugin.java | 61 +++++++++++++------ 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java index 63c2fa9270..ba19522d39 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java @@ -3,6 +3,17 @@ public class MengineFragmentAdvertisingId extends MengineFragment { public static MengineFragmentAdvertisingId INSTANCE = null; + public String m_advertisingId; + public boolean m_limitAdTracking; + + public String getAdvertisingId() { + return m_advertisingId; + } + + public boolean isLimitAdTracking() { + return m_limitAdTracking; + } + MengineFragmentAdvertisingId() { super(MengineListenerAdvertisingId.class); @@ -10,6 +21,9 @@ public class MengineFragmentAdvertisingId extends MengineFragment testDeviceAdvertisingIds = List.of(BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID); + if ("SELF".equals(BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID)) { + boolean limitAdTracking = MengineFragmentAdvertisingId.INSTANCE.isLimitAdTracking(); - builder.setTestDeviceAdvertisingIds(testDeviceAdvertisingIds); + if (limitAdTracking == false) { + String advertisingId = MengineFragmentAdvertisingId.INSTANCE.getAdvertisingId(); + + List testDeviceAdvertisingIds = List.of(advertisingId); + builder.setTestDeviceAdvertisingIds(testDeviceAdvertisingIds); + } else { + this.logWarning("can not set test device advertising id, user limit ad tracking"); + } + } else { + List testDeviceAdvertisingIds = List.of(BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID); + builder.setTestDeviceAdvertisingIds(testDeviceAdvertisingIds); + } } AppLovinSdkInitializationConfiguration config = builder.build(); diff --git a/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java b/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java index 2f8b03b3fe..2357dae104 100644 --- a/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java +++ b/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java @@ -77,15 +77,28 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS if (tcParam.getConsentAdStorage() == false) { this.logInfo("AdvertisingId disabled by consent ad storage"); - m_advertisingId = LIMIT_ADVERTISING_ID; - m_advertisingLimitTrackingEnabled = true; - m_advertisingLimitTrackingFetch = true; + synchronized (m_syncronizationAdvertising) { + m_advertisingId = LIMIT_ADVERTISING_ID; + m_advertisingLimitTrackingEnabled = true; + m_advertisingLimitTrackingFetch = true; + } MengineFragmentAdvertisingId.INSTANCE.setAdvertisingId(m_advertisingId, m_advertisingLimitTrackingEnabled); return; } + synchronized (m_syncronizationAdvertising) { + if (m_advertisingLimitTrackingFetch == true) { + this.logInfo("AdvertisingId: %s limit: %s" + , MengineUtils.getRedactedValue(m_advertisingId) + , m_advertisingLimitTrackingEnabled == true ? "true" : "false" + ); + + MengineFragmentAdvertisingId.INSTANCE.setAdvertisingId(m_advertisingId, m_advertisingLimitTrackingEnabled); + } + } + Runnable task = () -> { Context context = application.getApplicationContext(); @@ -132,38 +145,46 @@ public void onAppTerminate(@NonNull MengineApplication application) { private void postAdInfo(AdvertisingIdClient.Info adInfo) { synchronized (m_syncronizationAdvertising) { + String newAdvertisingId; + boolean newAdvertisingLimitTrackingEnabled; + if (adInfo == null) { - m_advertisingId = LIMIT_ADVERTISING_ID; - m_advertisingLimitTrackingEnabled = true; + newAdvertisingId = LIMIT_ADVERTISING_ID; + newAdvertisingLimitTrackingEnabled = true; } else if (adInfo.isLimitAdTrackingEnabled() == true) { - m_advertisingId = LIMIT_ADVERTISING_ID; - m_advertisingLimitTrackingEnabled = true; + newAdvertisingId = LIMIT_ADVERTISING_ID; + newAdvertisingLimitTrackingEnabled = true; } else { String adInfoAdvertisingId = adInfo.getId(); if (Objects.equals(adInfoAdvertisingId, LIMIT_ADVERTISING_ID) == true) { - m_advertisingId = LIMIT_ADVERTISING_ID; - m_advertisingLimitTrackingEnabled = true; + newAdvertisingId = LIMIT_ADVERTISING_ID; + newAdvertisingLimitTrackingEnabled = true; } else { - m_advertisingId = adInfoAdvertisingId; - m_advertisingLimitTrackingEnabled = false; + newAdvertisingId = adInfoAdvertisingId; + newAdvertisingLimitTrackingEnabled = false; } } m_advertisingLimitTrackingFetch = true; - } - this.logInfo("AdvertisingId: %s limit: %s" - , MengineUtils.getRedactedValue(m_advertisingId) - , m_advertisingLimitTrackingEnabled == true ? "true" : "false" - ); + m_advertisingThread = null; + + if (Objects.equals(m_advertisingId, newAdvertisingId) == true && m_advertisingLimitTrackingEnabled == newAdvertisingLimitTrackingEnabled) { + return; + } + + m_advertisingId = newAdvertisingId; + m_advertisingLimitTrackingEnabled = newAdvertisingLimitTrackingEnabled; + } MengineUtils.performOnMainThread(() -> { + this.logInfo("AdvertisingId: %s limit: %s" + , MengineUtils.getRedactedValue(m_advertisingId) + , m_advertisingLimitTrackingEnabled == true ? "true" : "false" + ); + MengineFragmentAdvertisingId.INSTANCE.setAdvertisingId(m_advertisingId, m_advertisingLimitTrackingEnabled); }); - - synchronized (m_syncronizationAdvertising) { - m_advertisingThread = null; - } } } From c2423eeacb410f7e5329b88a4c98022327273622 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 30 Sep 2025 21:24:00 +0300 Subject: [PATCH 069/169] add python pipeGlobal support win32 platform NOTIFICATOR_APPLICATION_*** --- gradle/build.gradle | 2 +- .../org/Mengine/Base/MengineAnalytics.java | 2 +- .../org/Mengine/Base/MengineFragment.java | 24 ++++++------ .../org/Mengine/Base/MenginePreferences.java | 2 +- gradle/plugins/AppLovin/Core/build.gradle | 18 ++++----- .../MengineAppLovinNonetBanners.java | 2 +- .../MengineGooglePlayBillingPlugin.java | 2 +- .../PythonFramework/EngineScriptEmbedding.cpp | 38 ++++++++++++++++--- .../PythonFramework/GameScriptEmbedding.cpp | 2 - .../PythonGameEventReceiver.cpp | 6 +-- .../PythonFramework/PythonGameEventReceiver.h | 2 - src/Interface/GameEventReceiverInterface.h | 4 -- src/Interface/NotificatorInterface.h | 5 --- src/Kernel/DocumentableHelper.h | 11 +++--- src/Kernel/DummyGameEventReceiver.cpp | 5 +-- src/Kernel/DummyGameEventReceiver.h | 3 -- .../Win32Platform/Win32PlatformService.cpp | 20 ++++++++++ src/Services/GameService/GameService.cpp | 8 ---- src/Services/GameService/GameService.h | 2 - 19 files changed, 86 insertions(+), 72 deletions(-) diff --git a/gradle/build.gradle b/gradle/build.gradle index 37f3073ab2..02104a8b41 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -34,7 +34,7 @@ buildscript { } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPLOVIN") == true && project.hasProperty("MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY") == true) { - classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:5.10.0' + classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:5.10.1' } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_DATADOG") == true) { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java index 5d917db984..126cfc94bb 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java @@ -92,7 +92,7 @@ static public Map collapseContextParameters() { return parameters; } - static private void collapseGetter(Map parameters) { + static private void collapseGetter(Map parameters) { for (Map.Entry entry : MengineAnalytics.m_getter.entrySet()) { String key = entry.getKey(); MengineAnalyticsGetter getter = (MengineAnalyticsGetter)entry.getValue(); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragment.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragment.java index 2a6c95c197..2b8cc1412a 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragment.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragment.java @@ -75,7 +75,7 @@ private void logException(Object propagate, L listener, Throwable t, List arg ); } - protected void propagate(MenginePropagateV0 propagate) { + protected void propagate(MenginePropagateV0 propagate) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -91,7 +91,7 @@ protected void propagate(MenginePropagateV0 propagate) { } } - protected void propagate(MenginePropagateV1 propagate, A1 a1) { + protected void propagate(MenginePropagateV1 propagate, A1 a1) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -107,7 +107,7 @@ protected void propagate(MenginePropagateV1 propagate, A1 a1) { } } - protected void propagate(MenginePropagateV2 propagate, A1 a1, A2 a2) { + protected void propagate(MenginePropagateV2 propagate, A1 a1, A2 a2) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -123,7 +123,7 @@ protected void propagate(MenginePropagateV2 propagate, A1 a1 } } - protected void propagate(MenginePropagateV3 propagate, A1 a1, A2 a2, A3 a3) { + protected void propagate(MenginePropagateV3 propagate, A1 a1, A2 a2, A3 a3) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -139,7 +139,7 @@ protected void propagate(MenginePropagateV3 propagat } } - protected void propagate(MenginePropagateV4 propagate, A1 a1, A2 a2, A3 a3, A4 a4) { + protected void propagate(MenginePropagateV4 propagate, A1 a1, A2 a2, A3 a3, A4 a4) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -155,7 +155,7 @@ protected void propagate(MenginePropagateV4 } } - protected void propagate(MenginePropagateV5 propagate, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + protected void propagate(MenginePropagateV5 propagate, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -171,7 +171,7 @@ protected void propagate(MenginePropagateV5 propagate) { + protected boolean propagateB(MenginePropagateB0 propagate) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -191,7 +191,7 @@ protected boolean propagateB(MenginePropagateB0 propagate) { return false; } - protected boolean propagateB(MenginePropagateB1 propagate, A1 a1) { + protected boolean propagateB(MenginePropagateB1 propagate, A1 a1) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -211,7 +211,7 @@ protected boolean propagateB(MenginePropagateB1 propagate, A1 a1) { return false; } - protected boolean propagateB(MenginePropagateB2 propagate, A1 a1, A2 a2) { + protected boolean propagateB(MenginePropagateB2 propagate, A1 a1, A2 a2) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -231,7 +231,7 @@ protected boolean propagateB(MenginePropagateB2 propagate, A return false; } - protected boolean propagateB(MenginePropagateB3 propagate, A1 a1, A2 a2, A3 a3) { + protected boolean propagateB(MenginePropagateB3 propagate, A1 a1, A2 a2, A3 a3) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -251,7 +251,7 @@ protected boolean propagateB(MenginePropagateB3 prop return false; } - protected boolean propagateB(MenginePropagateB4 propagate, A1 a1, A2 a2, A3 a3, A4 a4) { + protected boolean propagateB(MenginePropagateB4 propagate, A1 a1, A2 a2, A3 a3, A4 a4) { List listeners = this.getListeners(); for (L listener : listeners) { @@ -271,7 +271,7 @@ protected boolean propagateB(MenginePropagateB4 boolean propagateB(MenginePropagateB5 propagate, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + protected boolean propagateB(MenginePropagateB5 propagate, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { List listeners = this.getListeners(); for (L listener : listeners) { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java index 664e8937d0..b9c31f034c 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java @@ -219,7 +219,7 @@ static public void setPreferenceBundle(@NonNull String name, Bundle value) { MenginePreferences.setPreferenceJSON(name, json); } - static public JSONObject getPreferenceJSON(@NonNull String name, Supplier defaultValue) { + static public JSONObject getPreferenceJSON(@NonNull String name, Supplier defaultValue) { String value = MenginePreferences.getPreferenceString(name, null); if (value == null) { diff --git a/gradle/plugins/AppLovin/Core/build.gradle b/gradle/plugins/AppLovin/Core/build.gradle index 3071b605ad..93bbf78553 100644 --- a/gradle/plugins/AppLovin/Core/build.gradle +++ b/gradle/plugins/AppLovin/Core/build.gradle @@ -112,7 +112,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST == true) { - implementation 'com.applovin.mediation:chartboost-adapter:9.9.3.0' + implementation 'com.applovin.mediation:chartboost-adapter:9.10.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE == true) { @@ -128,21 +128,21 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI == true) { - implementation 'com.applovin.mediation:inmobi-adapter:10.8.7.0' + implementation 'com.applovin.mediation:inmobi-adapter:10.8.8.0' implementation 'com.squareup.picasso:picasso:2.8' implementation 'androidx.recyclerview:recyclerview:1.4.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE == true) { - implementation 'com.applovin.mediation:ironsource-adapter:8.11.1.0.0' + implementation 'com.applovin.mediation:ironsource-adapter:9.0.0.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF == true) { - implementation 'com.applovin.mediation:vungle-adapter:7.5.1.0' + implementation 'com.applovin.mediation:vungle-adapter:7.6.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE == true) { - implementation 'com.applovin.mediation:line-adapter:2025.7.18.1' + implementation 'com.applovin.mediation:line-adapter:2025.9.24.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO == true) { @@ -162,7 +162,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO == true) { - implementation 'com.applovin.mediation:moloco-adapter:4.0.0.0' + implementation 'com.applovin.mediation:moloco-adapter:4.1.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY == true) { @@ -174,7 +174,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC == true) { - implementation 'com.applovin.mediation:pubmatic-adapter:4.9.0.0' + implementation 'com.applovin.mediation:pubmatic-adapter:4.9.1.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO == true) { @@ -190,11 +190,11 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK == true) { - implementation 'com.applovin.mediation:mytarget-adapter:5.27.2.0' + implementation 'com.applovin.mediation:mytarget-adapter:5.27.3.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX == true) { - implementation 'com.applovin.mediation:yandex-adapter:7.15.1.0' + implementation 'com.applovin.mediation:yandex-adapter:7.16.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO == true) { diff --git a/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java b/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java index dca169c78d..4955072b59 100644 --- a/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java +++ b/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java @@ -42,7 +42,7 @@ public class MengineAppLovinNonetBanners implements MengineAppLovinNonetBannersI protected boolean m_visible; protected int m_requestId; - static class NonetBanner { + static protected class NonetBanner { public String image; public String url; } diff --git a/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java b/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java index da31287599..4b320708fe 100644 --- a/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java +++ b/gradle/plugins/GooglePlayBilling/src/main/java/org/Mengine/Plugin/GooglePlayBilling/MengineGooglePlayBillingPlugin.java @@ -715,7 +715,7 @@ private void handleConsumablePurchase(@NonNull Purchase purchase) { } @AnyThread - private void handlePurchases(List purchases) { + private void handlePurchases(List purchases) { for (Purchase purchase : purchases) { this.handlePurchase(purchase); } diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index 026a025432..96b61643a7 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -413,7 +413,7 @@ namespace Mengine ->destroyLayout( _layout ); } ////////////////////////////////////////////////////////////////////////// - uint32_t s_pipe( const pybind::object & _pipe, const pybind::object & _timing, const pybind::object & _event, const pybind::args & _args ) + UniqueId s_pipe( const pybind::object & _pipe, const pybind::object & _timing, const pybind::object & _event, const pybind::args & _args ) { PythonSchedulePipePtr py_pipe = m_factoryPythonSchedulePipe->createObject( MENGINE_DOCUMENT_PYTHON ); py_pipe->initialize( _pipe, _args ); @@ -432,12 +432,12 @@ namespace Mengine const SchedulerInterfacePtr & sm = PLAYER_SERVICE() ->getLocalScheduler(); - uint32_t id = sm->timing( py_pipe, py_timing, py_event, MENGINE_DOCUMENT_PYTHON ); + UniqueId id = sm->timing( py_pipe, py_timing, py_event, MENGINE_DOCUMENT_PYTHON ); return id; } ////////////////////////////////////////////////////////////////////////// - uint32_t s_schedule( float _timing, const pybind::object & _script, const pybind::args & _args ) + UniqueId s_schedule( float _timing, const pybind::object & _script, const pybind::args & _args ) { const SchedulerInterfacePtr & sm = PLAYER_SERVICE() ->getLocalScheduler(); @@ -445,7 +445,7 @@ namespace Mengine PythonScheduleEventPtr sl = m_factoryPythonScheduleEvent->createObject( MENGINE_DOCUMENT_PYTHON ); sl->initialize( _script, _args ); - uint32_t id = sm->event( _timing, sl, MENGINE_DOCUMENT_PYTHON ); + UniqueId id = sm->event( _timing, sl, MENGINE_DOCUMENT_PYTHON ); return id; } @@ -549,7 +549,7 @@ namespace Mengine return time; } ////////////////////////////////////////////////////////////////////////// - uint32_t s_scheduleGlobal( float _timing, const pybind::object & _cb, const pybind::args & _args ) + UniqueId s_scheduleGlobal( float _timing, const pybind::object & _cb, const pybind::args & _args ) { const SchedulerInterfacePtr & sm = PLAYER_SERVICE() ->getGlobalScheduler(); @@ -559,7 +559,32 @@ namespace Mengine PythonScheduleEventPtr sl = m_factoryPythonScheduleEvent->createObject( MENGINE_DOCUMENT_PYTHON ); sl->initialize( _cb, _args ); - uint32_t id = sm->event( _timing, sl, MENGINE_DOCUMENT_PYTHON ); + UniqueId id = sm->event( _timing, sl, MENGINE_DOCUMENT_PYTHON ); + + return id; + } + + ////////////////////////////////////////////////////////////////////////// + UniqueId s_pipeGlobal( const pybind::object & _pipe, const pybind::object & _timing, const pybind::object & _event, const pybind::args & _args ) + { + PythonSchedulePipePtr py_pipe = m_factoryPythonSchedulePipe->createObject( MENGINE_DOCUMENT_PYTHON ); + py_pipe->initialize( _pipe, _args ); + + PythonScheduleTimingPtr py_timing = m_factoryPythonScheduleTiming->createObject( MENGINE_DOCUMENT_PYTHON ); + py_timing->initialize( _timing, _args ); + + PythonScheduleEventPtr py_event; + + if( _event.is_none() == false ) + { + py_event = m_factoryPythonScheduleEvent->createObject( MENGINE_DOCUMENT_PYTHON ); + py_event->initialize( _event, _args ); + } + + const SchedulerInterfacePtr & sm = PLAYER_SERVICE() + ->getGlobalScheduler(); + + UniqueId id = sm->timing( py_pipe, py_timing, py_event, MENGINE_DOCUMENT_PYTHON ); return id; } @@ -4365,6 +4390,7 @@ namespace Mengine pybind::def_functor( _kernel, "scheduleTime", nodeScriptMethod, &EngineScriptMethod::s_scheduleTime ); pybind::def_functor_args( _kernel, "scheduleGlobal", nodeScriptMethod, &EngineScriptMethod::s_scheduleGlobal ); + pybind::def_functor_args( _kernel, "pipeGlobal", nodeScriptMethod, &EngineScriptMethod::s_pipeGlobal ); pybind::def_functor( _kernel, "scheduleGlobalRemove", nodeScriptMethod, &EngineScriptMethod::s_scheduleGlobalRemove ); pybind::def_functor( _kernel, "scheduleGlobalRemoveAll", nodeScriptMethod, &EngineScriptMethod::s_scheduleGlobalRemoveAll ); pybind::def_functor( _kernel, "scheduleGlobalFreeze", nodeScriptMethod, &EngineScriptMethod::s_scheduleGlobalFreeze ); diff --git a/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp b/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp index fe05f22a73..8ff583028a 100644 --- a/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp @@ -73,13 +73,11 @@ namespace Mengine Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onOverFillrate" ), EVENT_GAME_OVER_FILLRATE, _doc ); Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onFrameEnd" ), EVENT_GAME_FRAME_END, _doc ); -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onApplicationDidBecomeActive" ), EVENT_GAME_APPLICATION_DID_BECOME_ACTIVE, _doc ); Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onApplicationWillEnterForeground" ), EVENT_GAME_APPLICATION_WILL_ENTER_FOREGROUND, _doc ); Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onApplicationDidEnterBackground" ), EVENT_GAME_APPLICATION_DID_ENTER_BACKGROUD, _doc ); Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onApplicationWillResignActive" ), EVENT_GAME_APPLICATION_WILL_RESIGN_ACTIVE, _doc ); Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onApplicationWillTerminate" ), EVENT_GAME_APPLICATION_WILL_TERMINATE, _doc ); -#endif Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onAnalyticsEvent" ), EVENT_GAME_ANALYTICS_EVENT, _doc ); Helper::registerPythonEventReceiverModule( _kernel, py_module, game, STRINGIZE_STRING_LOCAL( "onAnalyticsScreenView" ), EVENT_GAME_ANALYTICS_SCREENVIEW, _doc ); diff --git a/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp b/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp index c24b65d0cc..cf2eb0d73d 100644 --- a/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp +++ b/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp @@ -282,9 +282,7 @@ namespace Mengine void PythonGameEventReceiver::onGameFrameEnd() { m_cb.call(); - } - ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) + } ////////////////////////////////////////////////////////////////////////// void PythonGameEventReceiver::onGameApplicationDidBecomeActive() { @@ -311,8 +309,6 @@ namespace Mengine m_cb.call(); } ////////////////////////////////////////////////////////////////////////// -#endif - ////////////////////////////////////////////////////////////////////////// void PythonGameEventReceiver::onGameAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) { pybind::kernel_interface * kernel = pybind::get_kernel(); diff --git a/src/Frameworks/PythonFramework/PythonGameEventReceiver.h b/src/Frameworks/PythonFramework/PythonGameEventReceiver.h index 59408d0446..b9d2266b03 100644 --- a/src/Frameworks/PythonFramework/PythonGameEventReceiver.h +++ b/src/Frameworks/PythonFramework/PythonGameEventReceiver.h @@ -61,13 +61,11 @@ namespace Mengine bool onGameClose() override; void onGameOverFillrate( double _fillrate, double _limit ) override; void onGameFrameEnd() override; -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) void onGameApplicationDidBecomeActive() override; void onGameApplicationWillEnterForeground() override; void onGameApplicationDidEnterBackground() override; void onGameApplicationWillResignActive() override; void onGameApplicationWillTerminate() override; -#endif void onGameAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) override; void onGameAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) override; void onGameAnalyticsFlush() override; diff --git a/src/Interface/GameEventReceiverInterface.h b/src/Interface/GameEventReceiverInterface.h index d7dff7c29d..b263518429 100644 --- a/src/Interface/GameEventReceiverInterface.h +++ b/src/Interface/GameEventReceiverInterface.h @@ -120,13 +120,11 @@ namespace Mengine virtual bool onGameClose() = 0; virtual void onGameOverFillrate( double _fillrate, double _limit ) = 0; virtual void onGameFrameEnd() = 0; -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) virtual void onGameApplicationDidBecomeActive() = 0; virtual void onGameApplicationWillEnterForeground() = 0; virtual void onGameApplicationDidEnterBackground() = 0; virtual void onGameApplicationWillResignActive() = 0; virtual void onGameApplicationWillTerminate() = 0; -#endif virtual void onGameAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) = 0; virtual void onGameAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) = 0; virtual void onGameAnalyticsFlush() = 0; @@ -175,13 +173,11 @@ namespace Mengine EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_CLOSE ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_OVER_FILLRATE ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_FRAME_END ); -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_APPLICATION_DID_BECOME_ACTIVE ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_APPLICATION_WILL_ENTER_FOREGROUND ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_APPLICATION_DID_ENTER_BACKGROUD ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_APPLICATION_WILL_RESIGN_ACTIVE ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_APPLICATION_WILL_TERMINATE ); -#endif EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_ANALYTICS_EVENT ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_ANALYTICS_SCREENVIEW ); EVENTATION_TYPEID( GameEventReceiverInterface, EVENT_GAME_ANALYTICS_FLUSH ); diff --git a/src/Interface/NotificatorInterface.h b/src/Interface/NotificatorInterface.h index f9a7c24038..aec03bb166 100644 --- a/src/Interface/NotificatorInterface.h +++ b/src/Interface/NotificatorInterface.h @@ -148,9 +148,6 @@ namespace Mengine MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_HTTP_CANCEL, HttpRequestId ); MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_HTTP_RESPONSE, const HttpResponseInterfacePtr & ); MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_SETTING_CHANGE, const SettingInterfacePtr &, const Char * ); - ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) - ////////////////////////////////////////////////////////////////////////// MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_APPLICATION_DID_BECOME_ACTIVE ); MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_APPLICATION_WILL_ENTER_FOREGROUND ); MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_APPLICATION_DID_ENTER_BACKGROUND ); @@ -159,8 +156,6 @@ namespace Mengine MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_APPLICATION_DID_RECEIVE_MEMORY_WARNING ); MENGINE_NOTIFICATOR_DECLARE( NOTIFICATOR_APPLICATION_DID_RECEIVE_TRIM_MEMORY, int32_t ); ////////////////////////////////////////////////////////////////////////// -#endif - ////////////////////////////////////////////////////////////////////////// MENGINE_NOTIFICATOR_DECLARE_END(); ////////////////////////////////////////////////////////////////////////// #undef MENGINE_NOTIFICATOR_DECLARE_BEGIN diff --git a/src/Kernel/DocumentableHelper.h b/src/Kernel/DocumentableHelper.h index d62b2b9623..81d9c33a17 100644 --- a/src/Kernel/DocumentableHelper.h +++ b/src/Kernel/DocumentableHelper.h @@ -6,6 +6,7 @@ #if defined(MENGINE_DOCUMENT_ENABLE) # include "Kernel/Documentable.h" # include "Kernel/Identity.h" +# include "Kernel/LoggerMessage.h" # include "Config/DynamicCast.h" # include "Config/StdString.h" @@ -27,11 +28,11 @@ namespace Mengine template const Char * getDocumentableThreadLocalMessage( const D * _documentable, const I * _identity, const Char * _message ) { - static MENGINE_THREAD_LOCAL Char message[4096 + 1] = {'\0'}; - Detail::getDocumentableMessage( _documentable, _identity, message, 4096 ); - StdString::strcat_safe( message, " [", 4096 ); - StdString::strcat_safe( message, _message, 4096 ); - StdString::strcat_safe( message, "]", 4096 ); + static MENGINE_THREAD_LOCAL Char message[MENGINE_LOGGER_MAX_MESSAGE + 1] = {'\0'}; + Detail::getDocumentableMessage( _documentable, _identity, message, MENGINE_LOGGER_MAX_MESSAGE ); + StdString::strcat_safe( message, " [", MENGINE_LOGGER_MAX_MESSAGE ); + StdString::strcat_safe( message, _message, MENGINE_LOGGER_MAX_MESSAGE ); + StdString::strcat_safe( message, "]", MENGINE_LOGGER_MAX_MESSAGE ); return message; } diff --git a/src/Kernel/DummyGameEventReceiver.cpp b/src/Kernel/DummyGameEventReceiver.cpp index caf7104db6..015b0fd0c5 100644 --- a/src/Kernel/DummyGameEventReceiver.cpp +++ b/src/Kernel/DummyGameEventReceiver.cpp @@ -298,8 +298,6 @@ namespace Mengine // Empty } ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) - ////////////////////////////////////////////////////////////////////////// void DummyGameEventReceiver::onGameApplicationDidBecomeActive() { // Empty @@ -325,5 +323,4 @@ namespace Mengine // Empty } ////////////////////////////////////////////////////////////////////////// -#endif -} +} \ No newline at end of file diff --git a/src/Kernel/DummyGameEventReceiver.h b/src/Kernel/DummyGameEventReceiver.h index a319e49eab..bb2094b8cf 100644 --- a/src/Kernel/DummyGameEventReceiver.h +++ b/src/Kernel/DummyGameEventReceiver.h @@ -53,13 +53,10 @@ namespace Mengine bool onGameClose() override; void onGameOverFillrate( double _fillrate, double _limit ) override; void onGameFrameEnd() override; - -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) void onGameApplicationDidBecomeActive() override; void onGameApplicationWillEnterForeground() override; void onGameApplicationDidEnterBackground() override; void onGameApplicationWillResignActive() override; void onGameApplicationWillTerminate() override; -#endif }; } diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index 3afaebf319..fad2a9991c 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -1477,6 +1477,8 @@ namespace Mengine LOGGER_MESSAGE( "quit application" ); + NOTIFICATION_NOTIFY( NOTIFICATOR_APPLICATION_WILL_TERMINATE ); + m_close = true; ::PostQuitMessage( 0 ); @@ -3503,6 +3505,15 @@ namespace Mengine m_active = _active; + if( m_active == false ) + { + NOTIFICATION_NOTIFY( NOTIFICATOR_APPLICATION_WILL_RESIGN_ACTIVE ); + } + else + { + NOTIFICATION_NOTIFY( NOTIFICATOR_APPLICATION_WILL_ENTER_FOREGROUND ); + } + bool nopause = APPLICATION_SERVICE() ->getNopause(); @@ -3551,6 +3562,15 @@ namespace Mengine ::SetCursor( NULL ); } } + + if( m_active == false ) + { + NOTIFICATION_NOTIFY( NOTIFICATOR_APPLICATION_DID_ENTER_BACKGROUND ); + } + else + { + NOTIFICATION_NOTIFY( NOTIFICATOR_APPLICATION_DID_BECOME_ACTIVE ); + } } ////////////////////////////////////////////////////////////////////////// void Win32PlatformService::messageBox( const Char * _caption, const Char * _format, ... ) const diff --git a/src/Services/GameService/GameService.cpp b/src/Services/GameService/GameService.cpp index c9cd981a05..59e1ae2729 100644 --- a/src/Services/GameService/GameService.cpp +++ b/src/Services/GameService/GameService.cpp @@ -61,13 +61,11 @@ namespace Mengine NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_TIME_FACTOR_CHANGE, &GameService::notifyTimeFactorChange_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_SETTING_CHANGE, &GameService::notifySettingChange_, MENGINE_DOCUMENT_FACTORABLE ); -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_APPLICATION_DID_BECOME_ACTIVE, &GameService::notifyApplicationDidBecomeActive_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_APPLICATION_WILL_ENTER_FOREGROUND, &GameService::notifyApplicationWillEnterForeground_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_APPLICATION_DID_ENTER_BACKGROUND, &GameService::notifyApplicationDidEnterBackground_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_APPLICATION_WILL_RESIGN_ACTIVE, &GameService::notifyApplicationWillResignActive_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_APPLICATION_WILL_TERMINATE, &GameService::notifyApplicationWillTerminate_, MENGINE_DOCUMENT_FACTORABLE ); -#endif ANALYTICS_SERVICE() ->addEventProvider( AnalyticsEventProviderInterfacePtr::from( this ) ); @@ -80,13 +78,11 @@ namespace Mengine NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_TIME_FACTOR_CHANGE ); NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_SETTING_CHANGE ); -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_APPLICATION_DID_BECOME_ACTIVE ); NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_APPLICATION_WILL_ENTER_FOREGROUND ); NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_APPLICATION_DID_ENTER_BACKGROUND ); NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_APPLICATION_WILL_RESIGN_ACTIVE ); NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_APPLICATION_WILL_TERMINATE ); -#endif ANALYTICS_SERVICE() ->removeEventProvider( AnalyticsEventProviderInterfacePtr::from( this ) ); @@ -531,8 +527,6 @@ namespace Mengine ->onGameSettingChange( _setting, _key ); } ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) - ////////////////////////////////////////////////////////////////////////// void GameService::notifyApplicationDidBecomeActive_() { EVENTABLE_METHOD( EVENT_GAME_APPLICATION_DID_BECOME_ACTIVE ) @@ -562,8 +556,6 @@ namespace Mengine ->onGameApplicationWillTerminate(); } ////////////////////////////////////////////////////////////////////////// -#endif - ////////////////////////////////////////////////////////////////////////// void GameService::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) { EVENTABLE_METHOD( EVENT_GAME_ANALYTICS_EVENT ) diff --git a/src/Services/GameService/GameService.h b/src/Services/GameService/GameService.h index 0b493e5091..b21413a354 100644 --- a/src/Services/GameService/GameService.h +++ b/src/Services/GameService/GameService.h @@ -89,13 +89,11 @@ namespace Mengine void notifyTimeFactorChange_( float _timeFactor ); void notifySettingChange_( const SettingInterfacePtr & _setting, const Char * _key ); -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) void notifyApplicationDidBecomeActive_(); void notifyApplicationWillEnterForeground_(); void notifyApplicationDidEnterBackground_(); void notifyApplicationWillResignActive_(); void notifyApplicationWillTerminate_(); -#endif protected: void onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) override; From a9e3864fa9a524e26c4d38fdd96922a845956bdf Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 1 Oct 2025 01:00:00 +0300 Subject: [PATCH 070/169] update apple AppLovin --- .../AppleAppLovinPlugin/CMakeLists.txt | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt index 0db9931cd9..2f8678650c 100644 --- a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt @@ -99,32 +99,32 @@ macro(ADD_APPLOVIN_MEDIATION MEDIATION POD VERSION) endmacro() ADD_APPLOVIN_MEDIATION(ADMOB "AppLovinMediationGoogleAdapter" "12.11.0.0") -ADD_APPLOVIN_MEDIATION(AMAZON "AppLovinMediationAmazonAdMarketplaceAdapter" "5.2.0.0") -ADD_APPLOVIN_MEDIATION(BIDMACHINE "AppLovinMediationBidMachineAdapter" "3.3.0.0.0") -ADD_APPLOVIN_MEDIATION(BIGO "AppLovinMediationBigoAdsAdapter" "4.7.0.2") -ADD_APPLOVIN_MEDIATION(CHARTBOOST "AppLovinMediationChartboostAdapter" "9.9.0.0") +ADD_APPLOVIN_MEDIATION(AMAZON "AppLovinMediationAmazonAdMarketplaceAdapter" "5.3.1.0") +ADD_APPLOVIN_MEDIATION(BIDMACHINE "AppLovinMediationBidMachineAdapter" "3.4.0.0.0") +ADD_APPLOVIN_MEDIATION(BIGO "AppLovinMediationBigoAdsAdapter" "4.9.3.0") +ADD_APPLOVIN_MEDIATION(CHARTBOOST "AppLovinMediationChartboostAdapter" "9.10.0.0") ADD_APPLOVIN_MEDIATION(CSJ "AppLovinMediationCSJAdapter" "6.7.1.6.0") -ADD_APPLOVIN_MEDIATION(DTEXCHANGE "AppLovinMediationFyberAdapter" "8.3.6.0") #DT Exchange +ADD_APPLOVIN_MEDIATION(DTEXCHANGE "AppLovinMediationFyberAdapter" "8.3.8.0") #DT Exchange ADD_APPLOVIN_MEDIATION(GOOGLEADMANAGER "AppLovinMediationGoogleAdManagerAdapter" "12.11.0.0") ADD_APPLOVIN_MEDIATION(HYPRMX "AppLovinMediationHyprMXAdapter" "6.4.2.0.0") -ADD_APPLOVIN_MEDIATION(INMOBI "AppLovinMediationInMobiAdapter" "10.8.3.1") -ADD_APPLOVIN_MEDIATION(IRONSOURCE "AppLovinMediationIronSourceAdapter" "8.8.0.0.0") -ADD_APPLOVIN_MEDIATION(LIFTOFF "AppLovinMediationLifftoffAdapter" "7.5.1.2") -ADD_APPLOVIN_MEDIATION(LINE "AppLovinMediationLineAdapter" "2.9.20250512.0") +ADD_APPLOVIN_MEDIATION(INMOBI "AppLovinMediationInMobiAdapter" "10.8.8.0") +ADD_APPLOVIN_MEDIATION(IRONSOURCE "AppLovinMediationIronSourceAdapter" "9.0.0.0.0") +ADD_APPLOVIN_MEDIATION(LIFTOFF "AppLovinMediationVungleAdapter" "7.6.0.0") +ADD_APPLOVIN_MEDIATION(LINE "AppLovinMediationLineAdapter" "2.9.20250930.0") ADD_APPLOVIN_MEDIATION(MAIO "AppLovinMediationMaioAdapter" "2.1.6.0") ADD_APPLOVIN_MEDIATION(META "AppLovinMediationFacebookAdapter" "6.20.1.0") #Meta -ADD_APPLOVIN_MEDIATION(MINTEGRAL "AppLovinMediationMintegralAdapter" "7.7.8.0.0") -ADD_APPLOVIN_MEDIATION(MOBILEFUSE "AppLovinMediationMobileFuseAdapter" "1.9.2.1") -ADD_APPLOVIN_MEDIATION(MOLOCO "AppLovinMediationMolocoAdapter" "3.9.1.1") -ADD_APPLOVIN_MEDIATION(OGURY "AppLovinMediationOguryPresageAdapter" "5.0.2.0") -ADD_APPLOVIN_MEDIATION(PANGLE "AppLovinMediationByteDanceAdapter" "7.1.1.1.0") #Pangle -ADD_APPLOVIN_MEDIATION(PUBMATIC "AppLovinMediationPubMaticAdapter" "4.5.2.0") +ADD_APPLOVIN_MEDIATION(MINTEGRAL "AppLovinMediationMintegralAdapter" "7.7.9.0.0") +ADD_APPLOVIN_MEDIATION(MOBILEFUSE "AppLovinMediationMobileFuseAdapter" "1.9.3.0") +ADD_APPLOVIN_MEDIATION(MOLOCO "AppLovinMediationMolocoAdapter" "3.13.0.0") +ADD_APPLOVIN_MEDIATION(OGURY "AppLovinMediationOguryPresageAdapter" "5.1.1.0") +ADD_APPLOVIN_MEDIATION(PANGLE "AppLovinMediationByteDanceAdapter" "7.6.0.6.0") #Pangle +ADD_APPLOVIN_MEDIATION(PUBMATIC "AppLovinMediationPubMaticAdapter" "4.9.0.0") ADD_APPLOVIN_MEDIATION(SMAATO "AppLovinMediationSmaatoAdapter" "22.9.3.1") ADD_APPLOVIN_MEDIATION(TENCENT "AppLovinMediationTencentGDTAdapter" "4.15.21.1") ADD_APPLOVIN_MEDIATION(UNITYADS "AppLovinMediationUnityAdsAdapter" "4.16.1.0") -ADD_APPLOVIN_MEDIATION(VERVE "AppLovinMediationVerveAdapter" "3.6.0.0") -ADD_APPLOVIN_MEDIATION(MYTARGET "AppLovinMediationMyTargetAdapter" "5.31.0.0") #VK -ADD_APPLOVIN_MEDIATION(YANDEX "AppLovinMediationYandexAdapter" "7.12.3.0") +ADD_APPLOVIN_MEDIATION(VERVE "AppLovinMediationVerveAdapter" "3.6.1.0") +ADD_APPLOVIN_MEDIATION(MYTARGET "AppLovinMediationMyTargetAdapter" "5.35.1.0") #VK +ADD_APPLOVIN_MEDIATION(YANDEX "AppLovinMediationYandexAdapter" "7.16.1.0") ADD_APPLOVIN_MEDIATION(YSO "AppLovinMediationYSONetworkAdapter" "1.1.31.1") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAppLovinApplicationDelegate") From 6f9420bf9128939be034d6d01cf577e4e55be15e Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 1 Oct 2025 19:03:08 +0300 Subject: [PATCH 071/169] fix AccountService fix android buildConfigField String --- gradle/app.gradle | 4 +-- gradle/plugins/AppLovin/build.gradle | 2 +- gradle/plugins/GoogleConsent/build.gradle | 4 ++- gradle/settings.gradle.kts | 16 +++++++++--- .../PythonFramework/HelperScriptEmbedding.cpp | 17 +++++++------ src/Services/AccountService/Account.cpp | 9 +------ .../AccountService/AccountService.cpp | 25 ++++++++++++++----- 7 files changed, 48 insertions(+), 29 deletions(-) diff --git a/gradle/app.gradle b/gradle/app.gradle index 583829da8c..874fd9da52 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -746,7 +746,7 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_OPTIONS", "\"${MENGINE_APP_OPTIONS}\"" + buildConfigField "String", "MENGINE_APP_OPTIONS", MENGINE_APP_OPTIONS.empty == false ? "\"MENGINE_APP_OPTIONS\"" : null } } } else { @@ -754,7 +754,7 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_OPTIONS", "\"\"" + buildConfigField "String", "MENGINE_APP_OPTIONS", null } } } diff --git a/gradle/plugins/AppLovin/build.gradle b/gradle/plugins/AppLovin/build.gradle index 00a376fec2..c942b636bd 100644 --- a/gradle/plugins/AppLovin/build.gradle +++ b/gradle/plugins/AppLovin/build.gradle @@ -140,7 +140,7 @@ dependencies { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", "${MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID}" + buildConfigField "String", "MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID != null ? "\"${MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID}\"" : null buildConfigField "boolean", "MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE", "${MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE}" buildConfigField "boolean", "MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER", "${MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER}" diff --git a/gradle/plugins/GoogleConsent/build.gradle b/gradle/plugins/GoogleConsent/build.gradle index e698452b19..79965faf8d 100644 --- a/gradle/plugins/GoogleConsent/build.gradle +++ b/gradle/plugins/GoogleConsent/build.gradle @@ -3,6 +3,8 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' def MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID = Utils.getStringProperty("MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", null) +Utils.logString("MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID) + android { namespace "org.Mengine.Plugin.GoogleConsent" } @@ -15,6 +17,6 @@ dependencies { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", "${MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID}" + buildConfigField "String", "MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID != null ? "\"MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID\"" : null } } diff --git a/gradle/settings.gradle.kts b/gradle/settings.gradle.kts index b7a335cc0e..b326ab3a46 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -17,12 +17,22 @@ fun getBooleanProperty(name: String, d: Boolean): Boolean { return d } -fun getStringProperty(name: String, d: String): String { +fun getStringProperty(name: String, d: String): String? { if (extra.has(name) == false) { return d } - return extra[name].toString() + val s = extra[name].toString() + + if (s.isEmpty() == true) { + return null + } + + if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) { + return s.substring(1, s.length - 1) + } + + return s } fun includeLibrary(name: String, path: String) { @@ -53,7 +63,7 @@ println("\u001b[32m" + "=== Start configure ===" + "\u001b[0m") val ANDROID_APP_MAIN_PROJECT = getStringProperty("ANDROID_APP_MAIN_PROJECT", "app"); -if (file(ANDROID_APP_MAIN_PROJECT).exists() == false) { +if (ANDROID_APP_MAIN_PROJECT == null || file(ANDROID_APP_MAIN_PROJECT).exists() == false) { println("\u001b[31m" + "[-] Not found $ANDROID_APP_MAIN_PROJECT" + "\u001b[0m") throw kotlin.Exception("Not found $ANDROID_APP_MAIN_PROJECT") diff --git a/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp index 1e0b835cf7..5cd93df13f 100644 --- a/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp @@ -28,6 +28,7 @@ #include "Environment/Python/PythonIncluder.h" #include "Environment/Python/PythonDocument.h" #include "Environment/Python/PythonCallbackProvider.h" +#include "Environment/Python/PythonTraceback.h" #if defined(MENGINE_PLATFORM_ANDROID) # include "Environment/Android/AndroidKernelServiceInterface.h" @@ -1800,8 +1801,8 @@ namespace Mengine return false; } - Char setting_value[32 + 1] = {'\0'}; - if( Helper::stringalized( _value, setting_value, 32 ) == false ) + Char setting_value[64 + 1] = {'\0'}; + if( Helper::stringalized( _value, setting_value, 64 ) == false ) { return false; } @@ -1830,8 +1831,8 @@ namespace Mengine return false; } - Char setting_value[32 + 1] = {'\0'}; - if( Helper::stringalized( _value, setting_value, 31 ) == false ) + Char setting_value[64 + 1] = {'\0'}; + if( Helper::stringalized( _value, setting_value, 64 ) == false ) { return false; } @@ -1860,8 +1861,8 @@ namespace Mengine return false; } - Char setting_value[32 + 1] = {'\0'}; - if( Helper::stringalized( _value, setting_value, 32 ) == false ) + Char setting_value[64 + 1] = {'\0'}; + if( Helper::stringalized( _value, setting_value, 64 ) == false ) { return false; } @@ -1890,8 +1891,8 @@ namespace Mengine return false; } - Char setting_value[64 + 1] = {'\0'}; - if( Helper::stringalized( _value, setting_value, 64 ) == false ) + Char setting_value[256 + 1] = {'\0'}; + if( Helper::stringalized( _value, setting_value, 256 ) == false ) { return false; } diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index 6f0d3c0a89..04ed9fa007 100644 --- a/src/Services/AccountService/Account.cpp +++ b/src/Services/AccountService/Account.cpp @@ -49,8 +49,6 @@ namespace Mengine m_folderName = _folderPath; m_projectVersion = _projectVersion; - Helper::makeUID( 20, m_uid.data ); - PathString settingsJSONPath; settingsJSONPath += m_folderName; settingsJSONPath += MENGINE_ACCOUNT_SETTINGS_JSON_PATH; @@ -260,11 +258,6 @@ namespace Mengine const Char * value; if( config->hasValue( "SETTINGS", key.c_str(), "", &value ) == false ) { - LOGGER_WARNING( "account '%s' failed get setting '%s'" - , m_accountId.c_str() - , key.c_str() - ); - continue; } @@ -361,7 +354,7 @@ namespace Mengine const FilePath & settingsJSONPath = m_settingsJSONContent->getFilePath(); - if( Helper::writeJSONFileCompact( j_root, m_fileGroup, settingsJSONPath, true, MENGINE_DOCUMENT_FACTORABLE ) == false ) + if( Helper::writeJSONFile( j_root, m_fileGroup, settingsJSONPath, true, MENGINE_DOCUMENT_FACTORABLE ) == false ) { LOGGER_ERROR( "account '%s' invalid write json to file '%s'" , m_accountId.c_str() diff --git a/src/Services/AccountService/AccountService.cpp b/src/Services/AccountService/AccountService.cpp index 4ef4525347..95d465290f 100644 --- a/src/Services/AccountService/AccountService.cpp +++ b/src/Services/AccountService/AccountService.cpp @@ -172,20 +172,25 @@ namespace Mengine , _accountId.c_str() ); - m_currentAccountId = newAccount->getAccountId(); + AccountUID uid; + Helper::makeUID( 20, uid.data ); + + newAccount->setUID( uid ); m_accounts.emplace( _accountId, newAccount ); + m_currentAccountId = _accountId; + if( m_accountProvider != nullptr ) { - m_accountProvider->onCreateAccount( _accountId, false ); + m_accountProvider->onCreateAccount( m_currentAccountId, false ); } newAccount->apply(); if( m_accountProvider != nullptr ) { - m_accountProvider->onSelectAccount( _accountId ); + m_accountProvider->onSelectAccount( m_currentAccountId ); } m_invalidateAccounts = true; @@ -214,10 +219,20 @@ namespace Mengine , _accountId.c_str() ); - m_globalAccountId = newAccount->getAccountId(); + AccountUID uid; + Helper::makeUID( 20, uid.data ); + + newAccount->setUID( uid ); m_accounts.emplace( _accountId, newAccount ); + m_globalAccountId = _accountId; + + if( m_accountProvider != nullptr ) + { + m_accountProvider->onCreateAccount( m_globalAccountId, true ); + } + newAccount->apply(); m_invalidateAccounts = true; @@ -366,8 +381,6 @@ namespace Mengine m_invalidateAccounts = true; - this->saveAccounts(); - return true; } ////////////////////////////////////////////////////////////////////////// From 6b816ae5205e846d068bdc894d28673df8e75ac4 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 1 Oct 2025 21:01:07 +0300 Subject: [PATCH 072/169] fix android buildConfigField String --- gradle/app.gradle | 4 ++-- gradle/plugins/AppLovin/build.gradle | 2 +- gradle/plugins/GoogleConsent/build.gradle | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/app.gradle b/gradle/app.gradle index 874fd9da52..78288b18b5 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -746,7 +746,7 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_OPTIONS", MENGINE_APP_OPTIONS.empty == false ? "\"MENGINE_APP_OPTIONS\"" : null + buildConfigField "String", "MENGINE_APP_OPTIONS", MENGINE_APP_OPTIONS.empty == false ? "\"MENGINE_APP_OPTIONS\"" : "\"\"" } } } else { @@ -754,7 +754,7 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_OPTIONS", null + buildConfigField "String", "MENGINE_APP_OPTIONS", "\"\"" } } } diff --git a/gradle/plugins/AppLovin/build.gradle b/gradle/plugins/AppLovin/build.gradle index c942b636bd..802f43feaa 100644 --- a/gradle/plugins/AppLovin/build.gradle +++ b/gradle/plugins/AppLovin/build.gradle @@ -140,7 +140,7 @@ dependencies { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID != null ? "\"${MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID}\"" : null + buildConfigField "String", "MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID != null ? "\"${MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID}\"" : "\"\"" buildConfigField "boolean", "MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE", "${MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE}" buildConfigField "boolean", "MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER", "${MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER}" diff --git a/gradle/plugins/GoogleConsent/build.gradle b/gradle/plugins/GoogleConsent/build.gradle index 79965faf8d..c0e235079c 100644 --- a/gradle/plugins/GoogleConsent/build.gradle +++ b/gradle/plugins/GoogleConsent/build.gradle @@ -17,6 +17,6 @@ dependencies { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID != null ? "\"MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID\"" : null + buildConfigField "String", "MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID != null ? "\"MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID\"" : "\"\"" } } From b8c0ead0f7626b2adf57e7a1cb19da10226d543c Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 1 Oct 2025 21:26:25 +0300 Subject: [PATCH 073/169] fix ios build --- .../AppleFirebaseAnalyticsApplicationDelegate.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm index 00b1751363..284e485680 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm @@ -39,7 +39,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSInteger sessionIndex = [iOSApplication.sharedInstance getSessionIndex]; NSInteger sessionTimestamp = [iOSApplication.sharedInstance getSessionTimestamp]; - [FIRAnalytics setUserPropertyString:MENGINE_PUBLISH_VALUE(@"true", @"false") forName:@"is_publish"]; + [FIRAnalytics setUserPropertyString:MENGINE_BUILD_PUBLISH_VALUE(@"true", @"false") forName:@"is_publish"]; [FIRAnalytics setUserPropertyString:MENGINE_DEBUG_VALUE(@"true", @"false") forName:@"is_debug"]; [FIRAnalytics setUserPropertyString:installId forName:@"install_id"]; [FIRAnalytics setUserPropertyString:[NSString stringWithFormat:@"%ld", (long)installTimestamp] forName:@"install_timestamp"]; From deaa51452a7359688a904e463bc18ff8c8832a79 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 2 Oct 2025 12:43:10 +0300 Subject: [PATCH 074/169] improve android MengineFragmentAdvertisingId improve android utils get properties fix tools build --- .../Base/MengineFragmentAdvertisingId.java | 6 ++-- .../MengineGoogleAdvertisingPlugin.java | 14 ++++---- gradle/settings.gradle.kts | 6 +++- gradle/utils.gradle | 36 +++++++++++++++---- .../NodeDebuggerPlugin/ModuleNodeDebugger.cpp | 11 +++--- src/Tools/ProjectBuilder/Image.cpp | 13 ++++--- src/Tools/ProjectBuilder/ProjectBuilder.cpp | 12 ++++--- 7 files changed, 68 insertions(+), 30 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java index ba19522d39..fab5f0313f 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java @@ -3,8 +3,10 @@ public class MengineFragmentAdvertisingId extends MengineFragment { public static MengineFragmentAdvertisingId INSTANCE = null; - public String m_advertisingId; - public boolean m_limitAdTracking; + public static final String LIMIT_ADVERTISING_ID = "00000000-0000-0000-0000-000000000000"; + + public String m_advertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; + public boolean m_limitAdTracking = true; public String getAdvertisingId() { return m_advertisingId; diff --git a/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java b/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java index 2357dae104..8bc1d959dd 100644 --- a/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java +++ b/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java @@ -25,8 +25,6 @@ public class MengineGoogleAdvertisingPlugin extends MengineService implements Me public static final String SERVICE_NAME = "Advertising"; public static final int SAVE_VERSION = 1; - private static final String LIMIT_ADVERTISING_ID = "00000000-0000-0000-0000-000000000000"; - protected String m_advertisingId; protected boolean m_advertisingLimitTrackingEnabled = false; protected boolean m_advertisingLimitTrackingFetch = false; @@ -64,7 +62,7 @@ public void onLoad(@NonNull MengineApplication application, @NonNull Bundle bund int version = bundle.getInt("version", 0); synchronized (m_syncronizationAdvertising) { - m_advertisingId = bundle.getString("advertisingId", LIMIT_ADVERTISING_ID); + m_advertisingId = bundle.getString("advertisingId", MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID); m_advertisingLimitTrackingEnabled = bundle.getBoolean("advertisingLimitTrackingEnabled", true); m_advertisingLimitTrackingFetch = bundle.getBoolean("advertisingLimitTrackingFetch", false); } @@ -78,7 +76,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS this.logInfo("AdvertisingId disabled by consent ad storage"); synchronized (m_syncronizationAdvertising) { - m_advertisingId = LIMIT_ADVERTISING_ID; + m_advertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; m_advertisingLimitTrackingEnabled = true; m_advertisingLimitTrackingFetch = true; } @@ -149,16 +147,16 @@ private void postAdInfo(AdvertisingIdClient.Info adInfo) { boolean newAdvertisingLimitTrackingEnabled; if (adInfo == null) { - newAdvertisingId = LIMIT_ADVERTISING_ID; + newAdvertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; newAdvertisingLimitTrackingEnabled = true; } else if (adInfo.isLimitAdTrackingEnabled() == true) { - newAdvertisingId = LIMIT_ADVERTISING_ID; + newAdvertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; newAdvertisingLimitTrackingEnabled = true; } else { String adInfoAdvertisingId = adInfo.getId(); - if (Objects.equals(adInfoAdvertisingId, LIMIT_ADVERTISING_ID) == true) { - newAdvertisingId = LIMIT_ADVERTISING_ID; + if (Objects.equals(adInfoAdvertisingId, MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID) == true) { + newAdvertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; newAdvertisingLimitTrackingEnabled = true; } else { newAdvertisingId = adInfoAdvertisingId; diff --git a/gradle/settings.gradle.kts b/gradle/settings.gradle.kts index b326ab3a46..2aa7ae9595 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -28,7 +28,11 @@ fun getStringProperty(name: String, d: String): String? { return null } - if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) { + if (s.startsWith('"') && s.endsWith('"')) { + return s.substring(1, s.length - 1) + } + + if (s.startsWith("'") && s.endsWith("'")) { return s.substring(1, s.length - 1) } diff --git a/gradle/utils.gradle b/gradle/utils.gradle index 992d0aa574..4686e29893 100644 --- a/gradle/utils.gradle +++ b/gradle/utils.gradle @@ -11,17 +11,35 @@ Utils.getBooleanProperty = { String name, Boolean d -> return false } - return true + if (p as Integer == 1) { + return true + } + + throw new IllegalArgumentException("Property '${name}' must be 0 or 1, but got '${p}'") + + return d } Utils.getStringProperty = { String name, String d -> - def p = project.findProperty(name) + def s = project.findProperty(name) - if (p == null) { + if (s == null) { return d } - return p + if (s.isEmpty() == true) { + return null + } + + if (s.startsWith('"') && s.endsWith('"')) { + return s.substring(1, s.length() - 1) + } + + if (s.startsWith("'") && s.endsWith("'")) { + return s.substring(1, s.length() - 1) + } + + return s } Utils.getIntegerProperty = { String name, Integer d -> @@ -31,9 +49,15 @@ Utils.getIntegerProperty = { String name, Integer d -> return d } - def v = p as Integer + try { + def v = p as Integer + + return v + } catch (ClassCastException e) { + throw new IllegalArgumentException("Property '${name}' must be integer, but got '${p}'") + } - return v + return d } Utils.isEnableAllLibrary = { -> diff --git a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp b/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp index 5664de14aa..4ce2ff76a1 100644 --- a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp +++ b/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp @@ -1955,10 +1955,7 @@ namespace Mengine uint32_t width = widthAttr.as_uint(); uint32_t height = heightAttr.as_uint(); - if( widthAttr ) - { - this->receiveResolutins( width, height ); - } + this->receiveResolutins( width, height ); } } else if( typeStr == "Settings" ) @@ -1970,7 +1967,11 @@ namespace Mengine pugi::xml_attribute keyAttr = xmlNode.attribute( "key" ); pugi::xml_attribute valueAttr = xmlNode.attribute( "value" ); - this->receiveSetting( nameAttr.as_string(), keyAttr.as_string(), valueAttr.as_string() ); + const Char * name = nameAttr.as_string(); + const Char * key = keyAttr.as_string(); + const Char * value = valueAttr.as_string(); + + this->receiveSetting( name, key, value ); } } } diff --git a/src/Tools/ProjectBuilder/Image.cpp b/src/Tools/ProjectBuilder/Image.cpp index c55dc09149..45f286c967 100644 --- a/src/Tools/ProjectBuilder/Image.cpp +++ b/src/Tools/ProjectBuilder/Image.cpp @@ -11,6 +11,7 @@ #include "Kernel/PixelFormatHelper.h" #include "Kernel/ImageCodecHelper.h" #include "Kernel/VocabularyHelper.h" +#include "Kernel/ContentHelper.h" namespace Mengine { @@ -30,7 +31,9 @@ namespace Mengine { FileGroupInterfacePtr globalFileGroup = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "FileGroup" ), STRINGIZE_STRING_LOCAL( "dev" ) ); - InputStreamInterfacePtr stream = Helper::openInputStreamFile( globalFileGroup, _path, false, false, MENGINE_DOCUMENT_FUNCTION ); + ContentInterfacePtr content = Helper::makeFileContent( globalFileGroup, _path, MENGINE_DOCUMENT_FUNCTION ); + + InputStreamInterfacePtr stream = content->openInputStreamFile( false, false, MENGINE_DOCUMENT_FUNCTION ); if( stream == nullptr ) { @@ -48,7 +51,7 @@ namespace Mengine return false; } - if( imageDecoder->prepareData( stream ) == false ) + if( imageDecoder->prepareData( content, stream ) == false ) { return false; } @@ -98,7 +101,9 @@ namespace Mengine { FileGroupInterfacePtr globalFileGroup = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "FileGroup" ), STRINGIZE_STRING_LOCAL( "dev" ) ); - OutputStreamInterfacePtr stream = Helper::openOutputStreamFile( globalFileGroup, _path, false, MENGINE_DOCUMENT_FUNCTION ); + ContentInterfacePtr content = Helper::makeFileContent( globalFileGroup, _path, MENGINE_DOCUMENT_FUNCTION ); + + OutputStreamInterfacePtr stream = content->openOutputStreamFile( false, MENGINE_DOCUMENT_FUNCTION ); if( stream == nullptr ) { @@ -116,7 +121,7 @@ namespace Mengine return false; } - if( encoder->initialize( stream ) == false ) + if( encoder->initialize( content, stream ) == false ) { return false; } diff --git a/src/Tools/ProjectBuilder/ProjectBuilder.cpp b/src/Tools/ProjectBuilder/ProjectBuilder.cpp index 4c7bcff287..fc64e370b6 100644 --- a/src/Tools/ProjectBuilder/ProjectBuilder.cpp +++ b/src/Tools/ProjectBuilder/ProjectBuilder.cpp @@ -546,7 +546,9 @@ static PyObject * py_isAlphaInImageFile( PyObject * _self, PyObject * _args ) Mengine::FileGroupInterfacePtr globalFileGroup = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "FileGroup" ), STRINGIZE_STRING_LOCAL( "dev" ) ); - Mengine::InputStreamInterfacePtr stream = Mengine::Helper::openInputStreamFile( globalFileGroup, c_path, false, false, MENGINE_DOCUMENT_FUNCTION ); + Mengine::ContentInterfacePtr content = Mengine::Helper::makeFileContent( globalFileGroup, c_path, MENGINE_DOCUMENT_FUNCTION ); + + Mengine::InputStreamInterfacePtr stream = content->openInputStreamFile( false, false, MENGINE_DOCUMENT_FUNCTION ); if( stream == nullptr ) { @@ -564,7 +566,7 @@ static PyObject * py_isAlphaInImageFile( PyObject * _self, PyObject * _args ) return nullptr; } - if( imageDecoder->prepareData( stream ) == false ) + if( imageDecoder->prepareData( content, stream ) == false ) { return nullptr; } @@ -633,7 +635,9 @@ static PyObject * py_isPow2SquadImageFile( PyObject * _self, PyObject * _args ) Mengine::FileGroupInterfacePtr globalFileGroup = VOCABULARY_GET( STRINGIZE_STRING_LOCAL( "FileGroup" ), STRINGIZE_STRING_LOCAL( "dev" ) ); - Mengine::InputStreamInterfacePtr stream = Mengine::Helper::openInputStreamFile( globalFileGroup, c_path, false, false, MENGINE_DOCUMENT_FUNCTION ); + Mengine::ContentInterfacePtr content = Mengine::Helper::makeFileContent( globalFileGroup, c_path, MENGINE_DOCUMENT_FUNCTION ); + + Mengine::InputStreamInterfacePtr stream = content->openInputStreamFile( false, false, MENGINE_DOCUMENT_FUNCTION ); if( stream == nullptr ) { @@ -651,7 +655,7 @@ static PyObject * py_isPow2SquadImageFile( PyObject * _self, PyObject * _args ) return nullptr; } - if( imageDecoder->prepareData( stream ) == false ) + if( imageDecoder->prepareData( content, stream ) == false ) { return nullptr; } From 6c1b85e30400622e790de3baa0fa9964886634d5 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 3 Oct 2025 12:56:51 +0300 Subject: [PATCH 075/169] ref-in android MengineMonitorConnectivityStatusService --- gradle/build.gradle | 2 +- .../org/Mengine/Base/MengineAnalytics.java | 7 + .../org/Mengine/Base/MengineApplication.java | 34 ++-- ...ngineMonitorConnectivityStatusService.java | 185 +++++++++++------- .../Mengine/Base/MengineNetworkTransport.java | 1 + 5 files changed, 148 insertions(+), 81 deletions(-) diff --git a/gradle/build.gradle b/gradle/build.gradle index 02104a8b41..6a4d86813d 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -69,7 +69,7 @@ allprojects { if (ANDROID_APP_BUILD_TOOLS_VERSION != null) { buildToolsVersion = ANDROID_APP_BUILD_TOOLS_VERSION } else { - buildToolsVersion = "36.0.0" + buildToolsVersion = "36.1.0" } if (ANDROID_APP_MIN_SDK_VERSION != null) { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java index 126cfc94bb..c36d281207 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java @@ -63,6 +63,13 @@ static public void addContextParameterDouble(@Size(min = 1L,max = 40L) String ke MengineAnalytics.m_bases.put(key, value); } + static public void addContextGetterParameterBoolean(@Size(min = 1L,max = 40L) String key, MengineAnalyticsGetter value) { + MengineAnalytics.assertContext(key); + MengineAnalytics.assertGetter(key); + + MengineAnalytics.m_getter.put(key, value); + } + static public void addContextGetterParameterString(@Size(min = 1L,max = 40L) String key, MengineAnalyticsGetter value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java index 5dc6805355..ad59fe0baf 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java @@ -775,17 +775,19 @@ public void onCreate() { return m_acquisitionCampaign; }); - MengineAnalytics.addContextGetterParameterLong("connection", () -> { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - return -3L; - } - + MengineAnalytics.addContextGetterParameterBoolean("network_available", () -> { boolean networkAvailable = MengineNetwork.isNetworkAvailable(); - if (networkAvailable == false) { - return -2L; - } + return networkAvailable; + }); + MengineAnalytics.addContextGetterParameterBoolean("network_unmetered", () -> { + boolean networkUnmetered = MengineNetwork.isNetworkUnmetered(); + + return networkUnmetered; + }); + + MengineAnalytics.addContextGetterParameterLong("network_transport", () -> { MengineNetworkTransport networkTransport = MengineNetwork.getNetworkTransport(); if (networkTransport == MengineNetworkTransport.NETWORKTRANSPORT_CELLULAR) { @@ -820,6 +822,14 @@ public void onCreate() { return 8L; } + if (networkTransport == MengineNetworkTransport.NETWORKTRANSPORT_THREAD) { + return 9L; + } + + if (networkTransport == MengineNetworkTransport.NETWORKTRANSPORT_SATELLITE) { + return 10L; + } + return -1L; }); @@ -835,8 +845,6 @@ public void onCreate() { MengineNative.AndroidEnv_setMengineAndroidClassLoaderJNI(cl); - this.setState("application.init", "services_version"); - this.setState("application.init", "services_prepare"); for (MengineListenerApplication l : applicationListeners) { @@ -914,6 +922,8 @@ public void onCreate() { } } + this.setState("application.init", "native_app_create"); + Object nativeApplication = this.createNativeApplication(); if (nativeApplication == null) { @@ -936,10 +946,10 @@ public void onCreate() { MengineNative.AndroidKernelService_addPlugin(tag.toString(), p); } - this.setState("application.init", "run_main"); - MengineNative.AndroidKernelService_addPlugin("Application", this); + this.setState("application.init", "native_app_run"); + m_main = new MengineMain(m_nativeApplication); m_main.start(); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java index 3b552a121c..222774a139 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java @@ -4,6 +4,7 @@ import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.os.Build; import androidx.annotation.NonNull; @@ -13,122 +14,170 @@ public class MengineMonitorConnectivityStatusService extends MengineService impl private ConnectivityManager.NetworkCallback m_networkCallback; - @Override - public void onAppCreate(@NonNull MengineApplication application) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - return; + private static MengineNetworkTransport getNetworkTransport(@NonNull NetworkCapabilities networkCapabilities) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_CELLULAR; } - ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { - @Override - public void onAvailable(@NonNull Network network) { - super.onAvailable(network); + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_WIFI; + } - MengineMonitorConnectivityStatusService.this.logInfo("network available"); + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_BLUETOOTH; + } - MengineNetwork.setNetworkAvailable(true); - } + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_ETHERNET; + } - @Override - public void onLost(@NonNull Network network) { - super.onLost(network); + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_VPN; + } + + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_WIFI_AWARE; + } - MengineMonitorConnectivityStatusService.this.logInfo("network lost"); + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_LOWPAN; + } + + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_USB; + } + + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_THREAD) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_THREAD; + } - MengineNetwork.setNetworkAvailable(false); + if (Build.VERSION.SDK_INT >= 34) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_SATELLITE; } + } - private MengineNetworkTransport getNetworkTransport(@NonNull NetworkCapabilities networkCapabilities) { - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_CELLULAR; - } + return MengineNetworkTransport.NETWORKTRANSPORT_UNKNOWN; + } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_WIFI; - } + private void recomputeAndPublish(@NonNull ConnectivityManager cm) { + boolean available = false; + boolean unmetered = false; + MengineNetworkTransport transport = MengineNetworkTransport.NETWORKTRANSPORT_UNKNOWN; - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_BLUETOOTH; - } + try { + Network[] networks = cm.getAllNetworks(); - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_ETHERNET; - } + for (Network network : networks) { + NetworkCapabilities nc = cm.getNetworkCapabilities(network); - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_VPN; - } + if (nc != null && + nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true && + nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) == true ) { - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_WIFI_AWARE; - } + available = true; + unmetered = nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + transport = MengineMonitorConnectivityStatusService.getNetworkTransport(nc); - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_LOWPAN; + break; } + } + } catch (SecurityException e) { + MengineMonitorConnectivityStatusService.this.logError("SecurityException ACCESS_NETWORK_STATE missing [exception: %s]" + , e.getMessage() + ); + } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_USB; - } + MengineNetwork.setNetworkAvailable(available); + MengineNetwork.setNetworkUnmetered(unmetered); + MengineNetwork.setNetworkTransport(transport); + } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_THREAD) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_THREAD; - } + @Override + public void onAppCreate(@NonNull MengineApplication application) { + Context context = application.getApplicationContext(); + ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); + + if (cm == null) { + this.logError("invalid get ConnectivityManager"); - return MengineNetworkTransport.NETWORKTRANSPORT_UNKNOWN; + return; + } + + ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { + @Override + public void onAvailable(@NonNull Network network) { + super.onAvailable(network); + + MengineMonitorConnectivityStatusService.this.logInfo("network %s available" + , network.toString() + ); + + MengineMonitorConnectivityStatusService.this.recomputeAndPublish(cm); } @Override - public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { - super.onCapabilitiesChanged(network, networkCapabilities); - final boolean unmetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + public void onLost(@NonNull Network network) { + super.onLost(network); - MengineNetworkTransport transport = this.getNetworkTransport(networkCapabilities); + MengineMonitorConnectivityStatusService.this.logInfo("network %s lost" + , network.toString() + ); - boolean last_unmetered = MengineNetwork.isNetworkUnmetered(); - MengineNetworkTransport last_transport = MengineNetwork.getNetworkTransport(); + MengineMonitorConnectivityStatusService.this.recomputeAndPublish(cm); + } - if (last_unmetered == unmetered && last_transport == transport) { - return; - } + @Override + public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { + super.onCapabilitiesChanged(network, networkCapabilities); + final boolean unmetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + MengineNetworkTransport transport = MengineMonitorConnectivityStatusService.getNetworkTransport(networkCapabilities); - MengineMonitorConnectivityStatusService.this.logInfo("network capabilities changed unmetered: %b transport: %s" + MengineMonitorConnectivityStatusService.this.logInfo("network %s capabilities changed unmetered: %b transport: %s" + , network.toString() , unmetered , transport ); - MengineNetwork.setNetworkUnmetered(unmetered); - MengineNetwork.setNetworkTransport(transport); + MengineMonitorConnectivityStatusService.this.recomputeAndPublish(cm); } }; - Context context = application.getApplicationContext(); + try { + NetworkRequest request = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); - ConnectivityManager connectivityManager = context.getSystemService(ConnectivityManager.class); + cm.registerNetworkCallback(request, networkCallback); - if (connectivityManager != null) { - connectivityManager.registerDefaultNetworkCallback(networkCallback); + m_networkCallback = networkCallback; + } catch (Exception e) { + this.logError("invalid registerNetworkCallback: %s" + , e.getMessage() + ); } - m_networkCallback = networkCallback; + this.recomputeAndPublish(cm, null); } @Override public void onAppTerminate(@NonNull MengineApplication application) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - return; - } - if (m_networkCallback == null) { return; } Context context = application.getApplicationContext(); - ConnectivityManager connectivityManager = context.getSystemService(ConnectivityManager.class); + ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); - if (connectivityManager != null) { - connectivityManager.unregisterNetworkCallback(m_networkCallback); + if (cm != null) { + try { + cm.unregisterNetworkCallback(m_networkCallback); + } catch (Exception e) { + this.logError("invalid unregisterNetworkCallback: %s" + , e.getMessage() + ); + } } m_networkCallback = null; diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetworkTransport.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetworkTransport.java index 60d71edfc1..37eae13899 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetworkTransport.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetworkTransport.java @@ -12,6 +12,7 @@ public class MengineNetworkTransport { public final static MengineNetworkTransport NETWORKTRANSPORT_LOWPAN = new MengineNetworkTransport("NETWORKTRANSPORT_LOWPAN"); public final static MengineNetworkTransport NETWORKTRANSPORT_USB = new MengineNetworkTransport("NETWORKTRANSPORT_USB"); public final static MengineNetworkTransport NETWORKTRANSPORT_THREAD = new MengineNetworkTransport("NETWORKTRANSPORT_THREAD"); + public final static MengineNetworkTransport NETWORKTRANSPORT_SATELLITE = new MengineNetworkTransport("NETWORKTRANSPORT_SATELLITE"); public final static MengineNetworkTransport NETWORKTRANSPORT_UNKNOWN = new MengineNetworkTransport("NETWORKTRANSPORT_UNKNOWN"); private final String m_name; From 35a871ab7c06177ef806070cae75074a3b1efeaa Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 3 Oct 2025 16:41:03 +0300 Subject: [PATCH 076/169] fix android MengineMonitorConnectivityStatusService --- ...ngineMonitorConnectivityStatusService.java | 39 +++++++++++++------ .../java/org/Mengine/Base/MengineUtils.java | 2 +- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java index 222774a139..bc99d78cf6 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMonitorConnectivityStatusService.java @@ -6,6 +6,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.os.Build; +import android.os.ext.SdkExtensions; import androidx.annotation.NonNull; @@ -35,25 +36,39 @@ private static MengineNetworkTransport getNetworkTransport(@NonNull NetworkCapab return MengineNetworkTransport.NETWORKTRANSPORT_VPN; } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_WIFI_AWARE; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_WIFI_AWARE; + } } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_LOWPAN; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_LOWPAN; + } } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_USB; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 12) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_USB; + } + } } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_THREAD) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_THREAD; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 7) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_THREAD) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_THREAD; + } + } } - if (Build.VERSION.SDK_INT >= 34) { - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_SATELLITE; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + if (SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 12) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_SATELLITE; + } } } @@ -157,7 +172,7 @@ public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapa ); } - this.recomputeAndPublish(cm, null); + this.recomputeAndPublish(cm); } @Override diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java index 0826a8012b..d1c683bc38 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineUtils.java @@ -1402,7 +1402,7 @@ static public String getOptionValueString(@NonNull MengineApplication applicatio String hyphen_option_value = hyphen_option + ":"; String double_hyphen_option_value = double_hyphen_option + ":"; - for(String o : options) { + for (String o : options) { if (o.equals(hyphen_option) == true) { MengineLog.logSingleWarning(TAG, "option [%s] has no value", option); From 623f233acf9a60171ff2667f358e83325bea5ef1 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 7 Oct 2025 01:31:22 +0300 Subject: [PATCH 077/169] fix default render camera&viewport --- src/Engine/Application.cpp | 6 + src/Engine/TextField.cpp | 5 - .../PythonFramework/EngineScriptEmbedding.cpp | 15 +- .../PythonFramework/KernelScriptEmbedding.cpp | 4 - .../PythonFramework/NodeScriptEmbedding.cpp | 12 ++ .../PythonFramework/ScriptHolder.cpp | 5 - src/Interface/PlayerServiceInterface.h | 6 +- src/Interface/RenderResolutionInterface.h | 3 - src/Kernel/CMakeLists.txt | 4 + src/Kernel/Entity.cpp | 5 - src/Kernel/HotSpot.cpp | 5 +- src/Kernel/RenderCamera.cpp | 5 - src/Kernel/RenderCamera.h | 1 + src/Kernel/RenderCameraOrthogonalDefault.cpp | 137 ++++++++++++++++++ src/Kernel/RenderCameraOrthogonalDefault.h | 37 +++++ src/Kernel/RenderResolution.cpp | 30 ++-- src/Kernel/RenderResolution.h | 20 ++- src/Kernel/RenderScissor.cpp | 5 - src/Kernel/RenderViewport.cpp | 5 - src/Kernel/RenderViewportDefault.cpp | 102 +++++++++++++ src/Kernel/RenderViewportDefault.h | 76 ++++++++++ .../AstralaxPlugin/AstralaxEmitter.cpp | 5 +- src/Plugins/MoviePlugin/Movie2.cpp | 5 - .../NodeDebuggerPlugin/ModuleNodeDebugger.cpp | 4 +- src/Services/PlayerService/PlayerService.cpp | 34 +---- src/Services/PlayerService/PlayerService.h | 16 +- 26 files changed, 437 insertions(+), 115 deletions(-) create mode 100644 src/Kernel/RenderCameraOrthogonalDefault.cpp create mode 100644 src/Kernel/RenderCameraOrthogonalDefault.h create mode 100644 src/Kernel/RenderViewportDefault.cpp create mode 100644 src/Kernel/RenderViewportDefault.h diff --git a/src/Engine/Application.cpp b/src/Engine/Application.cpp index 5d4d221de4..ab06db5a77 100644 --- a/src/Engine/Application.cpp +++ b/src/Engine/Application.cpp @@ -89,10 +89,12 @@ #include "Kernel/FileContent.h" #include "Kernel/RenderResolution.h" #include "Kernel/RenderViewport.h" +#include "Kernel/RenderViewportDefault.h" #include "Kernel/RenderScissor.h" #include "Kernel/RenderCameraOrthogonal.h" #include "Kernel/RenderCameraProjection.h" #include "Kernel/RenderCameraOrthogonalTarget.h" +#include "Kernel/RenderCameraOrthogonalDefault.h" #include "Kernel/BasePrototypeGenerator.h" #include "Kernel/AssertionMemoryPanic.h" #include "Kernel/AssertionUtf8.h" @@ -536,10 +538,12 @@ namespace Mengine NODE_FACTORY( Layer2D ); NODE_FACTORY( Landscape2D ); NODE_FACTORY( RenderViewport ); + NODE_FACTORY( RenderViewportDefault ); NODE_FACTORY( RenderScissor ); NODE_FACTORY( RenderCameraOrthogonal ); NODE_FACTORY( RenderCameraProjection ); NODE_FACTORY( RenderCameraOrthogonalTarget ); + NODE_FACTORY( RenderCameraOrthogonalDefault ); NODE_FACTORY( Window ); NODE_FACTORY( ShapeCircle ); NODE_FACTORY( ShapePacMan ); @@ -599,10 +603,12 @@ namespace Mengine NODE_FACTORY( Layer2D ); NODE_FACTORY( Landscape2D ); NODE_FACTORY( RenderViewport ); + NODE_FACTORY( RenderViewportDefault ); NODE_FACTORY( RenderScissor ); NODE_FACTORY( RenderCameraOrthogonal ); NODE_FACTORY( RenderCameraProjection ); NODE_FACTORY( RenderCameraOrthogonalTarget ); + NODE_FACTORY( RenderCameraOrthogonalDefault ); NODE_FACTORY( Window ); NODE_FACTORY( ShapeCircle ); NODE_FACTORY( ShapePacMan ); diff --git a/src/Engine/TextField.cpp b/src/Engine/TextField.cpp index 9d413139e6..86beadd751 100644 --- a/src/Engine/TextField.cpp +++ b/src/Engine/TextField.cpp @@ -74,11 +74,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool TextField::_activate() { - if( Node::_activate() == false ) - { - return false; - } - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_LOCALE_PREPARE, &TextField::notifyChangeLocalePrepare_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_LOCALE_POST, &TextField::notifyChangeLocalePost_, MENGINE_DOCUMENT_FACTORABLE ); NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_DEBUG_TEXT_MODE, &TextField::notifyDebugMode_, MENGINE_DOCUMENT_FACTORABLE ); diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index 96b61643a7..96dee8e68d 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -100,9 +100,6 @@ #include "Kernel/ResourceImage.h" #include "Kernel/RenderViewport.h" #include "Kernel/RenderScissor.h" -#include "Kernel/RenderCameraOrthogonal.h" -#include "Kernel/RenderCameraProjection.h" -#include "Kernel/RenderCameraOrthogonalTarget.h" #include "Kernel/SurfaceSound.h" #include "Kernel/SurfaceImage.h" #include "Kernel/SurfaceImageSequence.h" @@ -1694,25 +1691,25 @@ namespace Mengine return _kernel->string_from_char( deviceLanguage ); } ////////////////////////////////////////////////////////////////////////// - const RenderCameraOrthogonalPtr & s_getDefaultSceneRenderCamera2D() + const RenderCameraInterfacePtr & s_getDefaultSceneRenderCamera2D() { - const RenderCameraOrthogonalPtr & camera = PLAYER_SERVICE() + const RenderCameraInterfacePtr & camera = PLAYER_SERVICE() ->getDefaultSceneRenderCamera2D(); return camera; } ////////////////////////////////////////////////////////////////////////// - const RenderViewportPtr & s_getDefaultRenderViewport2D() + const RenderViewportInterfacePtr & s_getDefaultRenderViewport2D() { - const RenderViewportPtr & viewport = PLAYER_SERVICE() + const RenderViewportInterfacePtr & viewport = PLAYER_SERVICE() ->getDefaultRenderViewport2D(); return viewport; } ////////////////////////////////////////////////////////////////////////// - const RenderCameraOrthogonalPtr & s_getDefaultArrowRenderCamera2D() + const RenderCameraInterfacePtr & s_getDefaultArrowRenderCamera2D() { - const RenderCameraOrthogonalPtr & camera = PLAYER_SERVICE() + const RenderCameraInterfacePtr & camera = PLAYER_SERVICE() ->getDefaultArrowRenderCamera2D(); return camera; diff --git a/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp b/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp index 8ad1d45898..a29e8807d8 100644 --- a/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp @@ -62,9 +62,6 @@ #include "Kernel/Interender.h" #include "Kernel/RenderViewport.h" #include "Kernel/RenderScissor.h" -#include "Kernel/RenderCameraOrthogonal.h" -#include "Kernel/RenderCameraProjection.h" -#include "Kernel/RenderCameraOrthogonalTarget.h" #include "Kernel/ResourceImage.h" #include "Kernel/Shape.h" #include "Kernel/Entity.h" @@ -2860,7 +2857,6 @@ namespace Mengine pybind::interface_>( _kernel, "RenderResolutionInterface" ) .def( "getContentResolution", &RenderResolutionInterface::getContentResolution ) - .def( "getGameViewport", &RenderResolutionInterface::getGameViewport ) ; pybind::interface_>( _kernel, "RenderViewportInterface" ) diff --git a/src/Frameworks/PythonFramework/NodeScriptEmbedding.cpp b/src/Frameworks/PythonFramework/NodeScriptEmbedding.cpp index 62cd96a48e..066ac889a1 100644 --- a/src/Frameworks/PythonFramework/NodeScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/NodeScriptEmbedding.cpp @@ -81,10 +81,12 @@ #include "Kernel/SurfaceSolidColor.h" #include "Kernel/Interender.h" #include "Kernel/RenderViewport.h" +#include "Kernel/RenderViewportDefault.h" #include "Kernel/RenderScissor.h" #include "Kernel/RenderCameraOrthogonal.h" #include "Kernel/RenderCameraProjection.h" #include "Kernel/RenderCameraOrthogonalTarget.h" +#include "Kernel/RenderCameraOrthogonalDefault.h" #include "Kernel/ResourceImage.h" #include "Kernel/ResourceImageData.h" #include "Kernel/ResourceImageEmpty.h" @@ -783,6 +785,9 @@ namespace Mengine .def( "getViewport", &RenderViewport::getViewport ) ; + pybind::interface_>( _kernel, "RenderViewportDefault", false ) + ; + pybind::interface_>( _kernel, "RenderScissor", false ) .def( "setScissorViewport", &RenderScissor::setScissorViewport ) .def( "getScissorViewport", &RenderScissor::getScissorViewport ) @@ -824,6 +829,9 @@ namespace Mengine .def( "isFixedHorizont", &RenderCameraOrthogonalTarget::isFixedHorizont ) ; + pybind::interface_>( _kernel, "RenderCameraOrthogonalDefault", false ) + ; + { pybind::interface_>( _kernel, "SoundEmitter", false ) .def( "setSurfaceSound", &SoundEmitter::setSurfaceSound ) @@ -1205,10 +1213,12 @@ namespace Mengine SCRIPT_CLASS_WRAPPING( Window ); SCRIPT_CLASS_WRAPPING( RenderViewport ); + SCRIPT_CLASS_WRAPPING( RenderViewportDefault ); SCRIPT_CLASS_WRAPPING( RenderScissor ); SCRIPT_CLASS_WRAPPING( RenderCameraOrthogonal ); SCRIPT_CLASS_WRAPPING( RenderCameraProjection ); SCRIPT_CLASS_WRAPPING( RenderCameraOrthogonalTarget ); + SCRIPT_CLASS_WRAPPING( RenderCameraOrthogonalDefault ); SCRIPT_CLASS_WRAPPING( SurfaceSound ); SCRIPT_CLASS_WRAPPING( SurfaceImage ); @@ -1267,10 +1277,12 @@ namespace Mengine UNSCRIPT_CLASS_WRAPPING( Window ); UNSCRIPT_CLASS_WRAPPING( RenderViewport ); + UNSCRIPT_CLASS_WRAPPING( RenderViewportDefault ); UNSCRIPT_CLASS_WRAPPING( RenderScissor ); UNSCRIPT_CLASS_WRAPPING( RenderCameraOrthogonal ); UNSCRIPT_CLASS_WRAPPING( RenderCameraProjection ); UNSCRIPT_CLASS_WRAPPING( RenderCameraOrthogonalTarget ); + UNSCRIPT_CLASS_WRAPPING( RenderCameraOrthogonalDefault ); UNSCRIPT_CLASS_WRAPPING( SurfaceSound ); UNSCRIPT_CLASS_WRAPPING( SurfaceImage ); diff --git a/src/Frameworks/PythonFramework/ScriptHolder.cpp b/src/Frameworks/PythonFramework/ScriptHolder.cpp index fcda34dad4..24467143a5 100644 --- a/src/Frameworks/PythonFramework/ScriptHolder.cpp +++ b/src/Frameworks/PythonFramework/ScriptHolder.cpp @@ -17,11 +17,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool ScriptHolder::_activate() { - if( Node::_activate() == false ) - { - return false; - } - m_script = EVENTABLE_METHODR( EVENT_SCRIPT_HOLDER_KEEP, pybind::object() ) ->onScriptHolderKeepScript(); diff --git a/src/Interface/PlayerServiceInterface.h b/src/Interface/PlayerServiceInterface.h index 1f14f52df0..13fbd63cd2 100644 --- a/src/Interface/PlayerServiceInterface.h +++ b/src/Interface/PlayerServiceInterface.h @@ -51,9 +51,9 @@ namespace Mengine virtual void destroyLayout( const LayoutInterfacePtr & _layout ) = 0; public: - virtual const RenderCameraOrthogonalPtr & getDefaultSceneRenderCamera2D() const = 0; - virtual const RenderViewportPtr & getDefaultRenderViewport2D() const = 0; - virtual const RenderCameraOrthogonalPtr & getDefaultArrowRenderCamera2D() const = 0; + virtual const RenderCameraInterfacePtr & getDefaultSceneRenderCamera2D() const = 0; + virtual const RenderViewportInterfacePtr & getDefaultRenderViewport2D() const = 0; + virtual const RenderCameraInterfacePtr & getDefaultArrowRenderCamera2D() const = 0; public: virtual void setRenderResolution( const RenderResolutionInterfacePtr & _resolution ) = 0; diff --git a/src/Interface/RenderResolutionInterface.h b/src/Interface/RenderResolutionInterface.h index 8a7f631636..05f1f8eb74 100644 --- a/src/Interface/RenderResolutionInterface.h +++ b/src/Interface/RenderResolutionInterface.h @@ -14,9 +14,6 @@ namespace Mengine virtual void setContentResolution( const Resolution & _resolution ) = 0; virtual const Resolution & getContentResolution() const = 0; - virtual void setGameViewport( const Viewport & _viewport ) = 0; - virtual const Viewport & getGameViewport() const = 0; - public: virtual void fromContentToScreenPosition( const mt::vec2f & _contentPosition, mt::vec2f * const _screenPosition ) const = 0; virtual void fromScreenToContentPosition( const mt::vec2f & _screenPosition, mt::vec2f * const _contentPosition ) const = 0; diff --git a/src/Kernel/CMakeLists.txt b/src/Kernel/CMakeLists.txt index 5541ffacad..e04ea45ac0 100644 --- a/src/Kernel/CMakeLists.txt +++ b/src/Kernel/CMakeLists.txt @@ -298,8 +298,12 @@ RenderCamera RenderCameraProjection.h RenderCameraOrthogonalTarget.cpp RenderCameraOrthogonalTarget.h + RenderCameraOrthogonalDefault.cpp + RenderCameraOrthogonalDefault.h RenderViewport.h RenderViewport.cpp + RenderViewportDefault.h + RenderViewportDefault.cpp RenderScissor.h RenderScissor.cpp RenderResolution.h diff --git a/src/Kernel/Entity.cpp b/src/Kernel/Entity.cpp index 211682d270..61f3b9500f 100644 --- a/src/Kernel/Entity.cpp +++ b/src/Kernel/Entity.cpp @@ -118,11 +118,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Entity::_activate() { - if( Node::_activate() == false ) - { - return false; - } - bool successful = EVENTABLE_METHODR( EVENT_ENTITY_PREPARATION, true ) ->onEntityPreparation( m_behavior ); diff --git a/src/Kernel/HotSpot.cpp b/src/Kernel/HotSpot.cpp index 5a8fee2bae..9ea50ed118 100644 --- a/src/Kernel/HotSpot.cpp +++ b/src/Kernel/HotSpot.cpp @@ -339,10 +339,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool HotSpot::_activate() { - if( Node::_activate() == false ) - { - return false; - } + //Empty return true; } diff --git a/src/Kernel/RenderCamera.cpp b/src/Kernel/RenderCamera.cpp index 785a06688f..318ba116fe 100644 --- a/src/Kernel/RenderCamera.cpp +++ b/src/Kernel/RenderCamera.cpp @@ -23,11 +23,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool RenderCamera::_activate() { - if( Node::_activate() == false ) - { - return true; - } - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION, &RenderCamera::notifyChangeWindowResolution_, MENGINE_DOCUMENT_FACTORABLE ); this->invalidateViewMatrix_(); diff --git a/src/Kernel/RenderCamera.h b/src/Kernel/RenderCamera.h index 5fbe3fa9ce..1aeb68fb3b 100644 --- a/src/Kernel/RenderCamera.h +++ b/src/Kernel/RenderCamera.h @@ -156,6 +156,7 @@ namespace Mengine MENGINE_INLINE void RenderCamera::invalidateProjectionMatrix_() const { m_invalidateProjectionMatrix = true; + m_invalidateViewMatrix = true; m_invalidateViewProjectionMatrix = true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Kernel/RenderCameraOrthogonalDefault.cpp b/src/Kernel/RenderCameraOrthogonalDefault.cpp new file mode 100644 index 0000000000..d897256958 --- /dev/null +++ b/src/Kernel/RenderCameraOrthogonalDefault.cpp @@ -0,0 +1,137 @@ +#include "RenderCameraOrthogonalDefault.h" + +#include "Interface/ApplicationInterface.h" + +#include "Kernel/Logger.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + RenderCameraOrthogonalDefault::RenderCameraOrthogonalDefault() + { + } + ////////////////////////////////////////////////////////////////////////// + RenderCameraOrthogonalDefault::~RenderCameraOrthogonalDefault() + { + } + ////////////////////////////////////////////////////////////////////////// + void RenderCameraOrthogonalDefault::fromWorldToScreenPosition( const mt::mat4f & _worldMatrix, mt::vec2f * const _screenPosition ) const + { + const mt::mat4f & vpm = this->getCameraViewProjectionMatrix(); + + mt::mat4f wvpm; + mt::mul_m4_m4( &wvpm, _worldMatrix, vpm ); + + mt::vec2f v_clip; + mt::mul_v2_v2z_m4_homogenize( &v_clip, wvpm ); + + mt::vec2f v_wvpn; + v_wvpn.x = (1.f + v_clip.x) * 0.5f; + v_wvpn.y = (1.f - v_clip.y) * 0.5f; + + *_screenPosition = v_wvpn; + } + ////////////////////////////////////////////////////////////////////////// + void RenderCameraOrthogonalDefault::fromScreenToWorldPosition( const mt::vec2f & _screenPoint, float _deep, mt::vec3f * const _worldPosition ) const + { + const mt::mat4f & pm_inv = this->getCameraProjectionMatrixInv(); + + mt::vec2f p1 = _screenPoint * 2.f - mt::vec2f( 1.f, 1.f ); + p1.y = -p1.y; + + mt::vec2f p_pm; + mt::mul_v2_v2_m4( &p_pm, p1, pm_inv ); + + const mt::mat4f & vm = this->getCameraViewMatrix(); + + mt::mat4f vm_inv; + mt::inv_m4_m4( &vm_inv, vm ); + + mt::vec2f p = p_pm; + + mt::vec3f p_vm; + mt::mul_v3_v2_m4( &p_vm, p, vm_inv ); + + //Viewport vp; + //this->makeViewport_( &vp ); + + //mt::vec3f wp; + //wp.x = p_vm.x - vp.begin.x; + //wp.y = p_vm.y - vp.begin.y; + //wp.z = p_vm.z + _deep; + + mt::vec3f wp; + wp.x = p_vm.x; + wp.y = p_vm.y; + wp.z = p_vm.z + _deep; + + *_worldPosition = wp; + } + ////////////////////////////////////////////////////////////////////////// + void RenderCameraOrthogonalDefault::fromScreenToWorldDelta( const mt::vec2f & _screenDelta, float _deep, mt::vec3f * const _worldDelta ) const + { + MENGINE_UNUSED( _deep ); + //TODO: implement deep + + const mt::mat4f & pm_inv = this->getCameraViewProjectionMatrixInv(); + + mt::vec3f p_pm_base; + mt::mul_v3_v2z_m4( &p_pm_base, pm_inv ); + + mt::vec2f p_delta = _screenDelta * 2.f; + p_delta.y = -p_delta.y; + + mt::vec3f p_pm_delta; + mt::mul_v3_v2_m4( &p_pm_delta, p_delta, pm_inv ); + + mt::vec3f wd; + wd.x = p_pm_delta.x - p_pm_base.x; + wd.y = p_pm_delta.y - p_pm_base.y; + wd.z = 0.f; + + *_worldDelta = wd; + } + ////////////////////////////////////////////////////////////////////////// + void RenderCameraOrthogonalDefault::_updateViewMatrix() const + { + const mt::mat4f & wm = this->getWorldMatrix(); + + mt::inv_m4_m4( &m_viewMatrix, wm ); + m_viewMatrixInv = wm; + } + ////////////////////////////////////////////////////////////////////////// + void RenderCameraOrthogonalDefault::_updateProjectionMatrix() const + { + Viewport renderViewport; + this->makeViewport_( &renderViewport ); + + const mt::vec2f & rvbegin = renderViewport.begin; + const mt::vec2f & rvend = renderViewport.end; + + mt::make_projection_ortho_lh_m4( &m_projectionMatrix, rvbegin.x, rvend.x, rvbegin.y, rvend.y, -10000.f, 10000.f ); + + mt::inv_m4_m4( &m_projectionMatrixInv, m_projectionMatrix ); + } + ////////////////////////////////////////////////////////////////////////// + void RenderCameraOrthogonalDefault::makeViewport_( Viewport * const _viewport ) const + { + const mt::mat4f & wm = this->getWorldMatrix(); + + float gameViewportAspect; + Viewport gameViewport; + APPLICATION_SERVICE() + ->getGameViewport( &gameViewportAspect, &gameViewport ); + + Viewport renderViewportWM; + gameViewport.multiply( &renderViewportWM, wm ); + + renderViewportWM.clamp( gameViewport ); + + mt::mat4f wm_inv; + mt::inv_m4_m4( &wm_inv, wm ); + + mt::mul_v2_v2_m4( &_viewport->begin, renderViewportWM.begin, wm_inv ); + mt::mul_v2_v2_m4( &_viewport->end, renderViewportWM.end, wm_inv ); + } + ////////////////////////////////////////////////////////////////////////// +} diff --git a/src/Kernel/RenderCameraOrthogonalDefault.h b/src/Kernel/RenderCameraOrthogonalDefault.h new file mode 100644 index 0000000000..6a561d1705 --- /dev/null +++ b/src/Kernel/RenderCameraOrthogonalDefault.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Kernel/RenderCamera.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + class RenderCameraOrthogonalDefault + : public RenderCamera + { + DECLARE_FACTORABLE( RenderCameraOrthogonalDefault ); + + public: + RenderCameraOrthogonalDefault(); + ~RenderCameraOrthogonalDefault() override; + + protected: + void fromWorldToScreenPosition( const mt::mat4f & _worldMatrix, mt::vec2f * const _screenPosition ) const override; + + protected: + void fromScreenToWorldPosition( const mt::vec2f & _screenPoint, float _deep, mt::vec3f * const _worldPosition ) const override; + void fromScreenToWorldDelta( const mt::vec2f & _screenDelta, float _deep, mt::vec3f * const _worldDelta ) const override; + + protected: + void _updateViewMatrix() const override; + void _updateProjectionMatrix() const override; + + protected: + void makeViewport_( Viewport * const _viewport ) const; + + protected: + mutable Viewport m_renderViewport; + }; + ////////////////////////////////////////////////////////////////////////// + typedef IntrusivePtr RenderCameraOrthogonalDefaultPtr; + ////////////////////////////////////////////////////////////////////////// +} diff --git a/src/Kernel/RenderResolution.cpp b/src/Kernel/RenderResolution.cpp index bfd2dc6709..a1db6b78d6 100644 --- a/src/Kernel/RenderResolution.cpp +++ b/src/Kernel/RenderResolution.cpp @@ -1,5 +1,7 @@ #include "RenderResolution.h" +#include "Kernel/NotificationHelper.h" + namespace Mengine { ////////////////////////////////////////////////////////////////////////// @@ -11,27 +13,29 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - void RenderResolution::setContentResolution( const Resolution & _resolution ) + bool RenderResolution::_activate() { - m_contentResolution = _resolution; + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION, &RenderResolution::notifyChangeWindowResolution_, MENGINE_DOCUMENT_FACTORABLE ); - m_contentResolution.calcSize( &m_contentResolutionSize ); - m_contentResolution.calcSizeInv( &m_contentResolutionSizeInv ); + return true; } ////////////////////////////////////////////////////////////////////////// - const Resolution & RenderResolution::getContentResolution() const + void RenderResolution::_deactivate() { - return m_contentResolution; + NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION ); } ////////////////////////////////////////////////////////////////////////// - void RenderResolution::setGameViewport( const Viewport & _viewport ) + void RenderResolution::setContentResolution( const Resolution & _resolution ) { - m_gameViewport = _viewport; + m_contentResolution = _resolution; + + m_contentResolution.calcSize( &m_contentResolutionSize ); + m_contentResolution.calcSizeInv( &m_contentResolutionSizeInv ); } ////////////////////////////////////////////////////////////////////////// - const Viewport & RenderResolution::getGameViewport() const + const Resolution & RenderResolution::getContentResolution() const { - return m_gameViewport; + return m_contentResolution; } ////////////////////////////////////////////////////////////////////////// void RenderResolution::fromContentToScreenPosition( const mt::vec2f & _contentPosition, mt::vec2f * const _screenPosition ) const @@ -44,4 +48,10 @@ namespace Mengine *_contentPosition = _screenPosition * m_contentResolutionSize; } ////////////////////////////////////////////////////////////////////////// + void RenderResolution::notifyChangeWindowResolution_( bool _fullscreen, const Resolution & _resolution ) + { + MENGINE_UNUSED( _fullscreen ); + MENGINE_UNUSED( _resolution ); + } + ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/RenderResolution.h b/src/Kernel/RenderResolution.h index 17694cee2f..8ad1e165c0 100644 --- a/src/Kernel/RenderResolution.h +++ b/src/Kernel/RenderResolution.h @@ -2,16 +2,19 @@ #include "Interface/RenderResolutionInterface.h" +#include "Kernel/Node.h" +#include "Kernel/Observable.h" + #include "Kernel/Viewport.h" #include "Kernel/Resolution.h" -#include "Kernel/Factorable.h" namespace Mengine { ////////////////////////////////////////////////////////////////////////// class RenderResolution - : public RenderResolutionInterface - , public Factorable + : public Node + , public Observable + , public RenderResolutionInterface { DECLARE_FACTORABLE( RenderResolution ); @@ -19,20 +22,23 @@ namespace Mengine RenderResolution(); ~RenderResolution() override; + protected: + bool _activate() override; + void _deactivate() override; + public: void setContentResolution( const Resolution & _resolution ) override; const Resolution & getContentResolution() const override; - void setGameViewport( const Viewport & _viewport ) override; - const Viewport & getGameViewport() const override; - public: void fromContentToScreenPosition( const mt::vec2f & _contentPosition, mt::vec2f * const _screenPosition ) const override; void fromScreenToContentPosition( const mt::vec2f & _screenPosition, mt::vec2f * const _contentPosition ) const override; + protected: + void notifyChangeWindowResolution_( bool _fullscreen, const Resolution & _resolution ); + protected: Resolution m_contentResolution; - Viewport m_gameViewport; mt::vec2f m_contentResolutionSize; mt::vec2f m_contentResolutionSizeInv; diff --git a/src/Kernel/RenderScissor.cpp b/src/Kernel/RenderScissor.cpp index 867f3be7d2..398b8625b0 100644 --- a/src/Kernel/RenderScissor.cpp +++ b/src/Kernel/RenderScissor.cpp @@ -22,11 +22,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool RenderScissor::_activate() { - if( Node::_activate() == false ) - { - return true; - } - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION, &RenderScissor::notifyChangeWindowResolution, MENGINE_DOCUMENT_FACTORABLE ); this->invalidateViewport_(); diff --git a/src/Kernel/RenderViewport.cpp b/src/Kernel/RenderViewport.cpp index 203a56f63a..fd798c0166 100644 --- a/src/Kernel/RenderViewport.cpp +++ b/src/Kernel/RenderViewport.cpp @@ -23,11 +23,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool RenderViewport::_activate() { - if( Node::_activate() == false ) - { - return true; - } - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION, &RenderViewport::notifyChangeWindowResolution, MENGINE_DOCUMENT_FACTORABLE ); this->invalidateViewport_(); diff --git a/src/Kernel/RenderViewportDefault.cpp b/src/Kernel/RenderViewportDefault.cpp new file mode 100644 index 0000000000..d5d26dee90 --- /dev/null +++ b/src/Kernel/RenderViewportDefault.cpp @@ -0,0 +1,102 @@ +#include "RenderViewportDefault.h" + +#include "Interface/ApplicationInterface.h" + +#include "Kernel/AssertionObservable.h" +#include "Kernel/NotificationHelper.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + RenderViewportDefault::RenderViewportDefault() + : m_invalidateViewport( true ) + { + } + ////////////////////////////////////////////////////////////////////////// + RenderViewportDefault::~RenderViewportDefault() + { + MENGINE_ASSERTION_OBSERVABLE( this, "viewport '%s'" + , this->getName().c_str() + ); + } + ////////////////////////////////////////////////////////////////////////// + bool RenderViewportDefault::_activate() + { + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION, &RenderViewportDefault::notifyChangeWindowResolution, MENGINE_DOCUMENT_FACTORABLE ); + + this->invalidateViewport_(); + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void RenderViewportDefault::_deactivate() + { + Node::_deactivate(); + + NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_CHANGE_WINDOW_RESOLUTION ); + } + ////////////////////////////////////////////////////////////////////////// + void RenderViewportDefault::_invalidateWorldMatrix() const + { + this->invalidateViewport_(); + } + ////////////////////////////////////////////////////////////////////////// + void RenderViewportDefault::updateViewport_() const + { + m_invalidateViewport = false; + + float gameViewportAspect; + Viewport gameViewport; + APPLICATION_SERVICE() + ->getGameViewport( &gameViewportAspect, &gameViewport ); + + const Resolution & contentResolution = APPLICATION_SERVICE() + ->getContentResolution(); + + mt::vec2f contentResolutionSize; + contentResolution.calcSize( &contentResolutionSize ); + + mt::vec2f contentResolutionSizeInv; + contentResolution.calcSizeInv( &contentResolutionSizeInv ); + + mt::vec2f viewportMaskBegin = gameViewport.begin * contentResolutionSizeInv; + mt::vec2f viewportMaskEnd = gameViewport.end * contentResolutionSizeInv; + + mt::vec2f viewportMaskSize = viewportMaskEnd - viewportMaskBegin; + + Viewport viewport( 0.f, 0.f, contentResolutionSize.x, contentResolutionSize.y ); + + const mt::mat4f & wm = this->getWorldMatrix(); + + Viewport viewportWM; + mt::mul_v2_v2_m4( &viewportWM.begin, viewport.begin, wm ); + mt::mul_v2_v2_m4( &viewportWM.end, viewport.end, wm ); + + viewportWM.begin *= contentResolutionSizeInv; + viewportWM.end *= contentResolutionSizeInv; + + m_viewportWM.begin = (viewportWM.begin - viewportMaskBegin) / viewportMaskSize * contentResolutionSize; + m_viewportWM.end = (viewportWM.end - viewportMaskBegin) / viewportMaskSize * contentResolutionSize; + + m_viewportWM.clamp( contentResolutionSize ); + } + ////////////////////////////////////////////////////////////////////////// + void RenderViewportDefault::notifyChangeWindowResolution( bool _fullscreen, const Resolution & _resolution ) + { + MENGINE_UNUSED( _fullscreen ); + MENGINE_UNUSED( _resolution ); + + this->invalidateViewport_(); + } + ////////////////////////////////////////////////////////////////////////// + void RenderViewportDefault::fromCameraToContentPosition( const mt::vec2f & _cameraPosition, mt::vec2f * const _contentPosition ) const + { + const Viewport & vpwm = this->getViewportWM(); + + mt::vec2f wpwm_size; + vpwm.calcSize( &wpwm_size ); + + *_contentPosition = vpwm.begin + _cameraPosition * wpwm_size; + } + ////////////////////////////////////////////////////////////////////////// +} diff --git a/src/Kernel/RenderViewportDefault.h b/src/Kernel/RenderViewportDefault.h new file mode 100644 index 0000000000..31763703f2 --- /dev/null +++ b/src/Kernel/RenderViewportDefault.h @@ -0,0 +1,76 @@ +#pragma once + +#include "Interface/RenderViewportInterface.h" + +#include "Kernel/Node.h" +#include "Kernel/Observable.h" + +#include "Kernel/Viewport.h" +#include "Kernel/Resolution.h" + +#include "Kernel/BaseTransformation.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + class RenderViewportDefault + : public Node + , public Observable + , public RenderViewportInterface + , protected BaseTransformation + { + DECLARE_FACTORABLE( RenderViewportDefault ); + DECLARE_VISITABLE( Node ); + DECLARE_TRANSFORMABLE(); + + public: + RenderViewportDefault(); + ~RenderViewportDefault() override; + + protected: + bool _activate() override; + void _deactivate() override; + + public: + const Viewport & getViewportWM() const override; + + public: + void fromCameraToContentPosition( const mt::vec2f & _cameraPosition, mt::vec2f * const _contentPosition ) const override; + + protected: + void _invalidateWorldMatrix() const override; + + protected: + void invalidateViewport_() const; + + protected: + void updateViewport_() const; + + protected: + void notifyChangeWindowResolution( bool _fullscreen, const Resolution & _resolution ); + + protected: + Viewport m_viewport; + + mutable Viewport m_viewportWM; + mutable bool m_invalidateViewport; + }; + ////////////////////////////////////////////////////////////////////////// + typedef IntrusivePtr RenderViewportDefaultPtr; + ////////////////////////////////////////////////////////////////////////// + MENGINE_INLINE void RenderViewportDefault::invalidateViewport_() const + { + m_invalidateViewport = true; + } + ////////////////////////////////////////////////////////////////////////// + MENGINE_INLINE const Viewport & RenderViewportDefault::getViewportWM() const + { + if( m_invalidateViewport == true ) + { + this->updateViewport_(); + } + + return m_viewportWM; + } + ////////////////////////////////////////////////////////////////////////// +} diff --git a/src/Plugins/AstralaxPlugin/AstralaxEmitter.cpp b/src/Plugins/AstralaxPlugin/AstralaxEmitter.cpp index 687a2db0cc..a7bd5a61a8 100644 --- a/src/Plugins/AstralaxPlugin/AstralaxEmitter.cpp +++ b/src/Plugins/AstralaxPlugin/AstralaxEmitter.cpp @@ -44,10 +44,7 @@ namespace Mengine /////////////////////////////////////////////////////////////////////////// bool AstralaxEmitter::_activate() { - if( Node::_activate() == false ) - { - return false; - } + //Empty return true; } diff --git a/src/Plugins/MoviePlugin/Movie2.cpp b/src/Plugins/MoviePlugin/Movie2.cpp index ecb0e24905..9574402f14 100644 --- a/src/Plugins/MoviePlugin/Movie2.cpp +++ b/src/Plugins/MoviePlugin/Movie2.cpp @@ -2681,11 +2681,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Movie2::_activate() { - if( Node::_activate() == false ) - { - return false; - } - ae_vector3_t anchorPoint; if( ae_get_movie_composition_anchor_point( m_composition, anchorPoint ) == AE_TRUE ) { diff --git a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp b/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp index 4ce2ff76a1..ef642c9bd1 100644 --- a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp +++ b/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp @@ -2331,10 +2331,10 @@ namespace Mengine MENGINE_UNUSED( _width ); MENGINE_UNUSED( _height ); - Resolution resolution( 640, 480 ); + Resolution newResolution( _width, _height ); APPLICATION_SERVICE() - ->setWindowResolution( resolution ); + ->setWindowResolution( newResolution ); } ////////////////////////////////////////////////////////////////////////// void ModuleNodeDebugger::receiveSetting( const Char * _setting, const Char * _key, const Char * _value ) diff --git a/src/Services/PlayerService/PlayerService.cpp b/src/Services/PlayerService/PlayerService.cpp index 5b1efe1cb8..a4739e2900 100644 --- a/src/Services/PlayerService/PlayerService.cpp +++ b/src/Services/PlayerService/PlayerService.cpp @@ -26,8 +26,10 @@ #include "Kernel/Scene.h" #include "Kernel/NodeRenderHierarchy.h" #include "Kernel/RenderViewport.h" +#include "Kernel/RenderViewportDefault.h" #include "Kernel/RenderScissor.h" #include "Kernel/RenderCameraOrthogonal.h" +#include "Kernel/RenderCameraOrthogonalDefault.h" #include "Kernel/RenderCameraHelper.h" #include "Kernel/MT19937Randomizer.h" #include "Kernel/ThreadTask.h" @@ -324,45 +326,25 @@ namespace Mengine const Resolution & contentResolution = APPLICATION_SERVICE() ->getContentResolution(); - mt::vec2f cr; - contentResolution.calcSize( &cr ); - Viewport vp( 0.f, 0.f, cr.x, cr.y ); - - float gameViewportAspect; - Viewport gameViewport; - APPLICATION_SERVICE() - ->getGameViewport( &gameViewportAspect, &gameViewport ); - m_defaultResolution = Helper::generateFactorable( MENGINE_DOCUMENT_FACTORABLE ); - m_defaultResolution->setContentResolution( contentResolution ); - m_defaultResolution->setGameViewport( gameViewport ); this->setRenderResolution( m_defaultResolution ); - m_defaultCamera2D = Helper::generateNodeFactorable( MENGINE_DOCUMENT_FACTORABLE ); - + m_defaultCamera2D = Helper::generateNodeFactorable( MENGINE_DOCUMENT_FACTORABLE ); m_defaultCamera2D->setName( STRINGIZE_STRING_LOCAL( "DefaultCamera2D" ) ); - - m_defaultCamera2D->setOrthogonalViewport( gameViewport ); m_defaultCamera2D->enableForce(); this->setRenderCamera( m_defaultCamera2D ); - m_defaultViewport2D = Helper::generateNodeFactorable( MENGINE_DOCUMENT_FACTORABLE ); - + m_defaultViewport2D = Helper::generateNodeFactorable( MENGINE_DOCUMENT_FACTORABLE ); m_defaultViewport2D->setName( STRINGIZE_STRING_LOCAL( "DefaultViewport2D" ) ); - - m_defaultViewport2D->setViewport( vp ); m_defaultViewport2D->enableForce(); this->setRenderViewport( m_defaultViewport2D ); - m_defaultArrowCamera2D = Helper::generateNodeFactorable( MENGINE_DOCUMENT_FACTORABLE ); - + m_defaultArrowCamera2D = Helper::generateNodeFactorable( MENGINE_DOCUMENT_FACTORABLE ); m_defaultArrowCamera2D->setName( STRINGIZE_STRING_LOCAL( "DefaultArrowCamera2D" ) ); - - m_defaultArrowCamera2D->setOrthogonalViewport( gameViewport ); m_defaultArrowCamera2D->enableForce(); const NodePtr & node = ARROW_SERVICE() @@ -563,17 +545,17 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - const RenderCameraOrthogonalPtr & PlayerService::getDefaultSceneRenderCamera2D() const + const RenderCameraInterfacePtr & PlayerService::getDefaultSceneRenderCamera2D() const { return m_defaultCamera2D; } ////////////////////////////////////////////////////////////////////////// - const RenderViewportPtr & PlayerService::getDefaultRenderViewport2D() const + const RenderViewportInterfacePtr & PlayerService::getDefaultRenderViewport2D() const { return m_defaultViewport2D; } ////////////////////////////////////////////////////////////////////////// - const RenderCameraOrthogonalPtr & PlayerService::getDefaultArrowRenderCamera2D() const + const RenderCameraInterfacePtr & PlayerService::getDefaultArrowRenderCamera2D() const { return m_defaultArrowCamera2D; } diff --git a/src/Services/PlayerService/PlayerService.h b/src/Services/PlayerService/PlayerService.h index 05a35d3346..b7f5794f65 100644 --- a/src/Services/PlayerService/PlayerService.h +++ b/src/Services/PlayerService/PlayerService.h @@ -14,8 +14,8 @@ #include "Kernel/Resolution.h" #include "Kernel/Affectorable.h" #include "Kernel/RenderResolution.h" -#include "Kernel/RenderCameraOrthogonal.h" -#include "Kernel/RenderViewport.h" +#include "Kernel/RenderViewportDefault.h" +#include "Kernel/RenderCameraOrthogonalDefault.h" #include "Kernel/RenderRoot.h" namespace Mengine @@ -62,9 +62,9 @@ namespace Mengine const AffectorHubInterfacePtr & getGlobalAffectorHub() const override; public: - const RenderCameraOrthogonalPtr & getDefaultSceneRenderCamera2D() const override; - const RenderViewportPtr & getDefaultRenderViewport2D() const override; - const RenderCameraOrthogonalPtr & getDefaultArrowRenderCamera2D() const override; + const RenderCameraInterfacePtr & getDefaultSceneRenderCamera2D() const override; + const RenderViewportInterfacePtr & getDefaultRenderViewport2D() const override; + const RenderCameraInterfacePtr & getDefaultArrowRenderCamera2D() const override; public: void setRenderResolution( const RenderResolutionInterfacePtr & _resolution ) override; @@ -141,9 +141,9 @@ namespace Mengine protected: RenderResolutionPtr m_defaultResolution; - RenderCameraOrthogonalPtr m_defaultCamera2D; - RenderViewportPtr m_defaultViewport2D; - RenderCameraOrthogonalPtr m_defaultArrowCamera2D; + RenderCameraOrthogonalDefaultPtr m_defaultCamera2D; + RenderViewportDefaultPtr m_defaultViewport2D; + RenderCameraOrthogonalDefaultPtr m_defaultArrowCamera2D; RenderResolutionInterfacePtr m_renderResolution; RenderViewportInterfacePtr m_renderViewport; From c0f69bcc35360a5334afe903e9f8c4c822c7b98b Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 8 Oct 2025 14:23:31 +0300 Subject: [PATCH 078/169] fix application calc window resolution --- src/Engine/Application.cpp | 23 ++++++++++++---------- src/Kernel/RenderCameraOrthogonalDefault.h | 2 +- src/Kernel/Resolution.h | 2 ++ src/Tools/NodeDebugger/NodeDebuggerApp.cpp | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/Engine/Application.cpp b/src/Engine/Application.cpp index ab06db5a77..f5a69c59b5 100644 --- a/src/Engine/Application.cpp +++ b/src/Engine/Application.cpp @@ -1961,30 +1961,30 @@ namespace Mengine if( windowResolutionHeight > maxClientResolutionHeight ) { - uint32_t new_witdh = static_cast(float( windowResolutionHeight ) * aspect + 0.5f); + uint32_t new_width = static_cast(float( maxClientResolutionHeight ) * aspect + 0.5f); uint32_t new_height = maxClientResolutionHeight; - if( new_witdh > maxClientResolutionWidth ) + if( new_width > maxClientResolutionWidth ) { - new_witdh = maxClientResolutionWidth; + new_width = maxClientResolutionWidth; new_height = static_cast(float( maxClientResolutionWidth ) / aspect + 0.5f); } - _windowResolution->setWidth( new_witdh ); + _windowResolution->setWidth( new_width ); _windowResolution->setHeight( new_height ); } else if( windowResolutionWidth > maxClientResolutionWidth ) { - uint32_t new_witdh = maxClientResolutionWidth; - uint32_t new_height = static_cast(float( windowResolutionWidth ) / aspect + 0.5f); + uint32_t new_width = maxClientResolutionWidth; + uint32_t new_height = static_cast(float( maxClientResolutionWidth ) / aspect + 0.5f); if( new_height > maxClientResolutionHeight ) { - new_witdh = static_cast(float( maxClientResolutionHeight ) * aspect + 0.5f); + new_width = static_cast(float( maxClientResolutionHeight ) * aspect + 0.5f); new_height = maxClientResolutionHeight; } - _windowResolution->setWidth( new_witdh ); + _windowResolution->setWidth( new_width ); _windowResolution->setHeight( new_height ); } else @@ -2064,11 +2064,13 @@ namespace Mengine return; } - LOGGER_INFO( "system", "set change window resolution size %u:%u -> %u:%u" + LOGGER_INFO( "system", "set change window resolution size %u:%u -> %u:%u aspect %f -> %f" , m_windowResolution.getWidth() , m_windowResolution.getHeight() , _resolution.getWidth() , _resolution.getHeight() + , m_windowResolution.getAspectRatio() + , _resolution.getAspectRatio() ); m_windowResolution = _resolution; @@ -2138,10 +2140,11 @@ namespace Mengine return; } - LOGGER_INFO( "system", "current resolution [%s] [%u %u]" + LOGGER_INFO( "system", "current resolution [%s] [%u %u] aspect: %f" , fullscreen == true ? "Fullscreen" : "Window" , windowResolution.getWidth() , windowResolution.getHeight() + , windowResolution.getAspectRatio() ); m_currentWindowResolution = windowResolution; diff --git a/src/Kernel/RenderCameraOrthogonalDefault.h b/src/Kernel/RenderCameraOrthogonalDefault.h index 6a561d1705..f58df62b2d 100644 --- a/src/Kernel/RenderCameraOrthogonalDefault.h +++ b/src/Kernel/RenderCameraOrthogonalDefault.h @@ -28,7 +28,7 @@ namespace Mengine protected: void makeViewport_( Viewport * const _viewport ) const; - protected: + protected: mutable Viewport m_renderViewport; }; ////////////////////////////////////////////////////////////////////////// diff --git a/src/Kernel/Resolution.h b/src/Kernel/Resolution.h index b52f8edab7..378867ba57 100644 --- a/src/Kernel/Resolution.h +++ b/src/Kernel/Resolution.h @@ -23,8 +23,10 @@ namespace Mengine MENGINE_INLINE float getWidthF() const; MENGINE_INLINE float getHeightF() const; + public: float getAspectRatio() const; + public: void calcSize( mt::vec2f * const _size ) const; void calcSizeInv( mt::vec2f * const _size ) const; void calcScale( const Resolution & _resolution, mt::vec2f * const _scale ) const; diff --git a/src/Tools/NodeDebugger/NodeDebuggerApp.cpp b/src/Tools/NodeDebugger/NodeDebuggerApp.cpp index ecd4d2a22c..17d0379322 100644 --- a/src/Tools/NodeDebugger/NodeDebuggerApp.cpp +++ b/src/Tools/NodeDebugger/NodeDebuggerApp.cpp @@ -2281,7 +2281,7 @@ namespace Mengine ImGui::Spacing(); - ImGui::TextDisabled( "Android:" ); + ImGui::TextDisabled( "iPad:" ); for( const ResolutionDesc & res : resolutions_iPad ) { From 737e2f1c19195630c0225d90884276f4eeb32f2e Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 17 Oct 2025 16:03:02 +0300 Subject: [PATCH 079/169] update android NDK 29.0.14206865 fix HashHelper fix MixerAveraging fix MixerMultiplicative fix ValueFollowerLinear fix ValueFollowerAcceleration --- .circleci/config.yml | 2 +- build/android/build_depends_android.bat | 2 +- gradle/androidx.gradle | 16 +- gradle/app.gradle | 148 +++++++++--------- gradle/base.gradle | 2 +- gradle/build.gradle | 16 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/libraries/Mengine/build.gradle | 40 ++--- gradle/libraries/OpenAL32/build.gradle | 6 +- gradle/libraries/library.gradle | 4 +- gradle/minify.gradle | 6 +- gradle/plugins/Amplitude/build.gradle | 4 +- gradle/plugins/AppLovin/Core/build.gradle | 58 +++---- gradle/plugins/AppLovin/build.gradle | 84 +++++----- gradle/plugins/DevToDev/build.gradle | 2 +- gradle/plugins/Firebase/build.gradle | 2 +- .../plugins/FirebaseCrashlytics/build.gradle | 6 +- gradle/plugins/GoogleConsent/build.gradle | 2 +- gradle/plugins/MAR/build.gradle | 8 +- gradle/plugins/plugin.gradle | 6 +- gradle/settings.gradle.kts | 46 ++++-- gradle/split.gradle | 2 +- gradle/utils.gradle | 91 +++++------ .../PythonFramework/KernelScriptEmbedding.cpp | 10 +- src/Interface/SoundServiceInterface.h | 8 +- src/Kernel/HashHelper.h | 18 +-- src/Kernel/MixerAveraging.cpp | 12 +- src/Kernel/MixerMultiplicative.cpp | 12 +- src/Kernel/NodeScreenPosition.cpp | 4 +- src/Kernel/ValueFollower.h | 12 ++ src/Kernel/ValueFollowerAcceleration.h | 10 +- src/Kernel/ValueFollowerLinear.h | 6 +- src/Services/SoundService/SoundService.h | 10 +- 33 files changed, 333 insertions(+), 324 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ac6935e693..848812cf60 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,7 +17,7 @@ jobs: - android/accept-licenses - android/install-ndk: - version: 28.2.13676358 + version: 29.0.14206865 - run: name: install OpenJDK 17 diff --git a/build/android/build_depends_android.bat b/build/android/build_depends_android.bat index d303e4ad65..a6f95efb62 100644 --- a/build/android/build_depends_android.bat +++ b/build/android/build_depends_android.bat @@ -11,7 +11,7 @@ call :setESC set CONFIGURATION=%1 @echo Starting android dependencies build %CONFIGURATION% configuration... -set ANDROID_NDK_VERSION=28.2.13676358 +set ANDROID_NDK_VERSION=29.0.14206865 set ANDROID_CMAKE_VERSION=3.31.6 set ANDROID_PLATFORM_VERSION=23 diff --git a/gradle/androidx.gradle b/gradle/androidx.gradle index d5c6c869fa..c1db058c67 100644 --- a/gradle/androidx.gradle +++ b/gradle/androidx.gradle @@ -1,11 +1,11 @@ -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE", "1.17.0") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_ANNOTATION = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_ANNOTATION", "1.9.1") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_CONSTRAINTLAYOUT = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_CONSTRAINTLAYOUT", "2.2.1") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_PREFERENCE = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_PREFERENCE", "1.2.1") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT", "1.7.1") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW", "1.4.0") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS", "1.0.0") -def ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS", "2.9.4") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE", "1.17.0") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_ANNOTATION = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_ANNOTATION", "1.9.1") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_CONSTRAINTLAYOUT = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_CONSTRAINTLAYOUT", "2.2.1") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_PREFERENCE = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_PREFERENCE", "1.2.1") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_APPCOMPAT", "1.7.1") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW", "1.5.0") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_WINDOW_EXTENSIONS", "1.0.0") +final String ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS = Utils.getStringProperty("ANDROID_APP_IMPLEMENTATION_ANDROIDX_LIFECYCLE_PROCESS", "2.9.4") dependencies { implementation "androidx.core:core:$ANDROID_APP_IMPLEMENTATION_ANDROIDX_CORE" diff --git a/gradle/app.gradle b/gradle/app.gradle index 78288b18b5..cca370b751 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -7,56 +7,56 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/split.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/delivery.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' -def ANDROID_APP_BUILD_NUMBER = Utils.getIntegerProperty("ANDROID_APP_BUILD_NUMBER", 0) -def ANDROID_APP_BUILD_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_VERSION", "0.0.0") -def ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBLISH", false) -def ANDROID_APP_SPLIT_ENABLE = Utils.getBooleanProperty("ANDROID_APP_SPLIT_ENABLE", false) -def ANDROID_APP_BUNDLE_ENABLE = Utils.getBooleanProperty("ANDROID_APP_BUNDLE_ENABLE", false) -def ANDROID_APP_DELIVERY_PACKAGES = Utils.getStringProperty("ANDROID_APP_DELIVERY_PACKAGES", null) -def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") - -def MENGINE_APP_LIBRARY_MENGINE = Utils.existAppLibrary("MENGINE_APP_LIBRARY_MENGINE") -def MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OPENAL32") - -def MENGINE_APP_SERVICE_AD = Utils.existAppService("MENGINE_APP_SERVICE_AD") -def MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS = Utils.existAppService("MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS") -def MENGINE_APP_SERVICE_FILELOGGER = Utils.existAppService("MENGINE_APP_SERVICE_FILELOGGER") - -def MENGINE_APP_PLUGIN_SPLASHSCREEN = Utils.existAppPlugin("MENGINE_APP_PLUGIN_SPLASHSCREEN") -def MENGINE_APP_PLUGIN_LOCAL_NOTIFICATIONS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_LOCAL_NOTIFICATIONS") -def MENGINE_APP_PLUGIN_GOOGLE_SERVICE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_SERVICE") -def MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_GOOGLE_GAME_SOCIAL = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_GAME_SOCIAL", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_GOOGLE_PLAY_BILLING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_PLAY_BILLING", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_GOOGLE_INAPP_REVIEWS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_INAPP_REVIEWS", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_GOOGLE_CONSENT = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_CONSENT", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_FIREBASE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_FIREBASE_INSTALLATIONS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_INSTALLATIONS", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FIREBASE_APPCHECK = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_APPCHECK", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_NATIVE_SYMBOL_UPLOAD_ENABLE = Utils.getBooleanProperty("MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_NATIVE_SYMBOL_UPLOAD_ENABLE", false) -def MENGINE_APP_PLUGIN_FIREBASE_ANALYTICS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_ANALYTICS", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FIREBASE_MESSAGING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_MESSAGING", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FIREBASE_REMOTECONFIG = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_REMOTECONFIG", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FIREBASE_PERFORMANCEMONITORING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_PERFORMANCEMONITORING", ["MENGINE_APP_PLUGIN_FIREBASE"]) -def MENGINE_APP_PLUGIN_FLURRY = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FLURRY") -def MENGINE_APP_PLUGIN_APPMETRICA = Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPMETRICA") -def MENGINE_APP_PLUGIN_APPSFLYER = Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPSFLYER") -def MENGINE_APP_PLUGIN_DEVTODEV = Utils.existAppPlugin("MENGINE_APP_PLUGIN_DEVTODEV") -def MENGINE_APP_PLUGIN_FACEBOOK = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FACEBOOK") -def MENGINE_APP_PLUGIN_SENTRY = Utils.existAppPlugin("MENGINE_APP_PLUGIN_SENTRY") -def MENGINE_APP_PLUGIN_MAR = Utils.existAppPlugin("MENGINE_APP_PLUGIN_MAR") -def MENGINE_APP_PLUGIN_ADMOB = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ADMOB", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) -def MENGINE_APP_PLUGIN_AMAZON = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMAZON") -def MENGINE_APP_PLUGIN_APPLOVIN = Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPLOVIN") -def MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY = Utils.getStringProperty("MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY", null) -def MENGINE_APP_PLUGIN_ADJUST = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ADJUST") -def MENGINE_APP_PLUGIN_HELPSHIFT = Utils.existAppPlugin("MENGINE_APP_PLUGIN_HELPSHIFT") -def MENGINE_APP_PLUGIN_ONESIGNAL = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ONESIGNAL") -def MENGINE_APP_PLUGIN_LEANPLUM = Utils.existAppPlugin("MENGINE_APP_PLUGIN_LEANPLUM") -def MENGINE_APP_PLUGIN_DATADOG = Utils.existAppPlugin("MENGINE_APP_PLUGIN_DATADOG") -def MENGINE_APP_PLUGIN_VIBRATOR = Utils.existAppPlugin("MENGINE_APP_PLUGIN_VIBRATOR") -def MENGINE_APP_PLUGIN_AMPLITUDE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMPLITUDE") +final Integer ANDROID_APP_BUILD_NUMBER = Utils.getIntegerProperty("ANDROID_APP_BUILD_NUMBER", 0) +final String ANDROID_APP_BUILD_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_VERSION", "0.0.0") +final Boolean ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBLISH", false) +final Boolean ANDROID_APP_SPLIT_ENABLE = Utils.getBooleanProperty("ANDROID_APP_SPLIT_ENABLE", false) +final Boolean ANDROID_APP_BUNDLE_ENABLE = Utils.getBooleanProperty("ANDROID_APP_BUNDLE_ENABLE", false) +final String ANDROID_APP_DELIVERY_PACKAGES = Utils.getStringProperty("ANDROID_APP_DELIVERY_PACKAGES", null) +final String ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") + +final Boolean MENGINE_APP_LIBRARY_MENGINE = Utils.existAppLibrary("MENGINE_APP_LIBRARY_MENGINE") +final Boolean MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OPENAL32") + +final Boolean MENGINE_APP_SERVICE_AD = Utils.existAppService("MENGINE_APP_SERVICE_AD") +final Boolean MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS = Utils.existAppService("MENGINE_APP_SERVICE_MONITORCONNECTIVITYSTATUS") +final Boolean MENGINE_APP_SERVICE_FILELOGGER = Utils.existAppService("MENGINE_APP_SERVICE_FILELOGGER") + +final Boolean MENGINE_APP_PLUGIN_SPLASHSCREEN = Utils.existAppPlugin("MENGINE_APP_PLUGIN_SPLASHSCREEN") +final Boolean MENGINE_APP_PLUGIN_LOCAL_NOTIFICATIONS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_LOCAL_NOTIFICATIONS") +final Boolean MENGINE_APP_PLUGIN_GOOGLE_SERVICE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_SERVICE") +final Boolean MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_GOOGLE_GAME_SOCIAL = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_GAME_SOCIAL", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_GOOGLE_PLAY_BILLING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_PLAY_BILLING", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_GOOGLE_INAPP_REVIEWS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_INAPP_REVIEWS", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_GOOGLE_CONSENT = Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_CONSENT", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_INSTALLATIONS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_INSTALLATIONS", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_APPCHECK = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_APPCHECK", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_NATIVE_SYMBOL_UPLOAD_ENABLE = Utils.getBooleanProperty("MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_NATIVE_SYMBOL_UPLOAD_ENABLE", false) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_ANALYTICS = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_ANALYTICS", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_MESSAGING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_MESSAGING", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_REMOTECONFIG = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_REMOTECONFIG", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_PERFORMANCEMONITORING = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FIREBASE_PERFORMANCEMONITORING", ["MENGINE_APP_PLUGIN_FIREBASE"]) +final Boolean MENGINE_APP_PLUGIN_FLURRY = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FLURRY") +final Boolean MENGINE_APP_PLUGIN_APPMETRICA = Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPMETRICA") +final Boolean MENGINE_APP_PLUGIN_APPSFLYER = Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPSFLYER") +final Boolean MENGINE_APP_PLUGIN_DEVTODEV = Utils.existAppPlugin("MENGINE_APP_PLUGIN_DEVTODEV") +final Boolean MENGINE_APP_PLUGIN_FACEBOOK = Utils.existAppPlugin("MENGINE_APP_PLUGIN_FACEBOOK") +final Boolean MENGINE_APP_PLUGIN_SENTRY = Utils.existAppPlugin("MENGINE_APP_PLUGIN_SENTRY") +final Boolean MENGINE_APP_PLUGIN_MAR = Utils.existAppPlugin("MENGINE_APP_PLUGIN_MAR") +final Boolean MENGINE_APP_PLUGIN_ADMOB = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ADMOB", ["MENGINE_APP_PLUGIN_GOOGLE_SERVICE"]) +final Boolean MENGINE_APP_PLUGIN_AMAZON = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMAZON") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN = Utils.existAppPlugin("MENGINE_APP_PLUGIN_APPLOVIN") +final String MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY = Utils.getStringProperty("MENGINE_APP_PLUGIN_APPLOVIN_AD_REVIEW_KEY", null) +final Boolean MENGINE_APP_PLUGIN_ADJUST = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ADJUST") +final Boolean MENGINE_APP_PLUGIN_HELPSHIFT = Utils.existAppPlugin("MENGINE_APP_PLUGIN_HELPSHIFT") +final Boolean MENGINE_APP_PLUGIN_ONESIGNAL = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ONESIGNAL") +final Boolean MENGINE_APP_PLUGIN_LEANPLUM = Utils.existAppPlugin("MENGINE_APP_PLUGIN_LEANPLUM") +final Boolean MENGINE_APP_PLUGIN_DATADOG = Utils.existAppPlugin("MENGINE_APP_PLUGIN_DATADOG") +final Boolean MENGINE_APP_PLUGIN_VIBRATOR = Utils.existAppPlugin("MENGINE_APP_PLUGIN_VIBRATOR") +final Boolean MENGINE_APP_PLUGIN_AMPLITUDE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMPLITUDE") Utils.logString("ANDROID_APP_DELIVERY_PACKAGES", ANDROID_APP_DELIVERY_PACKAGES) Utils.logAvailable("ANDROID_APP_BUILD_PUBLISH", ANDROID_APP_BUILD_PUBLISH) @@ -99,7 +99,7 @@ android { ext.plugins = [] ext.activities = [] - gradle.taskGraph.whenReady { taskGraph -> + gradle.taskGraph.whenReady { final taskGraph -> if (taskGraph.hasTask(assembleDebug)) { //Empty } else if (taskGraph.hasTask(assembleRelease)) { @@ -138,7 +138,7 @@ android { println "HARDCODE ANDROID_APP_ID: $applicationId" } - def buildNumber = ANDROID_APP_BUILD_NUMBER + final def buildNumber = ANDROID_APP_BUILD_NUMBER if (ANDROID_APP_BUILD_PUBLISH == true) { if (ANDROID_APP_BUNDLE_ENABLE == true) { @@ -169,7 +169,7 @@ android { println "ANDROID_APP_DEBUG_KEY_ALIAS: $ANDROID_APP_DEBUG_KEY_ALIAS" println "ANDROID_APP_DEBUG_KEY_PASSWORD: $ANDROID_APP_DEBUG_KEY_PASSWORD" - def f = new File(ANDROID_APP_DEBUG_STORE_FILE) + final def f = new File(ANDROID_APP_DEBUG_STORE_FILE) if (f.exists() == false) { throw new GradleException("ANDROID_APP_DEBUG_STORE_FILE not found folder: $ANDROID_APP_DEBUG_STORE_FILE") @@ -191,7 +191,7 @@ android { println "ANDROID_APP_RELEASE_KEY_ALIAS: $ANDROID_APP_RELEASE_KEY_ALIAS" println "ANDROID_APP_RELEASE_KEY_PASSWORD: $ANDROID_APP_RELEASE_KEY_PASSWORD" - def f = new File(ANDROID_APP_RELEASE_STORE_FILE) + final def f = new File(ANDROID_APP_RELEASE_STORE_FILE) if (f.exists() == false) { throw new GradleException("ANDROID_APP_RELEASE_STORE_FILE not found folder: $ANDROID_APP_RELEASE_STORE_FILE") @@ -223,7 +223,7 @@ android { if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true) { if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_NATIVE_SYMBOL_UPLOAD_ENABLE == true) { buildTypes { - var buildDirectory = getLayout().getBuildDirectory(); + final var buildDirectory = getLayout().getBuildDirectory() debug { firebaseCrashlytics { @@ -273,12 +273,12 @@ android { } if (ANDROID_APP_DELIVERY_PACKAGES != null) { - def PACKAGES = ANDROID_APP_DELIVERY_PACKAGES.split(",") + final def PACKAGES = ANDROID_APP_DELIVERY_PACKAGES.split(",") - def deliveryPacks = [] as ArrayList + final def deliveryPacks = [] as ArrayList - for(PACKAGE_DESC in PACKAGES) { - var PACKAGE_NAME = PACKAGE_DESC.split(";")[0] + for(final PACKAGE_DESC in PACKAGES) { + final var PACKAGE_NAME = PACKAGE_DESC.split(";")[0] println "add delivery asset pack: $PACKAGE_NAME" @@ -297,7 +297,7 @@ android { if (project.hasProperty("ANDROID_APP_ASSETS_RES_DIR") == true) { println "ANDROID_APP_ASSETS_RES_DIR: $ANDROID_APP_ASSETS_RES_DIR" - def f = new File(ANDROID_APP_ASSETS_RES_DIR) + final def f = new File(ANDROID_APP_ASSETS_RES_DIR) if (f.exists() == false) { throw new GradleException("ANDROID_APP_ASSETS_RES_DIR not found folder: $ANDROID_APP_ASSETS_RES_DIR") @@ -313,7 +313,7 @@ android { if (project.hasProperty("ANDROID_APP_ASSETS_SRC_DIR") == true) { println "ANDROID_APP_ASSETS_SRC_DIR: $ANDROID_APP_ASSETS_SRC_DIR" - def f = new File(ANDROID_APP_ASSETS_SRC_DIR) + final def f = new File(ANDROID_APP_ASSETS_SRC_DIR) if (f.exists() == false) { throw new GradleException("ANDROID_APP_ASSETS_SRC_DIR not found folder: $ANDROID_APP_ASSETS_SRC_DIR") @@ -346,12 +346,12 @@ android { } if (ANDROID_APP_SPLIT_ENABLE == true) { - android.applicationVariants.configureEach { variant -> - variant.outputs.each { output -> - def abiCodes = ["arm64-v8a": 1, "armeabi-v7a": 2, "x86": 3, "x86_64": 4] + android.applicationVariants.configureEach { final variant -> + variant.outputs.each { final output -> + final def abiCodes = ["arm64-v8a": 1, "armeabi-v7a": 2, "x86": 3, "x86_64": 4] - def filter = output.getFilter("ABI") - def baseAbiVersionCode = abiCodes.get(filter) + final def filter = output.getFilter("ABI") + final def baseAbiVersionCode = abiCodes.get(filter) if (baseAbiVersionCode != null) { output.versionCodeOverride = baseAbiVersionCode * 1000000 + variant.versionCode @@ -782,10 +782,10 @@ if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true && MENGINE_APP_PLUGIN_FIREBA doLast { println "[TASK] checkDebugUnstrippedNativeLibsDir" - def f = android.buildTypes.debug.firebaseCrashlytics.unstrippedNativeLibsDir.get().getAsFile() + final File f = android.buildTypes.debug.firebaseCrashlytics.unstrippedNativeLibsDir.get().getAsFile() if (f.exists() == false) { - var fname = f.getCanonicalPath() + final var fname = f.getCanonicalPath() throw new GradleException("unstrippedNativeLibsDir not found folder: $fname") } @@ -798,10 +798,10 @@ if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true && MENGINE_APP_PLUGIN_FIREBA doLast { println "[TASK] checkReleaseUnstrippedNativeLibsDir" - def f = android.buildTypes.release.firebaseCrashlytics.unstrippedNativeLibsDir.get().getAsFile() + final File f = android.buildTypes.release.firebaseCrashlytics.unstrippedNativeLibsDir.get().getAsFile() if (f.exists() == false) { - var fname = f.getCanonicalPath() + final var fname = f.getCanonicalPath() throw new GradleException("unstrippedNativeLibsDir not found folder: $fname") } @@ -810,7 +810,7 @@ if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true && MENGINE_APP_PLUGIN_FIREBA } } - tasks.configureEach { task -> + tasks.configureEach { final task -> if (task.name == 'assembleRelease') { task.finalizedBy checkReleaseUnstrippedNativeLibsDir } else if(task.name == 'assembleDebug') { @@ -818,19 +818,19 @@ if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true && MENGINE_APP_PLUGIN_FIREBA } } - tasks.configureEach { task -> + tasks.configureEach { final task -> if (task.name.startsWith('generateCrashlyticsSymbolFile')) { task.dependsOn 'merge' + (task.name =~ /^generateCrashlyticsSymbolFile(.+)$/)[0][1] + 'NativeLibs' } } - tasks.configureEach { task -> + tasks.configureEach { final task -> if (task.name.startsWith('injectCrashlyticsBuildIds')) { task.dependsOn 'merge' + (task.name =~ /^injectCrashlyticsBuildIds(.+)$/)[0][1] + 'NativeLibs' } } - tasks.configureEach { task -> + tasks.configureEach { final task -> if (task.name == "bundleRelease") { task.finalizedBy 'uploadCrashlyticsSymbolFileRelease' } diff --git a/gradle/base.gradle b/gradle/base.gradle index bdc327ca65..ab77357188 100644 --- a/gradle/base.gradle +++ b/gradle/base.gradle @@ -23,5 +23,5 @@ android { dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' - implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.2.0' + implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.2.20' } \ No newline at end of file diff --git a/gradle/build.gradle b/gradle/build.gradle index 6a4d86813d..925b297f71 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -18,7 +18,7 @@ buildscript { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0' if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_GOOGLE_SERVICE") == true) { - classpath 'com.google.gms:google-services:4.4.3' + classpath 'com.google.gms:google-services:4.4.4' } if (Utils.existAppPlugin("MENGINE_APP_PLUGIN_SENTRY") == true) { @@ -43,12 +43,12 @@ buildscript { } } -def ANDROID_APP_NDK_VERSION = Utils.getStringProperty("ANDROID_APP_NDK_VERSION", null) -def ANDROID_APP_CMAKE_VERSION = Utils.getStringProperty("ANDROID_APP_CMAKE_VERSION", null) -def ANDROID_APP_BUILD_TOOLS_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_TOOLS_VERSION", null) -def ANDROID_APP_MIN_SDK_VERSION = Utils.getIntegerProperty("ANDROID_APP_MIN_SDK_VERSION", null) -def ANDROID_APP_TARGET_SDK_VERSION = Utils.getIntegerProperty("ANDROID_APP_TARGET_SDK_VERSION", null) -def ANDROID_APP_COMPILE_SDK_VERSION = Utils.getIntegerProperty("ANDROID_APP_COMPILE_SDK_VERSION", null) +final String ANDROID_APP_NDK_VERSION = Utils.getStringProperty("ANDROID_APP_NDK_VERSION", null) +final String ANDROID_APP_CMAKE_VERSION = Utils.getStringProperty("ANDROID_APP_CMAKE_VERSION", null) +final String ANDROID_APP_BUILD_TOOLS_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_TOOLS_VERSION", null) +final Integer ANDROID_APP_MIN_SDK_VERSION = Utils.getIntegerProperty("ANDROID_APP_MIN_SDK_VERSION", null) +final Integer ANDROID_APP_TARGET_SDK_VERSION = Utils.getIntegerProperty("ANDROID_APP_TARGET_SDK_VERSION", null) +final Integer ANDROID_APP_COMPILE_SDK_VERSION = Utils.getIntegerProperty("ANDROID_APP_COMPILE_SDK_VERSION", null) allprojects { layout.buildDirectory.set(layout.projectDirectory.dir(rootProject.projectDir.getAbsolutePath() + "/../outputs/gradle/build/${rootProject.name}/${project.name}")) @@ -57,7 +57,7 @@ allprojects { if (ANDROID_APP_NDK_VERSION != null) { ndkVersion = ANDROID_APP_NDK_VERSION } else { - ndkVersion = "28.2.13676358" + ndkVersion = "29.0.14206865" } if (ANDROID_APP_CMAKE_VERSION != null) { diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index 737a1463ee..e2a4851dde 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Sep 24 12:58:29 EEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index 31f6a7bd5a..67ce9eda2c 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -1,23 +1,23 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/libraries/library.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' -def ANDROID_APP_BUILD_NUMBER = Utils.getIntegerProperty("ANDROID_APP_BUILD_NUMBER", 0) -def ANDROID_APP_BUILD_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_VERSION", "0.0.0") -def ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBLISH", false) -def MENGINE_APP_SECURE_VALUE = Utils.getStringProperty("MENGINE_APP_SECURE_VALUE", "0123456789A") -def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") -def MENGINE_APP_DEPLOY_PATH = Utils.getStringProperty("MENGINE_APP_DEPLOY_PATH", rootProject.projectDir.getAbsolutePath() + "/$ANDROID_APP_MAIN_PROJECT") -def MENGINE_APP_BUILD_ASSERTION_DEBUG = Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -1) -def MENGINE_APP_BUILD_LOGGER_INFO = Utils.getIntegerProperty("MENGINE_APP_BUILD_LOGGER_INFO", -1) -def MENGINE_APP_BUILD_DEBUG_FILE_PATH = Utils.getIntegerProperty("MENGINE_APP_BUILD_DEBUG_FILE_PATH", -1) -def MENGINE_APP_BUILD_DEBUG_DOCUMENT = Utils.getIntegerProperty("MENGINE_APP_BUILD_DEBUG_DOCUMENT", -1) -def MENGINE_APP_ENABLE_STRICT_MODE = Utils.getBooleanProperty("MENGINE_APP_ENABLE_STRICT_MODE", false) - -def ANDROID_APP_SCREEN_ORIENTATION = Utils.getStringProperty("ANDROID_APP_SCREEN_ORIENTATION", "sensorPortrait") -def ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN", false) -def ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER", false) - -def MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OPENAL32") +final Integer ANDROID_APP_BUILD_NUMBER = Utils.getIntegerProperty("ANDROID_APP_BUILD_NUMBER", 0) +final String ANDROID_APP_BUILD_VERSION = Utils.getStringProperty("ANDROID_APP_BUILD_VERSION", "0.0.0") +final Boolean ANDROID_APP_BUILD_PUBLISH = Utils.getBooleanProperty("ANDROID_APP_BUILD_PUBLISH", false) +final String MENGINE_APP_SECURE_VALUE = Utils.getStringProperty("MENGINE_APP_SECURE_VALUE", "0123456789A") +final String ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") +final String MENGINE_APP_DEPLOY_PATH = Utils.getStringProperty("MENGINE_APP_DEPLOY_PATH", rootProject.projectDir.getAbsolutePath() + "/$ANDROID_APP_MAIN_PROJECT") +final Integer MENGINE_APP_BUILD_ASSERTION_DEBUG = Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -1) +final Integer MENGINE_APP_BUILD_LOGGER_INFO = Utils.getIntegerProperty("MENGINE_APP_BUILD_LOGGER_INFO", -1) +final Integer MENGINE_APP_BUILD_DEBUG_FILE_PATH = Utils.getIntegerProperty("MENGINE_APP_BUILD_DEBUG_FILE_PATH", -1) +final Integer MENGINE_APP_BUILD_DEBUG_DOCUMENT = Utils.getIntegerProperty("MENGINE_APP_BUILD_DEBUG_DOCUMENT", -1) +final Boolean MENGINE_APP_ENABLE_STRICT_MODE = Utils.getBooleanProperty("MENGINE_APP_ENABLE_STRICT_MODE", false) + +final String ANDROID_APP_SCREEN_ORIENTATION = Utils.getStringProperty("ANDROID_APP_SCREEN_ORIENTATION", "sensorPortrait") +final Boolean ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN", false) +final Boolean ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER", false) + +final Boolean MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OPENAL32") println("MENGINE_APP_SECURE_VALUE: $MENGINE_APP_SECURE_VALUE") println("MENGINE_APP_DEPLOY_PATH: $MENGINE_APP_DEPLOY_PATH") @@ -52,7 +52,7 @@ android { } buildTypes { - List cmake_arguments = new ArrayList() + final List cmake_arguments = new ArrayList() cmake_arguments.add("-DANDROID_PLATFORM=android-" + project.minSdkVersion) cmake_arguments.add("-DANDROID_ARM_NEON=TRUE") cmake_arguments.add("-DANDROID_STL=c++_shared") @@ -70,7 +70,7 @@ android { debug { externalNativeBuild { cmake { - for (String argument : cmake_arguments) { + for (final String argument : cmake_arguments) { arguments.add(argument) } @@ -98,7 +98,7 @@ android { release { externalNativeBuild { cmake { - for (String argument : cmake_arguments) { + for (final String argument : cmake_arguments) { arguments.add(argument) } diff --git a/gradle/libraries/OpenAL32/build.gradle b/gradle/libraries/OpenAL32/build.gradle index 947f02f475..05bcc26a05 100644 --- a/gradle/libraries/OpenAL32/build.gradle +++ b/gradle/libraries/OpenAL32/build.gradle @@ -9,7 +9,7 @@ android { } buildTypes { - List cmake_arguments = new ArrayList() + final List cmake_arguments = new ArrayList() cmake_arguments.add("-DANDROID_PLATFORM=android-" + project.minSdkVersion) cmake_arguments.add("-DANDROID_ARM_NEON=TRUE") cmake_arguments.add("-DANDROID_STL=c++_shared") @@ -20,7 +20,7 @@ android { debug { externalNativeBuild { cmake { - for (String argument : cmake_arguments) { + for (final String argument : cmake_arguments) { arguments.add(argument) } @@ -32,7 +32,7 @@ android { release { externalNativeBuild { cmake { - for (String argument : cmake_arguments) { + for (final String argument : cmake_arguments) { arguments.add(argument) } diff --git a/gradle/libraries/library.gradle b/gradle/libraries/library.gradle index 35abf091f4..fabcb03b79 100644 --- a/gradle/libraries/library.gradle +++ b/gradle/libraries/library.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.android.library' -def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") +final String ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") apply from: rootProject.projectDir.getAbsolutePath() + '/base.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/androidx.gradle' @@ -10,7 +10,7 @@ android { sourceSets { main { if (project.hasProperty("ANDROID_APP_ASSETS_RES_DIR") == true) { - def f = new File(ANDROID_APP_ASSETS_RES_DIR) + final def f = new File(ANDROID_APP_ASSETS_RES_DIR) if (f.exists() == false) { throw new GradleException("ANDROID_APP_ASSETS_RES_DIR not found folder: $ANDROID_APP_ASSETS_RES_DIR") diff --git a/gradle/minify.gradle b/gradle/minify.gradle index 05bc2f5ff9..dea9dade01 100644 --- a/gradle/minify.gradle +++ b/gradle/minify.gradle @@ -1,7 +1,7 @@ -def ANDROID_APP_DEBUG_MINIFY_ENABLE = Utils.getBooleanProperty("ANDROID_APP_DEBUG_MINIFY_ENABLE", false) -def ANDROID_APP_RELEASE_MINIFY_ENABLE = Utils.getBooleanProperty("ANDROID_APP_RELEASE_MINIFY_ENABLE", false) +final Boolean ANDROID_APP_DEBUG_MINIFY_ENABLE = Utils.getBooleanProperty("ANDROID_APP_DEBUG_MINIFY_ENABLE", false) +final Boolean ANDROID_APP_RELEASE_MINIFY_ENABLE = Utils.getBooleanProperty("ANDROID_APP_RELEASE_MINIFY_ENABLE", false) -def proguardUserFile = project.file('proguard-rules.pro') +final File proguardUserFile = project.file('proguard-rules.pro') android { buildTypes { diff --git a/gradle/plugins/Amplitude/build.gradle b/gradle/plugins/Amplitude/build.gradle index ffba08509c..6b587ff4a8 100644 --- a/gradle/plugins/Amplitude/build.gradle +++ b/gradle/plugins/Amplitude/build.gradle @@ -6,7 +6,7 @@ android { } dependencies { - implementation 'com.squareup.okhttp3:okhttp:5.1.0' + implementation 'com.squareup.okhttp3:okhttp:5.2.1' - implementation 'com.amplitude:analytics-android:1.22.3' + implementation 'com.amplitude:analytics-android:1.22.4' } \ No newline at end of file diff --git a/gradle/plugins/AppLovin/Core/build.gradle b/gradle/plugins/AppLovin/Core/build.gradle index 93bbf78553..0f69a25a6f 100644 --- a/gradle/plugins/AppLovin/Core/build.gradle +++ b/gradle/plugins/AppLovin/Core/build.gradle @@ -1,32 +1,34 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON", ["MENGINE_APP_PLUGIN_AMAZON"]) -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB", ["MENGINE_APP_PLUGIN_ADMOB"]) -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW") + +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON", ["MENGINE_APP_PLUGIN_AMAZON"]) +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB", ["MENGINE_APP_PLUGIN_ADMOB"]) +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO") Utils.logAvailable("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON", MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON) Utils.logAvailable("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE", MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE) @@ -55,7 +57,7 @@ Utils.logAvailable("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX", MENGINE_APP_P Utils.logAvailable("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO", MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO) if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON == true) { - def MENGINE_APP_PLUGIN_AMAZON = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMAZON") + final Boolean MENGINE_APP_PLUGIN_AMAZON = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMAZON") if (MENGINE_APP_PLUGIN_AMAZON == false) { throw new GradleException("Plugin [AppLovin] mediation [Amazon] require plugin [Amazon]") @@ -63,7 +65,7 @@ if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON == true) { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB == true) { - def MENGINE_APP_PLUGIN_ADMOB = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ADMOB") + final Boolean MENGINE_APP_PLUGIN_ADMOB = Utils.existAppPlugin("MENGINE_APP_PLUGIN_ADMOB") if (MENGINE_APP_PLUGIN_ADMOB == false) { throw new GradleException("Plugin [AppLovin] mediation [AdMob] require plugin [AdMob]") diff --git a/gradle/plugins/AppLovin/build.gradle b/gradle/plugins/AppLovin/build.gradle index 802f43feaa..00aa9305e8 100644 --- a/gradle/plugins/AppLovin/build.gradle +++ b/gradle/plugins/AppLovin/build.gradle @@ -1,48 +1,48 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' -def MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID = Utils.getStringProperty("MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", null) - -def MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE") -def MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER") -def MENGINE_APP_PLUGIN_APPLOVIN_SHOW_MEDIATION_DEBUGGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_SHOW_MEDIATION_DEBUGGER") - -def MENGINE_APP_PLUGIN_APPLOVIN_BANNERAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_BANNERAD") -def MENGINE_APP_PLUGIN_APPLOVIN_INTERSTITIALAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_INTERSTITIALAD") -def MENGINE_APP_PLUGIN_APPLOVIN_REWARDEDAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_REWARDEDAD") -def MENGINE_APP_PLUGIN_APPLOVIN_APPOPENAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_APPOPENAD") -def MENGINE_APP_PLUGIN_APPLOVIN_MRECAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MRECAD") -def MENGINE_APP_PLUGIN_APPLOVIN_NATIVEAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_NATIVEAD") - -def MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW") -def MENGINE_APP_PLUGIN_APPLOVIN_NONET_BANNERS = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_NONET_BANNERS") - -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON", ["MENGINE_APP_PLUGIN_AMAZON"]) -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB", ["MENGINE_APP_PLUGIN_ADMOB"]) -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX") -def MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO") +final String MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID = Utils.getStringProperty("MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", null) + +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_LOGGING_VERBOSE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_CREATIVE_DEBUGGER") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_SHOW_MEDIATION_DEBUGGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_SHOW_MEDIATION_DEBUGGER") + +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_BANNERAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_BANNERAD") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_INTERSTITIALAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_INTERSTITIALAD") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_REWARDEDAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_REWARDEDAD") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_APPOPENAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_APPOPENAD") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MRECAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MRECAD") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_NATIVEAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_NATIVEAD") + +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_CONSENT_FLOW") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_NONET_BANNERS = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_NONET_BANNERS") + +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON", ["MENGINE_APP_PLUGIN_AMAZON"]) +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB", ["MENGINE_APP_PLUGIN_ADMOB"]) +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_INMOBI") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_IRONSOURCE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LIFTOFF") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_LINE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_META") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX") +final Boolean MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO") Utils.logString("MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID", MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID) diff --git a/gradle/plugins/DevToDev/build.gradle b/gradle/plugins/DevToDev/build.gradle index 6aec55c727..229d98d069 100644 --- a/gradle/plugins/DevToDev/build.gradle +++ b/gradle/plugins/DevToDev/build.gradle @@ -3,7 +3,7 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gson.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/installreferrer.gradle' -def MENGINE_APP_PLUGIN_DEVTODEV_DEBUG_LOG = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_DEVTODEV_DEBUG_LOG") +final Boolean MENGINE_APP_PLUGIN_DEVTODEV_DEBUG_LOG = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_DEVTODEV_DEBUG_LOG") android { namespace "org.Mengine.Plugin.DevToDev" diff --git a/gradle/plugins/Firebase/build.gradle b/gradle/plugins/Firebase/build.gradle index c059046f3c..4bb08e57da 100644 --- a/gradle/plugins/Firebase/build.gradle +++ b/gradle/plugins/Firebase/build.gradle @@ -5,7 +5,7 @@ android { } dependencies { - api enforcedPlatform('com.google.firebase:firebase-bom:34.3.0') + api enforcedPlatform('com.google.firebase:firebase-bom:34.4.0') implementation 'com.google.firebase:firebase-common:22.0.1' } diff --git a/gradle/plugins/FirebaseCrashlytics/build.gradle b/gradle/plugins/FirebaseCrashlytics/build.gradle index 56d78233af..3000a57178 100644 --- a/gradle/plugins/FirebaseCrashlytics/build.gradle +++ b/gradle/plugins/FirebaseCrashlytics/build.gradle @@ -1,7 +1,7 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' -def MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_ANRMONITOR = Utils.getBooleanProperty("MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_ANRMONITOR", false) +final Boolean MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_ANRMONITOR = Utils.getBooleanProperty("MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_ANRMONITOR", false) android { namespace "org.Mengine.Plugin.FirebaseCrashlytics" @@ -10,8 +10,8 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-crashlytics:20.0.2' - implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.2' + implementation 'com.google.firebase:firebase-crashlytics:20.0.3' + implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.3' } android { diff --git a/gradle/plugins/GoogleConsent/build.gradle b/gradle/plugins/GoogleConsent/build.gradle index c0e235079c..e47b534d2c 100644 --- a/gradle/plugins/GoogleConsent/build.gradle +++ b/gradle/plugins/GoogleConsent/build.gradle @@ -1,7 +1,7 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' -def MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID = Utils.getStringProperty("MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", null) +final String MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID = Utils.getStringProperty("MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", null) Utils.logString("MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID) diff --git a/gradle/plugins/MAR/build.gradle b/gradle/plugins/MAR/build.gradle index a595d44152..02a1d365a6 100644 --- a/gradle/plugins/MAR/build.gradle +++ b/gradle/plugins/MAR/build.gradle @@ -6,10 +6,10 @@ android { if (project.hasProperty("MENGINE_APP_PLUGIN_MAR_RES_DIR") == true) { println "MENGINE_APP_PLUGIN_MAR_RES_DIR: $MENGINE_APP_PLUGIN_MAR_RES_DIR" - def f = new File(MENGINE_APP_PLUGIN_MAR_RES_DIR) + final def f = new File(MENGINE_APP_PLUGIN_MAR_RES_DIR) if (f.exists() == false) { - throw new GradleException("MENGINE_APP_PLUGIN_MAR_RES_DIR not found folder: $MENGINE_APP_PLUGIN_MAR_RES_DIR"); + throw new GradleException("MENGINE_APP_PLUGIN_MAR_RES_DIR not found folder: $MENGINE_APP_PLUGIN_MAR_RES_DIR") } res.srcDirs += [MENGINE_APP_PLUGIN_MAR_RES_DIR] @@ -22,10 +22,10 @@ android { if (project.hasProperty("MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR") == true) { println "MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR: $MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR" - def f = new File(MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR) + final def f = new File(MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR) if (f.exists() == false) { - throw new GradleException("MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR not found folder: $MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR"); + throw new GradleException("MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR not found folder: $MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR") } assets.srcDirs += [MENGINE_APP_PLUGIN_MAR_ASSETS_SRC_DIR] diff --git a/gradle/plugins/plugin.gradle b/gradle/plugins/plugin.gradle index 87551226bf..29a07418c3 100644 --- a/gradle/plugins/plugin.gradle +++ b/gradle/plugins/plugin.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.library' -def ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") +final String ANDROID_APP_MAIN_PROJECT = Utils.getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") apply from: rootProject.projectDir.getAbsolutePath() + '/base.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/androidx.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/minify.gradle' -def MENGINE_APP_LIBRARY_MENGINE = Utils.existAppLibrary("MENGINE_APP_LIBRARY_MENGINE") +final Boolean MENGINE_APP_LIBRARY_MENGINE = Utils.existAppLibrary("MENGINE_APP_LIBRARY_MENGINE") android { ext.extensions = [] @@ -14,7 +14,7 @@ android { sourceSets { main { if (project.hasProperty("ANDROID_APP_ASSETS_RES_DIR") == true) { - def f = new File(ANDROID_APP_ASSETS_RES_DIR) + final def f = new File(ANDROID_APP_ASSETS_RES_DIR) if (f.exists() == false) { throw new GradleException("ANDROID_APP_ASSETS_RES_DIR not found folder: $ANDROID_APP_ASSETS_RES_DIR") diff --git a/gradle/settings.gradle.kts b/gradle/settings.gradle.kts index 2aa7ae9595..7d23221970 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -1,3 +1,5 @@ +import java.util.Properties + fun getBooleanProperty(name: String, d: Boolean): Boolean { if (extra.has(name) == false) { return d @@ -17,7 +19,7 @@ fun getBooleanProperty(name: String, d: Boolean): Boolean { return d } -fun getStringProperty(name: String, d: String): String? { +fun getStringProperty(name: String, d: String?): String? { if (extra.has(name) == false) { return d } @@ -39,46 +41,58 @@ fun getStringProperty(name: String, d: String): String? { return s } +val RED: String = "\u001b[31m" +val GREEN: String = "\u001b[32m" +val RESET: String = "\u001b[0m" + +fun printredln(s: String) { + println(RED + s + RESET) +} + +fun printgreenln(s: String) { + println(GREEN + s + RESET) +} + fun includeLibrary(name: String, path: String) { if (getBooleanProperty("MENGINE_APP_LIBRARY_ALL", false) == false && getBooleanProperty(name, true) == false) { - println("\u001b[31m" + "[-] Exclude library: $path" + "\u001b[0m") + printredln("[-] Exclude library: $path") return } - println("\u001b[32m" + "[+] Include library: $path" + "\u001b[0m") + printgreenln("[+] Include library: $path") include(path) } fun includePlugin(name: String, path: String, required: List = emptyList()) { if (getBooleanProperty("MENGINE_APP_PLUGIN_ENABLE_ALL", false) == false && (getBooleanProperty(name, false) == false || required.all { getBooleanProperty(it, false) } == false)) { - println("\u001b[31m" + "[-] Exclude plugin: $path" + "\u001b[0m") + printredln("[-] Exclude plugin: $path") return } - println("\u001b[32m" + "[+] Include plugin: $path" + "\u001b[0m") + printgreenln("[+] Include plugin: $path") include(path) } -println("\u001b[32m" + "=== Start configure ===" + "\u001b[0m") +printgreenln("=== Start configure ===") -val ANDROID_APP_MAIN_PROJECT = getStringProperty("ANDROID_APP_MAIN_PROJECT", "app"); +val ANDROID_APP_MAIN_PROJECT: String? = getStringProperty("ANDROID_APP_MAIN_PROJECT", "app") if (ANDROID_APP_MAIN_PROJECT == null || file(ANDROID_APP_MAIN_PROJECT).exists() == false) { - println("\u001b[31m" + "[-] Not found $ANDROID_APP_MAIN_PROJECT" + "\u001b[0m") + printredln("[-] Not found $ANDROID_APP_MAIN_PROJECT") throw kotlin.Exception("Not found $ANDROID_APP_MAIN_PROJECT") } -val fileAppProperties = file("$ANDROID_APP_MAIN_PROJECT/app.properties") +val fileAppProperties: File = file("$ANDROID_APP_MAIN_PROJECT/app.properties") if (fileAppProperties.exists() == true) { - println("\u001b[32m" + "[+] Load $ANDROID_APP_MAIN_PROJECT/app.properties" + "\u001b[0m") + printgreenln("[+] Load $ANDROID_APP_MAIN_PROJECT/app.properties") - val appProperties = java.util.Properties() + val appProperties = Properties() fileAppProperties.reader().use { reader -> appProperties.load(reader) } @@ -92,23 +106,23 @@ if (fileAppProperties.exists() == true) { extra[key.toString()] = value } } else { - println("\u001b[31m" + "[-] Not found $ANDROID_APP_MAIN_PROJECT/app.properties" + "\u001b[0m") + printredln("[-] Not found $ANDROID_APP_MAIN_PROJECT/app.properties") } -println("\u001b[32m" + "[+] Include :$ANDROID_APP_MAIN_PROJECT" + "\u001b[0m") +printgreenln("[+] Include :$ANDROID_APP_MAIN_PROJECT") include(":$ANDROID_APP_MAIN_PROJECT") if (extra.has("ANDROID_APP_DELIVERY_PACKAGES") == true) { val PACKAGES = extra["ANDROID_APP_DELIVERY_PACKAGES"].toString().split(",") for(PACKAGE_DESC in PACKAGES) { - val PACKAGE_NAME = PACKAGE_DESC.split(";").get(0) + val PACKAGE_NAME = PACKAGE_DESC.split(";")[0] val PACKAGE_PATH = PACKAGE_DESC.split(";").getOrNull(1) if (PACKAGE_PATH == null || PACKAGE_PATH == "NO-PATH") { - println("\u001b[32m" + "[+] Include delivery: :$ANDROID_APP_MAIN_PROJECT:$PACKAGE_NAME" + "\u001b[0m") + printgreenln("[+] Include delivery: :$ANDROID_APP_MAIN_PROJECT:$PACKAGE_NAME") } else { - println("\u001b[32m" + "[+] Include delivery: :$ANDROID_APP_MAIN_PROJECT:$PACKAGE_NAME extra path $PACKAGE_PATH" + "\u001b[0m") + printgreenln("[+] Include delivery: :$ANDROID_APP_MAIN_PROJECT:$PACKAGE_NAME extra path $PACKAGE_PATH") } include(":$ANDROID_APP_MAIN_PROJECT:$PACKAGE_NAME") diff --git a/gradle/split.gradle b/gradle/split.gradle index 1f6f2e07f8..ebf31a85f8 100644 --- a/gradle/split.gradle +++ b/gradle/split.gradle @@ -1,4 +1,4 @@ -def ANDROID_APP_SPLIT_ENABLE = Utils.getBooleanProperty("ANDROID_APP_SPLIT_ENABLE", false) +final Boolean ANDROID_APP_SPLIT_ENABLE = Utils.getBooleanProperty("ANDROID_APP_SPLIT_ENABLE", false) android { defaultConfig { diff --git a/gradle/utils.gradle b/gradle/utils.gradle index 4686e29893..d21f392fd8 100644 --- a/gradle/utils.gradle +++ b/gradle/utils.gradle @@ -1,7 +1,7 @@ ext.Utils = [:] -Utils.getBooleanProperty = { String name, Boolean d -> - def p = project.findProperty(name) +Utils.getBooleanProperty = { final String name, final Boolean d -> + final def p = project.findProperty(name) if (p == null) { return d @@ -16,12 +16,10 @@ Utils.getBooleanProperty = { String name, Boolean d -> } throw new IllegalArgumentException("Property '${name}' must be 0 or 1, but got '${p}'") - - return d } -Utils.getStringProperty = { String name, String d -> - def s = project.findProperty(name) +Utils.getStringProperty = { final String name, final String d -> + final def s = project.findProperty(name) if (s == null) { return d @@ -42,26 +40,24 @@ Utils.getStringProperty = { String name, String d -> return s } -Utils.getIntegerProperty = { String name, Integer d -> - def p = project.findProperty(name) +Utils.getIntegerProperty = { final String name, final Integer d -> + final def p = project.findProperty(name) if (p == null) { return d } try { - def v = p as Integer + final def v = p as Integer return v - } catch (ClassCastException e) { - throw new IllegalArgumentException("Property '${name}' must be integer, but got '${p}'") + } catch (final ClassCastException e) { + throw new IllegalArgumentException("Property '${name}' must be integer, but got '${p}' [exception: ${e}]") } - - return d } -Utils.isEnableAllLibrary = { -> - def enableAll = project.findProperty("MENGINE_APP_LIBRARY_ENABLE_ALL") +Utils.isEnableAllLibrary = { -> Boolean + final def enableAll = project.findProperty("MENGINE_APP_LIBRARY_ENABLE_ALL") if (enableAll != null && (enableAll as Integer) == 1) { return true @@ -70,18 +66,18 @@ Utils.isEnableAllLibrary = { -> return false } -Utils.existAppLibrary = { String name -> +Utils.existAppLibrary = { final String name -> if (Utils.isEnableAllLibrary() == true) { return true } - boolean p = Utils.getBooleanProperty(name, true) + final boolean p = Utils.getBooleanProperty(name, true) return p } Utils.isEnableAllPlugins = { -> - def enableAll = project.findProperty("MENGINE_APP_PLUGIN_ENABLE_ALL") + final def enableAll = project.findProperty("MENGINE_APP_PLUGIN_ENABLE_ALL") if (enableAll != null && (enableAll as Integer) == 1) { return true @@ -90,76 +86,61 @@ Utils.isEnableAllPlugins = { -> return false } -Utils.existAppPlugin = { String name, List required = [] -> +Utils.existAppPlugin = { final String name, final List required = [] -> if (Utils.isEnableAllPlugins() == true) { return true } - for (String r : required) { + for (final String r : required) { if (Utils.existAppPlugin(r) == false) { - return false; + return false } } - boolean p = Utils.getBooleanProperty(name, false) + final boolean p = Utils.getBooleanProperty(name, false) - return p; + return p } -Utils.getBooleanAppPluginProperty = { String name, List required = [] -> +Utils.getBooleanAppPluginProperty = { final String name, final List required = [] -> if (Utils.isEnableAllPlugins() == true) { return true } - for (String r : required) { + for (final String r : required) { if (Utils.existAppPlugin(r) == false) { - return false; + return false } } - boolean p = Utils.getBooleanProperty(name, false) - - return p -} - -Utils.getStringAppPluginProperty = { String name -> - if (Utils.isEnableAllPlugins() == true) { - return true - } - - String p = Utils.getStringProperty(name) + final boolean p = Utils.getBooleanProperty(name, false) return p } -Utils.getIntegerAppPluginProperty = { String name -> - if (Utils.isEnableAllPlugins() == true) { - return true - } - - Integer p = Utils.getIntegerProperty(name) +Utils.existAppService = { final String name -> + final boolean p = Utils.getBooleanProperty(name, true) return p } -Utils.existAppService = { String name -> - boolean p = Utils.getBooleanProperty(name, true) - - return p -} +final String RED = "\u001b[31m" +final String GREEN = "\u001b[32m" +final String YELLOW = "\u001b[33m" +final String RESET = "\u001b[0m" -Utils.logAvailable = { String name, boolean value -> +Utils.logAvailable = { final String name, final boolean value -> if (value == false) { - println "\u001b[31m${name}: ${value}\u001b[0m" + println RED + "${name}: ${value}" + RESET } else { - println "\u001b[32m${name}: ${value}\u001b[0m" + println GREEN + "${name}: ${value}" + RESET } } -Utils.logString = { String name, String value -> - println "\u001b[33m${name}: ${value}\u001b[0m" +Utils.logString = { final String name, final String value -> + println YELLOW + "${name}: ${value}" + RESET } -Utils.logInteger = { String name, int value -> - println "\u001b[33m${name}: ${value}\u001b[0m" +Utils.logInteger = { final String name, final int value -> + println YELLOW + "${name}: ${value}" + RESET } \ No newline at end of file diff --git a/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp b/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp index a29e8807d8..88ef4909ea 100644 --- a/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp @@ -121,7 +121,7 @@ namespace Mengine m_factoryDelaySchedulePipe = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); m_factoryPythonScheduleTiming = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); m_factoryPythonSchedulePipe = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); - m_factoryNodeAffectorCallback = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); + m_factoryNodeAffectorCallback = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); m_factoryPythonLayoutElementGetter = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); m_factoryPythonLayoutElementSetter = Helper::makeFactoryPool( MENGINE_DOCUMENT_FACTORABLE ); @@ -366,8 +366,8 @@ namespace Mengine py_getter->initialize( _getter, _args ); PythonLayoutElementSetterPtr py_setter; - - if( _setter.is_none() == false ) + + if( _setter.is_none() == false ) { py_setter = m_factoryPythonLayoutElementSetter->createObject( MENGINE_DOCUMENT_PYTHON ); py_setter->initialize( _setter, _args ); @@ -2485,7 +2485,7 @@ namespace Mengine pybind::interface_>( _kernel, "Identity" ) .def( "setName", &Identity::setName ) - .def( "getName", &Identity::getName ) + .def( "getName", &Identity::getName ) ; pybind::interface_>( _kernel, "BoundingBox" ) @@ -2887,7 +2887,7 @@ namespace Mengine .def_member( "target", &RenderContext::target ) .def_member( "zGroup", &RenderContext::zGroup ) .def_member( "zIndex", &RenderContext::zIndex ) - ; + ; pybind::interface_>( _kernel, "SchedulerInterface", true ) .def_proxy_static_args( "timing", scriptMethod, &KernelScriptMethod::ScheduleInterface_timing ) diff --git a/src/Interface/SoundServiceInterface.h b/src/Interface/SoundServiceInterface.h index 09d0b8202c..049d3a5fe0 100644 --- a/src/Interface/SoundServiceInterface.h +++ b/src/Interface/SoundServiceInterface.h @@ -43,14 +43,14 @@ namespace Mengine virtual SoundBufferInterfacePtr createSoundBufferFromFile( const ContentInterfacePtr & _content, bool _isStream, const DocumentInterfacePtr & _doc ) = 0; public: - virtual void setSoundVolume( const ConstString & _type, float _volume, float _from, float _speed ) = 0; - virtual float getSoundVolume( const ConstString & _type ) const = 0; - virtual float mixSoundVolume() const = 0; - virtual void setCommonVolume( const ConstString & _type, float _volume, float _from, float _speed ) = 0; virtual float getCommonVolume( const ConstString & _type ) const = 0; virtual float mixCommonVolume() const = 0; + virtual void setSoundVolume( const ConstString & _type, float _volume, float _from, float _speed ) = 0; + virtual float getSoundVolume( const ConstString & _type ) const = 0; + virtual float mixSoundVolume() const = 0; + virtual void setMusicVolume( const ConstString & _type, float _volume, float _from, float _speed ) = 0; virtual float getMusicVolume( const ConstString & _type ) const = 0; virtual float mixMusicVolume() const = 0; diff --git a/src/Kernel/HashHelper.h b/src/Kernel/HashHelper.h index f2a4c440a7..f8964a401b 100644 --- a/src/Kernel/HashHelper.h +++ b/src/Kernel/HashHelper.h @@ -50,7 +50,7 @@ namespace Mengine for( size_t i = 0; i != _len; ++i ) { HashType b2 = (HashType)*p++; - HashType x2 = Helper::Detail::xmul12864( 1000003ULL, x ); + HashType x2 = Detail::xmul12864( 1000003ULL, x ); x = x2 ^ b2; } @@ -77,18 +77,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// } ////////////////////////////////////////////////////////////////////////// - namespace Literals - { - ////////////////////////////////////////////////////////////////////////// - MENGINE_CONSTEXPR HashType operator "" _hash( const Char * _value, size_t _size ) - { - return Helper::makeHash( _value, _size ); - } - } - ////////////////////////////////////////////////////////////////////////// - using namespace Literals; - ////////////////////////////////////////////////////////////////////////// } ////////////////////////////////////////////////////////////////////////// -using namespace Mengine::Literals; +MENGINE_CONSTEXPR Mengine::HashType operator ""_hash( const Mengine::Char * _value, size_t _size ) +{ + return Mengine::Helper::makeHash( _value, _size ); +} ////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/Kernel/MixerAveraging.cpp b/src/Kernel/MixerAveraging.cpp index 2daed0e3c5..3fc9050183 100644 --- a/src/Kernel/MixerAveraging.cpp +++ b/src/Kernel/MixerAveraging.cpp @@ -91,10 +91,18 @@ namespace Mengine { float used = 0.f; - if( m.follower.update( _context, &used ) == false ) + float old_value = m.follower.getValue(); + + m.follower.update( _context, &used ); + + float new_value = m.follower.getValue(); + + if( old_value == new_value ) { - process = true; + continue; } + + process = true; } return process; diff --git a/src/Kernel/MixerMultiplicative.cpp b/src/Kernel/MixerMultiplicative.cpp index 43f82cb4f4..1c0554dd6e 100644 --- a/src/Kernel/MixerMultiplicative.cpp +++ b/src/Kernel/MixerMultiplicative.cpp @@ -84,10 +84,18 @@ namespace Mengine { float used = 0.f; - if( m.follower.update( _context, &used ) == false ) + float old_value = m.follower.getValue(); + + m.follower.update( _context, &used ); + + float new_value = m.follower.getValue(); + + if( old_value == new_value ) { - process = true; + continue; } + + process = true; } return process; diff --git a/src/Kernel/NodeScreenPosition.cpp b/src/Kernel/NodeScreenPosition.cpp index b9c1b1b8a6..9771a715f0 100644 --- a/src/Kernel/NodeScreenPosition.cpp +++ b/src/Kernel/NodeScreenPosition.cpp @@ -52,8 +52,8 @@ namespace Mengine ->getRenderResolution(); resolution = player_resolution.get(); - } - + } + resolution->fromContentToScreenPosition( contentPosition, _screenPosition ); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Kernel/ValueFollower.h b/src/Kernel/ValueFollower.h index b7f200b5de..fd98595c1a 100644 --- a/src/Kernel/ValueFollower.h +++ b/src/Kernel/ValueFollower.h @@ -13,6 +13,7 @@ namespace Mengine ValueFollower() : m_value( T() ) , m_follow( T() ) + , m_eof( false ) { } @@ -54,6 +55,8 @@ namespace Mengine void overtake() { m_value = m_follow; + + m_eof = true; } void step( const T & _value ) @@ -75,6 +78,13 @@ namespace Mengine bool update( const UpdateContext * _context, float * const _used ) { + if( m_eof == true ) + { + *_used = 0.f; + + return true; + } + bool successful = this->_update( _context, _used ); return successful; @@ -86,5 +96,7 @@ namespace Mengine protected: T m_value; T m_follow; + + bool m_eof; }; } diff --git a/src/Kernel/ValueFollowerAcceleration.h b/src/Kernel/ValueFollowerAcceleration.h index c2010566df..4c6ac6938e 100644 --- a/src/Kernel/ValueFollowerAcceleration.h +++ b/src/Kernel/ValueFollowerAcceleration.h @@ -52,6 +52,8 @@ namespace Mengine { *_used = _context->time; + m_speed += m_acceleration * _context->time; + float value_length = this->getLength(); if( mt::equal_f_z( value_length ) == true ) @@ -61,8 +63,6 @@ namespace Mengine return true; } - m_speed += m_acceleration * _context->time; - float step = m_speed * _context->time; if( step >= value_length ) @@ -73,11 +73,7 @@ namespace Mengine } else if( step + m_minimalDistance >= value_length ) { - T offset = this->getDistance(); - - T add = offset * ((value_length - m_minimalDistance) / value_length); - - this->step( add ); + this->overtake(); return true; } diff --git a/src/Kernel/ValueFollowerLinear.h b/src/Kernel/ValueFollowerLinear.h index 9993230ca7..8c9c9c0562 100644 --- a/src/Kernel/ValueFollowerLinear.h +++ b/src/Kernel/ValueFollowerLinear.h @@ -60,11 +60,7 @@ namespace Mengine } else if( step + m_minimalDistance >= value_length ) { - T offset = this->getDistance(); - - T add = offset * ((value_length - m_minimalDistance) / value_length); - - this->step( add ); + this->overtake(); return true; } diff --git a/src/Services/SoundService/SoundService.h b/src/Services/SoundService/SoundService.h index 06fa91a500..44bad7865e 100644 --- a/src/Services/SoundService/SoundService.h +++ b/src/Services/SoundService/SoundService.h @@ -61,14 +61,14 @@ namespace Mengine SoundDecoderInterfacePtr createSoundDecoder_( const ContentInterfacePtr & _content, bool _streamable, const DocumentInterfacePtr & _doc ); public: - void setSoundVolume( const ConstString & _type, float _volume, float _from, float _speed ) override; - float getSoundVolume( const ConstString & _type ) const override; - float mixSoundVolume() const override; - void setCommonVolume( const ConstString & _type, float _volume, float _from, float _speed ) override; float getCommonVolume( const ConstString & _type ) const override; float mixCommonVolume() const override; + void setSoundVolume( const ConstString & _type, float _volume, float _from, float _speed ) override; + float getSoundVolume( const ConstString & _type ) const override; + float mixSoundVolume() const override; + void setMusicVolume( const ConstString & _type, float _volume, float _from, float _speed ) override; float getMusicVolume( const ConstString & _type ) const override; float mixMusicVolume() const override; @@ -105,7 +105,7 @@ namespace Mengine bool getMute( const ConstString & _type ) const override; bool mixMute() const override; - public: + protected: void updateVolume() override; protected: From bc835fc2307a5a12f2a2f02b8fb822cb31038e5f Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 19 Oct 2025 15:34:53 +0300 Subject: [PATCH 080/169] improve randomizer --- src/Config/CMakeLists.txt | 1 + src/Config/StdRandom.h | 18 ++++++++ .../PythonFramework/EngineScriptEmbedding.cpp | 1 - .../SimpleFramework/SimpleRandomizer.cpp | 8 ---- .../SimpleFramework/SimpleRandomizer.h | 2 - src/Interface/RandomizerInterface.h | 3 -- src/Kernel/MT19937Randomizer.cpp | 44 ++++++++++--------- src/Kernel/MT19937Randomizer.h | 8 ++-- src/Kernel/RandomDevice.cpp | 36 +++------------ src/Kernel/RandomDevice.h | 5 +-- src/Kernel/UID.cpp | 17 ++----- src/Kernel/UID.h | 1 - .../AndroidPlatformService.cpp | 6 --- .../Win32Platform/Win32PlatformService.cpp | 8 ---- src/Services/PlayerService/PlayerService.cpp | 10 ++--- 15 files changed, 61 insertions(+), 107 deletions(-) create mode 100644 src/Config/StdRandom.h diff --git a/src/Config/CMakeLists.txt b/src/Config/CMakeLists.txt index 3f4359c594..32e16f68b9 100644 --- a/src/Config/CMakeLists.txt +++ b/src/Config/CMakeLists.txt @@ -156,6 +156,7 @@ src StdUtility.h StdThread.h StdAssert.h + StdRandom.h Limits.h UInt32ToPointer.h Metaprogramming.h diff --git a/src/Config/StdRandom.h b/src/Config/StdRandom.h new file mode 100644 index 0000000000..3872378d58 --- /dev/null +++ b/src/Config/StdRandom.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Config/Config.h" + +#include + +namespace Mengine +{ + namespace StdRandom + { + using std::mt19937_64; + using std::random_device; + using std::seed_seq; + + using std::uniform_int_distribution; + using std::uniform_real_distribution; + } +} \ No newline at end of file diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index 96dee8e68d..780e61b246 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -4757,7 +4757,6 @@ namespace Mengine } pybind::interface_>( _kernel, "Randomizer" ) - .def( "setSeed", &RandomizerInterface::setSeed ) .def( "getRandom", &RandomizerInterface::getRandom32 ) .def( "getRandomRange", &RandomizerInterface::getRandomRange32 ) .def( "getRandomf", &RandomizerInterface::getRandomf ) diff --git a/src/Frameworks/SimpleFramework/SimpleRandomizer.cpp b/src/Frameworks/SimpleFramework/SimpleRandomizer.cpp index 71a31ca816..5d250060e4 100644 --- a/src/Frameworks/SimpleFramework/SimpleRandomizer.cpp +++ b/src/Frameworks/SimpleFramework/SimpleRandomizer.cpp @@ -7,14 +7,6 @@ namespace Mengine { namespace Helper { - ////////////////////////////////////////////////////////////////////////// - void setSimpleRandomizerSeed( uint64_t _seed ) - { - const RandomizerInterfacePtr & randomizer = PLAYER_SERVICE() - ->getRandomizer(); - - randomizer->setSeed( _seed ); - } ////////////////////////////////////////////////////////////////////////// uint32_t getSimpleRandomizerRandom32( uint32_t _max ) { diff --git a/src/Frameworks/SimpleFramework/SimpleRandomizer.h b/src/Frameworks/SimpleFramework/SimpleRandomizer.h index a7161937a3..0410ddad18 100644 --- a/src/Frameworks/SimpleFramework/SimpleRandomizer.h +++ b/src/Frameworks/SimpleFramework/SimpleRandomizer.h @@ -6,8 +6,6 @@ namespace Mengine { namespace Helper { - void setSimpleRandomizerSeed( uint64_t _seed ); - uint32_t getSimpleRandomizerRandom32( uint32_t _max ); uint32_t getSimpleRandomizerRandomRange32( uint32_t _min, uint32_t _max ); diff --git a/src/Interface/RandomizerInterface.h b/src/Interface/RandomizerInterface.h index 3c26309adc..9c0539b175 100644 --- a/src/Interface/RandomizerInterface.h +++ b/src/Interface/RandomizerInterface.h @@ -10,9 +10,6 @@ namespace Mengine class RandomizerInterface : public ServantInterface { - public: - virtual void setSeed( uint64_t _seed ) = 0; - public: virtual uint32_t getRandom32( uint32_t _max ) const = 0; virtual uint32_t getRandomRange32( uint32_t _min, uint32_t _max ) const = 0; diff --git a/src/Kernel/MT19937Randomizer.cpp b/src/Kernel/MT19937Randomizer.cpp index b4b5ede89e..be45d79d99 100644 --- a/src/Kernel/MT19937Randomizer.cpp +++ b/src/Kernel/MT19937Randomizer.cpp @@ -8,25 +8,27 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// MT19937Randomizer::MT19937Randomizer() + : m_engineRandomize( Helper::generateRandomDeviceMT19937() ) { - uint64_t seed = Helper::generateRandomLocaleSeed(); - - m_engineRandomize = std::mt19937_64{seed}; - - std::mt19937_64::result_type min_value = (m_engineRandomize.min)(); - std::mt19937_64::result_type max_value = (m_engineRandomize.max)(); + StdRandom::mt19937_64::result_type min_value = (m_engineRandomize.min)(); + StdRandom::mt19937_64::result_type max_value = (m_engineRandomize.max)(); m_epsilonf = 1.f / float( max_value - min_value ); m_epsilond = 1.0 / double( max_value - min_value ); } ////////////////////////////////////////////////////////////////////////// - MT19937Randomizer::~MT19937Randomizer() + MT19937Randomizer::MT19937Randomizer( uint64_t _seed ) + : m_engineRandomize{_seed} { + StdRandom::mt19937_64::result_type min_value = (m_engineRandomize.min)(); + StdRandom::mt19937_64::result_type max_value = (m_engineRandomize.max)(); + + m_epsilonf = 1.f / float( max_value - min_value ); + m_epsilond = 1.0 / double( max_value - min_value ); } ////////////////////////////////////////////////////////////////////////// - void MT19937Randomizer::setSeed( uint64_t _seed ) + MT19937Randomizer::~MT19937Randomizer() { - m_engineRandomize.seed( _seed ); } ////////////////////////////////////////////////////////////////////////// uint32_t MT19937Randomizer::getRandom32( uint32_t _max ) const @@ -36,7 +38,7 @@ namespace Mengine return 0U; } - std::uniform_int_distribution uid( 0, _max - 1 ); + StdRandom::uniform_int_distribution uid( 0, _max - 1 ); uint32_t rand_value = uid( m_engineRandomize ); @@ -55,7 +57,7 @@ namespace Mengine return _max - 1; } - std::uniform_int_distribution uid( _min, _max - 1 ); + StdRandom::uniform_int_distribution uid( _min, _max - 1 ); uint32_t rand_value = uid( m_engineRandomize ); @@ -64,7 +66,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// int32_t MT19937Randomizer::getRandom32i( int32_t _max ) const { - std::uniform_int_distribution uid( _max > 0 ? 0 : _max, _max > 0 ? _max : 0 ); + StdRandom::uniform_int_distribution uid( _max > 0 ? 0 : _max, _max > 0 ? _max : 0 ); int32_t rand_value = uid( m_engineRandomize ); @@ -78,7 +80,7 @@ namespace Mengine return _max - 1; } - std::uniform_int_distribution uid( _min, _max - 1 ); + StdRandom::uniform_int_distribution uid( _min, _max - 1 ); int32_t rand_value = uid( m_engineRandomize ); @@ -92,7 +94,7 @@ namespace Mengine return 0U; } - std::uniform_int_distribution uid( 0, _max - 1 ); + StdRandom::uniform_int_distribution uid( 0, _max - 1 ); uint64_t rand_value = uid( m_engineRandomize ); @@ -111,7 +113,7 @@ namespace Mengine return _max - 1; } - std::uniform_int_distribution uid( _min, _max - 1 ); + StdRandom::uniform_int_distribution uid( _min, _max - 1 ); uint64_t rand_value = uid( m_engineRandomize ); @@ -120,7 +122,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// int64_t MT19937Randomizer::getRandom64i( int64_t _max ) const { - std::uniform_int_distribution uid( _max > 0 ? 0 : _max, _max > 0 ? _max : 0 ); + StdRandom::uniform_int_distribution uid( _max > 0 ? 0 : _max, _max > 0 ? _max : 0 ); int64_t rand_value = uid( m_engineRandomize ); @@ -134,7 +136,7 @@ namespace Mengine return _max - 1; } - std::uniform_int_distribution uid( _min, _max - 1 ); + StdRandom::uniform_int_distribution uid( _min, _max - 1 ); int64_t rand_value = uid( m_engineRandomize ); @@ -152,7 +154,7 @@ namespace Mengine return 0.f; } - std::uniform_real_distribution uid( 0.f, _max ); + StdRandom::uniform_real_distribution uid( 0.f, _max ); float rand_value = uid( m_engineRandomize ); @@ -179,7 +181,7 @@ namespace Mengine return _max; } - std::uniform_real_distribution uid( _min, _max ); + StdRandom::uniform_real_distribution uid( _min, _max ); float rand_value = uid( m_engineRandomize ); @@ -197,7 +199,7 @@ namespace Mengine return 0.0; } - std::uniform_real_distribution uid( 0.0, _max ); + StdRandom::uniform_real_distribution uid( 0.0, _max ); double rand_value = uid( m_engineRandomize ); @@ -224,7 +226,7 @@ namespace Mengine return _max; } - std::uniform_real_distribution uid( _min, _max ); + StdRandom::uniform_real_distribution uid( _min, _max ); double rand_value = uid( m_engineRandomize ); diff --git a/src/Kernel/MT19937Randomizer.h b/src/Kernel/MT19937Randomizer.h index f772edf301..8635df8309 100644 --- a/src/Kernel/MT19937Randomizer.h +++ b/src/Kernel/MT19937Randomizer.h @@ -2,7 +2,7 @@ #include "Interface/RandomizerInterface.h" -#include +#include "Config/StdRandom.h" namespace Mengine { @@ -13,11 +13,9 @@ namespace Mengine public: MT19937Randomizer(); + MT19937Randomizer( uint64_t _seed ); ~MT19937Randomizer() override; - protected: - void setSeed( uint64_t _seed ) override; - protected: uint32_t getRandom32( uint32_t _max ) const override; uint32_t getRandomRange32( uint32_t _min, uint32_t _max ) const override; @@ -38,7 +36,7 @@ namespace Mengine double getRandomRanged( double _min, double _max ) const override; protected: - mutable std::mt19937_64 m_engineRandomize; + mutable StdRandom::mt19937_64 m_engineRandomize; float m_epsilonf; double m_epsilond; diff --git a/src/Kernel/RandomDevice.cpp b/src/Kernel/RandomDevice.cpp index 2e1752061c..1ae8aba8f7 100644 --- a/src/Kernel/RandomDevice.cpp +++ b/src/Kernel/RandomDevice.cpp @@ -1,43 +1,19 @@ #include "RandomDevice.h" -#include "Interface/ThreadSystemInterface.h" - -#include +#include "Kernel/Array.h" namespace Mengine { namespace Helper { ////////////////////////////////////////////////////////////////////////// - uint64_t generateRandomLocaleSeed() + StdRandom::mt19937_64 generateRandomDeviceMT19937() { - std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); - std::chrono::time_point now_ns = std::chrono::time_point_cast(now); - std::chrono::time_point::duration epoch = now_ns.time_since_epoch(); - std::chrono::nanoseconds value = std::chrono::duration_cast(epoch); - - uint64_t now_ns_count = (uint64_t)value.count(); - - return now_ns_count; - } - ////////////////////////////////////////////////////////////////////////// - uint64_t generateRandomDeviceSeed() - { - static uint64_t seed = 0; - - if( seed == 0 ) - { - for( uint32_t probe = 0; probe != 8; ++probe ) - { - uint64_t locale_seed = Helper::generateRandomLocaleSeed(); - - seed ^= locale_seed; - } - - return seed; - } + StdRandom::random_device rd; + Array data = {rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()}; + StdRandom::seed_seq seq( data.begin(), data.end() ); - return seed; + return StdRandom::mt19937_64{seq}; } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/RandomDevice.h b/src/Kernel/RandomDevice.h index d638b34069..267916a7ef 100644 --- a/src/Kernel/RandomDevice.h +++ b/src/Kernel/RandomDevice.h @@ -1,12 +1,11 @@ #pragma once -#include "Config/Typedef.h" +#include "Config/StdRandom.h" namespace Mengine { namespace Helper { - uint64_t generateRandomLocaleSeed(); - uint64_t generateRandomDeviceSeed(); + StdRandom::mt19937_64 generateRandomDeviceMT19937(); } } \ No newline at end of file diff --git a/src/Kernel/UID.cpp b/src/Kernel/UID.cpp index 5b85375475..eb07d1041d 100644 --- a/src/Kernel/UID.cpp +++ b/src/Kernel/UID.cpp @@ -2,9 +2,8 @@ #include "Kernel/RandomDevice.h" -#include -#include #include "Config/StdAlgorithm.h" +#include "Config/StdRandom.h" namespace Mengine { @@ -28,19 +27,11 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void makeUID( uint32_t _length, Char * const _uid ) { - uint64_t device_seed = Helper::generateRandomDeviceSeed(); - uint64_t locale_seed = Helper::generateRandomLocaleSeed(); + StdRandom::mt19937_64 rng = Helper::generateRandomDeviceMT19937(); - uint64_t seed = device_seed + locale_seed; + size_t char_array_size = MENGINE_STATIC_STRING_LENGTH( char_array ); - Helper::makeUIDSeed( seed, _length, _uid ); - } - ////////////////////////////////////////////////////////////////////////// - void makeUIDSeed( uint64_t _seed, uint32_t _length, Char * const _uid ) - { - std::mt19937_64 rng{_seed}; - - std::uniform_int_distribution dist( 0, MENGINE_STATIC_STRING_LENGTH( char_array ) ); + StdRandom::uniform_int_distribution dist( 0, char_array_size ); StdAlgorithm::generate_n( _uid, _length, [&dist, &rng]() { diff --git a/src/Kernel/UID.h b/src/Kernel/UID.h index 889eb643ab..40446c960e 100644 --- a/src/Kernel/UID.h +++ b/src/Kernel/UID.h @@ -7,6 +7,5 @@ namespace Mengine namespace Helper { void makeUID( uint32_t _length, Char * const _uid ); - void makeUIDSeed( uint64_t _seed, uint32_t _length, Char * const _uid ); } } \ No newline at end of file diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index 873c3156ae..b8363f497e 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -730,12 +730,6 @@ namespace Mengine , m_desktop ); - uint32_t deviceSeed = Helper::generateRandomDeviceSeed(); - - LOGGER_INFO_PROTECTED( "platform", "Device Seed: %u" - , deviceSeed - ); - m_analyticsEventProvider = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); ANALYTICS_SERVICE() diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index fad2a9991c..abb21331b0 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -339,14 +339,6 @@ namespace Mengine } #endif - uint64_t deviceSeed = Helper::generateRandomDeviceSeed(); - - MENGINE_UNUSED( deviceSeed ); - - LOGGER_INFO_PROTECTED( "platform", "device seed: %" MENGINE_PRIu64 - , deviceSeed - ); - return true; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Services/PlayerService/PlayerService.cpp b/src/Services/PlayerService/PlayerService.cpp index a4739e2900..535f75537f 100644 --- a/src/Services/PlayerService/PlayerService.cpp +++ b/src/Services/PlayerService/PlayerService.cpp @@ -96,21 +96,19 @@ namespace Mengine m_globalScheduler = schedulerGlobal; - m_randomizer = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); - if( HAS_OPTION( "seed" ) == true ) { - uint32_t randomSeed = GET_OPTION_VALUE_UINT32( "seed", 0U ); + uint64_t randomSeed = GET_OPTION_VALUE_UINT32( "seed", 0ULL ); - m_randomizer->setSeed( randomSeed ); + m_randomizer = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE, randomSeed ); } else { Timestamp milliseconds = Helper::getSystemTimestamp(); - uint32_t randomSeed = (uint32_t)milliseconds; + uint64_t randomSeed = (uint64_t)milliseconds; - m_randomizer->setSeed( randomSeed ); + m_randomizer = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE, randomSeed ); } m_affectorable = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); From 3fe071460ef7c161a29d4f9d00244411464e3143 Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 19 Oct 2025 16:05:12 +0300 Subject: [PATCH 081/169] update android dependencies --- gradle/gms.gradle | 4 ++-- gradle/gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/gson.gradle | 2 +- gradle/plugins/DataDog/build.gradle | 2 +- gradle/plugins/DevToDev/build.gradle | 2 +- gradle/settings.gradle.kts | 13 +++++-------- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/gradle/gms.gradle b/gradle/gms.gradle index a3ff25c7a4..49cfd9e92e 100644 --- a/gradle/gms.gradle +++ b/gradle/gms.gradle @@ -1,6 +1,6 @@ dependencies { - implementation 'com.google.android.gms:play-services-base:18.8.0' - implementation 'com.google.android.gms:play-services-basement:18.8.0' + implementation 'com.google.android.gms:play-services-base:18.9.0' + implementation 'com.google.android.gms:play-services-basement:18.9.0' implementation 'com.google.android.gms:play-services-gcm:17.0.0' implementation 'com.google.android.gms:play-services-location:21.3.0' implementation 'com.google.android.gms:play-services-ads-identifier:18.2.0' diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index e2a4851dde..737a1463ee 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Sep 24 12:58:29 EEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle/gson.gradle b/gradle/gson.gradle index 2c75e1f62a..3e550bc451 100644 --- a/gradle/gson.gradle +++ b/gradle/gson.gradle @@ -1,3 +1,3 @@ dependencies { - implementation 'com.google.code.gson:gson:2.13.1' + implementation 'com.google.code.gson:gson:2.13.2' } \ No newline at end of file diff --git a/gradle/plugins/DataDog/build.gradle b/gradle/plugins/DataDog/build.gradle index e9cf6059f3..5622a412a7 100644 --- a/gradle/plugins/DataDog/build.gradle +++ b/gradle/plugins/DataDog/build.gradle @@ -15,5 +15,5 @@ android { } dependencies { - implementation 'com.datadoghq:dd-sdk-android-logs:3.1.0' + implementation 'com.datadoghq:dd-sdk-android-logs:3.2.0' } \ No newline at end of file diff --git a/gradle/plugins/DevToDev/build.gradle b/gradle/plugins/DevToDev/build.gradle index 229d98d069..2eb102c178 100644 --- a/gradle/plugins/DevToDev/build.gradle +++ b/gradle/plugins/DevToDev/build.gradle @@ -11,7 +11,7 @@ android { dependencies { implementation 'com.devtodev:android-google:1.0.1' - implementation 'com.devtodev:android-analytics:2.5.1' + implementation 'com.devtodev:android-analytics:2.5.2' } android { diff --git a/gradle/settings.gradle.kts b/gradle/settings.gradle.kts index 7d23221970..23d7e97bc2 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -5,18 +5,15 @@ fun getBooleanProperty(name: String, d: Boolean): Boolean { return d } - try { - val value = extra[name].toString() - - if (value.toInt() == 0) { - return false - } + val value = extra[name].toString() + if (value.toInt() == 0) { + return false + } else if (value.toInt() == 1) { return true - } catch (e: Exception) { } - return d + throw kotlin.Exception("Get boolean property error: $name unexpected value: $value") } fun getStringProperty(name: String, d: String?): String? { From a660d65b8121681adc7539ade4ba2568098ca536 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 20 Oct 2025 15:32:56 +0300 Subject: [PATCH 082/169] rename SpinLock fix ValueFollower --- src/Config/CMakeLists.txt | 20 ++-- src/Kernel/BaseAffectorHub.h | 4 - src/Kernel/BaseContent.h | 4 - src/Kernel/BaseRender.h | 2 - src/Kernel/BaseTransformation.h | 4 - src/Kernel/BaseUpdation.cpp | 10 -- src/Kernel/BaseUpdation.h | 15 ++- src/Kernel/CMakeLists.txt | 12 +-- src/Kernel/CodecDataInfo.h | 2 - src/Kernel/Futex.cpp | 54 ----------- src/Kernel/FutexScope.h | 19 ---- src/Kernel/ImageDecoderArchive.h | 2 +- src/Kernel/ImageDecoderMemory.h | 2 +- src/Kernel/MixerMultiplicative.cpp | 9 +- src/Kernel/SpinLock.cpp | 91 +++++++++++++++++++ src/Kernel/{Futex.h => SpinLock.h} | 10 +- .../{FutexScope.cpp => SpinLockScope.cpp} | 12 +-- src/Kernel/SpinLockScope.h | 19 ++++ src/Kernel/ValueFollower.h | 16 +--- src/Kernel/ValueFollowerAcceleration.h | 24 ++--- src/Kernel/ValueFollowerLinear.h | 24 ++--- .../ProviderService/ServiceProvider.cpp | 20 ++-- .../ProviderService/ServiceProvider.h | 10 +- 23 files changed, 188 insertions(+), 197 deletions(-) delete mode 100644 src/Kernel/Futex.cpp delete mode 100644 src/Kernel/FutexScope.h create mode 100644 src/Kernel/SpinLock.cpp rename src/Kernel/{Futex.h => SpinLock.h} (53%) rename src/Kernel/{FutexScope.cpp => SpinLockScope.cpp} (58%) create mode 100644 src/Kernel/SpinLockScope.h diff --git a/src/Config/CMakeLists.txt b/src/Config/CMakeLists.txt index 32e16f68b9..9af3b65fed 100644 --- a/src/Config/CMakeLists.txt +++ b/src/Config/CMakeLists.txt @@ -43,15 +43,17 @@ MESSAGE("MENGINE_ENGINE_GIT_URL: ${MENGINE_ENGINE_GIT_URL}") MESSAGE("MENGINE_ENGINE_GIT_BRANCH: ${MENGINE_ENGINE_GIT_BRANCH}") MESSAGE("MENGINE_ENGINE_GIT_DATE: ${MENGINE_ENGINE_GIT_DATE}") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/GitSHA1.h.in ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/GitSHA1.h @ONLY) -MESSAGE("configure file: ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/GitSHA1.h") +SET(GITSHA1_FILEPATH ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/GitSHA1.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/GitSHA1.h.in ${GITSHA1_FILEPATH} @ONLY) +MESSAGE("configure file: ${GITSHA1_FILEPATH}") string(TIMESTAMP MENGINE_BUILD_DATE "%Y-%m-%d %H:%M:%S") set(MENGINE_BUILD_USERNAME $ENV{USERNAME} CACHE STRING "MENGINE_BUILD_USERNAME") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.h.in ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/BuildInfo.h @ONLY) -MESSAGE("configure file: ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/BuildInfo.h") +SET(BUILDINFO_FILEPATH ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/BuildInfo.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.h.in ${BUILDINFO_FILEPATH} @ONLY) +MESSAGE("configure file: ${BUILDINFO_FILEPATH}") MESSAGE("MENGINE_BUILD_USERNAME: ${MENGINE_BUILD_USERNAME}") MESSAGE("MENGINE_BUILD_DATE: ${MENGINE_BUILD_DATE}") @@ -86,8 +88,9 @@ endif() STRING(APPEND DEFINITIONS_BUFFER "#endif\n") -FILE(WRITE ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/Definitions.h ${DEFINITIONS_BUFFER}) -MESSAGE("configure file: ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/Definitions.h") +SET(DEFINITTIONS_FILEPATH ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/Definitions.h) +FILE(WRITE ${DEFINITTIONS_FILEPATH} ${DEFINITIONS_BUFFER}) +MESSAGE("configure file: ${DEFINITTIONS_FILEPATH}") SET(CONFIGURATIONS_BUFFER "") @@ -118,8 +121,9 @@ if(NOT LENGTH_MENGINE_CONFIG_CONFIGURATIONS EQUAL 0) endforeach() endif() -FILE(WRITE ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/Configurations.h ${CONFIGURATIONS_BUFFER}) -MESSAGE("configure file: ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/Configurations.h") +SET(CONFIGURATIONS_FILEPATH ${MENGINE_SOLUTIONS_CONFIG_DIR}/include/Configuration/Configurations.h) +FILE(WRITE ${CONFIGURATIONS_FILEPATH} ${CONFIGURATIONS_BUFFER}) +MESSAGE("configure file: ${CONFIGURATIONS_FILEPATH}") ADD_FILTER( src diff --git a/src/Kernel/BaseAffectorHub.h b/src/Kernel/BaseAffectorHub.h index 4a68db5da6..ac0879e22a 100644 --- a/src/Kernel/BaseAffectorHub.h +++ b/src/Kernel/BaseAffectorHub.h @@ -12,7 +12,6 @@ namespace Mengine { - ////////////////////////////////////////////////////////////////////////// class BaseAffectorHub : public AffectorHubInterface { @@ -53,7 +52,4 @@ namespace Mengine float m_angularSpeed; mt::vec3f m_linearSpeed; }; - ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr BaseAffectorHubPtr; - ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/BaseContent.h b/src/Kernel/BaseContent.h index 4b6e7e8b54..f828271a85 100644 --- a/src/Kernel/BaseContent.h +++ b/src/Kernel/BaseContent.h @@ -4,7 +4,6 @@ namespace Mengine { - ////////////////////////////////////////////////////////////////////////// class BaseContent : public ContentInterface { @@ -46,7 +45,4 @@ namespace Mengine bool m_validNoExist; }; - ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr ContentPtr; - ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/BaseRender.h b/src/Kernel/BaseRender.h index 4a533686da..ddc1521e97 100644 --- a/src/Kernel/BaseRender.h +++ b/src/Kernel/BaseRender.h @@ -158,8 +158,6 @@ namespace Mengine mutable bool m_invalidateRendering; }; ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr BaseRenderPtr; - ////////////////////////////////////////////////////////////////////////// MENGINE_INLINE bool BaseRender::isRendering() const { if( m_invalidateRendering == true ) diff --git a/src/Kernel/BaseTransformation.h b/src/Kernel/BaseTransformation.h index 421c2d17dc..12db5bc1d9 100644 --- a/src/Kernel/BaseTransformation.h +++ b/src/Kernel/BaseTransformation.h @@ -8,8 +8,6 @@ namespace Mengine { - ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr BaseTransformationPtr; ////////////////////////////////////////////////////////////////////////// class BaseTransformation : public TransformationInterface @@ -154,8 +152,6 @@ namespace Mengine mutable bool m_invalidateWorldMatrix; }; ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr BaseTransformationPtr; - ////////////////////////////////////////////////////////////////////////// MENGINE_INLINE BaseTransformation * BaseTransformation::getRelationTransformation() const { return m_relationTransformation; diff --git a/src/Kernel/BaseUpdation.cpp b/src/Kernel/BaseUpdation.cpp index d8508e1453..bc8f598252 100644 --- a/src/Kernel/BaseUpdation.cpp +++ b/src/Kernel/BaseUpdation.cpp @@ -78,14 +78,4 @@ namespace Mengine ->placeUpdatater( UpdationInterfacePtr::from( this ) ); } ////////////////////////////////////////////////////////////////////////// - EUpdateMode BaseUpdation::getUpdationMode() const - { - return m_mode; - } - ////////////////////////////////////////////////////////////////////////// - uint32_t BaseUpdation::getUpdationDeep() const - { - return m_deep; - } - ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Kernel/BaseUpdation.h b/src/Kernel/BaseUpdation.h index 42e0745667..fb0772170d 100644 --- a/src/Kernel/BaseUpdation.h +++ b/src/Kernel/BaseUpdation.h @@ -19,11 +19,22 @@ namespace Mengine void replace( uint32_t _deep ) override final; public: - EUpdateMode getUpdationMode() const final; - uint32_t getUpdationDeep() const final; + MENGINE_INLINE EUpdateMode getUpdationMode() const final; + MENGINE_INLINE uint32_t getUpdationDeep() const final; private: EUpdateMode m_mode; uint32_t m_deep; }; + ////////////////////////////////////////////////////////////////////////// + MENGINE_INLINE EUpdateMode BaseUpdation::getUpdationMode() const + { + return m_mode; + } + ////////////////////////////////////////////////////////////////////////// + MENGINE_INLINE uint32_t BaseUpdation::getUpdationDeep() const + { + return m_deep; + } + ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Kernel/CMakeLists.txt b/src/Kernel/CMakeLists.txt index e04ea45ac0..50eddf044f 100644 --- a/src/Kernel/CMakeLists.txt +++ b/src/Kernel/CMakeLists.txt @@ -721,13 +721,13 @@ Core ConstStringProxy.h VectorResourceImages.h - - Futex.h - Futex.cpp - FutexScope.h - FutexScope.cpp - + SpinLock.h + SpinLock.cpp + + SpinLockScope.h + SpinLockScope.cpp + UID.h UID.cpp diff --git a/src/Kernel/CodecDataInfo.h b/src/Kernel/CodecDataInfo.h index f5a7ef0206..d85374afcd 100644 --- a/src/Kernel/CodecDataInfo.h +++ b/src/Kernel/CodecDataInfo.h @@ -4,7 +4,6 @@ namespace Mengine { - ////////////////////////////////////////////////////////////////////////// struct CodecDataInfo { #if defined(MENGINE_ASSERTION_DEBUG_ENABLE) @@ -12,5 +11,4 @@ namespace Mengine virtual ~CodecDataInfo() = default; #endif }; - ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Kernel/Futex.cpp b/src/Kernel/Futex.cpp deleted file mode 100644 index d8674c6ad7..0000000000 --- a/src/Kernel/Futex.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "Futex.h" - -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - Futex::Futex() - : m_owner( StdThread::thread::id{} ) - , m_lock( 0 ) - { - } - ////////////////////////////////////////////////////////////////////////// - Futex::~Futex() - { - } - ////////////////////////////////////////////////////////////////////////// - void Futex::lock() - { - StdThread::thread::id this_id = StdThread::get_id(); - - if( m_owner.load( StdAtomic::memory_order_acquire ) == this_id ) - { - m_lock.fetch_add( 1, StdAtomic::memory_order_relaxed ); - - return; - } - - StdThread::thread::id no_owner = StdThread::thread::id{}; - - while( m_owner.compare_exchange_weak( no_owner, this_id, StdAtomic::memory_order_acquire, StdAtomic::memory_order_relaxed ) == false ) - { - no_owner = StdThread::thread::id{}; - - StdThread::yield(); - } - - m_lock.store( 1, StdAtomic::memory_order_release ); - } - ////////////////////////////////////////////////////////////////////////// - void Futex::unlock() - { - StdThread::thread::id this_id = StdThread::get_id(); - - if( m_owner.load( StdAtomic::memory_order_acquire ) != this_id ) - { - return; - } - - if( m_lock.fetch_sub( 1, StdAtomic::memory_order_acq_rel ) == 1 ) - { - m_owner.store( StdThread::thread::id{}, StdAtomic::memory_order_release ); - } - } - ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file diff --git a/src/Kernel/FutexScope.h b/src/Kernel/FutexScope.h deleted file mode 100644 index cd9c3d09bd..0000000000 --- a/src/Kernel/FutexScope.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "Kernel/Futex.h" - -namespace Mengine -{ - class FutexScope - { - public: - FutexScope( Futex & _futex ); - ~FutexScope(); - - protected: - Futex & m_futex; - }; -} - -#define MENGINE_FUTEX_SCOPE_I( Futex, Index ) FutexScope MENGINE_PP_CONCATENATE(__futex_scope_, Index)( Futex ) -#define MENGINE_FUTEX_SCOPE( Futex ) MENGINE_FUTEX_SCOPE_I( Futex, MENGINE_CODE_COUNTER ) \ No newline at end of file diff --git a/src/Kernel/ImageDecoderArchive.h b/src/Kernel/ImageDecoderArchive.h index c529be4077..7ce9cd0fea 100644 --- a/src/Kernel/ImageDecoderArchive.h +++ b/src/Kernel/ImageDecoderArchive.h @@ -36,6 +36,6 @@ namespace Mengine size_t m_uncompressSize; }; ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr ImageDecoderArchivePtr; + typedef IntrusivePtr ImageDecoderArchivePtr; ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/ImageDecoderMemory.h b/src/Kernel/ImageDecoderMemory.h index 439a081088..eb131dfcc2 100644 --- a/src/Kernel/ImageDecoderMemory.h +++ b/src/Kernel/ImageDecoderMemory.h @@ -21,6 +21,6 @@ namespace Mengine size_t decodeData_( void * const _buffer, size_t _bufferSize, size_t _pitch ) const; }; ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr ImageDecoderMemoryPtr; + typedef IntrusivePtr ImageDecoderMemoryPtr; ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Kernel/MixerMultiplicative.cpp b/src/Kernel/MixerMultiplicative.cpp index 1c0554dd6e..439d6f8702 100644 --- a/src/Kernel/MixerMultiplicative.cpp +++ b/src/Kernel/MixerMultiplicative.cpp @@ -83,14 +83,7 @@ namespace Mengine for( Element & m : m_mixer ) { float used = 0.f; - - float old_value = m.follower.getValue(); - - m.follower.update( _context, &used ); - - float new_value = m.follower.getValue(); - - if( old_value == new_value ) + if( m.follower.update( _context, &used ) == false ) { continue; } diff --git a/src/Kernel/SpinLock.cpp b/src/Kernel/SpinLock.cpp new file mode 100644 index 0000000000..d83aaf2fb3 --- /dev/null +++ b/src/Kernel/SpinLock.cpp @@ -0,0 +1,91 @@ +#include "SpinLock.h" + +#include "Kernel/Assertion.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + namespace Detail + { + ////////////////////////////////////////////////////////////////////////// + static size_t get_thread_cookie() + { + static Atomic s_cookie_counter{0}; + static MENGINE_THREAD_LOCAL size_t s_thread_cookie = 0; + + if( s_thread_cookie != 0 ) + { + return s_thread_cookie; + } + + size_t cookie; + + do + { + cookie = s_cookie_counter.fetch_add( 1, StdAtomic::memory_order_relaxed ) + 1; + } while( cookie == 0 ); + + s_thread_cookie = cookie; + + return cookie; + } + ////////////////////////////////////////////////////////////////////////// + } + ////////////////////////////////////////////////////////////////////////// + SpinLock::SpinLock() + : m_owner( 0 ) + , m_lock( 0 ) + { + } + ////////////////////////////////////////////////////////////////////////// + SpinLock::~SpinLock() + { + MENGINE_ASSERTION( m_owner.load( StdAtomic::memory_order_relaxed ) == 0, "SpinLock not released" ); + MENGINE_ASSERTION( m_lock.load( StdAtomic::memory_order_relaxed ) == 0, "SpinLock recursion not zero" ); + } + ////////////////////////////////////////////////////////////////////////// + void SpinLock::lock() + { + size_t me = Detail::get_thread_cookie(); + + if( m_owner.load( StdAtomic::memory_order_relaxed ) == me ) + { + m_lock.fetch_add( 1, StdAtomic::memory_order_relaxed ); + + return; + } + + size_t expected = 0; + + while( m_owner.compare_exchange_weak( expected, me, StdAtomic::memory_order_acquire, StdAtomic::memory_order_relaxed ) == false ) + { + expected = 0; + + StdThread::yield(); + } + + m_lock.store( 1, StdAtomic::memory_order_relaxed ); + } + ////////////////////////////////////////////////////////////////////////// + void SpinLock::unlock() + { + size_t me = Detail::get_thread_cookie(); + + if( m_owner.load( StdAtomic::memory_order_relaxed ) != me ) + { + MENGINE_ASSERTION( false, "SpinLock::unlock invalid owner thread id" ); + + return; + } + + size_t lock_count = m_lock.fetch_sub( 1, StdAtomic::memory_order_relaxed ); + + MENGINE_ASSERTION( lock_count > 0, "SpinLock::unlock invalid lock count" ); + + if( lock_count == 1 ) + { + m_owner.store( 0, StdAtomic::memory_order_release ); + } + } + ////////////////////////////////////////////////////////////////////////// +} \ No newline at end of file diff --git a/src/Kernel/Futex.h b/src/Kernel/SpinLock.h similarity index 53% rename from src/Kernel/Futex.h rename to src/Kernel/SpinLock.h index 634fff2127..75194b9f65 100644 --- a/src/Kernel/Futex.h +++ b/src/Kernel/SpinLock.h @@ -5,18 +5,18 @@ namespace Mengine { - class Futex + class SpinLock { public: - Futex(); - ~Futex(); + SpinLock(); + ~SpinLock(); public: void lock(); void unlock(); protected: - Atomic m_owner; - AtomicInt32 m_lock; + MENGINE_ALIGNAS( 64 ) Atomic m_owner; + MENGINE_ALIGNAS( 64 ) AtomicInt32 m_lock; }; } \ No newline at end of file diff --git a/src/Kernel/FutexScope.cpp b/src/Kernel/SpinLockScope.cpp similarity index 58% rename from src/Kernel/FutexScope.cpp rename to src/Kernel/SpinLockScope.cpp index 2c905d5405..d779ca80ab 100644 --- a/src/Kernel/FutexScope.cpp +++ b/src/Kernel/SpinLockScope.cpp @@ -1,17 +1,17 @@ -#include "FutexScope.h" +#include "SpinLockScope.h" namespace Mengine { ////////////////////////////////////////////////////////////////////////// - FutexScope::FutexScope( Futex & _futex ) - : m_futex( _futex ) + SpinLockScope::SpinLockScope( SpinLock & _futex ) + : m_spinlock( _futex ) { - m_futex.lock(); + m_spinlock.lock(); } ////////////////////////////////////////////////////////////////////////// - FutexScope::~FutexScope() + SpinLockScope::~SpinLockScope() { - m_futex.unlock(); + m_spinlock.unlock(); } ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Kernel/SpinLockScope.h b/src/Kernel/SpinLockScope.h new file mode 100644 index 0000000000..b7741e1751 --- /dev/null +++ b/src/Kernel/SpinLockScope.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Kernel/SpinLock.h" + +namespace Mengine +{ + class SpinLockScope + { + public: + SpinLockScope( SpinLock & _futex ); + ~SpinLockScope(); + + protected: + SpinLock & m_spinlock; + }; +} + +#define MENGINE_SPINLOCK_SCOPE_I( SpinLock, Index ) SpinLockScope MENGINE_PP_CONCATENATE(__spinlock_scope_, Index)( SpinLock ) +#define MENGINE_SPINLOCK_SCOPE( SpinLock ) MENGINE_SPINLOCK_SCOPE_I( SpinLock, MENGINE_CODE_COUNTER ) \ No newline at end of file diff --git a/src/Kernel/ValueFollower.h b/src/Kernel/ValueFollower.h index fd98595c1a..142bf0698b 100644 --- a/src/Kernel/ValueFollower.h +++ b/src/Kernel/ValueFollower.h @@ -13,7 +13,6 @@ namespace Mengine ValueFollower() : m_value( T() ) , m_follow( T() ) - , m_eof( false ) { } @@ -55,8 +54,6 @@ namespace Mengine void overtake() { m_value = m_follow; - - m_eof = true; } void step( const T & _value ) @@ -78,16 +75,9 @@ namespace Mengine bool update( const UpdateContext * _context, float * const _used ) { - if( m_eof == true ) - { - *_used = 0.f; - - return true; - } + bool process = this->_update( _context, _used ); - bool successful = this->_update( _context, _used ); - - return successful; + return process; } protected: @@ -96,7 +86,5 @@ namespace Mengine protected: T m_value; T m_follow; - - bool m_eof; }; } diff --git a/src/Kernel/ValueFollowerAcceleration.h b/src/Kernel/ValueFollowerAcceleration.h index 4c6ac6938e..e0e844c314 100644 --- a/src/Kernel/ValueFollowerAcceleration.h +++ b/src/Kernel/ValueFollowerAcceleration.h @@ -56,35 +56,27 @@ namespace Mengine float value_length = this->getLength(); - if( mt::equal_f_z( value_length ) == true ) + if( mt::equal_f_f( value_length, m_minimalDistance ) == true ) { this->overtake(); - return true; + return false; } + T offset = this->getDistance(); + float step = m_speed * _context->time; - if( step >= value_length ) - { - this->overtake(); + T add = (step + m_minimalDistance >= value_length) ? offset * (1.f - m_minimalDistance / value_length) : offset * (step / value_length); - return true; - } - else if( step + m_minimalDistance >= value_length ) + if( mt::sqrlength_f( add ) == 0.f ) { - this->overtake(); - - return true; + return false; } - T offset = this->getDistance(); - - T add = offset * (step / value_length); - this->step( add ); - return false; + return true; } protected: diff --git a/src/Kernel/ValueFollowerLinear.h b/src/Kernel/ValueFollowerLinear.h index 8c9c9c0562..a6e5e6f75b 100644 --- a/src/Kernel/ValueFollowerLinear.h +++ b/src/Kernel/ValueFollowerLinear.h @@ -43,35 +43,27 @@ namespace Mengine float value_length = this->getLength(); - if( mt::equal_f_z( value_length ) == true ) + if( mt::equal_f_f( value_length, m_minimalDistance ) == true ) { this->overtake(); - return true; + return false; } + T offset = this->getDistance(); + float step = m_speed * _context->time; - if( step >= value_length ) - { - this->overtake(); + T add = (step + m_minimalDistance >= value_length) ? offset * (1.f - m_minimalDistance / value_length) : offset * (step / value_length); - return true; - } - else if( step + m_minimalDistance >= value_length ) + if( mt::sqrlength_f( add ) == 0.f ) { - this->overtake(); - - return true; + return false; } - T offset = this->getDistance(); - - T add = offset * (step / value_length); - this->step( add ); - return false; + return true; } protected: diff --git a/src/Services/ProviderService/ServiceProvider.cpp b/src/Services/ProviderService/ServiceProvider.cpp index 9e5ff11d91..b82c53ca16 100644 --- a/src/Services/ProviderService/ServiceProvider.cpp +++ b/src/Services/ProviderService/ServiceProvider.cpp @@ -5,7 +5,7 @@ #include "Kernel/ConstStringHelper.h" #include "Kernel/Assertion.h" #include "Kernel/AssertionMemoryPanic.h" -#include "Kernel/FutexScope.h" +#include "Kernel/SpinLockScope.h" #include "Config/StdString.h" #include "Config/StdAlgorithm.h" @@ -66,7 +66,7 @@ namespace Mengine , MENGINE_DOCUMENT_STR( _doc ) ); - MENGINE_FUTEX_SCOPE( m_futexServices ); + MENGINE_SPINLOCK_SCOPE( m_futexServices ); ServiceInterfacePtr service = this->generateService_( _generator, _doc ); @@ -344,7 +344,7 @@ namespace Mengine , MENGINE_SERVICE_PROVIDER_NAME_SIZE ); - MENGINE_FUTEX_SCOPE( m_futexDependencies ); + MENGINE_SPINLOCK_SCOPE( m_futexDependencies ); uint32_t id = m_dependenciesCount++; @@ -363,7 +363,7 @@ namespace Mengine , MENGINE_SERVICE_PROVIDER_NAME_SIZE ); - MENGINE_FUTEX_SCOPE( m_futexWaits ); + MENGINE_SPINLOCK_SCOPE( m_futexWaits ); for( uint32_t index = 0; index != m_servicesCount; ++index ) { @@ -407,7 +407,7 @@ namespace Mengine , MENGINE_SERVICE_PROVIDER_NAME_SIZE ); - MENGINE_FUTEX_SCOPE( m_futexLeaves ); + MENGINE_SPINLOCK_SCOPE( m_futexLeaves ); uint32_t id = m_leaveCount++; @@ -471,7 +471,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void ServiceProvider::removeDependency_( const ServiceInterfacePtr & _service ) { - MENGINE_FUTEX_SCOPE( m_futexDependencies ); + MENGINE_SPINLOCK_SCOPE( m_futexDependencies ); const Char * name = _service->getServiceId(); @@ -502,7 +502,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool ServiceProvider::checkWaits_( const ServiceInterfacePtr & _service ) { - MENGINE_FUTEX_SCOPE( m_futexWaits ); + MENGINE_SPINLOCK_SCOPE( m_futexWaits ); const Char * name = _service->getServiceId(); @@ -602,7 +602,7 @@ namespace Mengine ); #endif - MENGINE_FUTEX_SCOPE( m_futexServices ); + MENGINE_SPINLOCK_SCOPE( m_futexServices ); for( uint32_t index = 0; index != m_servicesCount; ++index ) { @@ -641,7 +641,7 @@ namespace Mengine ); #endif - MENGINE_FUTEX_SCOPE( m_futexServices ); + MENGINE_SPINLOCK_SCOPE( m_futexServices ); for( uint32_t index = 0; index != m_servicesCount; ++index ) { @@ -680,7 +680,7 @@ namespace Mengine ); #endif - MENGINE_FUTEX_SCOPE( m_futexServices ); + MENGINE_SPINLOCK_SCOPE( m_futexServices ); for( uint32_t index = 0; index != m_servicesCount; ++index ) { diff --git a/src/Services/ProviderService/ServiceProvider.h b/src/Services/ProviderService/ServiceProvider.h index 9a0d766a60..6706234d71 100644 --- a/src/Services/ProviderService/ServiceProvider.h +++ b/src/Services/ProviderService/ServiceProvider.h @@ -3,7 +3,7 @@ #include "Interface/ServiceProviderInterface.h" #include "Kernel/StaticString.h" -#include "Kernel/Futex.h" +#include "Kernel/SpinLock.h" #ifndef MENGINE_SERVICE_PROVIDER_MAX_REQUIRED #define MENGINE_SERVICE_PROVIDER_MAX_REQUIRED 16 @@ -119,10 +119,10 @@ namespace Mengine uint32_t m_waitsCount; - Futex m_futexServices; - Futex m_futexDependencies; - Futex m_futexLeaves; - Futex m_futexWaits; + SpinLock m_futexServices; + SpinLock m_futexDependencies; + SpinLock m_futexLeaves; + SpinLock m_futexWaits; #if defined(MENGINE_DEBUG) const Char * m_initializeServiceName; From 097403c95cc8c83339e785ebb69b1dac1c9543c7 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 20 Oct 2025 19:33:59 +0300 Subject: [PATCH 083/169] add STATISTIC_HTTP_RESPONSE_COUNT improve Win32HttpNetwork revert RandomizerInterface::setSeed --- .../java/org/Mengine/Base/MengineNetwork.java | 50 +++++--- src/Bootstrapper/Bootstrapper.cpp | 18 +-- .../PythonFramework/EngineScriptEmbedding.cpp | 3 +- src/Interface/RandomizerInterface.h | 3 + src/Interface/StatisticInterface.h | 1 + src/Kernel/MT19937Randomizer.cpp | 5 + src/Kernel/MT19937Randomizer.h | 3 + .../Win32HttpSystem/Win32HttpNetwork.cpp | 112 +++++++++++------- 8 files changed, 126 insertions(+), 69 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetwork.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetwork.java index d8599f2e6f..12e547130a 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetwork.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNetwork.java @@ -53,6 +53,9 @@ protected static HttpURLConnection openConnection(@NonNull MengineParamHttpReque HttpURLConnection connection = (HttpURLConnection)httpUrl.openConnection(); + connection.setUseCaches(false); + connection.setDoInput(true); + connection.setInstanceFollowRedirects(true); connection.setRequestMethod(method); connection.setDoOutput(output); @@ -218,19 +221,20 @@ protected static MengineParamHttpResponse catchException(@NonNull MengineParamHt } catch (final UnknownHostException e) { MengineParamHttpResponse response = new MengineParamHttpResponse(); - response.HTTP_RESPONSE_CODE = HttpURLConnection.HTTP_NOT_FOUND; + response.HTTP_RESPONSE_CODE = HttpURLConnection.HTTP_UNAVAILABLE; response.HTTP_CONTENT_LENGTH = 0; - response.HTTP_CONTENT_DATA = null; + response.HTTP_CONTENT_DATA = new byte[0]; response.HTTP_ERROR_MESSAGE = e.getMessage(); return response; } catch (final Exception e) { - MengineLog.logMessage(TAG, "invalid http request url: %s exception: %s" - , request.HTTP_URL - , e.getMessage() - ); + MengineParamHttpResponse response = new MengineParamHttpResponse(); + response.HTTP_RESPONSE_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR; + response.HTTP_CONTENT_LENGTH = 0; + response.HTTP_CONTENT_DATA = new byte[0]; + response.HTTP_ERROR_MESSAGE = e.getMessage(); - return null; + return response; } } @@ -249,11 +253,14 @@ protected static void setBasicAuthorization(@NonNull HttpURLConnection connectio String userCredentials = login + ":" + password; - String basicAuth = "Basic " + Base64.encodeToString(userCredentials.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); + String basicAuth = "Basic " + Base64.encodeToString(userCredentials.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP); connection.setRequestProperty("Authorization", basicAuth); } protected static void setData(@NonNull HttpURLConnection connection, @NonNull byte[] data) throws IOException { + connection.setRequestProperty("Content-Type", "application/json"); + connection.setFixedLengthStreamingMode(data.length); + OutputStream output = connection.getOutputStream(); output.write(data); @@ -287,6 +294,7 @@ protected static void setMultipartFormData(@NonNull HttpURLConnection connection String boundary = MengineUtils.getSecureRandomHexString(32); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); + connection.setChunkedStreamingMode(0); OutputStream output = connection.getOutputStream(); @@ -296,15 +304,24 @@ protected static void setMultipartFormData(@NonNull HttpURLConnection connection String key = entry.getKey(); String value = entry.getValue(); - writer.append("--").append(boundary).append("\r\n"); - writer.append("Content-Disposition: form-data; name=\"").append(key).append("\"").append("\r\n"); - writer.append("Content-Type: text/plain; charset=UTF-8").append("\r\n"); + writer.append("--"); + writer.append(boundary); + writer.append("\r\n"); + writer.append("Content-Disposition: form-data; name=\""); + writer.append(key); + writer.append("\""); + writer.append("\r\n"); + writer.append("Content-Type: text/plain; charset=UTF-8"); + writer.append("\r\n"); + writer.append("\r\n"); + writer.append(value); writer.append("\r\n"); - writer.append(value).append("\r\n"); - writer.flush(); } - writer.append("--").append(boundary).append("--").append("\r\n"); + writer.append("--"); + writer.append(boundary); + writer.append("--"); + writer.append("\r\n"); writer.flush(); } @@ -344,6 +361,7 @@ protected static void getResponseContentData(@NonNull HttpURLConnection connecti if (length == 0) { response.HTTP_CONTENT_LENGTH = 0; + response.HTTP_CONTENT_DATA = new byte[0]; } else if (length == -1) { byte [] data = MengineUtils.inputStreamToByteArray(is); @@ -362,6 +380,10 @@ protected static void getResponseContentData(@NonNull HttpURLConnection connecti protected static void getResponseErrorMessage(@NonNull HttpURLConnection connection, @NonNull MengineParamHttpResponse response) throws IOException { InputStream is = connection.getErrorStream(); + if (is == null) { + return; + } + String HTTP_ERROR_MESSAGE = MengineUtils.inputStreamToString(is); if (HTTP_ERROR_MESSAGE.isEmpty() == false) { diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index 2cddb45c32..33d1721d40 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -901,31 +901,31 @@ namespace Mengine LOGGER_INFO( "bootstrapper", "register base generator..." ); if( PROTOTYPE_SERVICE() - ->addPrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "EntityEventable" ), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) + ->addPrototype( ConstString::none(), EntityEventable::getFactorableType(), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) { return false; } if( PROTOTYPE_SERVICE() - ->addPrototype( STRINGIZE_STRING_LOCAL( "Randomizer" ), STRINGIZE_STRING_LOCAL( "MT19937Randomizer" ), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) + ->addPrototype( STRINGIZE_STRING_LOCAL( "Randomizer" ), MT19937Randomizer::getFactorableType(), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) { return false; } if( PROTOTYPE_SERVICE() - ->addPrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "MixerMultiplicative" ), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) + ->addPrototype( ConstString::none(), MixerMultiplicative::getFactorableType(), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) { return false; } if( PROTOTYPE_SERVICE() - ->addPrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "MixerAveraging" ), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) + ->addPrototype( ConstString::none(), MixerAveraging::getFactorableType(), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) { return false; } if( PROTOTYPE_SERVICE() - ->addPrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "MixerBoolean" ), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) + ->addPrototype( ConstString::none(), MixerBoolean::getFactorableType(), Helper::makeDefaultPrototypeGenerator( MENGINE_DOCUMENT_FACTORABLE ) ) == false ) { return false; } @@ -938,19 +938,19 @@ namespace Mengine LOGGER_INFO( "bootstrapper", "unregister base generator..." ); PROTOTYPE_SERVICE() - ->removePrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "EntityEventable" ), nullptr ); + ->removePrototype( ConstString::none(), EntityEventable::getFactorableType(), nullptr ); PROTOTYPE_SERVICE() ->removePrototype( STRINGIZE_STRING_LOCAL( "Randomizer" ), MT19937Randomizer::getFactorableType(), nullptr ); PROTOTYPE_SERVICE() - ->removePrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "MixerMultiplicative" ), nullptr ); + ->removePrototype( ConstString::none(), MixerMultiplicative::getFactorableType(), nullptr ); PROTOTYPE_SERVICE() - ->removePrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "MixerAveraging" ), nullptr ); + ->removePrototype( ConstString::none(), MixerAveraging::getFactorableType(), nullptr ); PROTOTYPE_SERVICE() - ->removePrototype( ConstString::none(), STRINGIZE_STRING_LOCAL( "MixerBoolean" ), nullptr ); + ->removePrototype( ConstString::none(), MixerBoolean::getFactorableType(), nullptr ); } ////////////////////////////////////////////////////////////////////////// #define MENGINE_ADD_FRAMEWORK( Name, Info, Doc )\ diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index 780e61b246..5cc4225f75 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -4756,7 +4756,8 @@ namespace Mengine return false; } - pybind::interface_>( _kernel, "Randomizer" ) + pybind::interface_>( _kernel, "RandomizerInterface" ) + .def( "setSeed", &RandomizerInterface::setSeed ) .def( "getRandom", &RandomizerInterface::getRandom32 ) .def( "getRandomRange", &RandomizerInterface::getRandomRange32 ) .def( "getRandomf", &RandomizerInterface::getRandomf ) diff --git a/src/Interface/RandomizerInterface.h b/src/Interface/RandomizerInterface.h index 9c0539b175..3c26309adc 100644 --- a/src/Interface/RandomizerInterface.h +++ b/src/Interface/RandomizerInterface.h @@ -10,6 +10,9 @@ namespace Mengine class RandomizerInterface : public ServantInterface { + public: + virtual void setSeed( uint64_t _seed ) = 0; + public: virtual uint32_t getRandom32( uint32_t _max ) const = 0; virtual uint32_t getRandomRange32( uint32_t _min, uint32_t _max ) const = 0; diff --git a/src/Interface/StatisticInterface.h b/src/Interface/StatisticInterface.h index c0df45bc61..1205a25d43 100644 --- a/src/Interface/StatisticInterface.h +++ b/src/Interface/StatisticInterface.h @@ -46,6 +46,7 @@ namespace Mengine MENGINE_STATISTIC_DECLARE( STATISTIC_FILE_READ_BYTES, true ); MENGINE_STATISTIC_DECLARE( STATISTIC_FILE_WRITE_BYTES, true ); MENGINE_STATISTIC_DECLARE( STATISTIC_HTTP_REQUEST_COUNT, true ); + MENGINE_STATISTIC_DECLARE( STATISTIC_HTTP_RESPONSE_COUNT, true ); MENGINE_STATISTIC_DECLARE( STATISTIC_CURRENT_SCENE_NAME, true ); MENGINE_STATISTIC_DECLARE( STATISTIC_RENDER_FRAME_COUNT, true ); MENGINE_STATISTIC_DECLARE( STATISTIC_RENDER_PERFRAME_DRAWINDEXPRIMITIVES, true ); diff --git a/src/Kernel/MT19937Randomizer.cpp b/src/Kernel/MT19937Randomizer.cpp index be45d79d99..27b5ac3a6c 100644 --- a/src/Kernel/MT19937Randomizer.cpp +++ b/src/Kernel/MT19937Randomizer.cpp @@ -31,6 +31,11 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// + void MT19937Randomizer::setSeed( uint64_t _seed ) + { + m_engineRandomize.seed( _seed ); + } + ////////////////////////////////////////////////////////////////////////// uint32_t MT19937Randomizer::getRandom32( uint32_t _max ) const { if( _max < 2 ) diff --git a/src/Kernel/MT19937Randomizer.h b/src/Kernel/MT19937Randomizer.h index 8635df8309..970b6574d7 100644 --- a/src/Kernel/MT19937Randomizer.h +++ b/src/Kernel/MT19937Randomizer.h @@ -16,6 +16,9 @@ namespace Mengine MT19937Randomizer( uint64_t _seed ); ~MT19937Randomizer() override; + protected: + void setSeed( uint64_t _seed ) override; + protected: uint32_t getRandom32( uint32_t _max ) const override; uint32_t getRandomRange32( uint32_t _min, uint32_t _max ) const override; diff --git a/src/Systems/Win32HttpSystem/Win32HttpNetwork.cpp b/src/Systems/Win32HttpSystem/Win32HttpNetwork.cpp index 10832efa7b..1f2e1e7d14 100644 --- a/src/Systems/Win32HttpSystem/Win32HttpNetwork.cpp +++ b/src/Systems/Win32HttpSystem/Win32HttpNetwork.cpp @@ -11,6 +11,7 @@ #include "Kernel/Stringalized.h" #include "Kernel/StatisticHelper.h" +#include "Config/StdString.h" #include "Config/Version.h" namespace Mengine @@ -116,8 +117,8 @@ namespace Mengine Char userName[1024 + 1] = {'\0'}; Char scheme[1024 + 1] = {'\0'}; Char hostName[1024 + 1] = {'\0'}; - Char urlPath[1024 + 1] = {'\0'}; - Char extraInfo[1024 + 1] = {'\0'}; + Char urlPath[4096 + 1] = {'\0'}; + Char extraInfo[4096 + 1] = {'\0'}; urlComponents.lpszScheme = scheme; urlComponents.dwSchemeLength = MENGINE_STATIC_STRING_LENGTH( scheme ); @@ -180,9 +181,28 @@ namespace Mengine dwRequestFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID; } + ArrayString<4096> pathWithQuery; + pathWithQuery.append( urlComponents.lpszUrlPath ); + + if( urlComponents.lpszExtraInfo != NULL ) + { + const Char * hash = StdString::strchr( urlComponents.lpszExtraInfo, '#' ); + + if( hash != nullptr ) + { + pathWithQuery.append( urlComponents.lpszExtraInfo, (size_t)(hash - urlComponents.lpszExtraInfo) ); + } + else + { + pathWithQuery.append( urlComponents.lpszExtraInfo ); + } + } + + const Char * pathWithQuery_str = pathWithQuery.c_str(); + HINTERNET hRequest = ::HttpOpenRequestA( hConnect , _verb - , urlComponents.lpszUrlPath + , pathWithQuery_str , NULL , NULL , NULL @@ -266,6 +286,31 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// + static bool sendRequestData( HINTERNET _hRequest, const Data & _data ) + { + const Data::value_type * data_buffer = _data.data(); + Data::size_type data_size = _data.size(); + + INTERNET_BUFFERSA ib = {0}; + ib.dwStructSize = sizeof( ib ); + ib.dwBufferTotal = (DWORD)data_size; + + if( ::HttpSendRequestExA( _hRequest, &ib, NULL, 0, 0 ) == FALSE ) + { + return false; + } + + DWORD dwNumberOfBytesWritten = 0; + DWORD dwNumberOfBytesToWrite = (DWORD)data_size; + + if( ::InternetWriteFile( _hRequest, (LPCVOID)data_buffer, dwNumberOfBytesToWrite, &dwNumberOfBytesWritten ) == FALSE ) + { + return false; + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// static bool getResponseStatusCode( HINTERNET _hRequest, const HttpResponseInterfacePtr & _response ) { DWORD statusCode = 0; @@ -339,6 +384,8 @@ namespace Mengine return false; } + STATISTIC_INC_INTEGER( STATISTIC_HTTP_RESPONSE_COUNT ); + LOGGER_HTTP_INFO( "response [%u] code: %u data: %zu" , _response->getRequest()->getRequestId() , _response->getCode() @@ -412,12 +459,12 @@ namespace Mengine CRYPTOGRAPHY_SYSTEM() ->generateRandomHexadecimal( 16, boundary, false ); - ArrayString<1024> header; + ArrayString<4096> header; header.append( "Content-Type: multipart/form-data; boundary=" ); header.append( boundary ); const Char * header_str = header.c_str(); - ArrayString<1024>::size_type header_size = header.size(); + ArrayString<4096>::size_type header_size = header.size(); if( ::HttpAddRequestHeadersA( hRequest, header_str, header_size, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE ) == FALSE ) { @@ -451,7 +498,9 @@ namespace Mengine body.append( pair.key ); body.append( "\"\r\n" ); - body.append( "Content-Type: text/plain; charset=UTF-8\r\n" ); + body.append( "Content-Type: text/plain; charset=UTF-8" ); + body.append( "\r\n" ); + body.append( "\r\n" ); body.append( pair.value ); body.append( "\r\n" ); } @@ -476,6 +525,16 @@ namespace Mengine return false; } + if( dwNumberOfBytesWritten != dwNumberOfBytesToWrite ) + { + Detail::errorRequest( _response ); + + ::InternetCloseHandle( hRequest ); + ::InternetCloseHandle( hConnect ); + + return false; + } + if( Detail::makeResponseData( hRequest, _response, true ) == false ) { Detail::errorRequest( _response ); @@ -508,44 +567,7 @@ namespace Mengine return false; } - const Data::value_type * data_buffer = _data.data(); - Data::size_type data_size = _data.size(); - - ArrayString<1024> header; - header.append( "Content-Length: " ); - - Char strContentLength[32 + 1] = {'\0'}; - Helper::stringalized( data_size, strContentLength, 32 ); - - header.append( strContentLength ); - - const Char * header_str = header.c_str(); - ArrayString<1024>::size_type header_size = header.size(); - - if( ::HttpAddRequestHeadersA( hRequest, header_str, header_size, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE ) == FALSE ) - { - Detail::errorRequest( _response ); - - ::InternetCloseHandle( hRequest ); - ::InternetCloseHandle( hConnect ); - - return false; - } - - if( Detail::sendRequest( hRequest ) == false ) - { - Detail::errorRequest( _response ); - - ::InternetCloseHandle( hRequest ); - ::InternetCloseHandle( hConnect ); - - return false; - } - - DWORD dwNumberOfBytesWritten = 0; - DWORD dwNumberOfBytesToWrite = (DWORD)data_size; - - if( ::InternetWriteFile( hRequest, (LPCVOID)data_buffer, dwNumberOfBytesToWrite, &dwNumberOfBytesWritten ) == FALSE ) + if( Detail::sendRequestData( hRequest, _data ) == false ) { Detail::errorRequest( _response ); @@ -683,7 +705,7 @@ namespace Mengine CHAR bstrEncoded[1024 + 1] = {'\0'}; DWORD dwSize = 1024; - ::CryptBinaryToStringA( (const BYTE *)credentials_str, credentials_size, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, bstrEncoded, &dwSize ); + ::CryptBinaryToStringA( reinterpret_cast(credentials_str), credentials_size, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, bstrEncoded, &dwSize ); ArrayString<1024> header; header.append( "Authorization: Basic " ); From 75cb602f690c0d9199d6230c7095d2522dc15ac0 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 20 Oct 2025 21:46:53 +0300 Subject: [PATCH 084/169] fix build unix android --- build/unix_android/build_depends_android.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/unix_android/build_depends_android.bash b/build/unix_android/build_depends_android.bash index 590c1ff596..a5c672ffa4 100644 --- a/build/unix_android/build_depends_android.bash +++ b/build/unix_android/build_depends_android.bash @@ -4,10 +4,10 @@ BUILD_TYPE=$1 echo Starting dependencies build $BUILD_TYPE configuration... -ANDROID_NDK_VERSION=27.2.12479018 -ANDROID_CMAKE_VERSION=3.30.5 +ANDROID_NDK_VERSION=29.0.14206865 +ANDROID_CMAKE_VERSION=3.31.6 -ANDROID_PLATFORM_VERSION=21 +ANDROID_PLATFORM_VERSION=23 ANDROID_PLATFORM=android-$ANDROID_PLATFORM_VERSION ANDROID_SDK=/opt/android/sdk ANDROID_NDK=$ANDROID_SDK/ndk/$ANDROID_NDK_VERSION From 3772235106a68bf7d3b548586ba1148e6c83847a Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 20 Oct 2025 22:34:55 +0300 Subject: [PATCH 085/169] fix ci android res --- gradle/ci/res/values/mengine-strings.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 gradle/ci/res/values/mengine-strings.xml diff --git a/gradle/ci/res/values/mengine-strings.xml b/gradle/ci/res/values/mengine-strings.xml new file mode 100644 index 0000000000..5dbf776d86 --- /dev/null +++ b/gradle/ci/res/values/mengine-strings.xml @@ -0,0 +1,14 @@ + + + Account Deleted + Account data has been deleted. The application will now close. + Tired of or lost interest in the game + Want to start over from scratch + Too many ads + Support didn’t solve my problem + Other reason + Choose a reason + Delete Account + Click \'YES\' will delete all account data. All game progress, virtual goods, and currency will be permanently removed and unrecoverable. + \ No newline at end of file From 99b0a5b7001b6df8f12c6f549b09ff18a235023c Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 21 Oct 2025 21:16:04 +0300 Subject: [PATCH 086/169] fix ci android res --- gradle/ci/res/drawable/ic_launchscreen.png | Bin 0 -> 52485 bytes gradle/ci/res/mipmap/ic_launcher.png | Bin 0 -> 3310 bytes gradle/ci/res/mipmap/ic_launcher_round.png | Bin 0 -> 3310 bytes gradle/ci/res/values/app-string.xml | 4 ++++ gradle/ci/res/values/{strings.xml => app.xml} | 5 ++--- gradle/ci/res/xml/network_security_config.xml | 3 +++ 6 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 gradle/ci/res/drawable/ic_launchscreen.png create mode 100644 gradle/ci/res/mipmap/ic_launcher.png create mode 100644 gradle/ci/res/mipmap/ic_launcher_round.png create mode 100644 gradle/ci/res/values/app-string.xml rename gradle/ci/res/values/{strings.xml => app.xml} (84%) create mode 100644 gradle/ci/res/xml/network_security_config.xml diff --git a/gradle/ci/res/drawable/ic_launchscreen.png b/gradle/ci/res/drawable/ic_launchscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..80530c81335b6aedaf47a2d18b332091adbf5246 GIT binary patch literal 52485 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 literal 0 HcmV?d00001 diff --git a/gradle/ci/res/mipmap/ic_launcher.png b/gradle/ci/res/mipmap/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..309da340ac999f474d76e7f84d0156b09a716e99 GIT binary patch literal 3310 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 literal 0 HcmV?d00001 diff --git a/gradle/ci/res/mipmap/ic_launcher_round.png b/gradle/ci/res/mipmap/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..309da340ac999f474d76e7f84d0156b09a716e99 GIT binary patch literal 3310 zcmVyvAZ+> zuiwljyEA)bl3lZ{?&vVPvortW_y2vr@0bZddP{HV?aRI4m#CMo6r^d^rU6e+KfQg0 z`R5sTx8l#v`vw8_Mj-x=heCwL!T7|N2y=WS58$QRxAbkV%TyqvrV1b}t6M*Cd0u54 zJi%om%c1!kO1%NHdTim3hdXqD&0`U%0*Fu<%G38Ch88TiW9T!W$Rb58O4T@11`sIf zn3xt$R;u$g!ZkKk!%UfpF*8O-#RsFDK)fnt>zLHWrpzr8gQhRVe%HD)>V12)`ePJv z&EyAriGkP60>$+Mo_MCo7HkD1#60Xf>9|@ju1;2ecrm=qu6%`m+T-8E0mbu0-%0!F z@Wzw>b6!joKQav5S#N_-2AMV@^;O_&dP=Te{GkcV)W?cRb^Q=fxgLbbi!h~lBWt;i zTDTjZ%jk{CBJyxq@Za&(HMmqmr#wS1LcJE?y?QD00@&Nc6XUX>$|0m@P z5|e*c1R0%~IqH>>vySG!<1SbmykNA9%F?KmpMk$|cA_9DiGlObPzL880dSyokCf~< z4&(GGFqb{$4WiG4^>ldCi4F%yDSmh;csd!HQ)nBQ)igRP;-xUc29KCyXrAaZo|2ox7E z$?fKMu7{HT$86Udebk)q4CRL}2aE*hBhdU>hl;d%%>&(KR!#-$Pa&Aerr}!<)_ivr zlolQZ(v%=}$n4own+rF*b|W0G&tfLYD6T3NIH7BZ51B%P<=-lY8H202zYvR1)nU`2 ze3-KA7E6A>_e!k>8!t@IH!k_SLsJcH({E0r=6jMyZOJVOG$~AQe8%n%9KAjl4DWds zes$AkrmQrX78c;Nnl&0rK$?Jg#XDg}VGVe_u0S8nJ8@r{)$Gg_A_I9mCf)zon1P-@byaQ)#VZkZtLBXd5;%fytM)fx-_u(i)LX91B9Y2zcN|R z%9+tl@+1aOX6`WL-0H{1BE>IP*y-sK3T zTG&eNhKQuN?r~o+t=;o%_l>@yk^vlqT^Dtf)+!iTb`0s!?4l#^(@DEcJ&NVn4Y9v# z)Tc0Kd=-PE+WVmxtO*CpU{UW8S9Ul++o>F`{M1)nA(O(O#=c``QfAj}Jn+*%s506MS3_U9BegT#mdZg$9GV(6?pG7xpg{uorMd*&o z?JeFg91fiBVzwPq`|M>~j!xC7q`2pjD|0zzWN+05OrDuE6C=QWftrgoz$0g_fIlm| z>c6fmf;T?y4<46h%PqZr6>c9=&GF4H)2s}0`_Z^6`2Ofm!D|7>xW~BnZ@c@!a~p>R zz$ORaM0_{wU35mFj7VZlnq=$_1L_-YY-CHSiQ{L4M^=r8;g_9-t1dgk>``ob^f*Vz zn`?T&MUIf4Wv^w102FG^&E~i3L^qiG@A06S{ZX8ZjzU6?F_zq6nkAftOBmB(gp!Q- zEhxO=bq!f?-^z(_w#nUW9swqjsV5SCcUuL#HhTkf@%UL|tfd`-3!JXZSvd)6FJ^g#a@Z z25-UI(Xf#-b)yXejI5er8*^`THYJB{K6zz9bV*pYZ3z5fTOoMZi`gP=HY;7)6HX6D z-miZ=5MJ6`#2LGcKSXNFdZ9>~NZSfvm>7u+w{Mh+=B*hA6*YO_4g<-S46|q3cC0%* zy6S4sF`jBzf5W7%t#C?5Y)|FLmSI~8Xsk!)nlj-2e@=vx^%RBdyxwG=dbBjd=@`j*xmmOgNNoG!M2)h^EO71kJP#gOJ=PRgw3!K+AkJGe#?&mK z%1Bob;np#B+7bQ1q?!Og;SW^k2n$3*FlZC*8&c7PVxVw4(b0MERF#YlQQuRD-HU9`L$7mu!Htq@L@CBb6 z?pbjSJTPIe`O8aNhQOJ|4AZn?Pd~h9hLL6Lmam$3QO|V?pFG|U$yVDSBEfAxpHzMI zZ=!I`VM4mllT~7$dHt80m6kvC=q~!6Ctp+Fb6l6qalnW{$zyq!5X{WtiAgje(=@U^TtP zItif?tUFi$*S~rrEU7FqYVPI=J9p6NNO}y0>ilIX_hIx^ez2D%plm4vD8+iW{O=?( z$M(P7G2!0sl+pPO9z9LURVgcVhN!N-XxT4q3Ph;FP18Rd?N zy-&hZ<)h*GO~av4D$E=i<@H9hI5txBy6R1e^6FlKwTal9r|5R{=NByo)$_2uen624 zwkE*s@`FZ7t8c|P|D6~lGOLj-b!>_?A>)MZds&>Vouh4ECOgK&keCW$lH%q^+!qAF7!8Vs(?`6Ts!btzx8{9F`bDA)X?54p2S!R1*@sN{xc{}F657(wz3 z_`Q#zzwuptGd?$l+6ZjgRVY8}A)|^uI2X&(4iFZhG-v(CiM|O>( zmYhoW|6Q(q=8lw%GgSbA)VBu%OKQbs8`q|4Ayd^c>b@PZ-b^FgpDgef&G*q)4j|C{ zyE%YtwEB09;?#B8k=3Itgi1lqKw3oLHx3mi{ovMK^{g(dw s{`8inS9(it=`F1k=`BsI|EtOT7w_yDZ|rZbI{*Lx07*qoM6N<$f*RRjJpcdz literal 0 HcmV?d00001 diff --git a/gradle/ci/res/values/app-string.xml b/gradle/ci/res/values/app-string.xml new file mode 100644 index 0000000000..1f434c961c --- /dev/null +++ b/gradle/ci/res/values/app-string.xml @@ -0,0 +1,4 @@ + + + Continuous Integration + \ No newline at end of file diff --git a/gradle/ci/res/values/strings.xml b/gradle/ci/res/values/app.xml similarity index 84% rename from gradle/ci/res/values/strings.xml rename to gradle/ci/res/values/app.xml index a46b41d94f..b548641ccd 100644 --- a/gradle/ci/res/values/strings.xml +++ b/gradle/ci/res/values/app.xml @@ -1,9 +1,8 @@ + - Continuous Integration - https://en.wikipedia.org/wiki/Privacy_policy https://en.wikipedia.org/wiki/Terms_of_service false true - + \ No newline at end of file diff --git a/gradle/ci/res/xml/network_security_config.xml b/gradle/ci/res/xml/network_security_config.xml new file mode 100644 index 0000000000..bd37ab3671 --- /dev/null +++ b/gradle/ci/res/xml/network_security_config.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From 20453498fcf00e82d17eb96a36291c4bc3597e3b Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 23 Oct 2025 00:03:34 +0300 Subject: [PATCH 087/169] fix ios build --- src/Platforms/iOSPlatform/iOSPlatformService.mm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index ac29b3ad4b..75f0e406f1 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -574,14 +574,6 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit } m_sdlInput = sdlInput; - - uint64_t deviceSeed = Helper::generateRandomDeviceSeed(); - - MENGINE_UNUSED( deviceSeed ); - - LOGGER_INFO_PROTECTED( "platform", "Device Seed: %" MENGINE_PRIu64 - , deviceSeed - ); m_analyticsEventProvider = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); From 088eacad7a4e7ac350033ca58acc951ab64d59ae Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 23 Oct 2025 13:52:45 +0300 Subject: [PATCH 088/169] update circleci --- .circleci/config.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 848812cf60..70cf567eab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,16 +1,19 @@ version: 2.1 orbs: - android: circleci/android@2.5.0 + android: circleci/android@3.1.0 jobs: build: executor: name: android/android-machine - tag: 2024.04.1 + tag: 2025.10.1 parallelism: 4 + environment: + JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64 + steps: - checkout @@ -23,8 +26,8 @@ jobs: name: install OpenJDK 17 command: | sudo apt-get update && sudo apt-get install openjdk-17-jdk - sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java - sudo update-alternatives --set javac /usr/lib/jvm/java-17-openjdk-amd64/bin/javac + sudo update-alternatives --set java $JAVA_HOME/bin/java + sudo update-alternatives --set javac $JAVA_HOME/bin/javac java -version - run: @@ -48,7 +51,7 @@ jobs: - run: name: sdkmanager cmake command: | - yes | sdkmanager "cmake;3.31.6" + yes | sdkmanager "platforms;android-36;build-tools;36.1.0;cmake;3.31.6" shell: /bin/bash -e - run: From 4bc280da07f470d187eeb3e5f6b361463588b096 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 23 Oct 2025 13:59:42 +0300 Subject: [PATCH 089/169] wip circleci --- .circleci/config.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 70cf567eab..e7911609dc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,14 +11,9 @@ jobs: parallelism: 4 - environment: - JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64 - steps: - checkout - - android/accept-licenses - - android/install-ndk: version: 29.0.14206865 @@ -26,8 +21,8 @@ jobs: name: install OpenJDK 17 command: | sudo apt-get update && sudo apt-get install openjdk-17-jdk - sudo update-alternatives --set java $JAVA_HOME/bin/java - sudo update-alternatives --set javac $JAVA_HOME/bin/javac + sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java + sudo update-alternatives --set javac /usr/lib/jvm/java-17-openjdk-amd64/bin/javac java -version - run: From b4a4833868b6198b1f841213c104948f8d06f77a Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 23 Oct 2025 13:59:42 +0300 Subject: [PATCH 090/169] wip circleci # Conflicts: # .circleci/config.yml --- .circleci/config.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e7911609dc..d22ff8bd25 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,9 +14,6 @@ jobs: steps: - checkout - - android/install-ndk: - version: 29.0.14206865 - - run: name: install OpenJDK 17 command: | @@ -46,7 +43,7 @@ jobs: - run: name: sdkmanager cmake command: | - yes | sdkmanager "platforms;android-36;build-tools;36.1.0;cmake;3.31.6" + yes | sdkmanager "ndk;29.0.14206865;platforms;android-36;build-tools;36.1.0;cmake;3.31.6" shell: /bin/bash -e - run: From a3057cca1d6998834a743a4bf15e30f7ea5c0ec8 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 23 Oct 2025 13:59:42 +0300 Subject: [PATCH 091/169] wip circleci # Conflicts: # .circleci/config.yml --- .circleci/config.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d22ff8bd25..291ea1bfe7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - android: circleci/android@3.1.0 + android: circleci/android@2.5.0 jobs: build: @@ -14,6 +14,11 @@ jobs: steps: - checkout + - android/accept-licenses + + - android/install-ndk: + version: 29.0.14206865 + - run: name: install OpenJDK 17 command: | From 0ac60a1d1f36b5955a39a7190272c50d1a2f7c73 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 23 Oct 2025 14:43:42 +0300 Subject: [PATCH 092/169] Fix circleci --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 291ea1bfe7..0434cb7409 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,7 +48,10 @@ jobs: - run: name: sdkmanager cmake command: | - yes | sdkmanager "ndk;29.0.14206865;platforms;android-36;build-tools;36.1.0;cmake;3.31.6" + yes | sdkmanager "ndk;29.0.14206865" + yes | sdkmanager "platforms;android-36" + yes | sdkmanager "build-tools;36.1.0" + yes | sdkmanager "cmake;3.31.6" shell: /bin/bash -e - run: From f677135b03331dc3f4ef022b8557941e208d396e Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 31 Oct 2025 17:46:11 +0200 Subject: [PATCH 093/169] fix Hierarchy --- src/Interface/UpdateServiceInterface.h | 4 +- src/Kernel/AssertionObservable.cpp | 7 ++- src/Kernel/BaseUpdation.cpp | 16 +++-- src/Kernel/Hierarchy.cpp | 38 ++++------- src/Kernel/Hierarchy.h | 3 - src/Kernel/Node.cpp | 20 ++++++ src/Kernel/Node.h | 2 + src/Kernel/UpdateMode.h | 1 + src/Services/UpdateService/UpdateService.cpp | 66 ++++++++++++-------- src/Services/UpdateService/UpdateService.h | 26 ++++---- 10 files changed, 108 insertions(+), 75 deletions(-) diff --git a/src/Interface/UpdateServiceInterface.h b/src/Interface/UpdateServiceInterface.h index bdf07d7caf..f8c183ae29 100644 --- a/src/Interface/UpdateServiceInterface.h +++ b/src/Interface/UpdateServiceInterface.h @@ -16,8 +16,8 @@ namespace Mengine SERVICE_DECLARE( "UpdateService" ) public: - virtual void placeUpdatater( const UpdationInterfacePtr & _updation ) = 0; - virtual void removeUpdatater( const UpdationInterfacePtr & _updation ) = 0; + virtual void placeUpdatater( UpdationInterface * _updation ) = 0; + virtual void removeUpdatater( UpdationInterface * _updation ) = 0; }; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Kernel/AssertionObservable.cpp b/src/Kernel/AssertionObservable.cpp index 6c900efd45..97c14db84f 100644 --- a/src/Kernel/AssertionObservable.cpp +++ b/src/Kernel/AssertionObservable.cpp @@ -17,7 +17,12 @@ namespace Mengine bool observer = NOTIFICATION_SERVICE() ->hasObserver( _observer ); - return observer; + if( observer == false ) + { + return false; + } + + return true; } } } diff --git a/src/Kernel/BaseUpdation.cpp b/src/Kernel/BaseUpdation.cpp index bc8f598252..f87c4cee19 100644 --- a/src/Kernel/BaseUpdation.cpp +++ b/src/Kernel/BaseUpdation.cpp @@ -34,8 +34,8 @@ namespace Mengine } ////////////////////////////////////////////////////////////////////////// BaseUpdation::BaseUpdation() - : m_mode( EUM_NODE_BASE ) - , m_deep( 0U ) + : m_mode( EUM_UNKNOWN ) + , m_deep( ~0U ) { } ////////////////////////////////////////////////////////////////////////// @@ -48,16 +48,20 @@ namespace Mengine m_mode = _mode; uint32_t mode_deep = Detail::calcModeDeep( m_mode, _deep ); + m_deep = mode_deep; UPDATE_SERVICE() - ->placeUpdatater( UpdationInterfacePtr::from( this ) ); + ->placeUpdatater( this ); } ////////////////////////////////////////////////////////////////////////// void BaseUpdation::deactivate() { UPDATE_SERVICE() - ->removeUpdatater( UpdationInterfacePtr::from( this ) ); + ->removeUpdatater( this ); + + m_mode = EUM_UNKNOWN; + m_deep = ~0U; } ////////////////////////////////////////////////////////////////////////// void BaseUpdation::replace( uint32_t _deep ) @@ -70,12 +74,12 @@ namespace Mengine } UPDATE_SERVICE() - ->removeUpdatater( UpdationInterfacePtr::from( this ) ); + ->removeUpdatater( this ); m_deep = mode_deep; UPDATE_SERVICE() - ->placeUpdatater( UpdationInterfacePtr::from( this ) ); + ->placeUpdatater( this ); } ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Kernel/Hierarchy.cpp b/src/Kernel/Hierarchy.cpp index 59f5199295..d3fe3e0854 100644 --- a/src/Kernel/Hierarchy.cpp +++ b/src/Kernel/Hierarchy.cpp @@ -5,6 +5,8 @@ #include "Kernel/IntrusivePtrScope.h" #include "Kernel/MixinDebug.h" +#include "Config/StdException.h" + namespace Mengine { ////////////////////////////////////////////////////////////////////////// @@ -17,25 +19,6 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - HashType Hierarchy::getHierarchyHash() const - { - const ConstString & name = static_cast(this)->getName(); - - HashType hash = name.hash(); - - for( Hierarchy * parent = this->getParent(); parent != nullptr; parent = parent->getParent() ) - { - const ConstString & parent_name = static_cast(parent)->getName(); - - HashType parent_hash = parent_name.hash(); - - hash = (hash << 5) | (hash >> (sizeof( HashType ) * 8 - 5)); - hash ^= parent_hash; - } - - return hash; - } - ////////////////////////////////////////////////////////////////////////// void Hierarchy::addChild( const NodePtr & _node ) { MENGINE_ASSERTION_FATAL( _node != nullptr, "node '%s' invalid add child NULL node" @@ -95,9 +78,18 @@ namespace Mengine { IntrusivePtrScope ankh( this ); +#if defined(MENGINE_DEBUG) + if( dynamic_cast(this) == nullptr ) + { + throw StdException::runtime_error( "hierarchy this not node" ); + } +#endif + + Node * self = static_cast(this); + Node * child_parent = _child->getParent(); - if( child_parent == this ) + if( child_parent == self ) { if( _hint != EHierarchyInsert::EHI_BACK ) { @@ -124,13 +116,9 @@ namespace Mengine this->insertChild_( _insert, _child ); - Node * parentNode = static_cast(this); - - _child->setParent_( parentNode, _hint ); + _child->setParent_( self, _hint ); } - const Node * self = static_cast(this); - bool self_freeze = self->isFreeze(); bool child_freeze = _child->isFreeze(); diff --git a/src/Kernel/Hierarchy.h b/src/Kernel/Hierarchy.h index 471d0688f3..0c42838fc2 100644 --- a/src/Kernel/Hierarchy.h +++ b/src/Kernel/Hierarchy.h @@ -35,9 +35,6 @@ namespace Mengine MENGINE_INLINE Node * getParent() const; MENGINE_INLINE bool hasParent() const; - public: - HashType getHierarchyHash() const; - public: void addChild( const NodePtr & _node ); void addChildFront( const NodePtr & _node ); diff --git a/src/Kernel/Node.cpp b/src/Kernel/Node.cpp index c74ce4073e..1fd470e580 100644 --- a/src/Kernel/Node.cpp +++ b/src/Kernel/Node.cpp @@ -463,6 +463,26 @@ namespace Mengine } } } + + ////////////////////////////////////////////////////////////////////////// + HashType Node::getHierarchyHash() const + { + const ConstString & name = this->getName(); + + HashType hash = name.hash(); + + for( Node * parent = this->getParent(); parent != nullptr; parent = parent->getParent() ) + { + const ConstString & parent_name = parent->getName(); + + HashType parent_hash = parent_name.hash(); + + hash = (hash << 5) | (hash >> (sizeof( HashType ) * 8 - 5)); + hash ^= parent_hash; + } + + return hash; + } ////////////////////////////////////////////////////////////////////////// NodePtr Node::findUniqueChild( UniqueId _uniqueIdentity ) const { diff --git a/src/Kernel/Node.h b/src/Kernel/Node.h index 6e132ea3ec..17e66dea39 100644 --- a/src/Kernel/Node.h +++ b/src/Kernel/Node.h @@ -62,6 +62,8 @@ namespace Mengine ~Node() override; public: + HashType getHierarchyHash() const; + NodePtr findUniqueChild( UniqueId _uniqueIdentity ) const; protected: diff --git a/src/Kernel/UpdateMode.h b/src/Kernel/UpdateMode.h index 5f214bcc3a..c4cd496a5d 100644 --- a/src/Kernel/UpdateMode.h +++ b/src/Kernel/UpdateMode.h @@ -6,6 +6,7 @@ namespace Mengine { enum EUpdateMode { + EUM_UNKNOWN, EUM_NODE_BASE, EUM_NODE_AFFECTOR, EUM_SERVICE_BEFORE, diff --git a/src/Services/UpdateService/UpdateService.cpp b/src/Services/UpdateService/UpdateService.cpp index efc28991b6..75adca7ef7 100644 --- a/src/Services/UpdateService/UpdateService.cpp +++ b/src/Services/UpdateService/UpdateService.cpp @@ -16,6 +16,29 @@ SERVICE_FACTORY( UpdateService, Mengine::UpdateService ); ////////////////////////////////////////////////////////////////////////// namespace Mengine { + ////////////////////////////////////////////////////////////////////////// + namespace Detail + { + ////////////////////////////////////////////////////////////////////////// + bool findLeafUpdatater( const LeafUpdatables & _leafs, const UpdationInterface * _updation ) + { + for( const LeafUpdatable & leaf : _leafs ) + { + if( std::find( leaf.indecies.begin(), leaf.indecies.end(), _updation ) != leaf.indecies.end() ) + { + return true; + } + + if( std::find( leaf.indeciesAdd.begin(), leaf.indeciesAdd.end(), _updation ) != leaf.indeciesAdd.end() ) + { + return true; + } + } + + return false; + } + ////////////////////////////////////////////////////////////////////////// + } ////////////////////////////////////////////////////////////////////////// UpdateService::UpdateService() { @@ -52,7 +75,7 @@ namespace Mengine m_afterLeafs.clear(); } ////////////////////////////////////////////////////////////////////////// - UpdateService::LeafUpdatable * UpdateService::getLeafUpdatable( EUpdateMode _mode, uint32_t _deep ) + LeafUpdatable * UpdateService::getLeafUpdatable( EUpdateMode _mode, uint32_t _deep ) { switch( _mode ) { @@ -95,13 +118,16 @@ namespace Mengine return nullptr; } ////////////////////////////////////////////////////////////////////////// - void UpdateService::placeUpdatater( const UpdationInterfacePtr & _updation ) + void UpdateService::placeUpdatater( UpdationInterface * _updation ) { MENGINE_ASSERTION_FATAL( this->findUpdatater_( _updation ) == false, "updation already exist" ); EUpdateMode update_mode = _updation->getUpdationMode(); uint32_t update_deep = _updation->getUpdationDeep(); + MENGINE_ASSERTION_FATAL( update_mode != EUM_UNKNOWN, "updation mode is UNKNOWN" ); + MENGINE_ASSERTION_FATAL( update_deep != ~0U, "updation deep is INVALID" ); + LeafUpdatable * leaf = this->getLeafUpdatable( update_mode, update_deep ); MENGINE_ASSERTION_MEMORY_PANIC( leaf, "unsupport mode '%u' deep '%u'" @@ -112,13 +138,16 @@ namespace Mengine leaf->indeciesAdd.emplace_back( _updation ); } ////////////////////////////////////////////////////////////////////////// - void UpdateService::removeUpdatater( const UpdationInterfacePtr & _updation ) + void UpdateService::removeUpdatater( UpdationInterface * _updation ) { MENGINE_ASSERTION_FATAL( this->findUpdatater_( _updation ) == true, "updation already exist" ); EUpdateMode update_mode = _updation->getUpdationMode(); uint32_t update_deep = _updation->getUpdationDeep(); + MENGINE_ASSERTION_FATAL( update_mode != EUM_UNKNOWN, "updation mode is UNKNOWN" ); + MENGINE_ASSERTION_FATAL( update_deep != ~0U, "updation deep is INVALID" ); + LeafUpdatable * leaf = this->getLeafUpdatable( update_mode, update_deep ); MENGINE_ASSERTION_MEMORY_PANIC( leaf, "unsupport mode '%u' deep '%u'" @@ -143,39 +172,26 @@ namespace Mengine return; } - } - ////////////////////////////////////////////////////////////////////////// - bool UpdateService::findLeafUpdatater_( const LeafUpdatables & _leafs, const UpdationInterfacePtr & _updation ) const - { - for( const LeafUpdatable & leaf : _leafs ) - { - if( std::find( leaf.indecies.begin(), leaf.indecies.end(), _updation ) != leaf.indecies.end() ) - { - return true; - } - - if( std::find( leaf.indeciesAdd.begin(), leaf.indeciesAdd.end(), _updation ) != leaf.indeciesAdd.end() ) - { - return true; - } - } - return false; + MENGINE_ASSERTION_FATAL( false, "updation not found mode '%u' deep '%u'" + , update_mode + , update_deep + ); } ////////////////////////////////////////////////////////////////////////// - bool UpdateService::findUpdatater_( const UpdationInterfacePtr & _updation ) const + bool UpdateService::findUpdatater_( const UpdationInterface * _updation ) const { - if( this->findLeafUpdatater_( m_beforeLeafs, _updation ) == true ) + if( Detail::findLeafUpdatater( m_beforeLeafs, _updation ) == true ) { return true; } - if( this->findLeafUpdatater_( m_leafs, _updation ) == true ) + if( Detail::findLeafUpdatater( m_leafs, _updation ) == true ) { return true; } - if( this->findLeafUpdatater_( m_afterLeafs, _updation ) == true ) + if( Detail::findLeafUpdatater( m_afterLeafs, _updation ) == true ) { return true; } @@ -198,7 +214,7 @@ namespace Mengine leaf_indecies.erase( StdAlgorithm::remove( leaf_indecies.begin(), leaf_indecies.end(), nullptr ), leaf_indecies.end() ); - for( const UpdationInterfacePtr & updation : leaf_indecies ) + for( UpdationInterface * updation : leaf_indecies ) { if( updation == nullptr ) { diff --git a/src/Services/UpdateService/UpdateService.h b/src/Services/UpdateService/UpdateService.h index 1d506a5596..5132b0a9b9 100644 --- a/src/Services/UpdateService/UpdateService.h +++ b/src/Services/UpdateService/UpdateService.h @@ -10,6 +10,16 @@ namespace Mengine { + ////////////////////////////////////////////////////////////////////////// + typedef Vector VectorUpdatableIndecies; + ////////////////////////////////////////////////////////////////////////// + struct LeafUpdatable + { + VectorUpdatableIndecies indecies; + VectorUpdatableIndecies indeciesAdd; + }; + ////////////////////////////////////////////////////////////////////////// + typedef Vector LeafUpdatables; ////////////////////////////////////////////////////////////////////////// class UpdateService : public ServiceBase @@ -25,29 +35,19 @@ namespace Mengine void _stopService() override; public: - void placeUpdatater( const UpdationInterfacePtr & _updation ) override; - void removeUpdatater( const UpdationInterfacePtr & _updation ) override; + void placeUpdatater( UpdationInterface * _updation ) override; + void removeUpdatater( UpdationInterface * _updation ) override; public: void onTimepipe( const UpdateContext * _context ) override; protected: - typedef Vector VectorUpdatableIndecies; - - struct LeafUpdatable - { - VectorUpdatableIndecies indecies; - VectorUpdatableIndecies indeciesAdd; - }; - - typedef Vector LeafUpdatables; LeafUpdatables m_beforeLeafs; LeafUpdatables m_leafs; LeafUpdatables m_afterLeafs; protected: - bool findLeafUpdatater_( const LeafUpdatables & _leafs, const UpdationInterfacePtr & _updation ) const; - bool findUpdatater_( const UpdationInterfacePtr & _updation ) const; + bool findUpdatater_( const UpdationInterface * _updation ) const; void updateLeaf_( uint32_t _deep, LeafUpdatable * const _leaf, const UpdateContext * _context ); LeafUpdatable * getLeafUpdatable( EUpdateMode _mode, uint32_t _deep ); }; From 86be99c707caa62f183e83a51875af9bf69d1699 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 00:09:17 +0200 Subject: [PATCH 094/169] Wip AppleUserMessagingPlatformPlugin --- cmake/Dependencies/CMakeLists.txt | 8 +- cmake/Dependencies/box2d/CMakeLists.txt | 123 ---- .../box2d/include/box2d/math_functions.h | 568 ------------------ cmake/Dependencies/box2d/src/allocate.c | 115 ---- cmake/Dependencies/box2d/src/core.h | 173 ------ .../libtheora/lib/encoder_disabled.c | 69 +++ cmake/Downloads/CMakeLists.txt | 5 +- gradle/app.gradle | 24 + .../org/Mengine/Project/FinalApplication.java | 5 + gradle/build.gradle | 2 +- .../org/Mengine/Project/FinalApplication.java | 5 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../org/Mengine/Base/MengineAnalytics.java | 20 +- .../Base/MengineAnalyticsEventBuilder.java | 16 +- .../MengineAnalyticsEventBuilderDummy.java | 16 +- ...MengineAnalyticsEventBuilderInterface.java | 14 +- .../org/Mengine/Base/MengineApplication.java | 3 +- .../java/org/Mengine/Base/MengineService.java | 87 ++- .../Mengine/Base/MengineServiceInterface.java | 57 +- .../java/org/Mengine/Base/MengineTag.java | 4 +- .../Plugin/Adjust/MengineAdjustPlugin.java | 30 +- gradle/plugins/Amplitude/build.gradle | 2 +- .../Amplitude/MengineAmplitudePlugin.java | 8 +- .../AppOpenAd/MengineAppLovinAppOpenAd.java | 12 +- .../BannerAd/MengineAppLovinBannerAd.java | 14 +- gradle/plugins/AppLovin/Core/build.gradle | 28 +- .../AppLovin/Core/MengineAppLovinBase.java | 24 +- .../MengineAppLovinInterstitialAd.java | 13 +- .../MRECAd/MengineAppLovinMRECAd.java | 12 +- .../NativeAd/MengineAppLovinNativeAd.java | 12 +- .../MengineAppLovinNonetBanners.java | 2 +- .../RewardedAd/MengineAppLovinRewardedAd.java | 12 +- gradle/plugins/Firebase/build.gradle | 2 +- .../MengineFirebaseCrashlyticsPlugin.java | 2 +- .../build.gradle | 2 +- src/Engine/Application.cpp | 8 +- .../PythonFramework/GameScriptEmbedding.cpp | 2 +- src/Interface/RenderBatchInterface.h | 4 + src/Interface/RenderSystemInterface.h | 1 + src/Interface/ThreadProcessorInterface.h | 2 +- src/Kernel/BaseTransformation.cpp | 6 +- src/Kernel/Delegate.h | 4 +- src/Kernel/Node.h | 3 +- ...UserMessagingPlatformApplicationDelegate.h | 7 + ...serMessagingPlatformApplicationDelegate.mm | 73 +++ .../CMakeLists.txt | 15 + src/Plugins/Box2DPlugin/Box2DBody.cpp | 24 +- src/Plugins/Box2DPlugin/Box2DIncluder.h | 5 +- src/Plugins/Box2DPlugin/Box2DWorld.cpp | 8 +- src/Plugins/Box2DPlugin/CMakeLists.txt | 2 +- .../CameraDebugGizmoPlugin/CMakeLists.txt | 4 +- ...ugGizmo.cpp => CameraDebugGizmoModule.cpp} | 16 +- ...aDebugGizmo.h => CameraDebugGizmoModule.h} | 8 +- .../CameraDebugGizmoPlugin.cpp | 6 +- src/Plugins/DebugPanelPlugin/CMakeLists.txt | 4 +- ...uleDebugPanel.cpp => DebugPanelModule.cpp} | 24 +- ...{ModuleDebugPanel.h => DebugPanelModule.h} | 8 +- .../DebugPanelPlugin/DebugPanelPlugin.cpp | 6 +- src/Plugins/ImGUIPlugin/ImGUIInterface.h | 1 + src/Plugins/NodeDebuggerPlugin/CMakeLists.txt | 4 +- .../NodeDebuggerPlugin/NodeDebuggerPlugin.cpp | 6 +- .../RenderService/BatchRenderPipeline.cpp | 62 ++ .../RenderService/BatchRenderPipeline.h | 6 + src/Services/RenderService/RenderBatch.h | 4 +- src/Services/ThreadService/ThreadService.cpp | 8 +- src/Services/UpdateService/UpdateService.cpp | 9 +- .../Win32ThreadProcessor.cpp | 7 +- .../Win32ThreadSystem/Win32ThreadProcessor.h | 4 +- 68 files changed, 573 insertions(+), 1269 deletions(-) delete mode 100644 cmake/Dependencies/box2d/CMakeLists.txt delete mode 100644 cmake/Dependencies/box2d/include/box2d/math_functions.h delete mode 100644 cmake/Dependencies/box2d/src/allocate.c delete mode 100644 cmake/Dependencies/box2d/src/core.h create mode 100644 cmake/Dependencies/libtheora/lib/encoder_disabled.c create mode 100644 src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h create mode 100644 src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm create mode 100644 src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt rename src/Plugins/CameraDebugGizmoPlugin/{ModuleCameraDebugGizmo.cpp => CameraDebugGizmoModule.cpp} (90%) rename src/Plugins/CameraDebugGizmoPlugin/{ModuleCameraDebugGizmo.h => CameraDebugGizmoModule.h} (77%) rename src/Plugins/DebugPanelPlugin/{ModuleDebugPanel.cpp => DebugPanelModule.cpp} (92%) rename src/Plugins/DebugPanelPlugin/{ModuleDebugPanel.h => DebugPanelModule.h} (94%) diff --git a/cmake/Dependencies/CMakeLists.txt b/cmake/Dependencies/CMakeLists.txt index b5adbf5bcb..b33ae43b40 100644 --- a/cmake/Dependencies/CMakeLists.txt +++ b/cmake/Dependencies/CMakeLists.txt @@ -122,17 +122,14 @@ endif() if(MENGINE_DEPENDENCE_BOX2D) message("================box2d================") - configure_file(${CMAKE_CURRENT_LIST_DIR}/box2d/include/box2d/math_functions.h ${THIRDPARTY_DIR}/box2d/include/box2d/math_functions.h COPYONLY) - configure_file(${CMAKE_CURRENT_LIST_DIR}/box2d/src/core.h ${THIRDPARTY_DIR}/box2d/src/core.h COPYONLY) - configure_file(${CMAKE_CURRENT_LIST_DIR}/box2d/src/allocate.c ${THIRDPARTY_DIR}/box2d/src/allocate.c COPYONLY) - configure_file(${CMAKE_CURRENT_LIST_DIR}/box2d/CMakeLists.txt ${THIRDPARTY_DIR}/box2d/CMakeLists.txt COPYONLY) - + SET(BOX2D_SAMPLES OFF CACHE BOOL "BOX2D_SAMPLES" FORCE) SET(BOX2D_BENCHMARKS OFF CACHE BOOL "BOX2D_BENCHMARKS" FORCE) SET(BOX2D_DOCS OFF CACHE BOOL "BOX2D_DOCS" FORCE) SET(BOX2D_PROFILE OFF CACHE BOOL "BOX2D_PROFILE" FORCE) SET(BOX2D_VALIDATE OFF CACHE BOOL "BOX2D_VALIDATE" FORCE) SET(BOX2D_UNIT_TESTS OFF CACHE BOOL "BOX2D_UNIT_TESTS" FORCE) + SET(BOX2D_COMPILE_WARNING_AS_ERROR OFF CACHE BOOL "BOX2D_COMPILE_WARNING_AS_ERROR" FORCE) ADD_SUBDIRECTORY(${THIRDPARTY_DIR}/box2d ${THIRDPARTY_CONFIG_DIR}/box2d) endif() @@ -173,6 +170,7 @@ endif() if(MENGINE_DEPENDENCE_THEORA) message("================libtheora================") + configure_file(${CMAKE_CURRENT_LIST_DIR}/libtheora/lib/encoder_disabled.c ${THIRDPARTY_DIR}/libtheora/lib/encoder_disabled.c COPYONLY) ADD_SUBDIRECTORY(libtheora ${THIRDPARTY_CONFIG_DIR}/libtheora) endif() diff --git a/cmake/Dependencies/box2d/CMakeLists.txt b/cmake/Dependencies/box2d/CMakeLists.txt deleted file mode 100644 index 0fa736ac4b..0000000000 --- a/cmake/Dependencies/box2d/CMakeLists.txt +++ /dev/null @@ -1,123 +0,0 @@ -cmake_minimum_required(VERSION 3.22) -include(FetchContent) - -project(box2d - VERSION 3.0.0 - DESCRIPTION "A 2D physics engine for games" - HOMEPAGE_URL "https://box2d.org" - LANGUAGES C CXX -) - -# stuff to help debug cmake -# message(STATUS "cmake source dir: ${CMAKE_SOURCE_DIR}") -# message(STATUS "library postfix: ${CMAKE_DEBUG_POSTFIX}") -message(STATUS "CMake C compiler: ${CMAKE_C_COMPILER_ID}") -message(STATUS "CMake C++ compiler: ${CMAKE_CXX_COMPILER_ID}") -message(STATUS "CMake system name: ${CMAKE_SYSTEM_NAME}") -message(STATUS "CMake host system processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}") - -if (MSVC OR APPLE) - option(BOX2D_SANITIZE "Enable sanitizers for some builds" OFF) - if(BOX2D_SANITIZE) - message(STATUS "Box2D Sanitize") - # sanitizers need to apply to all compiled libraries to work well - if(MSVC) - # address sanitizer only in the debug build - add_compile_options("$<$:/fsanitize=address>") - add_link_options("$<$:/INCREMENTAL:NO>") - elseif(APPLE) - # more sanitizers on Apple clang - # add_compile_options(-fsanitize=thread -fno-omit-frame-pointer) - add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined) - add_link_options(-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined) - endif() - endif() -endif() - -if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") - option(BOX2D_AVX2 "Enable AVX2 (faster)" ON) -endif() - -if(PROJECT_IS_TOP_LEVEL) - # Needed for samples.exe to find box2d.dll - # set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") -endif() - -# C++17 needed for imgui -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) - -# set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set_property(GLOBAL PROPERTY USE_FOLDERS ON) -set(CMAKE_VERBOSE_MAKEFILE ON) - -# The Box2D library uses simde https://github.com/simd-everywhere/simde -add_subdirectory(extern/simde) -add_subdirectory(src) - -# This hides samples, test, and doxygen from apps that use box2d via FetchContent -if(PROJECT_IS_TOP_LEVEL) - option(BOX2D_SAMPLES "Build the Box2D samples" ON) - option(BOX2D_BENCHMARKS "Build the Box2D benchmarks" OFF) - option(BOX2D_DOCS "Build the Box2D documentation" OFF) - option(BOX2D_PROFILE "Enable profiling with Tracy" OFF) - option(BOX2D_VALIDATE "Enable heavy validation" ON) - option(BOX2D_UNIT_TESTS "Build the Box2D unit tests" ON) - - if(MSVC AND WIN32) - # Enable edit and continue only in debug due to perf hit in release - # add_link_options($<$:/INCREMENTAL>) - # add_compile_options($<$:/ZI>) - # add_compile_options(/fsanitize=address) - # set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/GS- /Gy /O2 /Oi /Ot") - # set(CMAKE_CXX_FLAGS_RELEASE "/GS- /Gy /O2 /Oi /Ot") - # set(CMAKE_C_FLAGS_RELWITHDEBINFO "/GS- /Gy /O2 /Oi /Ot") - # set(CMAKE_C_FLAGS_RELEASE "/GS- /Gy /O2 /Oi /Ot") - endif() - - # enkiTS is used by all the test apps, but not directly by the Box2D library - if(BOX2D_UNIT_TESTS OR BOX2D_SAMPLES OR BOX2D_BENCHMARKS) - SET(ENKITS_BUILD_EXAMPLES OFF CACHE BOOL "Build enkiTS examples") - - # Used in tests and samples - FetchContent_Declare( - enkits - GIT_REPOSITORY https://github.com/dougbinks/enkiTS.git - GIT_TAG master - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE - ) - FetchContent_MakeAvailable(enkits) - endif() - - # Tests need static linkage because they test internal Box2D functions - if(NOT BUILD_SHARED_LIBS AND BOX2D_UNIT_TESTS) - message(STATUS "Adding Box2D unit tests") - add_subdirectory(test) - else() - message(STATUS "Skipping Box2D unit tests") - endif() - - if(BOX2D_SAMPLES) - add_subdirectory(samples) - - # default startup project for Visual Studio - if(MSVC) - set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT samples) - set_property(TARGET samples PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") - endif() - endif() - - if(BOX2D_BENCHMARKS) - add_subdirectory(benchmark) - endif() - - if(BOX2D_DOCS) - add_subdirectory(docs) - endif() -endif() - -# # Building on clang in windows -# cmake -S .. -B . -G "Visual Studio 17 2022" -A x64 -T ClangCL -# https://clang.llvm.org/docs/UsersManual.html#clang-cl diff --git a/cmake/Dependencies/box2d/include/box2d/math_functions.h b/cmake/Dependencies/box2d/include/box2d/math_functions.h deleted file mode 100644 index 0a7d37d6fd..0000000000 --- a/cmake/Dependencies/box2d/include/box2d/math_functions.h +++ /dev/null @@ -1,568 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Erin Catto -// SPDX-License-Identifier: MIT - -#pragma once - -#include "base.h" - -#include -#include - -/** - * @defgroup math Math - * @brief Vector math types and functions - * @{ - */ - -/// https://en.wikipedia.org/wiki/Pi -#define b2_pi 3.14159265359f - -/// 2D vector -/// This can be used to represent a point or free vector -typedef struct b2Vec2 -{ - /// coordinates - float x, y; -} b2Vec2; - -/// 2D rotation -/// This is similar to using a complex number for rotation -typedef struct b2Rot -{ - /// cosine and sine - float c, s; -} b2Rot; - -/// A 2D rigid transform -typedef struct b2Transform -{ - b2Vec2 p; - b2Rot q; -} b2Transform; - -/// A 2-by-2 Matrix -typedef struct b2Mat22 -{ - /// columns - b2Vec2 cx, cy; -} b2Mat22; - -/// Axis-aligned bounding box -typedef struct b2AABB -{ - b2Vec2 lowerBound; - b2Vec2 upperBound; -} b2AABB; - -/**@}*/ - -/** - * @addtogroup math - * @{ - */ - -static const b2Vec2 b2Vec2_zero = { 0.0f, 0.0f }; -static const b2Rot b2Rot_identity = { 1.0f, 0.0f }; -static const b2Transform b2Transform_identity = { { 0.0f, 0.0f }, { 1.0f, 0.0f } }; -static const b2Mat22 b2Mat22_zero = { { 0.0f, 0.0f }, { 0.0f, 0.0f } }; - -/// @return the minimum of two floats -B2_INLINE float b2MinFloat( float a, float b ) -{ - return a < b ? a : b; -} - -/// @return the maximum of two floats -B2_INLINE float b2MaxFloat( float a, float b ) -{ - return a > b ? a : b; -} - -/// @return the absolute value of a float -B2_INLINE float b2AbsFloat( float a ) -{ - return a < 0 ? -a : a; -} - -/// @return a float clamped between a lower and upper bound -B2_INLINE float b2ClampFloat( float a, float lower, float upper ) -{ - return a < lower ? lower : ( a > upper ? upper : a ); -} - -/// @return the minimum of two integers -B2_INLINE int b2MinInt( int a, int b ) -{ - return a < b ? a : b; -} - -/// @return the maximum of two integers -B2_INLINE int b2MaxInt( int a, int b ) -{ - return a > b ? a : b; -} - -/// @return the absolute value of an integer -B2_INLINE int b2AbsInt( int a ) -{ - return a < 0 ? -a : a; -} - -/// @return an integer clamped between a lower and upper bound -B2_INLINE int b2ClampInt( int a, int lower, int upper ) -{ - return a < lower ? lower : ( a > upper ? upper : a ); -} - -/// Vector dot product -B2_INLINE float b2Dot( b2Vec2 a, b2Vec2 b ) -{ - return a.x * b.x + a.y * b.y; -} - -/// Vector cross product. In 2D this yields a scalar. -B2_INLINE float b2Cross( b2Vec2 a, b2Vec2 b ) -{ - return a.x * b.y - a.y * b.x; -} - -/// Perform the cross product on a vector and a scalar. In 2D this produces a vector. -B2_INLINE b2Vec2 b2CrossVS( b2Vec2 v, float s ) -{ - return B2_LITERAL( b2Vec2 ){ s * v.y, -s * v.x }; -} - -/// Perform the cross product on a scalar and a vector. In 2D this produces a vector. -B2_INLINE b2Vec2 b2CrossSV( float s, b2Vec2 v ) -{ - return B2_LITERAL( b2Vec2 ){ -s * v.y, s * v.x }; -} - -/// Get a left pointing perpendicular vector. Equivalent to b2CrossSV(1.0f, v) -B2_INLINE b2Vec2 b2LeftPerp( b2Vec2 v ) -{ - return B2_LITERAL( b2Vec2 ){ -v.y, v.x }; -} - -/// Get a right pointing perpendicular vector. Equivalent to b2CrossVS(v, 1.0f) -B2_INLINE b2Vec2 b2RightPerp( b2Vec2 v ) -{ - return B2_LITERAL( b2Vec2 ){ v.y, -v.x }; -} - -/// Vector addition -B2_INLINE b2Vec2 b2Add( b2Vec2 a, b2Vec2 b ) -{ - return B2_LITERAL( b2Vec2 ){ a.x + b.x, a.y + b.y }; -} - -/// Vector subtraction -B2_INLINE b2Vec2 b2Sub( b2Vec2 a, b2Vec2 b ) -{ - return B2_LITERAL( b2Vec2 ){ a.x - b.x, a.y - b.y }; -} - -/// Vector negation -B2_INLINE b2Vec2 b2Neg( b2Vec2 a ) -{ - return B2_LITERAL( b2Vec2 ){ -a.x, -a.y }; -} - -/// Vector linear interpolation -/// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ -B2_INLINE b2Vec2 b2Lerp( b2Vec2 a, b2Vec2 b, float t ) -{ - return B2_LITERAL( b2Vec2 ){ ( 1.0f - t ) * a.x + t * b.x, ( 1.0f - t ) * a.y + t * b.y }; -} - -/// Component-wise multiplication -B2_INLINE b2Vec2 b2Mul( b2Vec2 a, b2Vec2 b ) -{ - return B2_LITERAL( b2Vec2 ){ a.x * b.x, a.y * b.y }; -} - -/// Multiply a scalar and vector -B2_INLINE b2Vec2 b2MulSV( float s, b2Vec2 v ) -{ - return B2_LITERAL( b2Vec2 ){ s * v.x, s * v.y }; -} - -/// a + s * b -B2_INLINE b2Vec2 b2MulAdd( b2Vec2 a, float s, b2Vec2 b ) -{ - return B2_LITERAL( b2Vec2 ){ a.x + s * b.x, a.y + s * b.y }; -} - -/// a - s * b -B2_INLINE b2Vec2 b2MulSub( b2Vec2 a, float s, b2Vec2 b ) -{ - return B2_LITERAL( b2Vec2 ){ a.x - s * b.x, a.y - s * b.y }; -} - -/// Component-wise absolute vector -B2_INLINE b2Vec2 b2Abs( b2Vec2 a ) -{ - b2Vec2 b; - b.x = b2AbsFloat( a.x ); - b.y = b2AbsFloat( a.y ); - return b; -} - -/// Component-wise minimum vector -B2_INLINE b2Vec2 b2Min( b2Vec2 a, b2Vec2 b ) -{ - b2Vec2 c; - c.x = b2MinFloat( a.x, b.x ); - c.y = b2MinFloat( a.y, b.y ); - return c; -} - -/// Component-wise maximum vector -B2_INLINE b2Vec2 b2Max( b2Vec2 a, b2Vec2 b ) -{ - b2Vec2 c; - c.x = b2MaxFloat( a.x, b.x ); - c.y = b2MaxFloat( a.y, b.y ); - return c; -} - -/// Component-wise clamp vector v into the range [a, b] -B2_INLINE b2Vec2 b2Clamp( b2Vec2 v, b2Vec2 a, b2Vec2 b ) -{ - b2Vec2 c; - c.x = b2ClampFloat( v.x, a.x, b.x ); - c.y = b2ClampFloat( v.y, a.y, b.y ); - return c; -} - -/// Get the length of this vector (the norm) -B2_INLINE float b2Length( b2Vec2 v ) -{ - return sqrtf( v.x * v.x + v.y * v.y ); -} - -/// Get the length squared of this vector -B2_INLINE float b2LengthSquared( b2Vec2 v ) -{ - return v.x * v.x + v.y * v.y; -} - -/// Get the distance between two points -B2_INLINE float b2Distance( b2Vec2 a, b2Vec2 b ) -{ - float dx = b.x - a.x; - float dy = b.y - a.y; - return sqrtf( dx * dx + dy * dy ); -} - -/// Get the distance squared between points -B2_INLINE float b2DistanceSquared( b2Vec2 a, b2Vec2 b ) -{ - b2Vec2 c = { b.x - a.x, b.y - a.y }; - return c.x * c.x + c.y * c.y; -} - -/// Make a rotation using an angle in radians -B2_INLINE b2Rot b2MakeRot( float angle ) -{ - // todo determinism - b2Rot q = { cosf( angle ), sinf( angle ) }; - return q; -} - -/// Normalize rotation -B2_INLINE b2Rot b2NormalizeRot( b2Rot q ) -{ - float mag = sqrtf( q.s * q.s + q.c * q.c ); - float invMag = mag > 0.0 ? 1.0f / mag : 0.0f; - b2Rot qn = { q.c * invMag, q.s * invMag }; - return qn; -} - -/// Is this rotation normalized? -B2_INLINE bool b2IsNormalized( b2Rot q ) -{ - // larger tolerance due to failure on mingw 32-bit - float qq = q.s * q.s + q.c * q.c; - return 1.0f - 0.0006f < qq && qq < 1.0f + 0.0006f; -} - -/// Normalized linear interpolation -/// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ -B2_INLINE b2Rot b2NLerp( b2Rot q1, b2Rot q2, float t ) -{ - float omt = 1.0f - t; - b2Rot q = { - omt * q1.c + t * q2.c, - omt * q1.s + t * q2.s, - }; - - return b2NormalizeRot( q ); -} - -/// Integration rotation from angular velocity -/// @param q1 initial rotation -/// @param deltaAngle the angular displacement in radians -B2_INLINE b2Rot b2IntegrateRotation( b2Rot q1, float deltaAngle ) -{ - // dc/dt = -omega * sin(t) - // ds/dt = omega * cos(t) - // c2 = c1 - omega * h * s1 - // s2 = s1 + omega * h * c1 - b2Rot q2 = { q1.c - deltaAngle * q1.s, q1.s + deltaAngle * q1.c }; - float mag = sqrtf( q2.s * q2.s + q2.c * q2.c ); - float invMag = mag > 0.0 ? 1.0f / mag : 0.0f; - b2Rot qn = { q2.c * invMag, q2.s * invMag }; - return qn; -} - -/// Compute the angular velocity necessary to rotate between two rotations over a give time -/// @param q1 initial rotation -/// @param q2 final rotation -/// @param inv_h inverse time step -B2_INLINE float b2ComputeAngularVelocity( b2Rot q1, b2Rot q2, float inv_h ) -{ - // ds/dt = omega * cos(t) - // dc/dt = -omega * sin(t) - // s2 = s1 + omega * h * c1 - // c2 = c1 - omega * h * s1 - - // omega * h * s1 = c1 - c2 - // omega * h * c1 = s2 - s1 - // omega * h = (c1 - c2) * s1 + (s2 - s1) * c1; - // omega * h = s1 * c1 - c2 * s1 + s2 * c1 - s1 * c1 - // omega * h = s2 * c1 - c2 * s1 = sin(a2 - a1) ~= a2 - a1 for small delta - float omega = inv_h * ( q2.s * q1.c - q2.c * q1.s ); - return omega; -} - -/// Get the angle in radians in the range [-pi, pi] -B2_INLINE float b2Rot_GetAngle( b2Rot q ) -{ - // todo determinism - return atan2f( q.s, q.c ); -} - -/// Get the x-axis -B2_INLINE b2Vec2 b2Rot_GetXAxis( b2Rot q ) -{ - b2Vec2 v = { q.c, q.s }; - return v; -} - -/// Get the y-axis -B2_INLINE b2Vec2 b2Rot_GetYAxis( b2Rot q ) -{ - b2Vec2 v = { -q.s, q.c }; - return v; -} - -/// Multiply two rotations: q * r -B2_INLINE b2Rot b2MulRot( b2Rot q, b2Rot r ) -{ - // [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc] - // [qs qc] [rs rc] [qs*rc+qc*rs -qs*rs+qc*rc] - // s(q + r) = qs * rc + qc * rs - // c(q + r) = qc * rc - qs * rs - b2Rot qr; - qr.s = q.s * r.c + q.c * r.s; - qr.c = q.c * r.c - q.s * r.s; - return qr; -} - -/// Transpose multiply two rotations: qT * r -B2_INLINE b2Rot b2InvMulRot( b2Rot q, b2Rot r ) -{ - // [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc] - // [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc] - // s(q - r) = qc * rs - qs * rc - // c(q - r) = qc * rc + qs * rs - b2Rot qr; - qr.s = q.c * r.s - q.s * r.c; - qr.c = q.c * r.c + q.s * r.s; - return qr; -} - -/// relative angle between b and a (rot_b * inv(rot_a)) -B2_INLINE float b2RelativeAngle( b2Rot b, b2Rot a ) -{ - // sin(b - a) = bs * ac - bc * as - // cos(b - a) = bc * ac + bs * as - float s = b.s * a.c - b.c * a.s; - float c = b.c * a.c + b.s * a.s; - return atan2f( s, c ); -} - -/// Convert an angle in the range [-2*pi, 2*pi] into the range [-pi, pi] -B2_INLINE float b2UnwindAngle( float angle ) -{ - if ( angle < -b2_pi ) - { - return angle + 2.0f * b2_pi; - } - else if ( angle > b2_pi ) - { - return angle - 2.0f * b2_pi; - } - - return angle; -} - -/// Rotate a vector -B2_INLINE b2Vec2 b2RotateVector( b2Rot q, b2Vec2 v ) -{ - return B2_LITERAL( b2Vec2 ){ q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y }; -} - -/// Inverse rotate a vector -B2_INLINE b2Vec2 b2InvRotateVector( b2Rot q, b2Vec2 v ) -{ - return B2_LITERAL( b2Vec2 ){ q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y }; -} - -/// Transform a point (e.g. local space to world space) -B2_INLINE b2Vec2 b2TransformPoint( b2Transform t, const b2Vec2 p ) -{ - float x = ( t.q.c * p.x - t.q.s * p.y ) + t.p.x; - float y = ( t.q.s * p.x + t.q.c * p.y ) + t.p.y; - - return B2_LITERAL( b2Vec2 ){ x, y }; -} - -/// Inverse transform a point (e.g. world space to local space) -B2_INLINE b2Vec2 b2InvTransformPoint( b2Transform t, const b2Vec2 p ) -{ - float vx = p.x - t.p.x; - float vy = p.y - t.p.y; - return B2_LITERAL( b2Vec2 ){ t.q.c * vx + t.q.s * vy, -t.q.s * vx + t.q.c * vy }; -} - -/// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p -/// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p -B2_INLINE b2Transform b2MulTransforms( b2Transform A, b2Transform B ) -{ - b2Transform C; - C.q = b2MulRot( A.q, B.q ); - C.p = b2Add( b2RotateVector( A.q, B.p ), A.p ); - return C; -} - -/// v2 = A.q' * (B.q * v1 + B.p - A.p) -/// = A.q' * B.q * v1 + A.q' * (B.p - A.p) -B2_INLINE b2Transform b2InvMulTransforms( b2Transform A, b2Transform B ) -{ - b2Transform C; - C.q = b2InvMulRot( A.q, B.q ); - C.p = b2InvRotateVector( A.q, b2Sub( B.p, A.p ) ); - return C; -} - -/// Multiply a 2-by-2 matrix times a 2D vector -B2_INLINE b2Vec2 b2MulMV( b2Mat22 A, b2Vec2 v ) -{ - b2Vec2 u = { - A.cx.x * v.x + A.cy.x * v.y, - A.cx.y * v.x + A.cy.y * v.y, - }; - return u; -} - -/// Get the inverse of a 2-by-2 matrix -B2_INLINE b2Mat22 b2GetInverse22( b2Mat22 A ) -{ - float a = A.cx.x, b = A.cy.x, c = A.cx.y, d = A.cy.y; - float det = a * d - b * c; - if ( det != 0.0f ) - { - det = 1.0f / det; - } - - b2Mat22 B = { - { det * d, -det * c }, - { -det * b, det * a }, - }; - return B; -} - -/// Solve A * x = b, where b is a column vector. This is more efficient -/// than computing the inverse in one-shot cases. -B2_INLINE b2Vec2 b2Solve22( b2Mat22 A, b2Vec2 b ) -{ - float a11 = A.cx.x, a12 = A.cy.x, a21 = A.cx.y, a22 = A.cy.y; - float det = a11 * a22 - a12 * a21; - if ( det != 0.0f ) - { - det = 1.0f / det; - } - b2Vec2 x = { det * ( a22 * b.x - a12 * b.y ), det * ( a11 * b.y - a21 * b.x ) }; - return x; -} - -/// Does a fully contain b -B2_INLINE bool b2AABB_Contains( b2AABB a, b2AABB b ) -{ - bool s = true; - s = s && a.lowerBound.x <= b.lowerBound.x; - s = s && a.lowerBound.y <= b.lowerBound.y; - s = s && b.upperBound.x <= a.upperBound.x; - s = s && b.upperBound.y <= a.upperBound.y; - return s; -} - -/// Get the center of the AABB. -B2_INLINE b2Vec2 b2AABB_Center( b2AABB a ) -{ - b2Vec2 b = { 0.5f * ( a.lowerBound.x + a.upperBound.x ), 0.5f * ( a.lowerBound.y + a.upperBound.y ) }; - return b; -} - -/// Get the extents of the AABB (half-widths). -B2_INLINE b2Vec2 b2AABB_Extents( b2AABB a ) -{ - b2Vec2 b = { 0.5f * ( a.upperBound.x - a.lowerBound.x ), 0.5f * ( a.upperBound.y - a.lowerBound.y ) }; - return b; -} - -/// Union of two AABBs -B2_INLINE b2AABB b2AABB_Union( b2AABB a, b2AABB b ) -{ - b2AABB c; - c.lowerBound.x = b2MinFloat( a.lowerBound.x, b.lowerBound.x ); - c.lowerBound.y = b2MinFloat( a.lowerBound.y, b.lowerBound.y ); - c.upperBound.x = b2MaxFloat( a.upperBound.x, b.upperBound.x ); - c.upperBound.y = b2MaxFloat( a.upperBound.y, b.upperBound.y ); - return c; -} - -/// Is this a valid number? Not NaN or infinity. -B2_API bool b2IsValid( float a ); - -/// Is this a valid vector? Not NaN or infinity. -B2_API bool b2Vec2_IsValid( b2Vec2 v ); - -/// Is this a valid rotation? Not NaN or infinity. Is normalized. -B2_API bool b2Rot_IsValid( b2Rot q ); - -/// Is this a valid bounding box? Not Nan or infinity. Upper bound greater than or equal to lower bound. -B2_API bool b2AABB_IsValid( b2AABB aabb ); - -/// Convert a vector into a unit vector if possible, otherwise returns the zero vector. -B2_API b2Vec2 b2Normalize( b2Vec2 v ); - -/// Convert a vector into a unit vector if possible, otherwise asserts. -B2_API b2Vec2 b2NormalizeChecked( b2Vec2 v ); - -/// Convert a vector into a unit vector if possible, otherwise returns the zero vector. Also -/// outputs the length. -B2_API b2Vec2 b2GetLengthAndNormalize( float* length, b2Vec2 v ); - -/// Box2D bases all length units on meters, but you may need different units for your game. -/// You can set this value to use different units. This should be done at application startup -/// and only modified once. Default value is 1. -/// @warning This must be modified before any calls to Box2D -B2_API void b2SetLengthUnitsPerMeter( float lengthUnits ); - -/// Get the current length units per meter. -B2_API float b2GetLengthUnitsPerMeter( void ); - -/**@}*/ diff --git a/cmake/Dependencies/box2d/src/allocate.c b/cmake/Dependencies/box2d/src/allocate.c deleted file mode 100644 index 4657b135c7..0000000000 --- a/cmake/Dependencies/box2d/src/allocate.c +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Erin Catto -// SPDX-License-Identifier: MIT - -#include "allocate.h" - -#include "core.h" - -#include "box2d/base.h" - -#if defined( B2_COMPILER_MSVC ) - #define _CRTDBG_MAP_ALLOC - #include - #include -#else - #include -#endif - -#include - -#include -#include - -#ifdef BOX2D_PROFILE - - #include - #define b2TracyCAlloc( ptr, size ) TracyCAlloc( ptr, size ) - #define b2TracyCFree( ptr ) TracyCFree( ptr ) - -#else - - #define b2TracyCAlloc( ptr, size ) - #define b2TracyCFree( ptr ) - -#endif - -static b2AllocFcn* b2_allocFcn = NULL; -static b2FreeFcn* b2_freeFcn = NULL; - -static _Atomic int b2_byteCount; - -void b2SetAllocator( b2AllocFcn* allocFcn, b2FreeFcn* freeFcn ) -{ - b2_allocFcn = allocFcn; - b2_freeFcn = freeFcn; -} - -// Use 32 byte alignment for everything. Works with 256bit SIMD. -#define B2_ALIGNMENT 32 - -void* b2Alloc( uint32_t size ) -{ - // This could cause some sharing issues, however Box2D rarely calls b2Alloc. - atomic_fetch_add_explicit( &b2_byteCount, size, memory_order_relaxed ); - - // Allocation must be a multiple of 32 or risk a seg fault - // https://en.cppreference.com/w/c/memory/aligned_alloc - uint32_t size32 = ( ( size - 1 ) | 0x1F ) + 1; - - if ( b2_allocFcn != NULL ) - { - void* ptr = b2_allocFcn( size32, B2_ALIGNMENT ); - b2TracyCAlloc( ptr, size ); - - B2_ASSERT( ptr != NULL ); - B2_ASSERT( ( (uintptr_t)ptr & 0x1F ) == 0 ); - - return ptr; - } - -#ifdef B2_PLATFORM_WINDOWS - void* ptr = _aligned_malloc( size32, B2_ALIGNMENT ); -#elif defined(B2_PLATFORM_ANDROID) - void * ptr = NULL; - posix_memalign( &ptr, B2_ALIGNMENT, size32 ); -#else - void* ptr = aligned_alloc( B2_ALIGNMENT, size32 ); -#endif - - b2TracyCAlloc( ptr, size ); - - B2_ASSERT( ptr != NULL ); - B2_ASSERT( ( (uintptr_t)ptr & 0x1F ) == 0 ); - - return ptr; -} - -void b2Free( void* mem, uint32_t size ) -{ - if ( mem == NULL ) - { - return; - } - - b2TracyCFree( mem ); - - if ( b2_freeFcn != NULL ) - { - b2_freeFcn( mem ); - } - else - { -#ifdef B2_PLATFORM_WINDOWS - _aligned_free( mem ); -#else - free( mem ); -#endif - } - - atomic_fetch_sub_explicit( &b2_byteCount, size, memory_order_relaxed ); -} - -int b2GetByteCount( void ) -{ - return atomic_load_explicit( &b2_byteCount, memory_order_relaxed ); -} diff --git a/cmake/Dependencies/box2d/src/core.h b/cmake/Dependencies/box2d/src/core.h deleted file mode 100644 index 39a29eea8d..0000000000 --- a/cmake/Dependencies/box2d/src/core.h +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Erin Catto -// SPDX-License-Identifier: MIT - -#pragma once - -#include "box2d/base.h" - -#define B2_NULL_INDEX ( -1 ) - -#ifdef NDEBUG - #define B2_DEBUG 0 -#else - #define B2_DEBUG 1 -#endif - -#if defined( BOX2D_VALIDATE ) && !defined( NDEBUG ) - #define B2_VALIDATE 1 -#else - #define B2_VALIDATE 0 -#endif - -// Define platform -#if defined( _WIN32 ) - #define B2_PLATFORM_WINDOWS -#elif defined( __ANDROID__ ) - #define B2_PLATFORM_ANDROID -#elif defined( __linux__ ) - #define B2_PLATFORM_LINUX -#elif defined( __APPLE__ ) - #include - #if defined( TARGET_OS_IPHONE ) && !TARGET_OS_IPHONE - #define B2_PLATFORM_MACOS - #else - #define B2_PLATFORM_IOS - #endif -#elif defined( __EMSCRIPTEN__ ) - #define B2_PLATFORM_WASM -#else - #error Unsupported platform -#endif - -// Define CPU -#if defined ( __i386 ) || defined( _M_IX86 ) - #define B2_CPU_X86 -#elif defined( __x86_64__ ) || defined( _M_X64 ) - #define B2_CPU_X64 -#elif defined( __aarch64__ ) || defined( _M_ARM64 ) - #define B2_CPU_ARM -#elif defined( __EMSCRIPTEN__ ) - #define B2_CPU_WASM -#elif defined( __ANDROID__ ) - #if defined( __i386__ ) - #define B2_CPU_X86 - #elif defined( __x86_64__ ) - #define B2_CPU_X64 - #elif defined( __aarch64__ ) - #define B2_CPU_ARM - #elif defined( __arm__ ) - #define B2_CPU_ARM32 - #else - #error Unsupported ANDROID CPU - #endif -#else - #error Unsupported CPU -#endif - -// Define compiler -#if defined( __clang__ ) - #define B2_COMPILER_CLANG -#elif defined( __GNUC__ ) - #define B2_COMPILER_GCC -#elif defined( _MSC_VER ) - #define B2_COMPILER_MSVC -#endif - -#if defined( B2_COMPILER_MSVC ) - #define B2_BREAKPOINT __debugbreak() -#elif defined( B2_PLATFORM_WASM ) - #define B2_BREAKPOINT \ - do \ - { \ - } \ - while ( 0 ) -#elif defined( B2_COMPILER_GCC ) || defined( B2_COMPILER_CLANG ) - #if defined( B2_CPU_X64 ) || defined( B2_CPU_X86 ) - #define B2_BREAKPOINT __asm volatile( "int $0x3" ) - #elif defined( B2_CPU_ARM ) || defined( B2_CPU_ARM32 ) - #define B2_BREAKPOINT __builtin_trap() - #else - #error B2_BREAKPOINT Unknown CPU - #endif -#else - #error B2_BREAKPOINT Unknown platform -#endif - -#if !defined( NDEBUG ) || defined( B2_ENABLE_ASSERT ) -extern b2AssertFcn* b2AssertHandler; - #define B2_ASSERT( condition ) \ - do \ - { \ - if ( !( condition ) && b2AssertHandler( #condition, __FILE__, (int)__LINE__ ) ) \ - B2_BREAKPOINT; \ - } \ - while ( 0 ) -#else - #define B2_ASSERT( ... ) ( (void)0 ) -#endif - -/// Tracy profiler instrumentation -/// https://github.com/wolfpld/tracy -#ifdef BOX2D_PROFILE - - #include - #define b2TracyCZoneC( ctx, color, active ) TracyCZoneC( ctx, color, active ) - #define b2TracyCZoneNC( ctx, name, color, active ) TracyCZoneNC( ctx, name, color, active ) - #define b2TracyCZoneEnd( ctx ) TracyCZoneEnd( ctx ) - -#else - - #define b2TracyCZoneC( ctx, color, active ) - #define b2TracyCZoneNC( ctx, name, color, active ) - #define b2TracyCZoneEnd( ctx ) - -#endif - -extern float b2_lengthUnitsPerMeter; - -// Used to detect bad values. Positions greater than about 16km will have precision -// problems, so 100km as a limit should be fine in all cases. -#define b2_huge ( 100000.0f * b2_lengthUnitsPerMeter ) - -// Maximum parallel workers. Used to size some static arrays. -#define b2_maxWorkers 64 - -// Maximum number of colors in the constraint graph. Constraints that cannot -// find a color are added to the overflow set which are solved single-threaded. -#define b2_graphColorCount 12 - -// A small length used as a collision and constraint tolerance. Usually it is -// chosen to be numerically significant, but visually insignificant. In meters. -// @warning modifying this can have a significant impact on stability -#define b2_linearSlop ( 0.005f * b2_lengthUnitsPerMeter ) - -// Maximum number of simultaneous worlds that can be allocated -#define b2_maxWorlds 128 - -// The maximum rotation of a body per time step. This limit is very large and is used -// to prevent numerical problems. You shouldn't need to adjust this. -// @warning increasing this to 0.5f * b2_pi or greater will break continuous collision. -#define b2_maxRotation ( 0.25f * b2_pi ) - -// @warning modifying this can have a significant impact on performance and stability -#define b2_speculativeDistance ( 4.0f * b2_linearSlop ) - -// This is used to fatten AABBs in the dynamic tree. This allows proxies -// to move by a small amount without triggering a tree adjustment. -// This is in meters. -// @warning modifying this can have a significant impact on performance -#define b2_aabbMargin ( 0.1f * b2_lengthUnitsPerMeter ) - -// The time that a body must be still before it will go to sleep. In seconds. -#define b2_timeToSleep 0.5f - -// Returns the number of elements of an array -#define B2_ARRAY_COUNT( A ) (int)( sizeof( A ) / sizeof( A[0] ) ) - -// Used to prevent the compiler from warning about unused variables -#define B2_MAYBE_UNUSED( x ) ( (void)( x ) ) - -// Use to validate definitions. Do not take my cookie. -#define B2_SECRET_COOKIE 1152023 - -#define b2CheckDef( DEF ) B2_ASSERT( DEF->internalValue == B2_SECRET_COOKIE ) diff --git a/cmake/Dependencies/libtheora/lib/encoder_disabled.c b/cmake/Dependencies/libtheora/lib/encoder_disabled.c new file mode 100644 index 0000000000..17d19f1a11 --- /dev/null +++ b/cmake/Dependencies/libtheora/lib/encoder_disabled.c @@ -0,0 +1,69 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation https://www.xiph.org/ * + * * + ******************************************************************** + + function: + + ********************************************************************/ +#include "apiwrapper.h" +#include "encint.h" + +const th_quant_info TH_VP31_QUANT_INFO = {0}; +const th_huff_code TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]; + +th_enc_ctx *th_encode_alloc(const th_info *_info){ + return NULL; +} + +void th_encode_free(th_enc_ctx *_enc){} + + +int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){ + return OC_DISABLED; +} + +int th_encode_flushheader(th_enc_ctx *_enc,th_comment *_tc,ogg_packet *_op){ + return OC_DISABLED; +} + +int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){ + return OC_DISABLED; +} + +int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){ + return OC_DISABLED; +} + + + +int theora_encode_init(theora_state *_te,theora_info *_ci){ + return OC_DISABLED; +} + +int theora_encode_YUVin(theora_state *_te,yuv_buffer *_yuv){ + return OC_DISABLED; +} + +int theora_encode_packetout(theora_state *_te,int _last_p,ogg_packet *_op){ + return OC_DISABLED; +} + +int theora_encode_header(theora_state *_te,ogg_packet *_op){ + return OC_DISABLED; +} + +int theora_encode_comment(theora_comment *_tc,ogg_packet *_op){ + return OC_DISABLED; +} + +int theora_encode_tables(theora_state *_te,ogg_packet *_op){ + return OC_DISABLED; +} diff --git a/cmake/Downloads/CMakeLists.txt b/cmake/Downloads/CMakeLists.txt index 4918d9d4b3..9b2ea22b67 100644 --- a/cmake/Downloads/CMakeLists.txt +++ b/cmake/Downloads/CMakeLists.txt @@ -59,7 +59,8 @@ GIT_CLONE(python https://github.com/python/cpython.git "v2.7.18") GIT_CLONE(ozz https://github.com/guillaumeblanc/ozz-animation.git "0.15.0") GIT_CLONE(glad https://github.com/Dav1dde/glad.git "v2.0.8") GIT_CLONE(glfw3 https://github.com/glfw/glfw.git "3.4") -GIT_CLONE(imgui https://github.com/ocornut/imgui.git "v1.91.7") + +GIT_CLONE(imgui https://github.com/ocornut/imgui.git "v1.92.4-docking") GIT_CLONE(zed_net https://github.com/Smilex/zed_net) GIT_CLONE(spine https://github.com/EsotericSoftware/spine-runtimes.git "4.1.00") GIT_CLONE(dazzle https://github.com/irov/dazzle.git) @@ -67,7 +68,7 @@ GIT_CLONE(GOAP https://github.com/irov/GOAP.git) GIT_CLONE(SDL2 https://github.com/libsdl-org/SDL.git "release-2.30.12") GIT_CLONE(SDL3 https://github.com/libsdl-org/SDL.git "release-3.2.8") GIT_CLONE(xmlsax https://github.com/irov/xmlsax.git) -GIT_CLONE(box2d https://github.com/erincatto/Box2D.git "v3.0.0") +GIT_CLONE(box2d https://github.com/erincatto/Box2D.git "v3.1.1") GIT_CLONE(graphics https://github.com/irov/graphics.git) GIT_CLONE(cmake-modules https://github.com/rpavlik/cmake-modules.git "228f41efa54d6b552f5ef65e5ef46b14f8316f8b") GIT_CLONE(emsdk https://github.com/emscripten-core/emsdk.git "4.0.0") diff --git a/gradle/app.gradle b/gradle/app.gradle index cca370b751..27e1f4e2b7 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -58,12 +58,15 @@ final Boolean MENGINE_APP_PLUGIN_DATADOG = Utils.existAppPlugin("MENGINE_APP_PLU final Boolean MENGINE_APP_PLUGIN_VIBRATOR = Utils.existAppPlugin("MENGINE_APP_PLUGIN_VIBRATOR") final Boolean MENGINE_APP_PLUGIN_AMPLITUDE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMPLITUDE") +final Boolean MENGINE_APP_HAS_ADS = Utils.getBooleanProperty("MENGINE_APP_HAS_ADS", false) + Utils.logString("ANDROID_APP_DELIVERY_PACKAGES", ANDROID_APP_DELIVERY_PACKAGES) Utils.logAvailable("ANDROID_APP_BUILD_PUBLISH", ANDROID_APP_BUILD_PUBLISH) Utils.logAvailable("ANDROID_APP_SPLIT_ENABLE", ANDROID_APP_SPLIT_ENABLE) Utils.logAvailable("ANDROID_APP_BUNDLE_ENABLE", ANDROID_APP_BUNDLE_ENABLE) Utils.logInteger("ANDROID_APP_BUILD_NUMBER", ANDROID_APP_BUILD_NUMBER) Utils.logString("ANDROID_APP_BUILD_VERSION", ANDROID_APP_BUILD_VERSION) +Utils.logAvailable("MENGINE_APP_HAS_ADS", MENGINE_APP_HAS_ADS) if (MENGINE_APP_PLUGIN_GOOGLE_SERVICE == true) { apply plugin: 'com.google.gms.google-services' @@ -379,6 +382,10 @@ if (MENGINE_APP_LIBRARY_MENGINE == true) { Utils.logAvailable("MENGINE_APP_SERVICE_AD", MENGINE_APP_SERVICE_AD) if (MENGINE_APP_SERVICE_AD == true) { + if (MENGINE_APP_HAS_ADS == false) { + throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_SERVICE_AD is enabled. Set -PMENGINE_APP_HAS_ADS=true") + } + android.ext.plugins += 'org.Mengine.Base.MengineAdService' } @@ -417,6 +424,10 @@ if (MENGINE_APP_PLUGIN_GOOGLE_SERVICE == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING", MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING) if (MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING == true) { + if (MENGINE_APP_HAS_ADS == false) { + throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING is enabled. Set -PMENGINE_APP_HAS_ADS=true") + } + android.ext.plugins += 'org.Mengine.Plugin.GoogleAdvertising.MengineGoogleAdvertisingPlugin' dependencies { @@ -664,6 +675,10 @@ if (MENGINE_APP_PLUGIN_MAR == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_ADMOB", MENGINE_APP_PLUGIN_ADMOB) if (MENGINE_APP_PLUGIN_ADMOB == true) { + if (MENGINE_APP_HAS_ADS == false) { + throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_ADMOB is enabled. Set -PMENGINE_APP_HAS_ADS=true") + } + android.ext.plugins += 'org.Mengine.Plugin.AdMob.MengineAdMobPlugin' dependencies { @@ -674,6 +689,10 @@ if (MENGINE_APP_PLUGIN_ADMOB == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_AMAZON", MENGINE_APP_PLUGIN_AMAZON) if (MENGINE_APP_PLUGIN_AMAZON == true) { + if (MENGINE_APP_HAS_ADS == false) { + throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_AMAZON is enabled. Set -PMENGINE_APP_HAS_ADS=true") + } + android.ext.plugins += 'org.Mengine.Plugin.Amazon.MengineAmazonPlugin' dependencies { @@ -684,6 +703,10 @@ if (MENGINE_APP_PLUGIN_AMAZON == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_APPLOVIN", MENGINE_APP_PLUGIN_APPLOVIN) if (MENGINE_APP_PLUGIN_APPLOVIN == true) { + if (MENGINE_APP_HAS_ADS == false) { + throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_APPLOVIN is enabled. Set -PMENGINE_APP_HAS_ADS=true") + } + android.ext.plugins += 'org.Mengine.Plugin.AppLovin.MengineAppLovinPlugin' dependencies { @@ -762,6 +785,7 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { buildConfigField "boolean", "ANDROID_APP_BUILD_PUBLISH", "${ANDROID_APP_BUILD_PUBLISH}" + buildConfigField "boolean", "MENGINE_APP_HAS_ADS", "${MENGINE_APP_HAS_ADS}" } } diff --git a/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java b/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java index 4b5aa8c85c..3c617d2ed4 100644 --- a/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java +++ b/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java @@ -35,4 +35,9 @@ public boolean isBuildPublish() { public String getApplicationOptions() { return BuildConfig.MENGINE_APP_OPTIONS; } + + @Override + public boolean hasAds() { + return BuildConfig.MENGINE_APP_HAS_ADS; + } } \ No newline at end of file diff --git a/gradle/build.gradle b/gradle/build.gradle index 925b297f71..f794746c61 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -13,7 +13,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.13.0' + classpath 'com.android.tools.build:gradle:8.13.1' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0' diff --git a/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java b/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java index 4b5aa8c85c..3c617d2ed4 100644 --- a/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java +++ b/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java @@ -35,4 +35,9 @@ public boolean isBuildPublish() { public String getApplicationOptions() { return BuildConfig.MENGINE_APP_OPTIONS; } + + @Override + public boolean hasAds() { + return BuildConfig.MENGINE_APP_HAS_ADS; + } } \ No newline at end of file diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index 737a1463ee..a302e1d920 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Sep 24 12:58:29 EEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java index c36d281207..e74c968d7e 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java @@ -35,56 +35,56 @@ static private void assertGetter(String key) { } } - static public void addContextParameterBoolean(@Size(min = 1L,max = 40L) String key, boolean value) { + static public void addContextParameterBoolean(@Size(min = 1L, max = 40L) String key, boolean value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_bases.put(key, value); } - static public void addContextParameterString(@Size(min = 1L,max = 40L) String key, @Size(min = 1L,max = 100L) String value) { + static public void addContextParameterString(@Size(min = 1L, max = 40L) String key, @Size(min = 1L, max = 100L) String value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_bases.put(key, value); } - static public void addContextParameterLong(@Size(min = 1L,max = 40L) String key, long value) { + static public void addContextParameterLong(@Size(min = 1L, max = 40L) String key, long value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_bases.put(key, value); } - static public void addContextParameterDouble(@Size(min = 1L,max = 40L) String key, double value) { + static public void addContextParameterDouble(@Size(min = 1L, max = 40L) String key, double value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_bases.put(key, value); } - static public void addContextGetterParameterBoolean(@Size(min = 1L,max = 40L) String key, MengineAnalyticsGetter value) { + static public void addContextGetterParameterBoolean(@Size(min = 1L, max = 40L) String key, MengineAnalyticsGetter value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_getter.put(key, value); } - static public void addContextGetterParameterString(@Size(min = 1L,max = 40L) String key, MengineAnalyticsGetter value) { + static public void addContextGetterParameterString(@Size(min = 1L, max = 40L) String key, MengineAnalyticsGetter value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_getter.put(key, value); } - static public void addContextGetterParameterLong(@Size(min = 1L,max = 40L) String key, MengineAnalyticsGetter value) { + static public void addContextGetterParameterLong(@Size(min = 1L, max = 40L) String key, MengineAnalyticsGetter value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); MengineAnalytics.m_getter.put(key, value); } - static public void addContextGetterParameterDouble(@Size(min = 1L,max = 40L) String key, MengineAnalyticsGetter value) { + static public void addContextGetterParameterDouble(@Size(min = 1L, max = 40L) String key, MengineAnalyticsGetter value) { MengineAnalytics.assertContext(key); MengineAnalytics.assertGetter(key); @@ -110,7 +110,7 @@ static private void collapseGetter(Map parameters) { } } - static public MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L,max = 40L) String name) { + static public MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L, max = 40L) String name) { Map parameters = new HashMap<>(); MengineAnalytics.collapseGetter(parameters); @@ -120,7 +120,7 @@ static public MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L,ma return eventBuilder; } - static public MengineAnalyticsEventBuilderInterface buildEventDummy(@Size(min = 1L,max = 40L) String name) { + static public MengineAnalyticsEventBuilderInterface buildEventDummy(@Size(min = 1L, max = 40L) String name) { MengineAnalyticsEventBuilderInterface eventBuilder = new MengineAnalyticsEventBuilderDummy(name); return eventBuilder; diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilder.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilder.java index 6d99d067aa..db40db0c6f 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilder.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilder.java @@ -11,7 +11,7 @@ public class MengineAnalyticsEventBuilder implements MengineAnalyticsEventBuilde private final Map m_bases; private final Map m_parameters; - MengineAnalyticsEventBuilder(Map bases, Map parameters, @NonNull @Size(min = 1L,max = 40L) String name) { + MengineAnalyticsEventBuilder(Map bases, Map parameters, @NonNull @Size(min = 1L, max = 40L) String name) { m_bases = bases; m_parameters = parameters; m_name = name; @@ -54,7 +54,7 @@ private void assertJSON(@NonNull String key, @NonNull String json) { } @Override - public MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size(min = 1L,max = 40L) String key, boolean value) { + public MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size(min = 1L, max = 40L) String key, boolean value) { this.assertBases(key); this.assertParameters(key); @@ -64,7 +64,7 @@ public MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size( } @Override - public MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { + public MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { this.assertBases(key); this.assertParameters(key); @@ -74,7 +74,7 @@ public MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(m } @Override - public MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Size(min = 1L,max = 40L) String key, @Nullable Exception e) { + public MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Size(min = 1L, max = 40L) String key, @Nullable Exception e) { String message = e != null ? e.getMessage() : null; this.addParameterString(key, message != null ? message : "null"); @@ -83,7 +83,7 @@ public MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Siz } @Override - public MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull Throwable e) { + public MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull Throwable e) { String message = e.getMessage(); this.addParameterString(key, message != null ? message : "null"); @@ -92,7 +92,7 @@ public MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Siz } @Override - public MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { + public MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { this.assertJSON(key, value); this.addParameterString(key, value); @@ -101,7 +101,7 @@ public MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min } @Override - public MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min = 1L,max = 40L) String key, long value) { + public MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min = 1L, max = 40L) String key, long value) { this.assertBases(key); this.assertParameters(key); @@ -111,7 +111,7 @@ public MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min } @Override - public MengineAnalyticsEventBuilderInterface addParameterDouble(@NonNull @Size(min = 1L,max = 40L) String key, double value) { + public MengineAnalyticsEventBuilderInterface addParameterDouble(@NonNull @Size(min = 1L, max = 40L) String key, double value) { this.assertBases(key); this.assertParameters(key); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderDummy.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderDummy.java index e6df7f85be..420d244474 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderDummy.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderDummy.java @@ -7,43 +7,43 @@ public class MengineAnalyticsEventBuilderDummy implements MengineAnalyticsEventBuilderInterface { private final String m_name; - MengineAnalyticsEventBuilderDummy(@NonNull @Size(min = 1L,max = 40L) String name) { + MengineAnalyticsEventBuilderDummy(@NonNull @Size(min = 1L, max = 40L) String name) { m_name = name; } @Override - public MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size(min = 1L,max = 40L) String key, boolean value) { + public MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size(min = 1L, max = 40L) String key, boolean value) { return this; } @Override - public MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { + public MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { return this; } @Override - public MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Size(min = 1L,max = 40L) String key, @Nullable Exception e) { + public MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Size(min = 1L, max = 40L) String key, @Nullable Exception e) { return this; } @Override - public MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull Throwable e) { + public MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull Throwable e) { return this; } @Override - public MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { + public MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value) { return this; } @Override - public MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min = 1L,max = 40L) String key, long value) { + public MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min = 1L, max = 40L) String key, long value) { return this; } @Override - public MengineAnalyticsEventBuilderInterface addParameterDouble(@NonNull @Size(min = 1L,max = 40L) String key, double value) { + public MengineAnalyticsEventBuilderInterface addParameterDouble(@NonNull @Size(min = 1L, max = 40L) String key, double value) { return this; } diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderInterface.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderInterface.java index 56cc41afbf..5fe30e8d10 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderInterface.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalyticsEventBuilderInterface.java @@ -5,13 +5,13 @@ import androidx.annotation.Size; public interface MengineAnalyticsEventBuilderInterface { - MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size(min = 1L,max = 40L) String key, boolean value); - MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value); - MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Size(min = 1L,max = 40L) String key, @Nullable Exception e); - MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull Throwable e); - MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min = 1L,max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value); - MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min = 1L,max = 40L) String key, long value); - MengineAnalyticsEventBuilderInterface addParameterDouble(@NonNull @Size(min = 1L,max = 40L) String key, double value); + MengineAnalyticsEventBuilderInterface addParameterBoolean(@NonNull @Size(min = 1L, max = 40L) String key, boolean value); + MengineAnalyticsEventBuilderInterface addParameterString(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value); + MengineAnalyticsEventBuilderInterface addParameterException(@NonNull @Size(min = 1L, max = 40L) String key, @Nullable Exception e); + MengineAnalyticsEventBuilderInterface addParameterThrowable(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull Throwable e); + MengineAnalyticsEventBuilderInterface addParameterJSON(@NonNull @Size(min = 1L, max = 40L) String key, @NonNull @Size(min = 0L,max = 100L) String value); + MengineAnalyticsEventBuilderInterface addParameterLong(@NonNull @Size(min = 1L, max = 40L) String key, long value); + MengineAnalyticsEventBuilderInterface addParameterDouble(@NonNull @Size(min = 1L, max = 40L) String key, double value); long logAndFlush(); long log(); } \ No newline at end of file diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java index ad59fe0baf..84771508c4 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java @@ -103,6 +103,7 @@ public static String getBuildUsername() { public abstract String getVersionName(); public abstract boolean isBuildPublish(); public abstract String getApplicationOptions(); + public abstract boolean hasAds(); public void createFragment(Class cls) { MengineFragmentInterface fragment = (MengineFragmentInterface) MengineUtils.newInstance(TAG, cls, true); @@ -262,7 +263,7 @@ private String getSecureAndroidId() { return androidId; } - public void setState(@NonNull @Size(min = 1L,max = 1024L) String name, Object value) { + public void setState(@NonNull @Size(min = 1L, max = 1024L) String name, Object value) { MengineLog.logDebug(TAG, "setState: %s = %s" , name , value diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java index dee13018ec..9d8b98d139 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java @@ -18,11 +18,12 @@ public class MengineService implements MengineServiceInterface { private String m_serviceName; private MengineTag m_serviceTag; private boolean m_embedding; + private JSONObject m_serviceConfig = null; private Boolean m_availableStatus = null; private Boolean m_availableAnalytics = null; @Override - public void onAppInitialize(@NonNull MengineApplication application, String serviceName, boolean embedding) { + public void onAppInitialize(@NonNull MengineApplication application, @NonNull String serviceName, boolean embedding) { m_application = application; m_serviceName = serviceName; m_embedding = embedding; @@ -74,7 +75,7 @@ public T getService(Class cls) { } @Override - public Object newInstance(String name, boolean required, Object ... args) { + public Object newInstance(@NonNull String name, boolean required, Object ... args) { ClassLoader cl = this.getClass().getClassLoader(); Object instance = MengineUtils.newInstance(cl, m_serviceTag, name, required, args); @@ -97,40 +98,40 @@ public boolean isEmbedding() { } @Override - public boolean hasOption(String option) { + public boolean hasOption(@NonNull String option) { boolean value = MengineUtils.hasOption(m_application, option); return value; } @Override - public int getOptionValueInteger(String option, int defaultValue) { + public int getOptionValueInteger(@NonNull String option, int defaultValue) { int value = MengineUtils.getOptionValueInteger(m_application, option, defaultValue); return value; } @Override - public long getOptionValueLong(String option, long defaultValue) { + public long getOptionValueLong(@NonNull String option, long defaultValue) { long value = MengineUtils.getOptionValueLong(m_application, option, defaultValue); return value; } @Override - public String getOptionValueString(String option, String defaultValue) { + public String getOptionValueString(@NonNull String option, String defaultValue) { String value = MengineUtils.getOptionValueString(m_application, option, defaultValue); return value; } @Override - public void setStatisticInteger(@Size(min = 1L,max = 40L) String key, long value) { + public void setStatisticInteger(@Size(min = 1L, max = 40L) String key, long value) { MengineStatistic.setInteger(key, value); } @Override - public void increaseStatisticInteger(@Size(min = 1L,max = 40L) String key, long value) { + public void increaseStatisticInteger(@Size(min = 1L, max = 40L) String key, long value) { if (value == 0L) { return; } @@ -139,7 +140,7 @@ public void increaseStatisticInteger(@Size(min = 1L,max = 40L) String key, long } @Override - public void decreaseStatisticInteger(@Size(min = 1L,max = 40L) String key, long value) { + public void decreaseStatisticInteger(@Size(min = 1L, max = 40L) String key, long value) { if (value == 0L) { return; } @@ -148,12 +149,12 @@ public void decreaseStatisticInteger(@Size(min = 1L,max = 40L) String key, long } @Override - public void setStatisticDouble(@Size(min = 1L,max = 40L) String key, double value) { + public void setStatisticDouble(@Size(min = 1L, max = 40L) String key, double value) { MengineStatistic.setDouble(key, value); } @Override - public void increaseStatisticDouble(@Size(min = 1L,max = 40L) String key, double value) { + public void increaseStatisticDouble(@Size(min = 1L, max = 40L) String key, double value) { if (value == 0.0) { return; } @@ -162,7 +163,7 @@ public void increaseStatisticDouble(@Size(min = 1L,max = 40L) String key, double } @Override - public void decreaseStatisticDouble(@Size(min = 1L,max = 40L) String key, double value) { + public void decreaseStatisticDouble(@Size(min = 1L, max = 40L) String key, double value) { if (value == 0.0) { return; } @@ -193,12 +194,12 @@ public String getUserId() { } @Override - public void setState(@NonNull @Size(min = 1L,max = 1024L) String name, Object value) { + public void setState(@NonNull @Size(min = 1L, max = 1024L) String name, Object value) { m_application.setState(name, value); } @Override - public String logVerbose(String format, Object ... args) { + public String logVerbose(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logVerbose(t, format, args); @@ -206,7 +207,7 @@ public String logVerbose(String format, Object ... args) { } @Override - public String logDebug(String format, Object ... args) { + public String logDebug(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logDebug(t, format, args); @@ -214,7 +215,7 @@ public String logDebug(String format, Object ... args) { } @Override - public String logInfo(String format, Object ... args) { + public String logInfo(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logInfo(t, format, args); @@ -222,7 +223,7 @@ public String logInfo(String format, Object ... args) { } @Override - public String logMessage(String format, Object ... args) { + public String logMessage(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logMessage(t, format, args); @@ -230,7 +231,7 @@ public String logMessage(String format, Object ... args) { } @Override - public String logMessageProtected(String format, Object ... args) { + public String logMessageProtected(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logMessageProtected(t, format, args); @@ -238,7 +239,7 @@ public String logMessageProtected(String format, Object ... args) { } @Override - public String logMessageRelease(String format, Object ... args) { + public String logMessageRelease(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logMessageRelease(t, format, args); @@ -246,7 +247,7 @@ public String logMessageRelease(String format, Object ... args) { } @Override - public String logWarning(String format, Object ... args) { + public String logWarning(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logWarning(t, format, args); @@ -254,7 +255,7 @@ public String logWarning(String format, Object ... args) { } @Override - public String logError(String format, Object ... args) { + public String logError(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); String m = MengineLog.logError(t, format, args); @@ -268,19 +269,45 @@ public void logException(@NonNull Throwable e, @NonNull Map attr } @Override - public void assertionError(String format, Object ... args) { + public void assertionError(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); MengineUtils.throwAssertionError(t, null, format, args); } - private boolean availableAnalytics() { + @Override + public JSONObject getServiceConfig() { + if (m_serviceConfig == null) { + String serviceTag = m_serviceTag.toString(); + + JSONObject serviceConfig = MengineFragmentRemoteConfig.INSTANCE.getRemoteConfigValue(serviceTag); + + m_serviceConfig = serviceConfig; + } + + return m_serviceConfig; + } + + @Override + public String getServiceConfigOptString(@NonNull String key, @NonNull String defaultValue) { + JSONObject serviceConfig = this.getServiceConfig(); + + if (serviceConfig == null) { + return defaultValue; + } + + String value = serviceConfig.optString(key, defaultValue); + + return value; + } + + public boolean availableAnalytics() { if (m_availableAnalytics == null) { - JSONObject config_analytics = MengineFragmentRemoteConfig.INSTANCE.getRemoteConfigValue("plugin_" + m_serviceName); + JSONObject serviceConfig = this.getServiceConfig(); - if (config_analytics == null) { + if (serviceConfig == null) { m_availableAnalytics = false; } else { - boolean enabled = config_analytics.optBoolean("enable_analytics", false); + boolean enabled = serviceConfig.optBoolean("enable_analytics", false); m_availableAnalytics = enabled; } @@ -290,7 +317,7 @@ private boolean availableAnalytics() { } @Override - public MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L,max = 40L) String name) { + public MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L, max = 40L) String name) { if (this.availableAnalytics() == false) { MengineAnalyticsEventBuilderInterface eventBuilderDummy = MengineAnalytics.buildEventDummy(name); eventBuilderDummy.addParameterString("service", m_serviceName); @@ -305,18 +332,18 @@ public MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L,max = 40L } @Override - public void nativeCall(String method, Object ... args) { + public void nativeCall(@NonNull String method, Object ... args) { MengineTag t = this.getServiceTag(); m_application.nativeCall(t.toString(), method, args); } @Override - public void activateSemaphore(String name) { + public void activateSemaphore(@NonNull String name) { m_application.activateSemaphore(name); } @Override - public void deactivateSemaphore(String name) { + public void deactivateSemaphore(@NonNull String name) { m_application.deactivateSemaphore(name); } diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java index bbe467d6bf..4a658fd6a0 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java @@ -9,6 +9,8 @@ import androidx.annotation.Size; import androidx.annotation.StringRes; +import org.json.JSONObject; + import java.util.Map; public interface MengineServiceInterface { @@ -18,7 +20,7 @@ default boolean onAvailable(@NonNull MengineApplication application) { return true; } - void onAppInitialize(@NonNull MengineApplication application, String serviceName, boolean embedding); + void onAppInitialize(@NonNull MengineApplication application, @NonNull String serviceName, boolean embedding); void onAppFinalize(@NonNull MengineApplication application); void onActivityInitialize(@NonNull MengineActivity activity); @@ -39,48 +41,51 @@ default Bundle onSave(@NonNull MengineApplication application) { MengineTag getServiceTag(); T getService(Class cls); - Object newInstance(String name, boolean required, Object ... args); + Object newInstance(@NonNull String name, boolean required, Object ... args); boolean isAvailable(); boolean isEmbedding(); - boolean hasOption(String option); - int getOptionValueInteger(String option, int defaultValue); - long getOptionValueLong(String option, long defaultValue); - String getOptionValueString(String option, String defaultValue); + boolean hasOption(@NonNull String option); + int getOptionValueInteger(@NonNull String option, int defaultValue); + long getOptionValueLong(@NonNull String option, long defaultValue); + String getOptionValueString(@NonNull String option, String defaultValue); + + void setStatisticInteger(@Size(min = 1L, max = 40L) String key, long value); + void increaseStatisticInteger(@Size(min = 1L, max = 40L) String key, long value); + void decreaseStatisticInteger(@Size(min = 1L, max = 40L) String key, long value); + void setStatisticDouble(@Size(min = 1L, max = 40L) String key, double value); + void increaseStatisticDouble(@Size(min = 1L, max = 40L) String key, double value); + void decreaseStatisticDouble(@Size(min = 1L, max = 40L) String key, double value); - void setStatisticInteger(@Size(min = 1L,max = 40L) String key, long value); - void increaseStatisticInteger(@Size(min = 1L,max = 40L) String key, long value); - void decreaseStatisticInteger(@Size(min = 1L,max = 40L) String key, long value); - void setStatisticDouble(@Size(min = 1L,max = 40L) String key, double value); - void increaseStatisticDouble(@Size(min = 1L,max = 40L) String key, double value); - void decreaseStatisticDouble(@Size(min = 1L,max = 40L) String key, double value); + JSONObject getServiceConfig(); + String getServiceConfigOptString(@NonNull String key, @NonNull String defaultValue); boolean runOnUiThread(String doc, Runnable action); String getUserId(); - void setState(@NonNull @Size(min = 1L,max = 1024L) String name, Object value); + void setState(@NonNull @Size(min = 1L, max = 1024L) String name, Object value); - String logVerbose(String format, Object ... args); - String logDebug(String format, Object ... args); - String logInfo(String format, Object ... args); - String logMessage(String format, Object ... args); - String logMessageProtected(String format, Object ... args); - String logMessageRelease(String format, Object ... args); - String logWarning(String format, Object ... args); - String logError(String format, Object ... args); + String logVerbose(@NonNull String format, Object ... args); + String logDebug(@NonNull String format, Object ... args); + String logInfo(@NonNull String format, Object ... args); + String logMessage(@NonNull String format, Object ... args); + String logMessageProtected(@NonNull String format, Object ... args); + String logMessageRelease(@NonNull String format, Object ... args); + String logWarning(@NonNull String format, Object ... args); + String logError(@NonNull String format, Object ... args); void logException(@NonNull Throwable e, @NonNull Map attributes); - void assertionError(String format, Object ... args); + void assertionError(@NonNull String format, Object ... args); - MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L,max = 40L) String name); + MengineAnalyticsEventBuilderInterface buildEvent(@Size(min = 1L, max = 40L) String name); - void nativeCall(String method, Object ... args); + void nativeCall(@NonNull String method, Object ... args); - void activateSemaphore(String name); - void deactivateSemaphore(String name); + void activateSemaphore(@NonNull String name); + void deactivateSemaphore(@NonNull String name); String getResourceName(@AnyRes int id); boolean getResourceBoolean(@BoolRes int id); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineTag.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineTag.java index b8c3430de5..12cfc182a7 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineTag.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineTag.java @@ -8,11 +8,11 @@ public final class MengineTag { private final String value; - private MengineTag(@NonNull @Size(min = 1L,max = MengineTag.MAX_LENGTH) String value) { + private MengineTag(@NonNull @Size(min = 1L, max = MengineTag.MAX_LENGTH) String value) { this.value = value; } - public static MengineTag of(@NonNull @Size(min = 1L,max = MengineTag.MAX_LENGTH) String value) { + public static MengineTag of(@NonNull @Size(min = 1L, max = MengineTag.MAX_LENGTH) String value) { return new MengineTag(value); } diff --git a/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java b/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java index 3cf592407d..c773d57392 100644 --- a/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java +++ b/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java @@ -97,13 +97,19 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS config.setLogLevel(LogLevel.INFO); } - Adjust.getAdid(adid -> { - this.logInfo("Adjust adid: %s" - , MengineUtils.getRedactedValue(adid) - ); - - application.setADID(adid); - }); + boolean hasAds = application.hasAds(); + + if (hasAds == true) { + Adjust.getAdid(adid -> { + this.logInfo("Adjust adid: %s" + , MengineUtils.getRedactedValue(adid) + ); + + application.setADID(adid); + }); + } else { + this.logInfo("Skip Adjust AdID request, ads disabled"); + } config.setOnAttributionChangedListener(attribution -> { this.logInfo("Adjust attribution changed: %s" @@ -201,6 +207,11 @@ public void onMengineChangePushToken(@NonNull MengineApplication application, St @Override public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull MengineParamAdRevenue revenue) { + if (application.hasAds() == false) { + this.logInfo("Skip Adjust AdRevenue, ads disabled"); + return; + } + MengineAdMediation mediation = revenue.ADREVENUE_MEDIATION; String AdjustMediation = MengineAdjustPlugin.getAdjustMediation(mediation); String network = revenue.ADREVENUE_NETWORK; @@ -222,6 +233,11 @@ public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull @Override public void onMengineTransparencyConsent(@NonNull MengineApplication application, @NonNull MengineParamTransparencyConsent tcParam) { + if (application.hasAds() == false) { + this.logInfo("Skip Adjust third-party sharing, ads disabled"); + return; + } + boolean EEA = tcParam.isEEA(); boolean AD_PERSONALIZATION = tcParam.getConsentAdPersonalization(); boolean AD_USER_DATA = tcParam.getConsentAdUserData(); diff --git a/gradle/plugins/Amplitude/build.gradle b/gradle/plugins/Amplitude/build.gradle index 6b587ff4a8..a5484031f1 100644 --- a/gradle/plugins/Amplitude/build.gradle +++ b/gradle/plugins/Amplitude/build.gradle @@ -6,7 +6,7 @@ android { } dependencies { - implementation 'com.squareup.okhttp3:okhttp:5.2.1' + implementation 'com.squareup.okhttp3:okhttp:5.3.0' implementation 'com.amplitude:analytics-android:1.22.4' } \ No newline at end of file diff --git a/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java b/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java index b083e916ca..172431f59a 100644 --- a/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java +++ b/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Set; import okhttp3.OkHttpClient; @@ -40,9 +41,10 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS String MengineAmplitudePlugin_ApiKey = this.getResourceString(METADATA_API_KEY); Configuration configuration = new Configuration(MengineAmplitudePlugin_ApiKey, application); - configuration.getAutocapture().add(AutocaptureOption.SESSIONS); - configuration.getAutocapture().add(AutocaptureOption.APP_LIFECYCLES); - configuration.getAutocapture().add(AutocaptureOption.SCREEN_VIEWS); + Set autocaptureOptions = configuration.getAutocapture(); + autocaptureOptions.add(AutocaptureOption.SESSIONS); + autocaptureOptions.add(AutocaptureOption.APP_LIFECYCLES); + autocaptureOptions.add(AutocaptureOption.SCREEN_VIEWS); configuration.setFlushEventsOnClose(true); Amplitude amplitude = new Amplitude(configuration); diff --git a/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java b/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java index 707187a831..630b32a9ac 100644 --- a/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java +++ b/gradle/plugins/AppLovin/AppOpenAd/src/main/java/org/Mengine/Plugin/AppLovin/AppOpenAd/MengineAppLovinAppOpenAd.java @@ -40,22 +40,14 @@ public class MengineAppLovinAppOpenAd extends MengineAppLovinBase implements Men public MengineAppLovinAppOpenAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.APP_OPEN); - String MengineAppLovinPlugin_AppOpen_AdUnitId = plugin.getResourceString(METADATA_APPOPEN_ADUNITID); - - if (MengineAppLovinPlugin_AppOpen_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , METADATA_APPOPEN_ADUNITID - ); - } - - this.setAdUnitId(MengineAppLovinPlugin_AppOpen_AdUnitId); + this.setAdUnitId(METADATA_APPOPEN_ADUNITID, "AppOpenAdUnitId"); String MengineAppLovinPlugin_AppOpen_Placement = plugin.getResourceString(METADATA_APPOPEN_PLACEMENT); m_placement = MengineAppLovinPlugin_AppOpen_Placement; } - protected MengineAnalyticsEventBuilderInterface buildAppOpenAdEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildAppOpenAdEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_applovin_appopen_" + event) .addParameterString("placement", m_placement) ; diff --git a/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java b/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java index 0c5fef0dab..1a12acb6de 100644 --- a/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java +++ b/gradle/plugins/AppLovin/BannerAd/src/main/java/org/Mengine/Plugin/AppLovin/BannerAd/MengineAppLovinBannerAd.java @@ -23,6 +23,7 @@ import org.Mengine.Base.MengineActivity; import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineFragmentRemoteConfig; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineUtils; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinBannerAdInterface; @@ -46,16 +47,7 @@ public class MengineAppLovinBannerAd extends MengineAppLovinBase implements Meng public MengineAppLovinBannerAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.BANNER); - String MengineAppLovinPlugin_Banner_AdUnitId = plugin.getResourceString(METADATA_BANNER_ADUNITID); - - if (MengineAppLovinPlugin_Banner_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , plugin.getResourceName(METADATA_BANNER_ADUNITID) - , MengineAppLovinPlugin_Banner_AdUnitId - ); - } - - this.setAdUnitId(MengineAppLovinPlugin_Banner_AdUnitId); + this.setAdUnitId(METADATA_BANNER_ADUNITID, "BannerAdUnitId"); String MengineAppLovinPlugin_Banner_Placement = plugin.getResourceString(METADATA_BANNER_PLACEMENT); @@ -68,7 +60,7 @@ protected AppLovinSdkUtils.Size getBannerSize(@NonNull MengineActivity activity) return size; } - protected MengineAnalyticsEventBuilderInterface buildBannerAdEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildBannerAdEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_applovin_banner_" + event) .addParameterString("placement", m_placement); diff --git a/gradle/plugins/AppLovin/Core/build.gradle b/gradle/plugins/AppLovin/Core/build.gradle index 0f69a25a6f..69168f5990 100644 --- a/gradle/plugins/AppLovin/Core/build.gradle +++ b/gradle/plugins/AppLovin/Core/build.gradle @@ -98,19 +98,19 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_ADMOB == true) { - implementation 'com.applovin.mediation:google-adapter:24.6.0.0' + implementation 'com.applovin.mediation:google-adapter:24.7.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_AMAZON == true) { - implementation 'com.applovin.mediation:amazon-tam-adapter:11.0.4.0' + implementation 'com.applovin.mediation:amazon-tam-adapter:11.1.0.1' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIDMACHINE == true) { - implementation 'com.applovin.mediation:bidmachine-adapter:3.4.0.0' + implementation 'com.applovin.mediation:bidmachine-adapter:3.5.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_BIGO == true) { - implementation 'com.applovin.mediation:bigoads-adapter:5.5.1.2' + implementation 'com.applovin.mediation:bigoads-adapter:5.5.2.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_CHARTBOOST == true) { @@ -118,11 +118,11 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_DTEXCHANGE == true) { - implementation 'com.applovin.mediation:fyber-adapter:8.3.8.0' + implementation 'com.applovin.mediation:fyber-adapter:8.4.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_GOOGLEADMANAGER == true) { - implementation 'com.applovin.mediation:google-ad-manager-adapter:24.6.0.0' + implementation 'com.applovin.mediation:google-ad-manager-adapter:24.7.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX == true) { @@ -156,7 +156,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MINTEGRAL == true) { - implementation 'com.applovin.mediation:mintegral-adapter:16.9.91.0' + implementation 'com.applovin.mediation:mintegral-adapter:16.10.11.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOBILEFUSE == true) { @@ -164,7 +164,7 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MOLOCO == true) { - implementation 'com.applovin.mediation:moloco-adapter:4.1.0.0' + implementation 'com.applovin.mediation:moloco-adapter:4.2.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY == true) { @@ -172,11 +172,11 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PANGLE == true) { - implementation 'com.applovin.mediation:bytedance-adapter:7.6.0.2.0' + implementation 'com.applovin.mediation:bytedance-adapter:7.7.0.2.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_PUBMATIC == true) { - implementation 'com.applovin.mediation:pubmatic-adapter:4.9.1.0' + implementation 'com.applovin.mediation:pubmatic-adapter:4.10.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_SMAATO == true) { @@ -184,19 +184,19 @@ dependencies { } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_UNITYADS == true) { - implementation 'com.applovin.mediation:unityads-adapter:4.16.1.0' + implementation 'com.applovin.mediation:unityads-adapter:4.16.3.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VERVE == true) { - implementation 'com.applovin.mediation:verve-adapter:3.6.2.0' + implementation 'com.applovin.mediation:verve-adapter:3.7.1.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_VK == true) { - implementation 'com.applovin.mediation:mytarget-adapter:5.27.3.0' + implementation 'com.applovin.mediation:mytarget-adapter:5.27.4.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YANDEX == true) { - implementation 'com.applovin.mediation:yandex-adapter:7.16.0.0' + implementation 'com.applovin.mediation:yandex-adapter:7.16.1.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_YSO == true) { diff --git a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java index 8aba79dd89..5631bc2e5a 100644 --- a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java +++ b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinBase.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Size; +import androidx.annotation.StringRes; import com.applovin.mediation.MaxAd; import com.applovin.mediation.MaxAdFormat; @@ -25,6 +26,7 @@ import org.Mengine.Base.MengineParamAdRevenue; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineUtils; +import org.json.JSONObject; import java.util.List; import java.util.Locale; @@ -59,7 +61,23 @@ public MengineAppLovinPluginInterface getPlugin() { return m_plugin; } - protected void setAdUnitId(@NonNull String adUnitId) { + protected void setAdUnitId(@StringRes int METADATA_ADUNITID, @NonNull String configAdUnitId) throws MengineServiceInvalidInitializeException { + String metadataAdUnitId = m_plugin.getResourceString(METADATA_ADUNITID); + + if (metadataAdUnitId.isEmpty() == true) { + this.invalidInitialize("meta %s not found" + , m_plugin.getResourceName(METADATA_ADUNITID) + ); + } + + String adUnitId = m_plugin.getServiceConfigOptString(configAdUnitId, metadataAdUnitId); + + if (adUnitId == null) { + this.invalidInitialize("config %s is empty" + , configAdUnitId + ); + } + m_adUnitId = adUnitId; } @@ -227,11 +245,11 @@ protected String getMaxErrorParams(@NonNull MaxError error) { return params; } - protected void setState(@NonNull @Size(min = 1L,max = 1024L) String name, Object value) { + protected void setState(@NonNull @Size(min = 1L, max = 1024L) String name, Object value) { m_plugin.setState(name, value); } - protected MengineAnalyticsEventBuilderInterface buildAdEvent(@Size(min = 1L,max = 40L) String name) { + protected MengineAnalyticsEventBuilderInterface buildAdEvent(@Size(min = 1L, max = 40L) String name) { long requestTime = this.getRequestTime(); MengineAnalyticsEventBuilderInterface eventBuilder = m_plugin.buildEvent(name); diff --git a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java index fa5b7c5797..1df5e64711 100644 --- a/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java +++ b/gradle/plugins/AppLovin/InterstitialAd/src/main/java/org/Mengine/Plugin/AppLovin/InterstitialAd/MengineAppLovinInterstitialAd.java @@ -27,6 +27,7 @@ import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinBase; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinInterstitialAdInterface; import org.Mengine.Plugin.AppLovin.Core.MengineAppLovinPluginInterface; +import org.json.JSONObject; import java.util.Map; @@ -40,18 +41,10 @@ public class MengineAppLovinInterstitialAd extends MengineAppLovinBase implement public MengineAppLovinInterstitialAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.INTERSTITIAL); - String MengineAppLovinPlugin_Interstitial_AdUnitId = plugin.getResourceString(METADATA_INTERSTITIAL_ADUNITID); - - if (MengineAppLovinPlugin_Interstitial_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , plugin.getResourceName(METADATA_INTERSTITIAL_ADUNITID) - ); - } - - this.setAdUnitId(MengineAppLovinPlugin_Interstitial_AdUnitId); + this.setAdUnitId(METADATA_INTERSTITIAL_ADUNITID, "InterstitialAdUnitId"); } - protected MengineAnalyticsEventBuilderInterface buildInterstitialAdEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildInterstitialAdEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_applovin_interstitial_" + event); return builder; diff --git a/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java b/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java index 5ddbc1cf5d..73c17dc7a4 100644 --- a/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java +++ b/gradle/plugins/AppLovin/MRECAd/src/main/java/org/Mengine/Plugin/AppLovin/MRECAd/MengineAppLovinMRECAd.java @@ -46,22 +46,14 @@ public class MengineAppLovinMRECAd extends MengineAppLovinBase implements Mengin public MengineAppLovinMRECAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.MREC); - String MengineAppLovinPlugin_MREC_AdUnitId = plugin.getResourceString(METADATA_MREC_ADUNITID); - - if (MengineAppLovinPlugin_MREC_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , METADATA_MREC_ADUNITID - ); - } - - this.setAdUnitId(MengineAppLovinPlugin_MREC_AdUnitId); + this.setAdUnitId(METADATA_MREC_ADUNITID, "MRECAdUnitId"); String MengineAppLovinPlugin_MREC_Placement = plugin.getResourceString(METADATA_MREC_PLACEMENT); m_placement = MengineAppLovinPlugin_MREC_Placement; } - protected MengineAnalyticsEventBuilderInterface buildMRECAdEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildMRECAdEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_applovin_mrec_" + event) .addParameterString("placement", m_placement); diff --git a/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java b/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java index c3cfbf8469..dfcea963f3 100644 --- a/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java +++ b/gradle/plugins/AppLovin/NativeAd/src/main/java/org/Mengine/Plugin/AppLovin/NativeAd/MengineAppLovinNativeAd.java @@ -47,22 +47,14 @@ public class MengineAppLovinNativeAd extends MengineAppLovinBase implements Meng public MengineAppLovinNativeAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.NATIVE); - String MengineAppLovinPlugin_Native_AdUnitId = plugin.getResourceString(METADATA_NATIVE_ADUNITID); - - if (MengineAppLovinPlugin_Native_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , METADATA_NATIVE_ADUNITID - ); - } - - this.setAdUnitId(MengineAppLovinPlugin_Native_AdUnitId); + this.setAdUnitId(METADATA_NATIVE_ADUNITID, "NativeAdUnitId"); String MengineAppLovinPlugin_Native_Placement = plugin.getResourceString(METADATA_NATIVE_PLACEMENT); m_placement = MengineAppLovinPlugin_Native_Placement; } - protected MengineAnalyticsEventBuilderInterface buildNativeAdEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildNativeAdEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_applovin_native_" + event) .addParameterString("placement", m_placement); diff --git a/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java b/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java index 4955072b59..92f8b44f0c 100644 --- a/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java +++ b/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java @@ -56,7 +56,7 @@ static protected class NonetBanner { protected MengineRunnablePeriodically m_refreshTimer; - protected MengineAnalyticsEventBuilderInterface buildNonetBannersEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildNonetBannersEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = m_plugin.buildEvent("mng_applovin_nonet_banners_" + event); return builder; diff --git a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java index 8bf5395e70..9778fae336 100644 --- a/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java +++ b/gradle/plugins/AppLovin/RewardedAd/src/main/java/org/Mengine/Plugin/AppLovin/RewardedAd/MengineAppLovinRewardedAd.java @@ -42,18 +42,10 @@ public class MengineAppLovinRewardedAd extends MengineAppLovinBase implements Me public MengineAppLovinRewardedAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { super(adService, plugin, MaxAdFormat.REWARDED); - String MengineAppLovinPlugin_Rewarded_AdUnitId = plugin.getResourceString(METADATA_REWARDED_ADUNITID); - - if (MengineAppLovinPlugin_Rewarded_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , plugin.getResourceName(METADATA_REWARDED_ADUNITID) - ); - } - - this.setAdUnitId(MengineAppLovinPlugin_Rewarded_AdUnitId); + this.setAdUnitId(METADATA_REWARDED_ADUNITID, "RewardedAdUnitId"); } - protected MengineAnalyticsEventBuilderInterface buildRewardedAdEvent(@Size(min = 1L,max = 40L) String event) { + protected MengineAnalyticsEventBuilderInterface buildRewardedAdEvent(@Size(min = 1L, max = 40L) String event) { MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_applovin_rewarded_" + event); return builder; diff --git a/gradle/plugins/Firebase/build.gradle b/gradle/plugins/Firebase/build.gradle index 4bb08e57da..61279123e8 100644 --- a/gradle/plugins/Firebase/build.gradle +++ b/gradle/plugins/Firebase/build.gradle @@ -5,7 +5,7 @@ android { } dependencies { - api enforcedPlatform('com.google.firebase:firebase-bom:34.4.0') + api enforcedPlatform('com.google.firebase:firebase-bom:34.6.0') implementation 'com.google.firebase:firebase-common:22.0.1' } diff --git a/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java b/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java index 761fc1af80..90e294670a 100644 --- a/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java +++ b/gradle/plugins/FirebaseCrashlytics/src/main/java/org/Mengine/Plugin/FirebaseCrashlytics/MengineFirebaseCrashlyticsPlugin.java @@ -142,7 +142,7 @@ public void recordException(Throwable throwable) { FirebaseCrashlytics.getInstance().recordException(throwable); } - public void setCustomKey(@NonNull @Size(min = 1L,max = 1024L) String key, Object value) { + public void setCustomKey(@NonNull @Size(min = 1L, max = 1024L) String key, Object value) { if (value == null) { FirebaseCrashlytics.getInstance().setCustomKey(key, "null"); } else if (value instanceof Boolean booleanValue) { diff --git a/gradle/plugins/FirebasePerformanceMonitoring/build.gradle b/gradle/plugins/FirebasePerformanceMonitoring/build.gradle index 7fed37c23a..de9613a38c 100644 --- a/gradle/plugins/FirebasePerformanceMonitoring/build.gradle +++ b/gradle/plugins/FirebasePerformanceMonitoring/build.gradle @@ -8,5 +8,5 @@ android { dependencies { implementation project(':plugins:Firebase') - implementation 'com.google.firebase:firebase-perf:22.0.2' + implementation 'com.google.firebase:firebase-perf:22.0.4' } \ No newline at end of file diff --git a/src/Engine/Application.cpp b/src/Engine/Application.cpp index f5a69c59b5..6f8d6ed650 100644 --- a/src/Engine/Application.cpp +++ b/src/Engine/Application.cpp @@ -1821,10 +1821,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Application::render() { + m_renderPipeline->clear(); + if( m_nopause == false && m_focus == false ) { - m_renderPipeline->clear(); - return false; } @@ -1838,9 +1838,7 @@ namespace Mengine ->render( m_renderPipeline ); RENDER_SERVICE() - ->endScene( m_renderPipeline ); - - m_renderPipeline->clear(); + ->endScene( m_renderPipeline ); return true; } diff --git a/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp b/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp index 8ff583028a..6f93beaad0 100644 --- a/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp @@ -103,7 +103,7 @@ namespace Mengine return false; } - ConstString Game_PersonalityModule = CONFIG_VALUE_CONSTSTRING( "Game", "PersonalityModule", STRINGIZE_FILEPATH_LOCAL( "Personality" ) ); + ConstString Game_PersonalityModule = CONFIG_VALUE_CONSTSTRING( "Game", "PersonalityModule", STRINGIZE_STRING_LOCAL( "Personality" ) ); ScriptModuleInterfacePtr module = SCRIPT_SERVICE() ->importModule( Game_PersonalityModule ); diff --git a/src/Interface/RenderBatchInterface.h b/src/Interface/RenderBatchInterface.h index e2c0f69da2..9b13d2f946 100644 --- a/src/Interface/RenderBatchInterface.h +++ b/src/Interface/RenderBatchInterface.h @@ -42,6 +42,10 @@ namespace Mengine virtual void setIndexBuffer( const RenderIndexBufferInterfacePtr & _vertexBuffer ) = 0; virtual const RenderIndexBufferInterfacePtr & getIndexBuffer() const = 0; + public: + virtual bool lock() = 0; + virtual bool unlock() = 0; + public: virtual RenderBatchLockData * getLockData() = 0; }; diff --git a/src/Interface/RenderSystemInterface.h b/src/Interface/RenderSystemInterface.h index 98f5ad45cf..2d5dd86b99 100644 --- a/src/Interface/RenderSystemInterface.h +++ b/src/Interface/RenderSystemInterface.h @@ -102,6 +102,7 @@ namespace Mengine virtual RenderVertexShaderInterfacePtr createVertexShader( const ConstString & _name, const MemoryInterfacePtr & _memory, bool _compile, const DocumentInterfacePtr & _doc ) = 0; virtual RenderProgramInterfacePtr createProgram( const ConstString & _name, const RenderVertexShaderInterfacePtr & _vertex, const RenderFragmentShaderInterfacePtr & _fragment, const RenderVertexAttributeInterfacePtr & _vertexAttribute, uint32_t _samplerCount, const DocumentInterfacePtr & _doc ) = 0; + public: virtual void setProgram( const RenderProgramInterfacePtr & _program ) = 0; virtual void updateProgram( const RenderProgramInterfacePtr & _program ) = 0; virtual RenderProgramVariableInterfacePtr createProgramVariable( uint32_t _vertexCount, uint32_t _pixelCount, const DocumentInterfacePtr & _doc ) = 0; diff --git a/src/Interface/ThreadProcessorInterface.h b/src/Interface/ThreadProcessorInterface.h index 37b264d3ec..78d0cca9de 100644 --- a/src/Interface/ThreadProcessorInterface.h +++ b/src/Interface/ThreadProcessorInterface.h @@ -23,7 +23,7 @@ namespace Mengine virtual ThreadId getThreadId() const = 0; public: - virtual bool processTask( ThreadTaskInterface * _task ) = 0; + virtual bool processTask( const ThreadTaskInterfacePtr & _task ) = 0; virtual void removeTask() = 0; public: diff --git a/src/Kernel/BaseTransformation.cpp b/src/Kernel/BaseTransformation.cpp index 5be1b00d71..a72e90f4cb 100644 --- a/src/Kernel/BaseTransformation.cpp +++ b/src/Kernel/BaseTransformation.cpp @@ -292,14 +292,14 @@ namespace Mengine this->invalidateLocalMatrix(); } ////////////////////////////////////////////////////////////////////////// - void BaseTransformation::setLocalOrientation( const mt::vec3f & _euler ) + void BaseTransformation::setLocalOrientation( const mt::vec3f & _orientation ) { - if( mt::cmp_v3_v3( m_orientation, _euler ) == true ) + if( mt::cmp_v3_v3( m_orientation, _orientation ) == true ) { return; } - m_orientation = _euler; + m_orientation = _orientation; if( mt::equal_f_z( m_orientation.x ) == true ) { diff --git a/src/Kernel/Delegate.h b/src/Kernel/Delegate.h index 7bb9715ed2..3390a0f8d1 100644 --- a/src/Kernel/Delegate.h +++ b/src/Kernel/Delegate.h @@ -23,7 +23,7 @@ namespace Mengine template auto operator () ( Args && ... _args ) const { - return std::apply( m_method, std::tuple_cat( std::make_tuple( m_ptr ), std::tuple_cat( std::make_tuple( std::forward( _args ) ... ), m_forwards ) ) ); + return std::apply( m_method, std::tuple_cat( std::make_tuple( m_ptr ), std::tuple_cat( std::forward_as_tuple( std::forward( _args ) ... ), m_forwards ) ) ); } protected: @@ -49,7 +49,7 @@ namespace Mengine { P * ptr = m_ptr.get(); - return std::apply( m_method, std::tuple_cat( std::make_tuple( ptr ), std::tuple_cat( std::make_tuple( std::forward( _args ) ... ), m_forwards ) ) ); + return std::apply( m_method, std::tuple_cat( std::make_tuple( ptr ), std::tuple_cat( std::forward_as_tuple( std::forward( _args ) ... ), m_forwards ) ) ); } protected: diff --git a/src/Kernel/Node.h b/src/Kernel/Node.h index 17e66dea39..1198af8770 100644 --- a/src/Kernel/Node.h +++ b/src/Kernel/Node.h @@ -45,7 +45,7 @@ namespace Mengine , public AffectorHubProviderInterface , public Updatable , public Renderable - , public Transformable + , public Transformable , public Animatable , public Eventable , public Pickerable @@ -64,6 +64,7 @@ namespace Mengine public: HashType getHierarchyHash() const; + public: NodePtr findUniqueChild( UniqueId _uniqueIdentity ) const; protected: diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h new file mode 100644 index 0000000000..de60ce8df7 --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h @@ -0,0 +1,7 @@ +#import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" + +@interface AppleUserMessagingPlatformApplicationDelegate : NSObject + +@end + + diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm new file mode 100644 index 0000000000..58ea3d5873 --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -0,0 +1,73 @@ +#import "AppleUserMessagingPlatformApplicationDelegate.h" + +#import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSTransparencyConsentParam.h" +#import "Environment/iOS/iOSConsentFlowUserGeography.h" + +#import + +@implementation AppleUserMessagingPlatformApplicationDelegate + +#pragma mark - helpers + +- (void)notifyConsentChangedFromDefaults { + iOSTransparencyConsentParam * consent = [[iOSTransparencyConsentParam alloc] initFromUserDefaults]; + + // Infer geography based on IABTCF_gdprApplies when present + if ([consent isEEA] == YES) { + [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyGDPR]; + } else { + [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; + } + + [iOSDetail transparencyConsent:consent]; +} + +- (void)runUMPFlow { + UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init]; + // Debug settings can be added later via bundle config if needed + + [UMPConsentInformation.sharedInstance requestConsentInfoUpdateWithParameters:parameters completionHandler:^(NSError * _Nullable error) { + if (error != nil) { + IOS_LOGGER_MESSAGE(@"[UMP] requestConsentInfoUpdate error: %@", error); + [self notifyConsentChangedFromDefaults]; + return; + } + + UMPFormStatus formStatus = UMPConsentInformation.sharedInstance.formStatus; + if (formStatus == UMPFormStatusAvailable) { + [UMPConsentForm loadWithCompletionHandler:^(UMPConsentForm * _Nullable form, NSError * _Nullable loadError) { + if (loadError != nil) { + IOS_LOGGER_MESSAGE(@"[UMP] loadWithCompletionHandler error: %@", loadError); + [self notifyConsentChangedFromDefaults]; + return; + } + + UIViewController * rootVC = [iOSDetail getRootViewController]; + [form presentFromViewController:rootVC completionHandler:^(NSError * _Nullable dismissError) { + if (dismissError != nil) { + IOS_LOGGER_MESSAGE(@"[UMP] present dismiss error: %@", dismissError); + } + + // After form dismissal, UMP writes IABTCF_* to NSUserDefaults. Broadcast updated consent. + [self notifyConsentChangedFromDefaults]; + }]; + }]; + } else { + // No form to show; just propagate current consent state from defaults + [self notifyConsentChangedFromDefaults]; + } + }]; +} + +#pragma mark - iOSPluginApplicationDelegateInterface + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [self runUMPFlow]; + return YES; +} + +@end + + diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt new file mode 100644 index 0000000000..639ffdefec --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt @@ -0,0 +1,15 @@ +MENGINE_PROJECT(AppleUserMessagingPlatformPlugin) + +ADD_FILTER( +src + AppleUserMessagingPlatformApplicationDelegate.h + AppleUserMessagingPlatformApplicationDelegate.mm +) + +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM) + +ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleUserMessagingPlatformApplicationDelegate") + +ADD_MENGINE_COCOAPOD("GoogleUserMessagingPlatform" "NO-GIT" "2.2.0") + + diff --git a/src/Plugins/Box2DPlugin/Box2DBody.cpp b/src/Plugins/Box2DPlugin/Box2DBody.cpp index d9f687f542..85b661be98 100644 --- a/src/Plugins/Box2DPlugin/Box2DBody.cpp +++ b/src/Plugins/Box2DPlugin/Box2DBody.cpp @@ -56,12 +56,12 @@ namespace Mengine { uint32_t num_points = _polygon.size(); - if( num_points > b2_maxPolygonVertices ) + if( num_points > B2_MAX_POLYGON_VERTICES) { return false; } - b2Vec2 vertices[b2_maxPolygonVertices]; + b2Vec2 vertices[B2_MAX_POLYGON_VERTICES]; for( uint32_t i = 0; i != num_points; ++i ) { const mt::vec2f & v = _polygon[i]; @@ -79,8 +79,9 @@ namespace Mengine shapeDef.userData = (Box2DBodyInterface *)this; shapeDef.density = _density; - shapeDef.friction = _friction; - shapeDef.restitution = _restitution; + shapeDef.material = ::b2DefaultSurfaceMaterial(); + shapeDef.material.friction = _friction; + shapeDef.material.restitution = _restitution; shapeDef.isSensor = _isSensor; shapeDef.filter.categoryBits = _categoryBits; shapeDef.filter.maskBits = _collisionMask; @@ -114,8 +115,9 @@ namespace Mengine shapeDef.userData = (Box2DBodyInterface *)this; shapeDef.density = _density; - shapeDef.friction = _friction; - shapeDef.restitution = _restitution; + shapeDef.material = ::b2DefaultSurfaceMaterial(); + shapeDef.material.friction = _friction; + shapeDef.material.restitution = _restitution; shapeDef.isSensor = _isSensor; shapeDef.filter.categoryBits = _categoryBits; shapeDef.filter.maskBits = _collisionMask; @@ -143,15 +145,17 @@ namespace Mengine b2Vec2 b2_position = m_scaler.toBox2DWorld( _position ); float b2_width = m_scaler.toBox2DWorld( _width ); float b2_height = m_scaler.toBox2DWorld( _height ); + b2Rot b2_rot = ::b2MakeRot( _angle ); - b2Polygon box = ::b2MakeOffsetBox( b2_width, b2_height, b2_position, _angle ); + b2Polygon box = ::b2MakeOffsetBox( b2_width, b2_height, b2_position, b2_rot ); b2ShapeDef shapeDef = ::b2DefaultShapeDef(); shapeDef.userData = (Box2DBodyInterface *)this; shapeDef.density = _density; - shapeDef.friction = _friction; - shapeDef.restitution = _restitution; + shapeDef.material = ::b2DefaultSurfaceMaterial(); + shapeDef.material.friction = _friction; + shapeDef.material.restitution = _restitution; shapeDef.isSensor = _isSensor; shapeDef.filter.categoryBits = _categoryBits; shapeDef.filter.maskBits = _collisionMask; @@ -205,7 +209,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// float Box2DBody::getBodyInertiaTensor() const { - float inertiaTensor = ::b2Body_GetInertiaTensor( m_bodyId ); + float inertiaTensor = ::b2Body_GetRotationalInertia( m_bodyId ); return inertiaTensor; } diff --git a/src/Plugins/Box2DPlugin/Box2DIncluder.h b/src/Plugins/Box2DPlugin/Box2DIncluder.h index f18bfa167b..5d4472ee75 100644 --- a/src/Plugins/Box2DPlugin/Box2DIncluder.h +++ b/src/Plugins/Box2DPlugin/Box2DIncluder.h @@ -2,7 +2,4 @@ #include "Config/Config.h" -extern "C" -{ - #include "box2d/box2d.h" -} \ No newline at end of file +#include "box2d/box2d.h" \ No newline at end of file diff --git a/src/Plugins/Box2DPlugin/Box2DWorld.cpp b/src/Plugins/Box2DPlugin/Box2DWorld.cpp index 1d6d733881..d297c9f836 100644 --- a/src/Plugins/Box2DPlugin/Box2DWorld.cpp +++ b/src/Plugins/Box2DPlugin/Box2DWorld.cpp @@ -124,11 +124,9 @@ namespace Mengine b2Vec2 b2_position = m_scaler.toBox2DWorld( _position ); float b2_radius = m_scaler.toBox2DWorld( _radius ); - b2Circle b2_circle = {{0.f, 0.f}, b2_radius}; - b2Transform b2_transform = {b2_position, ::b2MakeRot( 0.f )}; + b2ShapeProxy b2_proxy = ::b2MakeProxy( &b2_position, 1, b2_radius ); - b2QueryFilter b2_queryFilter = ::b2DefaultQueryFilter(); - + b2QueryFilter b2_queryFilter = ::b2DefaultQueryFilter(); b2_queryFilter.categoryBits = _categoryBits; b2_queryFilter.maskBits = _maskBits; @@ -137,7 +135,7 @@ namespace Mengine desc.capacity = _capacity; desc.found = 0; - ::b2World_OverlapCircle( m_worldId, &b2_circle, b2_transform, b2_queryFilter, &Detail::b2OverlapResult, &desc ); + ::b2World_OverlapShape( m_worldId, &b2_proxy, b2_queryFilter, &Detail::b2OverlapResult, &desc ); return desc.found; } diff --git a/src/Plugins/Box2DPlugin/CMakeLists.txt b/src/Plugins/Box2DPlugin/CMakeLists.txt index bd8a195d83..40d8680c64 100644 --- a/src/Plugins/Box2DPlugin/CMakeLists.txt +++ b/src/Plugins/Box2DPlugin/CMakeLists.txt @@ -25,6 +25,6 @@ INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/box2d/include) ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_BOX2D) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${THIRDPARTY_LIB_DIR}/${MENGINE_LIB_PREFIX}box2d${MENGINE_LIB_SUFFIX}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${THIRDPARTY_LIB_DIR}/${MENGINE_LIB_PREFIX}box2dd${MENGINE_LIB_SUFFIX}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${THIRDPARTY_LIB_DIR}/${MENGINE_LIB_PREFIX}math${MENGINE_LIB_SUFFIX}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} Kernel) \ No newline at end of file diff --git a/src/Plugins/CameraDebugGizmoPlugin/CMakeLists.txt b/src/Plugins/CameraDebugGizmoPlugin/CMakeLists.txt index e701aab5b2..2f10d0665b 100644 --- a/src/Plugins/CameraDebugGizmoPlugin/CMakeLists.txt +++ b/src/Plugins/CameraDebugGizmoPlugin/CMakeLists.txt @@ -6,8 +6,8 @@ src CameraDebugGizmoPlugin.def CameraDebugGizmoPlugin.cpp - ModuleCameraDebugGizmo.cpp - ModuleCameraDebugGizmo.h + CameraDebugGizmoModule.cpp + CameraDebugGizmoModule.h ) ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_CAMERADEBUGGIZMO) diff --git a/src/Plugins/CameraDebugGizmoPlugin/ModuleCameraDebugGizmo.cpp b/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoModule.cpp similarity index 90% rename from src/Plugins/CameraDebugGizmoPlugin/ModuleCameraDebugGizmo.cpp rename to src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoModule.cpp index b6c7af0158..c06b6c8292 100644 --- a/src/Plugins/CameraDebugGizmoPlugin/ModuleCameraDebugGizmo.cpp +++ b/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoModule.cpp @@ -1,4 +1,4 @@ -#include "ModuleCameraDebugGizmo.h" +#include "CameraDebugGizmoModule.h" #include "Interface/PlayerServiceInterface.h" #include "Interface/InputServiceInterface.h" @@ -9,18 +9,18 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// - ModuleCameraDebugGizmo::ModuleCameraDebugGizmo() + CameraDebugGizmoModule::CameraDebugGizmoModule() : m_scaleStepMin( 0.f ) , m_scaleStepStep( 0.f ) , m_scaleStepMax( 0.f ) { } ////////////////////////////////////////////////////////////////////////// - ModuleCameraDebugGizmo::~ModuleCameraDebugGizmo() + CameraDebugGizmoModule::~CameraDebugGizmoModule() { } ////////////////////////////////////////////////////////////////////////// - bool ModuleCameraDebugGizmo::_initializeModule() + bool CameraDebugGizmoModule::_initializeModule() { m_scaleStepMin = CONFIG_VALUE_FLOAT( "CameraDebugGizmoPlugin", "ScaleStepMin", 0.05f ); m_scaleStepStep = CONFIG_VALUE_FLOAT( "CameraDebugGizmoPlugin", "ScaleStepStep", 0.05f ); @@ -29,12 +29,12 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void ModuleCameraDebugGizmo::_finalizeModule() + void CameraDebugGizmoModule::_finalizeModule() { //Empty } ////////////////////////////////////////////////////////////////////////// - bool ModuleCameraDebugGizmo::_handleKeyEvent( const InputKeyEvent & _event ) + bool CameraDebugGizmoModule::_handleKeyEvent( const InputKeyEvent & _event ) { if( _event.code == KC_ESCAPE && _event.isDown == true ) { @@ -48,7 +48,7 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool ModuleCameraDebugGizmo::_handleMouseMove( const InputMouseMoveEvent & _event ) + bool CameraDebugGizmoModule::_handleMouseMove( const InputMouseMoveEvent & _event ) { bool controlDown = _event.special.isControl; @@ -74,7 +74,7 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - bool ModuleCameraDebugGizmo::_handleMouseWheel( const InputMouseWheelEvent & _event ) + bool CameraDebugGizmoModule::_handleMouseWheel( const InputMouseWheelEvent & _event ) { bool controlDown = _event.special.isControl; diff --git a/src/Plugins/CameraDebugGizmoPlugin/ModuleCameraDebugGizmo.h b/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoModule.h similarity index 77% rename from src/Plugins/CameraDebugGizmoPlugin/ModuleCameraDebugGizmo.h rename to src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoModule.h index 14a4f87f41..8477d5a5a3 100644 --- a/src/Plugins/CameraDebugGizmoPlugin/ModuleCameraDebugGizmo.h +++ b/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoModule.h @@ -4,14 +4,14 @@ namespace Mengine { - class ModuleCameraDebugGizmo + class CameraDebugGizmoModule : public ModuleBase { - DECLARE_FACTORABLE( ModuleCameraDebugGizmo ); + DECLARE_FACTORABLE( CameraDebugGizmoModule ); public: - ModuleCameraDebugGizmo(); - ~ModuleCameraDebugGizmo() override; + CameraDebugGizmoModule(); + ~CameraDebugGizmoModule() override; public: bool _initializeModule() override; diff --git a/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoPlugin.cpp b/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoPlugin.cpp index f94c4bfac6..4746e2fba1 100644 --- a/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoPlugin.cpp +++ b/src/Plugins/CameraDebugGizmoPlugin/CameraDebugGizmoPlugin.cpp @@ -1,6 +1,6 @@ #include "CameraDebugGizmoPlugin.h" -#include "ModuleCameraDebugGizmo.h" +#include "CameraDebugGizmoModule.h" #include "Kernel/ConfigHelper.h" #include "Kernel/ModuleFactory.h" @@ -35,14 +35,14 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool CameraDebugGizmoPlugin::_initializePlugin() { - this->addModuleFactory( ModuleCameraDebugGizmo::getFactorableType(), Helper::makeModuleFactory( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); + this->addModuleFactory( CameraDebugGizmoModule::getFactorableType(), Helper::makeModuleFactory( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); return true; } ////////////////////////////////////////////////////////////////////////// void CameraDebugGizmoPlugin::_finalizePlugin() { - this->removeModuleFactory( ModuleCameraDebugGizmo::getFactorableType() ); + this->removeModuleFactory( CameraDebugGizmoModule::getFactorableType() ); } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Plugins/DebugPanelPlugin/CMakeLists.txt b/src/Plugins/DebugPanelPlugin/CMakeLists.txt index a336f2b4d7..c87cd1d34e 100644 --- a/src/Plugins/DebugPanelPlugin/CMakeLists.txt +++ b/src/Plugins/DebugPanelPlugin/CMakeLists.txt @@ -6,8 +6,8 @@ src DebugPanelPlugin.def DebugPanelPlugin.cpp - ModuleDebugPanel.cpp - ModuleDebugPanel.h + DebugPanelModule.cpp + DebugPanelModule.h ) INCLUDE_DIRECTORIES(${THIRDPARTY_CONFIG_DIR}/imgui) diff --git a/src/Plugins/DebugPanelPlugin/ModuleDebugPanel.cpp b/src/Plugins/DebugPanelPlugin/DebugPanelModule.cpp similarity index 92% rename from src/Plugins/DebugPanelPlugin/ModuleDebugPanel.cpp rename to src/Plugins/DebugPanelPlugin/DebugPanelModule.cpp index ea749b662e..98d8e0b8a7 100644 --- a/src/Plugins/DebugPanelPlugin/ModuleDebugPanel.cpp +++ b/src/Plugins/DebugPanelPlugin/DebugPanelModule.cpp @@ -1,4 +1,4 @@ -#include "ModuleDebugPanel.h" +#include "DebugPanelModule.h" #include "Interface/RenderMaterialServiceInterface.h" @@ -11,16 +11,16 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// - ModuleDebugPanel::ModuleDebugPanel() + DebugPanelModule::DebugPanelModule() : m_show( false ) { } ////////////////////////////////////////////////////////////////////////// - ModuleDebugPanel::~ModuleDebugPanel() + DebugPanelModule::~DebugPanelModule() { } ////////////////////////////////////////////////////////////////////////// - bool ModuleDebugPanel::_initializeModule() + bool DebugPanelModule::_initializeModule() { const ImGUIRenderProviderInterfacePtr & imguiRenderProvider = IMGUI_SERVICE() ->getRenderProvider(); @@ -30,12 +30,12 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::_finalizeModule() + void DebugPanelModule::_finalizeModule() { m_imguiRenderProvider = nullptr; } ////////////////////////////////////////////////////////////////////////// - bool ModuleDebugPanel::_handleKeyEvent( const InputKeyEvent & _event ) + bool DebugPanelModule::_handleKeyEvent( const InputKeyEvent & _event ) { if( _event.code == KC_F9 && _event.isDown == true ) { @@ -45,7 +45,7 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::updateHistogramUpdate( HistogramUpdate * const _histogram, uint32_t _statisticId, float _coeffTime, float _multiplier ) + void DebugPanelModule::updateHistogramUpdate( HistogramUpdate * const _histogram, uint32_t _statisticId, float _coeffTime, float _multiplier ) { static int64_t old_value[MENGINE_STATISTIC_MAX_COUNT] = {0}; @@ -59,7 +59,7 @@ namespace Mengine _histogram->add( value ); } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::drawHistogramUpdate( const HistogramUpdate & _histogram, const Char * _label, const Char * _overlayFormat, float _maxValue, float _height ) const + void DebugPanelModule::drawHistogramUpdate( const HistogramUpdate & _histogram, const Char * _label, const Char * _overlayFormat, float _maxValue, float _height ) const { float currentValue = _histogram.getLastValue(); const float * values = _histogram.getValues(); @@ -73,7 +73,7 @@ namespace Mengine ImGui::PlotHistogram( imGuiLabel, values, MENGINE_DEBUG_PANEL_HISTOGRAM_UPDATE_COUNT, 0, overlayText, 0.f, _maxValue, ImVec2( 0, _height ) ); } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::drawHistogramPerFrame( const HistogramPerframe & _histogram, const Char * _label, const Char * _overlayFormat, float _maxValue, float _height ) const + void DebugPanelModule::drawHistogramPerFrame( const HistogramPerframe & _histogram, const Char * _label, const Char * _overlayFormat, float _maxValue, float _height ) const { float currentValue = _histogram.getLastValue(); const float * values = _histogram.getValues(); @@ -87,7 +87,7 @@ namespace Mengine ImGui::PlotHistogram( imGuiLabel, values, MENGINE_DEBUG_PANEL_HISTOGRAM_PERFRAME_COUNT, 0, overlayText, 0.f, _maxValue, ImVec2( 0, _height ) ); } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::_beginUpdate( bool _focus ) + void DebugPanelModule::_beginUpdate( bool _focus ) { MENGINE_UNUSED( _focus ); @@ -111,7 +111,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::_render( const RenderPipelineInterfacePtr & _renderPipeline, const RenderContext * _context ) + void DebugPanelModule::_render( const RenderPipelineInterfacePtr & _renderPipeline, const RenderContext * _context ) { if( m_show == false ) { @@ -148,7 +148,7 @@ namespace Mengine _renderPipeline->addRenderExternal( _context, renderMaterial, nullptr, RenderDrawPrimitiveInterfacePtr::from( this ), MENGINE_DOCUMENT_FACTORABLE ); } ////////////////////////////////////////////////////////////////////////// - void ModuleDebugPanel::onRenderDrawPrimitives( const RenderPrimitive * _primitives, uint32_t _count ) const + void DebugPanelModule::onRenderDrawPrimitives( const RenderPrimitive * _primitives, uint32_t _count ) const { MENGINE_UNUSED( _primitives ); MENGINE_UNUSED( _count ); diff --git a/src/Plugins/DebugPanelPlugin/ModuleDebugPanel.h b/src/Plugins/DebugPanelPlugin/DebugPanelModule.h similarity index 94% rename from src/Plugins/DebugPanelPlugin/ModuleDebugPanel.h rename to src/Plugins/DebugPanelPlugin/DebugPanelModule.h index 0b58fd88eb..1fca0cd680 100644 --- a/src/Plugins/DebugPanelPlugin/ModuleDebugPanel.h +++ b/src/Plugins/DebugPanelPlugin/DebugPanelModule.h @@ -15,15 +15,15 @@ namespace Mengine { - class ModuleDebugPanel + class DebugPanelModule : public ModuleBase , public RenderDrawPrimitiveInterface { - DECLARE_FACTORABLE( ModuleDebugPanel ); + DECLARE_FACTORABLE( DebugPanelModule ); public: - ModuleDebugPanel(); - ~ModuleDebugPanel() override; + DebugPanelModule(); + ~DebugPanelModule() override; public: bool _initializeModule() override; diff --git a/src/Plugins/DebugPanelPlugin/DebugPanelPlugin.cpp b/src/Plugins/DebugPanelPlugin/DebugPanelPlugin.cpp index 08ef73a037..3cac6bd9a0 100644 --- a/src/Plugins/DebugPanelPlugin/DebugPanelPlugin.cpp +++ b/src/Plugins/DebugPanelPlugin/DebugPanelPlugin.cpp @@ -1,6 +1,6 @@ #include "DebugPanelPlugin.h" -#include "ModuleDebugPanel.h" +#include "DebugPanelModule.h" #include "Kernel/ModuleFactory.h" #include "Kernel/ConfigHelper.h" @@ -35,14 +35,14 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool DebugPanelPlugin::_initializePlugin() { - this->addModuleFactory( ModuleDebugPanel::getFactorableType(), Helper::makeModuleFactory( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); + this->addModuleFactory( DebugPanelModule::getFactorableType(), Helper::makeModuleFactory( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); return true; } ////////////////////////////////////////////////////////////////////////// void DebugPanelPlugin::_finalizePlugin() { - this->removeModuleFactory( ModuleDebugPanel::getFactorableType() ); + this->removeModuleFactory( DebugPanelModule::getFactorableType() ); } ////////////////////////////////////////////////////////////////////////// } \ No newline at end of file diff --git a/src/Plugins/ImGUIPlugin/ImGUIInterface.h b/src/Plugins/ImGUIPlugin/ImGUIInterface.h index 6f7c483d9d..293d7ff2f4 100644 --- a/src/Plugins/ImGUIPlugin/ImGUIInterface.h +++ b/src/Plugins/ImGUIPlugin/ImGUIInterface.h @@ -7,6 +7,7 @@ #include "Config/Lambda.h" #include "imgui.h" +#include "imgui_internal.h" namespace Mengine { diff --git a/src/Plugins/NodeDebuggerPlugin/CMakeLists.txt b/src/Plugins/NodeDebuggerPlugin/CMakeLists.txt index 2979a7f5da..b3ff375cad 100644 --- a/src/Plugins/NodeDebuggerPlugin/CMakeLists.txt +++ b/src/Plugins/NodeDebuggerPlugin/CMakeLists.txt @@ -6,8 +6,8 @@ ADD_FILTER( NodeDebuggerPlugin.def NodeDebuggerPlugin.cpp - ModuleNodeDebugger.h - ModuleNodeDebugger.cpp + NodeDebuggerModule.h + NodeDebuggerModule.cpp NodeDebuggerSerialization.h diff --git a/src/Plugins/NodeDebuggerPlugin/NodeDebuggerPlugin.cpp b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerPlugin.cpp index 54a1d360e9..71225a9d99 100644 --- a/src/Plugins/NodeDebuggerPlugin/NodeDebuggerPlugin.cpp +++ b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerPlugin.cpp @@ -1,6 +1,6 @@ #include "NodeDebuggerPlugin.h" -#include "ModuleNodeDebugger.h" +#include "NodeDebuggerModule.h" #include "Kernel/ModuleFactory.h" #include "Kernel/ConstStringHelper.h" @@ -22,14 +22,14 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool NodeDebuggerPlugin::_initializePlugin() { - this->addModuleFactory( ModuleNodeDebugger::getFactorableType(), Helper::makeModuleFactory( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); + this->addModuleFactory( NodeDebuggerModule::getFactorableType(), Helper::makeModuleFactory( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); return true; } ////////////////////////////////////////////////////////////////////////// void NodeDebuggerPlugin::_finalizePlugin() { - this->removeModuleFactory( ModuleNodeDebugger::getFactorableType() ); + this->removeModuleFactory( NodeDebuggerModule::getFactorableType() ); } ////////////////////////////////////////////////////////////////////////// void NodeDebuggerPlugin::_destroyPlugin() diff --git a/src/Services/RenderService/BatchRenderPipeline.cpp b/src/Services/RenderService/BatchRenderPipeline.cpp index fec77366cb..5733cbd349 100644 --- a/src/Services/RenderService/BatchRenderPipeline.cpp +++ b/src/Services/RenderService/BatchRenderPipeline.cpp @@ -732,6 +732,8 @@ namespace Mengine m_renderService->endRenderPass( context ); } + + m_renderPrimitives.clear(); } ////////////////////////////////////////////////////////////////////////// void BatchRenderPipeline::clear() @@ -750,6 +752,66 @@ namespace Mengine return empty; } ////////////////////////////////////////////////////////////////////////// + bool BatchRenderPipeline::lockBatches() + { + for( const RenderPass & pass : m_renderPasses ) + { + if( (pass.flags & RENDER_PASS_FLAG_SINGLE) == RENDER_PASS_FLAG_SINGLE ) + { + continue; + } + + const RenderBatchInterfacePtr & batch = pass.batch; + + if( batch == nullptr ) + { + continue; + } + + bool alreadyLocked = false; + + for( const RenderBatchInterfacePtr & lockedBatch : m_lockedBatches ) + { + if( lockedBatch.get() == batch.get() ) + { + alreadyLocked = true; + break; + } + } + + if( alreadyLocked == true ) + { + continue; + } + + if( batch->lock() == false ) + { + this->unlockBatches(); + + return false; + } + + m_lockedBatches.emplace_back( batch ); + } + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void BatchRenderPipeline::unlockBatches() + { + for( const RenderBatchInterfacePtr & batch : m_lockedBatches ) + { + if( batch == nullptr ) + { + continue; + } + + batch->unlock(); + } + + m_lockedBatches.clear(); + } + ////////////////////////////////////////////////////////////////////////// void BatchRenderPipeline::insertRenderObjects_( const RenderPass & _renderPass, const MemoryInterfacePtr & _vertexMemory, uint32_t _vertexSize, const MemoryInterfacePtr & _indexMemory, uint32_t * const _vbPos, uint32_t * const _ibPos ) { uint32_t vbPos = *_vbPos; diff --git a/src/Services/RenderService/BatchRenderPipeline.h b/src/Services/RenderService/BatchRenderPipeline.h index 9a429107ff..ca1c23a445 100644 --- a/src/Services/RenderService/BatchRenderPipeline.h +++ b/src/Services/RenderService/BatchRenderPipeline.h @@ -135,6 +135,10 @@ namespace Mengine void clear() override; bool isEmpty() const override; + public: + bool lockBatches(); + void unlockBatches(); + protected: bool testRenderPass_( const RenderContext * _context , const RenderVertexBufferInterfacePtr & _vertexBuffer @@ -171,6 +175,8 @@ namespace Mengine DynamicArrayRenderIndices m_indicesQuad; DynamicArrayRenderIndices m_indicesLine; + Vector m_lockedBatches; + #if defined(MENGINE_MASTER_RELEASE_DISABLE) struct DebugRenderObject { diff --git a/src/Services/RenderService/RenderBatch.h b/src/Services/RenderService/RenderBatch.h index 2a8510463d..141006124b 100644 --- a/src/Services/RenderService/RenderBatch.h +++ b/src/Services/RenderService/RenderBatch.h @@ -35,8 +35,8 @@ namespace Mengine bool process( const RenderVertexAttributeInterfacePtr & _vertexAttribute, uint32_t _vertexCount, uint32_t _indexCount ); public: - bool lock(); - bool unlock(); + bool lock() override; + bool unlock() override; public: void deviceLostPrepare(); diff --git a/src/Services/ThreadService/ThreadService.cpp b/src/Services/ThreadService/ThreadService.cpp index 185988085b..6aaf19b624 100644 --- a/src/Services/ThreadService/ThreadService.cpp +++ b/src/Services/ThreadService/ThreadService.cpp @@ -382,8 +382,6 @@ namespace Mengine } else { - ThreadTaskInterface * task = desc_task.task.get(); - for( ThreadProcessorDesc & desc_thread : m_threadProcessors ) { if( desc_thread.name != desc_task.processorName ) @@ -391,7 +389,7 @@ namespace Mengine continue; } - if( desc_thread.processor->processTask( task ) == false ) + if( desc_thread.processor->processTask( desc_task.task ) == false ) { continue; } @@ -541,9 +539,7 @@ namespace Mengine continue; } - ThreadTaskInterface * task_ptr = _desc.task.get(); - - if( desc_thread.processor->processTask( task_ptr ) == true ) + if( desc_thread.processor->processTask( _desc.task ) == true ) { _desc.processor = desc_thread.processor; _desc.progress = true; diff --git a/src/Services/UpdateService/UpdateService.cpp b/src/Services/UpdateService/UpdateService.cpp index 75adca7ef7..41a1460e8b 100644 --- a/src/Services/UpdateService/UpdateService.cpp +++ b/src/Services/UpdateService/UpdateService.cpp @@ -20,7 +20,7 @@ namespace Mengine namespace Detail { ////////////////////////////////////////////////////////////////////////// - bool findLeafUpdatater( const LeafUpdatables & _leafs, const UpdationInterface * _updation ) + static bool findLeafUpdatater( const LeafUpdatables & _leafs, const UpdationInterface * _updation ) { for( const LeafUpdatable & leaf : _leafs ) { @@ -201,8 +201,6 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void UpdateService::updateLeaf_( uint32_t _deep, LeafUpdatable * const _leaf, const UpdateContext * _context ) { - MENGINE_UNUSED( _deep ); - VectorUpdatableIndecies & leaf_indecies = _leaf->indecies; VectorUpdatableIndecies & leaf_indeciesAdd = _leaf->indeciesAdd; @@ -216,11 +214,6 @@ namespace Mengine for( UpdationInterface * updation : leaf_indecies ) { - if( updation == nullptr ) - { - continue; - } - uint32_t updation_deep = updation->getUpdationDeep(); if( updation_deep != _deep ) diff --git a/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.cpp b/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.cpp index 8a19020e0c..f837a7db0c 100644 --- a/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.cpp +++ b/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.cpp @@ -48,7 +48,6 @@ namespace Mengine : m_priority( ETP_NORMAL ) , m_thread( INVALID_HANDLE_VALUE ) , m_threadId( 0 ) - , m_task( nullptr ) , m_exit( false ) { } @@ -140,6 +139,7 @@ namespace Mengine ::DeleteCriticalSection( &m_conditionLock ); #endif + m_task = nullptr; m_mutex = nullptr; } ////////////////////////////////////////////////////////////////////////// @@ -193,6 +193,7 @@ namespace Mengine MENGINE_PROFILER_FRAME( "thread" ); m_task->process(); + m_mutex->unlock(); } @@ -226,7 +227,7 @@ namespace Mengine return (ThreadId)m_threadId; } ////////////////////////////////////////////////////////////////////////// - bool Win32ThreadProcessor::processTask( ThreadTaskInterface * _task ) + bool Win32ThreadProcessor::processTask( const ThreadTaskInterfacePtr & _task ) { MENGINE_ASSERTION_MEMORY_PANIC( _task, "invalid process task" ); @@ -275,10 +276,12 @@ namespace Mengine } ::EnterCriticalSection( &m_taskLock ); + if( m_task != nullptr ) { m_task->cancel(); } + ::LeaveCriticalSection( &m_taskLock ); ::EnterCriticalSection( &m_processLock ); diff --git a/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.h b/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.h index c8458049d5..d12960721a 100644 --- a/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.h +++ b/src/Systems/Win32ThreadSystem/Win32ThreadProcessor.h @@ -39,7 +39,7 @@ namespace Mengine ThreadId getThreadId() const override; public: - bool processTask( ThreadTaskInterface * _task ) override; + bool processTask( const ThreadTaskInterfacePtr & _task ) override; void removeTask() override; public: @@ -66,7 +66,7 @@ namespace Mengine CONDITION_VARIABLE m_conditionVariable; #endif - ThreadTaskInterface * m_task; + ThreadTaskInterfacePtr m_task; AtomicBool m_exit; }; ////////////////////////////////////////////////////////////////////////// From 444bcde218a9a760f89810fd4f4d23bd6aafe335 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 00:42:49 +0200 Subject: [PATCH 095/169] wip AppleUserMessagingPlatformPlugin --- cmake/Xcode_MacOS/CMakeLists.txt | 1 + cmake/Xcode_iOS/CMakeLists.txt | 3 +- cmake/Xcode_iOS_Simulator/CMakeLists.txt | 1 + gradle/app.gradle | 8 +- src/Plugins/CMakeLists.txt | 4 + ...odeDebugger.cpp => NodeDebuggerModule.cpp} | 138 +++++++++--------- ...uleNodeDebugger.h => NodeDebuggerModule.h} | 8 +- 7 files changed, 85 insertions(+), 78 deletions(-) rename src/Plugins/NodeDebuggerPlugin/{ModuleNodeDebugger.cpp => NodeDebuggerModule.cpp} (96%) rename src/Plugins/NodeDebuggerPlugin/{ModuleNodeDebugger.h => NodeDebuggerModule.h} (98%) diff --git a/cmake/Xcode_MacOS/CMakeLists.txt b/cmake/Xcode_MacOS/CMakeLists.txt index f7f28457ea..8804ddffa3 100644 --- a/cmake/Xcode_MacOS/CMakeLists.txt +++ b/cmake/Xcode_MacOS/CMakeLists.txt @@ -101,6 +101,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_WIN32_ANTIFREEZEMONITOR OFF OFF "MENGINE_PLUGIN_WIN32_ ADD_PLUGIN(MENGINE_PLUGIN_WIN32_CRITICALERRORSMONITOR OFF OFF "MENGINE_PLUGIN_WIN32_CRITICALERRORSMONITOR") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER OFF OFF "MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM OFF OFF "MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_SKADNETWORK OFF OFF "MENGINE_PLUGIN_APPLE_SKADNETWORK") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_GAMECENTER OFF OFF "MENGINE_PLUGIN_APPLE_GAMECENTER") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_APPTRACKING OFF OFF "MENGINE_PLUGIN_APPLE_APPTRACKING") diff --git a/cmake/Xcode_iOS/CMakeLists.txt b/cmake/Xcode_iOS/CMakeLists.txt index ba25c3f84e..b6ed35a4ae 100644 --- a/cmake/Xcode_iOS/CMakeLists.txt +++ b/cmake/Xcode_iOS/CMakeLists.txt @@ -22,7 +22,7 @@ SET_MENGINE_ENVIRONMENT(IOS METAL SDL2 XCODE) ADD_MENGINE_FRAMEWORK() -# platform +# platform ADD_PLATFORM(iOSPlatform "MENGINE_PLATFORM") # systems @@ -102,6 +102,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_WIN32_CRITICALERRORSMONITOR OFF OFF "MENGINE_PLUGIN_WI ADD_PLUGIN(MENGINE_PLUGIN_APPLE_NATIVE_PYTHON ON OFF "MENGINE_PLUGIN_APPLE_NATIVE_PYTHON") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ADVERTISEMENT ON OFF "MENGINE_PLUGIN_APPLE_ADVERTISEMENT") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER OFF OFF "MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM OFF OFF "MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_SKADNETWORK OFF OFF "MENGINE_PLUGIN_APPLE_SKADNETWORK") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_GAMECENTER OFF OFF "MENGINE_PLUGIN_APPLE_GAMECENTER") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_APPTRACKING OFF OFF "MENGINE_PLUGIN_APPLE_APPTRACKING") diff --git a/cmake/Xcode_iOS_Simulator/CMakeLists.txt b/cmake/Xcode_iOS_Simulator/CMakeLists.txt index eba47c876d..7874fbec65 100644 --- a/cmake/Xcode_iOS_Simulator/CMakeLists.txt +++ b/cmake/Xcode_iOS_Simulator/CMakeLists.txt @@ -95,6 +95,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_WIN32_CRITICALERRORSMONITOR OFF OFF "MENGINE_PLUGIN_WI ADD_PLUGIN(MENGINE_PLUGIN_DEVTODEBUG OFF OFF "MENGINE_PLUGIN_DEVTODEBUG") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER OFF OFF "MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM OFF OFF "MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_SKADNETWORK OFF OFF "MENGINE_PLUGIN_APPLE_SKADNETWORK") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_GAMECENTER OFF OFF "MENGINE_PLUGIN_APPLE_GAMECENTER") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_APPTRACKING OFF OFF "MENGINE_PLUGIN_APPLE_APPTRACKING") diff --git a/gradle/app.gradle b/gradle/app.gradle index 27e1f4e2b7..eda7369057 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -226,7 +226,7 @@ android { if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true) { if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS_NATIVE_SYMBOL_UPLOAD_ENABLE == true) { buildTypes { - final var buildDirectory = getLayout().getBuildDirectory() + final def buildDirectory = getLayout().getBuildDirectory() debug { firebaseCrashlytics { @@ -281,7 +281,7 @@ android { final def deliveryPacks = [] as ArrayList for(final PACKAGE_DESC in PACKAGES) { - final var PACKAGE_NAME = PACKAGE_DESC.split(";")[0] + final def PACKAGE_NAME = PACKAGE_DESC.split(";")[0] println "add delivery asset pack: $PACKAGE_NAME" @@ -809,7 +809,7 @@ if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true && MENGINE_APP_PLUGIN_FIREBA final File f = android.buildTypes.debug.firebaseCrashlytics.unstrippedNativeLibsDir.get().getAsFile() if (f.exists() == false) { - final var fname = f.getCanonicalPath() + final def fname = f.getCanonicalPath() throw new GradleException("unstrippedNativeLibsDir not found folder: $fname") } @@ -825,7 +825,7 @@ if (MENGINE_APP_PLUGIN_FIREBASE_CRASHLYTICS == true && MENGINE_APP_PLUGIN_FIREBA final File f = android.buildTypes.release.firebaseCrashlytics.unstrippedNativeLibsDir.get().getAsFile() if (f.exists() == false) { - final var fname = f.getCanonicalPath() + final def fname = f.getCanonicalPath() throw new GradleException("unstrippedNativeLibsDir not found folder: $fname") } diff --git a/src/Plugins/CMakeLists.txt b/src/Plugins/CMakeLists.txt index 27ee4388be..afbf172a1f 100644 --- a/src/Plugins/CMakeLists.txt +++ b/src/Plugins/CMakeLists.txt @@ -322,6 +322,10 @@ if(MENGINE_PLUGIN_APPLE_USERNOTIFICATIONCENTER) ADD_SUBDIRECTORY(AppleUserNotificationCenterPlugin) endif() +if(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM) + ADD_SUBDIRECTORY(AppleUserMessagingPlatformPlugin) +endif() + if(MENGINE_PLUGIN_APPLE_SKADNETWORK) ADD_SUBDIRECTORY(AppleSKAdNetworkPlugin) endif() diff --git a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.cpp similarity index 96% rename from src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp rename to src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.cpp index ef642c9bd1..d83edaba27 100644 --- a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp +++ b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.cpp @@ -1,4 +1,4 @@ -#include "ModuleNodeDebugger.h" +#include "NodeDebuggerModule.h" #include "Interface/PlatformServiceInterface.h" #include "Interface/AllocatorSystemInterface.h" @@ -78,7 +78,7 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// - ModuleNodeDebugger::ModuleNodeDebugger() + NodeDebuggerModule::NodeDebuggerModule() : m_serverState( ENodeDebuggerServerState::Invalid ) , m_shouldRecreateServer( false ) , m_shouldUpdateScene( false ) @@ -88,22 +88,22 @@ namespace Mengine { } ////////////////////////////////////////////////////////////////////////// - ModuleNodeDebugger::~ModuleNodeDebugger() + NodeDebuggerModule::~NodeDebuggerModule() { } ////////////////////////////////////////////////////////////////////////// - bool ModuleNodeDebugger::_initializeModule() + bool NodeDebuggerModule::_initializeModule() { VOCABULARY_SET( DebuggerBoundingBoxInterface, STRINGIZE_STRING_LOCAL( "DebuggerBoundingBox" ), HotSpotPolygon::getFactorableType(), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); VOCABULARY_SET( DebuggerBoundingBoxInterface, STRINGIZE_STRING_LOCAL( "DebuggerBoundingBox" ), HotSpotSurface::getFactorableType(), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); VOCABULARY_SET( DebuggerBoundingBoxInterface, STRINGIZE_STRING_LOCAL( "DebuggerBoundingBox" ), TextField::getFactorableType(), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ), MENGINE_DOCUMENT_FACTORABLE ); - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_SCENE_DESTROY, &ModuleNodeDebugger::notifyChangeSceneDestroy, MENGINE_DOCUMENT_FACTORABLE ); - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_SCENE_COMPLETE, &ModuleNodeDebugger::notifyChangeSceneComplete, MENGINE_DOCUMENT_FACTORABLE ); - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_REMOVE_SCENE_DESTROY, &ModuleNodeDebugger::notifyRemoveSceneDestroy, MENGINE_DOCUMENT_FACTORABLE ); - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_INCREF_FACTORY_GENERATION, &ModuleNodeDebugger::notifyIncrefFactoryGeneration, MENGINE_DOCUMENT_FACTORABLE ); - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_HTTP_REQUEST, &ModuleNodeDebugger::notifyHttpRequest, MENGINE_DOCUMENT_FACTORABLE ); - NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_HTTP_RESPONSE, &ModuleNodeDebugger::notifyHttpResponse, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_SCENE_DESTROY, &NodeDebuggerModule::notifyChangeSceneDestroy, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_CHANGE_SCENE_COMPLETE, &NodeDebuggerModule::notifyChangeSceneComplete, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_REMOVE_SCENE_DESTROY, &NodeDebuggerModule::notifyRemoveSceneDestroy, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_INCREF_FACTORY_GENERATION, &NodeDebuggerModule::notifyIncrefFactoryGeneration, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_HTTP_REQUEST, &NodeDebuggerModule::notifyHttpRequest, MENGINE_DOCUMENT_FACTORABLE ); + NOTIFICATION_ADDOBSERVERMETHOD_THIS( NOTIFICATOR_HTTP_RESPONSE, &NodeDebuggerModule::notifyHttpResponse, MENGINE_DOCUMENT_FACTORABLE ); #if defined(MENGINE_PLATFORM_WINDOWS) UniqueId globalKeyHandlerF2 = Helper::addGlobalKeyHandler( KC_F2, true, []( const InputKeyEvent & ) @@ -150,7 +150,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::_finalizeModule() + void NodeDebuggerModule::_finalizeModule() { VOCABULARY_REMOVE( STRINGIZE_STRING_LOCAL( "DebuggerBoundingBox" ), HotSpotPolygon::getFactorableType() ); VOCABULARY_REMOVE( STRINGIZE_STRING_LOCAL( "DebuggerBoundingBox" ), HotSpotSurface::getFactorableType() ); @@ -202,7 +202,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - bool ModuleNodeDebugger::_availableModule() const + bool NodeDebuggerModule::_availableModule() const { if( SERVICE_IS_INITIALIZE( SocketSystemInterface ) == false ) { @@ -212,12 +212,12 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::onThreadWorkerUpdate( UniqueId _id ) + void NodeDebuggerModule::onThreadWorkerUpdate( UniqueId _id ) { MENGINE_UNUSED( _id ); } ////////////////////////////////////////////////////////////////////////// - bool ModuleNodeDebugger::onThreadWorkerWork( UniqueId ) + bool NodeDebuggerModule::onThreadWorkerWork( UniqueId ) { switch( m_serverState ) { @@ -353,14 +353,14 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::onThreadWorkerDone( UniqueId _id ) + void NodeDebuggerModule::onThreadWorkerDone( UniqueId _id ) { MENGINE_UNUSED( _id ); //Empty } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::setScene( const ScenePtr & _scene ) + void NodeDebuggerModule::setScene( const ScenePtr & _scene ) { if( m_scene != _scene ) { @@ -370,7 +370,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::updateScene() + void NodeDebuggerModule::updateScene() { if( m_serverState == ENodeDebuggerServerState::Connected ) { @@ -415,7 +415,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::_beginUpdate( bool _focus ) + void NodeDebuggerModule::_beginUpdate( bool _focus ) { MENGINE_UNUSED( _focus ); @@ -510,7 +510,7 @@ namespace Mengine return successul; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::_render( const RenderPipelineInterfacePtr & _renderPipeline, const RenderContext * _context ) + void NodeDebuggerModule::_render( const RenderPipelineInterfacePtr & _renderPipeline, const RenderContext * _context ) { if( m_selectedNodePath.empty() == true ) { @@ -622,7 +622,7 @@ namespace Mengine , false, MENGINE_DOCUMENT_FORWARD ); } ////////////////////////////////////////////////////////////////////////// - bool ModuleNodeDebugger::privateInit() + bool NodeDebuggerModule::privateInit() { m_shouldRecreateServer = true; @@ -658,7 +658,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::recreateServer() + void NodeDebuggerModule::recreateServer() { m_socket = SOCKET_SYSTEM() ->createSocket( MENGINE_DOCUMENT_FACTORABLE ); @@ -675,7 +675,7 @@ namespace Mengine m_shouldRecreateServer = false; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::compressPacket( NodeDebuggerPacket & _packet, PacketHeader & _hdr ) + void NodeDebuggerModule::compressPacket( NodeDebuggerPacket & _packet, PacketHeader & _hdr ) { const size_t payloadSize = _packet.payload.size(); @@ -706,7 +706,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::uncompressPacket( NodeDebuggerPacket & _packet, PacketHeader & _hdr, const uint8_t * _receivedData ) + void NodeDebuggerModule::uncompressPacket( NodeDebuggerPacket & _packet, PacketHeader & _hdr, const uint8_t * _receivedData ) { if( _hdr.uncompressedSize == 0 ) { @@ -724,7 +724,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendPacket( NodeDebuggerPacket & _packet ) + void NodeDebuggerModule::sendPacket( NodeDebuggerPacket & _packet ) { if( _packet.payload.empty() == true ) { @@ -742,7 +742,7 @@ namespace Mengine m_outgoingPackets.emplace_back( _packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeTransformation( const TransformablePtr & _transformable, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeTransformation( const TransformablePtr & _transformable, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlNode = _xmlParentNode.append_child( "Transformation" ); @@ -758,7 +758,7 @@ namespace Mengine Detail::serializeNodeProp( transformation->getWorldOrientation(), "worldOrientation", xmlNode ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeRender( const RenderInterface * _render, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeRender( const RenderInterface * _render, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlRender = _xmlParentNode.append_child( "Render" ); @@ -854,7 +854,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeAnimation( const Compilable * _compilable, const AnimationInterface * _animation, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeAnimation( const Compilable * _compilable, const AnimationInterface * _animation, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlNode = _xmlParentNode.append_child( "Animation" ); @@ -874,7 +874,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeTextField( const TextFieldPtr & _textField, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeTextField( const TextFieldPtr & _textField, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlNode = _xmlParentNode.append_child( "Type:TextField" ); @@ -1022,7 +1022,7 @@ namespace Mengine Detail::serializeNodeProp( _textField->getPixelsnap(), "Pixelsnap", xmlNode ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeMovie2( const Compilable * _compilable, const UnknownMovie2Interface * _unknownMovie2, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeMovie2( const Compilable * _compilable, const UnknownMovie2Interface * _unknownMovie2, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlNode = _xmlParentNode.append_child( "Type:Movie2" ); @@ -1047,7 +1047,7 @@ namespace Mengine } ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeSpine( const UnknownSpineInterface * _unknownSpine, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeSpine( const UnknownSpineInterface * _unknownSpine, pugi::xml_node & _xmlParentNode ) { const ResourcePtr & resourceSpineSkeleton = _unknownSpine->getResourceSpineSkeleton(); @@ -1069,7 +1069,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeShape( const ShapePtr & _shape, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeShape( const ShapePtr & _shape, pugi::xml_node & _xmlParentNode ) { const SurfacePtr & surface = _shape->getSurface(); @@ -1122,7 +1122,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeSurfaceImage( const SurfaceImagePtr & _surfaceImage, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeSurfaceImage( const SurfaceImagePtr & _surfaceImage, pugi::xml_node & _xmlParentNode ) { const ResourceImagePtr & resourceImage = _surfaceImage->getResourceImage(); @@ -1164,7 +1164,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeSurfaceImageSequence( const SurfaceImageSequencePtr & _surfaceImageSequence, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeSurfaceImageSequence( const SurfaceImageSequencePtr & _surfaceImageSequence, pugi::xml_node & _xmlParentNode ) { const ResourceImageSequencePtr & resourceImageSequence = _surfaceImageSequence->getResourceImageSequence(); @@ -1194,7 +1194,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeContent( const ContentInterfacePtr & _content, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeContent( const ContentInterfacePtr & _content, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlNode = _xmlParentNode.append_child( "Content" ); @@ -1212,7 +1212,7 @@ namespace Mengine Detail::serializeNodeProp( _content->getConverterType(), "ConverterType", xmlNode ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeNode( const NodePtr & _node, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeNode( const NodePtr & _node, pugi::xml_node & _xmlParentNode ) { pugi::xml_node xmlNode = _xmlParentNode.append_child( "Node" ); @@ -1229,7 +1229,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeNodeSingle( const NodePtr & _node, pugi::xml_node & _xmlNode ) + void NodeDebuggerModule::serializeNodeSingle( const NodePtr & _node, pugi::xml_node & _xmlNode ) { Detail::serializeNodeProp( _node->getHierarchyHash(), "hhash", _xmlNode ); Detail::serializeNodeProp( _node->getUniqueIdentity(), "uid", _xmlNode ); @@ -1282,7 +1282,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializePickerable( PickerInterface * _picker, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializePickerable( PickerInterface * _picker, pugi::xml_node & _xmlParentNode ) { Pickerable * pickerable = _picker->getPickerable(); @@ -1306,7 +1306,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::serializeRenderable( RenderInterface * _render, pugi::xml_node & _xmlParentNode ) + void NodeDebuggerModule::serializeRenderable( RenderInterface * _render, pugi::xml_node & _xmlParentNode ) { Renderable * renderable = _render->getRenderable(); @@ -1330,7 +1330,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendArrow( const NodePtr & _arrow ) + void NodeDebuggerModule::sendArrow( const NodePtr & _arrow ) { pugi::xml_document doc; @@ -1358,7 +1358,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendScene( const ScenePtr & _scene ) + void NodeDebuggerModule::sendScene( const ScenePtr & _scene ) { pugi::xml_document doc; @@ -1386,7 +1386,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendPickerable( const ScenePtr & _scene ) + void NodeDebuggerModule::sendPickerable( const ScenePtr & _scene ) { pugi::xml_document doc; @@ -1416,7 +1416,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendRenderable( const ScenePtr & _scene ) + void NodeDebuggerModule::sendRenderable( const ScenePtr & _scene ) { pugi::xml_document doc; @@ -1446,7 +1446,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendSettings() + void NodeDebuggerModule::sendSettings() { pugi::xml_document doc; @@ -1566,7 +1566,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendSounds() + void NodeDebuggerModule::sendSounds() { pugi::xml_document doc; @@ -1626,7 +1626,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendMemory() + void NodeDebuggerModule::sendMemory() { pugi::xml_document xml_doc; @@ -1700,7 +1700,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendObjectsLeak() + void NodeDebuggerModule::sendObjectsLeak() { #if defined(MENGINE_DEBUG_FACTORY_ENABLE) uint32_t generation = FACTORY_SERVICE() @@ -1791,7 +1791,7 @@ namespace Mengine #endif } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendNetwork() + void NodeDebuggerModule::sendNetwork() { pugi::xml_document xml_doc; @@ -1825,7 +1825,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::sendSelectedNode() + void NodeDebuggerModule::sendSelectedNode() { pugi::xml_document xml_doc; pugi::xml_node packetNode = xml_doc.append_child( "Packet" ); @@ -1868,7 +1868,7 @@ namespace Mengine this->sendPacket( packet ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::processPacket( NodeDebuggerPacket & _packet ) + void NodeDebuggerModule::processPacket( NodeDebuggerPacket & _packet ) { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_buffer( _packet.payload.data(), _packet.payload.size() ); @@ -1976,7 +1976,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::receiveChangedNode( const pugi::xml_node & _xmlNode ) + void NodeDebuggerModule::receiveChangedNode( const pugi::xml_node & _xmlNode ) { String pathStr = _xmlNode.attribute( "path" ).value(); @@ -2302,7 +2302,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::receiveGameControlCommand( const String & _command ) + void NodeDebuggerModule::receiveGameControlCommand( const String & _command ) { if( _command == "pause" ) { @@ -2326,7 +2326,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::receiveResolutins( uint32_t _width, uint32_t _height ) + void NodeDebuggerModule::receiveResolutins( uint32_t _width, uint32_t _height ) { MENGINE_UNUSED( _width ); MENGINE_UNUSED( _height ); @@ -2337,7 +2337,7 @@ namespace Mengine ->setWindowResolution( newResolution ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::receiveSetting( const Char * _setting, const Char * _key, const Char * _value ) + void NodeDebuggerModule::receiveSetting( const Char * _setting, const Char * _key, const Char * _value ) { ConstString setting_cstr = Helper::stringizeString( _setting ); @@ -2407,7 +2407,7 @@ namespace Mengine NOTIFICATION_NOTIFY( NOTIFICATOR_SETTING_CHANGE, setting, _key ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::stringToPath( const String & _str, VectorNodePath * const _path ) const + void NodeDebuggerModule::stringToPath( const String & _str, VectorNodePath * const _path ) const { if( _str.empty() == false && _str[0] != '-' ) { @@ -2432,7 +2432,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::pathToString( const VectorNodePath & _path, String * const _outStr ) const + void NodeDebuggerModule::pathToString( const VectorNodePath & _path, String * const _outStr ) const { Stringstream stream; StdAlgorithm::copy( _path.begin(), _path.end(), std::ostream_iterator( stream, "/" ) ); @@ -2440,31 +2440,31 @@ namespace Mengine *_outStr = stream.str(); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyChangeSceneComplete( const ScenePtr & _scene ) + void NodeDebuggerModule::notifyChangeSceneComplete( const ScenePtr & _scene ) { this->setScene( _scene ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyChangeSceneDestroy( const ScenePtr & _scene ) + void NodeDebuggerModule::notifyChangeSceneDestroy( const ScenePtr & _scene ) { MENGINE_UNUSED( _scene ); this->setScene( nullptr ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyRemoveSceneDestroy() + void NodeDebuggerModule::notifyRemoveSceneDestroy() { this->setScene( nullptr ); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyIncrefFactoryGeneration( uint32_t _generator ) + void NodeDebuggerModule::notifyIncrefFactoryGeneration( uint32_t _generator ) { MENGINE_UNUSED( _generator ); m_shouldUpdateScene = true; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyHttpRequest( HttpRequestId _id, const String & _url ) + void NodeDebuggerModule::notifyHttpRequest( HttpRequestId _id, const String & _url ) { NodeDebuggerRequestData requestData; @@ -2479,7 +2479,7 @@ namespace Mengine this->clearRequestDatas_(); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyHttpResponse( const HttpResponseInterfacePtr & _response ) + void NodeDebuggerModule::notifyHttpResponse( const HttpResponseInterfacePtr & _response ) { NodeDebuggerRequestData responseData; @@ -2494,7 +2494,7 @@ namespace Mengine this->clearRequestDatas_(); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::foreachRequestData( const LambdaNodeDebuggerRequestData & _lambda ) + void NodeDebuggerModule::foreachRequestData( const LambdaNodeDebuggerRequestData & _lambda ) { for( const NodeDebuggerRequestData & data : m_requestDatas ) { @@ -2502,7 +2502,7 @@ namespace Mengine }; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::clearRequestDatas_() + void NodeDebuggerModule::clearRequestDatas_() { if( m_requestDatas.size() <= 128 ) { @@ -2512,12 +2512,12 @@ namespace Mengine m_requestDatas.pop_front(); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::setUpdateSceneFlag( bool _flag ) + void NodeDebuggerModule::setUpdateSceneFlag( bool _flag ) { m_shouldUpdateScene = _flag; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::findChildRecursive( const NodePtr & _currentNode, const mt::vec2f & _point ) + void NodeDebuggerModule::findChildRecursive( const NodePtr & _currentNode, const mt::vec2f & _point ) { const RenderContext * renderContext = PLAYER_SERVICE() ->getRenderContext(); @@ -2632,7 +2632,7 @@ namespace Mengine MENGINE_UNUSED( result ); } ////////////////////////////////////////////////////////////////////////// - bool ModuleNodeDebugger::checkHit( const ShapePtr & _currentNode, const mt::vec2f & _point ) + bool NodeDebuggerModule::checkHit( const ShapePtr & _currentNode, const mt::vec2f & _point ) { const SurfacePtr & surface = _currentNode->getSurface(); @@ -2688,7 +2688,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool ModuleNodeDebugger::checkIsTransparencePoint( const ShapePtr & _currentNode + bool NodeDebuggerModule::checkIsTransparencePoint( const ShapePtr & _currentNode , const mt::vec2f & _point , const RenderImageLoaderInterfacePtr & _imageLoader , const RenderTextureInterfacePtr & _renderTexture @@ -2775,7 +2775,7 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::getScreenBoundingBox( const ShapePtr & _node, const RenderImageDesc & _imageDesc, mt::box2f * const _bb ) const + void NodeDebuggerModule::getScreenBoundingBox( const ShapePtr & _node, const RenderImageDesc & _imageDesc, mt::box2f * const _bb ) const { mt::box2f boundingBox; this->getWorldBoundingBox( _node, _imageDesc, &boundingBox ); @@ -2794,7 +2794,7 @@ namespace Mengine *_bb = bb_screen; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::getWorldBoundingBox( const ShapePtr & _node, const RenderImageDesc & _imageDesc, mt::box2f * const _bb ) const + void NodeDebuggerModule::getWorldBoundingBox( const ShapePtr & _node, const RenderImageDesc & _imageDesc, mt::box2f * const _bb ) const { TransformationInterface * currentNodeTransformation = _node->getTransformation(); const mt::mat4f & worldMatrix = currentNodeTransformation->getWorldMatrix(); diff --git a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.h b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.h similarity index 98% rename from src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.h rename to src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.h index 347d636f23..905e33f121 100644 --- a/src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.h +++ b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.h @@ -57,16 +57,16 @@ namespace Mengine String url; }; ////////////////////////////////////////////////////////////////////////// - class ModuleNodeDebugger + class NodeDebuggerModule : public ModuleBase , public ThreadWorkerInterface , public SceneDataProviderInterface { - DECLARE_FACTORABLE( ModuleNodeDebugger ); + DECLARE_FACTORABLE( NodeDebuggerModule ); public: - ModuleNodeDebugger(); - ~ModuleNodeDebugger() override; + NodeDebuggerModule(); + ~NodeDebuggerModule() override; protected: bool _initializeModule() override; From dde860b7b70f5d7eb71f00d811488f0145ac525c Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:13:58 +0200 Subject: [PATCH 096/169] wip plugin AppleAdMobPlugin --- .../AppleAdMobApplicationDelegate.h | 32 ++ .../AppleAdMobApplicationDelegate.mm | 351 ++++++++++++++++++ .../AppleAdMobBannerDelegate.h | 34 ++ .../AppleAdMobBannerDelegate.mm | 205 ++++++++++ .../AppleAdMobPlugin/AppleAdMobBaseDelegate.h | 39 ++ .../AppleAdMobBaseDelegate.mm | 149 ++++++++ .../AppleAdMobPlugin/AppleAdMobInterface.h | 10 + .../AppleAdMobInterstitialDelegate.h | 26 ++ .../AppleAdMobInterstitialDelegate.mm | 207 +++++++++++ .../AppleAdMobPlugin/AppleAdMobPlugin.h | 21 ++ .../AppleAdMobPlugin/AppleAdMobPlugin.mm | 57 +++ .../AppleAdMobRewardedDelegate.h | 27 ++ .../AppleAdMobRewardedDelegate.mm | 257 +++++++++++++ src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 37 ++ src/Plugins/CMakeLists.txt | 4 + 15 files changed, 1456 insertions(+) create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobInterface.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.mm create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm create mode 100644 src/Plugins/AppleAdMobPlugin/CMakeLists.txt diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h new file mode 100644 index 0000000000..0c6112f27f --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h @@ -0,0 +1,32 @@ +#pragma once + +#import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" + +#import "Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h" + +#import "AppleAdMobInterface.h" + +#import "AppleAdMobBannerDelegate.h" +#import "AppleAdMobInterstitialDelegate.h" +#import "AppleAdMobRewardedDelegate.h" + +#import + +#define PLUGIN_BUNDLE_NAME "MengineAppleAdMobPlugin" + +@interface AppleAdMobApplicationDelegate : NSObject + +- (id)getAdvertisementBannerCallback; +- (id)getAdvertisementInterstitialCallback; +- (id)getAdvertisementRewardedCallback; + +- (AppleAdMobBannerDelegate *)getBanner; +- (AppleAdMobInterstitialDelegate *)getInterstitial; +- (AppleAdMobRewardedDelegate *)getRewarded; + +@property (nonatomic, strong) AppleAdMobBannerDelegate * m_bannerAd; +@property (nonatomic, strong) AppleAdMobInterstitialDelegate * m_interstitialAd; +@property (nonatomic, strong) AppleAdMobRewardedDelegate * m_rewardedAd; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm new file mode 100644 index 0000000000..476b71489b --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -0,0 +1,351 @@ +#import "AppleAdMobApplicationDelegate.h" + +#import "Environment/Apple/AppleBundle.h" +#import "Environment/Apple/AppleSemaphoreService.h" +#import "Environment/Apple/AppleDetail.h" + +#import "Environment/iOS/iOSApplication.h" +#import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSNetwork.h" +#import "Environment/iOS/iOSLog.h" + +#import "Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h" + +#include "Config/Version.h" + +#include "Configuration/Configurations.h" + +#if defined(MENGINE_DEBUG) +# import +#endif + +@implementation AppleAdMobApplicationDelegate + +- (instancetype)init { + self = [super init]; + + if (self) { + self.m_bannerAd = nil; + self.m_interstitialAd = nil; + self.m_rewardedAd = nil; + } + + return self; +} + +- (id)getAdvertisementBannerCallback { + id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; + + id callback = [advertisement getBannerCallback]; + + return callback; +} + +- (id)getAdvertisementInterstitialCallback { + id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; + + id callback = [advertisement getInterstitialCallback]; + + return callback; +} + +- (id)getAdvertisementRewardedCallback { + id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; + + id callback = [advertisement getRewardedCallback]; + + return callback; +} + +- (AppleAdMobBannerDelegate *)getBanner { + return self.m_bannerAd; +} + +- (AppleAdMobInterstitialDelegate *)getInterstitial { + return self.m_interstitialAd; +} + +- (AppleAdMobRewardedDelegate *)getRewarded { + return self.m_rewardedAd; +} + +#pragma mark - AppleAdMobInterface + ++ (instancetype)sharedInstance { + static AppleAdMobApplicationDelegate * sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [iOSDetail getPluginDelegateOfClass:[AppleAdMobApplicationDelegate class]]; + }); + return sharedInstance; +} + +#pragma mark - iOSPluginApplicationDelegateInterface + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + if ([AppleBundle hasPluginConfig:@PLUGIN_BUNDLE_NAME] == NO) { + IOS_LOGGER_ERROR(@"[ERROR] AdMob plugin not found bundle config [%@]", @PLUGIN_BUNDLE_NAME); + + return NO; + } + + GADMobileAds * mobileAds = [GADMobileAds sharedInstance]; + + GADVersionNumber version = [GADMobileAds versionNumber]; + NSString * versionString = [NSString stringWithFormat:@"%lu.%lu.%lu", version.majorVersion, version.minorVersion, version.patchVersion]; + + IOS_LOGGER_MESSAGE(@"AdMob: %@", versionString); + + NSString * MengineAppleAdMobPlugin_AppId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"AppId" withDefault:nil]; + + if (MengineAppleAdMobPlugin_AppId != nil && [MengineAppleAdMobPlugin_AppId length] > 0) { + [GADMobileAds configureWithApplicationID:MengineAppleAdMobPlugin_AppId]; + + IOS_LOGGER_MESSAGE(@"[AdMob] configure with AppId: %@", MengineAppleAdMobPlugin_AppId); + } + + BOOL MengineAppleAdMobPlugin_RequestConfigurationTestDeviceIdsEnabled = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"RequestConfigurationTestDeviceIdsEnabled" withDefault:NO]; + + if (MengineAppleAdMobPlugin_RequestConfigurationTestDeviceIdsEnabled == YES) { + GADRequestConfiguration * requestConfiguration = mobileAds.requestConfiguration; + +#if defined(MENGINE_DEBUG) + if ([AppleDetail hasOption:@"admob.test_device_advertising"] == YES) { + NSString * testDeviceId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; + requestConfiguration.testDeviceIdentifiers = @[testDeviceId]; + + IOS_LOGGER_MESSAGE(@"[AdMob] test device id: %@", testDeviceId); + } +#endif + } + + id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; + + [advertisement setProvider:self]; + + NSString * MengineAppleAdMobPlugin_BannerAdUnitId = nil; + NSString * MengineAppleAdMobPlugin_InterstitialAdUnitId = nil; + NSString * MengineAppleAdMobPlugin_RewardedAdUnitId = nil; + +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_BANNER) + MengineAppleAdMobPlugin_BannerAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdUnitId" withDefault:nil]; +#endif + +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_INTERSTITIAL) + MengineAppleAdMobPlugin_InterstitialAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"InterstitialAdUnitId" withDefault:nil]; +#endif + +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_REWARDED) + MengineAppleAdMobPlugin_RewardedAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"RewardedAdUnitId" withDefault:nil]; +#endif + + __weak AppleAdMobApplicationDelegate * weakSelf = self; + + [mobileAds startWithCompletionHandler:^(GADInitializationStatus * _Nonnull status) { + __strong AppleAdMobApplicationDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + + IOS_LOGGER_MESSAGE(@"[AdMob] plugin initialize complete"); + + id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; + +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_BANNER) + if (MengineAppleAdMobPlugin_BannerAdUnitId != nil) { + NSString * MengineAppleAdMobPlugin_BannerPlacement = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerPlacement" withDefault:@"banner"]; + + BOOL MengineAppleAdMobPlugin_BannerAdaptive = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdaptive" withDefault:YES]; + + AppleAdMobBannerDelegate * bannerAd = [[AppleAdMobBannerDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_BannerAdUnitId advertisement:advertisement placement:MengineAppleAdMobPlugin_BannerPlacement adaptive:MengineAppleAdMobPlugin_BannerAdaptive]; + + strongSelf.m_bannerAd = bannerAd; + } +#endif + +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_INTERSTITIAL) + if (MengineAppleAdMobPlugin_InterstitialAdUnitId != nil) { + AppleAdMobInterstitialDelegate * interstitialAd = [[AppleAdMobInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_InterstitialAdUnitId advertisement:advertisement]; + + strongSelf.m_interstitialAd = interstitialAd; + } +#endif + +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_REWARDED) + if (MengineAppleAdMobPlugin_RewardedAdUnitId != nil) { + AppleAdMobRewardedDelegate * rewardedAd = [[AppleAdMobRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_RewardedAdUnitId advertisement:advertisement]; + + strongSelf.m_rewardedAd = rewardedAd; + } +#endif + + [advertisement readyAdProvider]; + }]; + + return YES; +} + +#pragma mark - AppleAdvertisementProviderInterface + +- (BOOL)hasBanner { + if (self.m_bannerAd == nil) { + return NO; + } + + return YES; +} + +- (BOOL)showBanner { + if (self.m_bannerAd == nil) { + return NO; + } + + [self.m_bannerAd show]; + + return YES; +} + +- (BOOL)hideBanner { + if (self.m_bannerAd == nil) { + return NO; + } + + [self.m_bannerAd hide]; + + return YES; +} + +- (BOOL)getBannerWidth:(uint32_t *)width height:(uint32_t *)height { + if (self.m_bannerAd == nil) { + return NO; + } + + *width = [self.m_bannerAd getWidthPx]; + *height = [self.m_bannerAd getHeightPx]; + + return YES; +} + +- (BOOL)hasInterstitial { + if (self.m_interstitialAd == nil) { + return NO; + } + + return YES; +} + +- (BOOL)canYouShowInterstitial:(NSString *)placement { + if (self.m_interstitialAd == nil) { + return NO; + } + + if ([[iOSNetwork sharedInstance] isNetworkAvailable] == NO) { + return NO; + } + + if ([self.m_interstitialAd canYouShow:placement] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)showInterstitial:(NSString *)placement { + if (self.m_interstitialAd == nil) { + return NO; + } + + if ([[iOSNetwork sharedInstance] isNetworkAvailable] == NO) { + return NO; + } + + if ([self.m_interstitialAd show:placement] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)isShowingInterstitial { + if (self.m_interstitialAd == nil) { + return NO; + } + + if ([self.m_interstitialAd isShowing] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)hasRewarded { + if (self.m_rewardedAd == nil) { + return NO; + } + + return YES; +} + +- (BOOL)canOfferRewarded:(NSString *)placement { + if (self.m_rewardedAd == nil) { + return NO; + } + + if ([[iOSNetwork sharedInstance] isNetworkAvailable] == NO) { + return NO; + } + + if ([self.m_rewardedAd canOffer:placement] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)canYouShowRewarded:(NSString *)placement { + if (self.m_rewardedAd == nil) { + return NO; + } + + if ([[iOSNetwork sharedInstance] isNetworkAvailable] == NO) { + return NO; + } + + if ([self.m_rewardedAd canYouShow:placement] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)showRewarded:(NSString *)placement { + if (self.m_rewardedAd == nil) { + return NO; + } + + if ([[iOSNetwork sharedInstance] isNetworkAvailable] == NO) { + return NO; + } + + if ([self.m_rewardedAd show:placement] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)isShowingRewarded { + if (self.m_rewardedAd == nil) { + return NO; + } + + if ([self.m_rewardedAd isShowing] == NO) { + return NO; + } + + return YES; +} + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.h new file mode 100644 index 0000000000..209a78d31a --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.h @@ -0,0 +1,34 @@ +#pragma once + +#import "Environment/Apple/AppleIncluder.h" + +#import "AppleAdMobBaseDelegate.h" + +#include "Configuration/Configurations.h" + +#import + +@interface AppleAdMobBannerDelegate : AppleAdMobBaseDelegate + +- (instancetype _Nullable)initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId + advertisement:(id _Nonnull)advertisement + placement:(NSString * _Nonnull) placement + adaptive:(BOOL) adaptive; + +- (void)show; +- (void)hide; + +- (void)loadAd; + +- (CGSize)getSize; +- (CGRect)getRect; + +- (CGFloat)getHeightPx; +- (CGFloat)getWidthPx; + +@property (nonatomic, strong) GADBannerView * _Nullable m_bannerView; + +@property (assign) BOOL m_bannerAdaptive; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm new file mode 100644 index 0000000000..52bd0e24a7 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm @@ -0,0 +1,205 @@ +#import "AppleAdMobBannerDelegate.h" + +#import "Environment/Apple/AppleDetail.h" +#import "Environment/Apple/AppleBundle.h" +#import "Environment/Apple/AppleString.h" + +#import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSLog.h" + +#import "AppleAdMobApplicationDelegate.h" + +@implementation AppleAdMobBannerDelegate + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId + advertisement:(id _Nonnull)advertisement + placement:(NSString * _Nonnull)placement + adaptive:(BOOL)adaptive { + self = [super initWithAdUnitIdentifier:adUnitId advertisement:advertisement]; + + self.m_bannerAdaptive = adaptive; + + GADBannerView * bannerView; + + @try { + GADAdSize adSize; + if (adaptive == YES) { + CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); + adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width); + } else { + BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; + + if (isPad == YES) { + adSize = GADAdSizeLeaderboard; + } else { + adSize = GADAdSizeBanner; + } + } + + bannerView = [[GADBannerView alloc] initWithAdSize:adSize]; + bannerView.adUnitID = adUnitId; + } @catch (NSException * ex) { + IOS_LOGGER_ERROR(@"[Error] AppleAdMobBannerDelegate invalid create GADBannerView adUnitId: %@ exception: %@ [%@]" + , adUnitId + , ex.reason + , ex.name + ); + + return nil; + } + + bannerView.delegate = self; + + CGSize size = [self getSize]; + + CGFloat banner_height = size.height; + + CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); + CGFloat screen_height = CGRectGetHeight(UIScreen.mainScreen.bounds); + + CGRect rect = CGRectMake(0, screen_height - banner_height, screen_width, banner_height); + + bannerView.frame = rect; + + bannerView.backgroundColor = UIColor.clearColor; + + UIViewController * viewController = [iOSDetail getRootViewController]; + [viewController.view addSubview:bannerView]; + bannerView.hidden = YES; + + self.m_bannerView = bannerView; + + [self loadAd]; + + return self; +} + +- (void) dealloc { + if (self.m_bannerView != nil) { + self.m_bannerView.delegate = nil; + + [self.m_bannerView removeFromSuperview]; + self.m_bannerView = nil; + } +} + +- (void) eventBanner:(NSString * _Nonnull) eventName params:(NSDictionary * _Nullable) params { + [self event:[@"mng_admob_banner_" stringByAppendingString:eventName] params:params]; +} + +- (void) show { + self.m_bannerView.hidden = NO; +} + +- (void) hide { + self.m_bannerView.hidden = YES; +} + +- (void) loadAd { + if (self.m_bannerView == nil) { + return; + } + + [self increaseRequestId]; + + [self log:@"loadAd"]; + + [self eventBanner:@"load" params:@{}]; + + UIViewController * viewController = [iOSDetail getRootViewController]; + self.m_bannerView.rootViewController = viewController; + + GADRequest * request = [GADRequest request]; + [self.m_bannerView loadRequest:request]; +} + +- (CGSize) getSize { + if (self.m_bannerView == nil) { + if (self.m_bannerAdaptive == YES) { + CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); + return GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width).size; + } else { + BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; + + if (isPad == YES) { + return GADAdSizeLeaderboard.size; + } else { + return GADAdSizeBanner.size; + } + } + } + + return self.m_bannerView.adSize.size; +} + +- (CGRect) getRect { + if (self.m_bannerView == nil) { + return CGRectZero; + } + + CGRect frame = self.m_bannerView.frame; + + return frame; +} + +- (CGFloat) getHeightPx { + CGSize banner_size = [self getSize]; + + return banner_size.height; +} + +- (CGFloat) getWidthPx { + CGSize banner_size = [self getSize]; + + return banner_size.width; +} + +#pragma mark - GADBannerViewDelegate + +- (void)bannerViewDidReceiveAd:(GADBannerView *)bannerView { + [self log:@"bannerViewDidReceiveAd" withParams:[self getGADResponseInfoParams:bannerView.responseInfo]]; + + [self eventBanner:@"loaded" params:@{ + @"response": [self getGADResponseInfoParams:bannerView.responseInfo] + }]; + + self.m_requestAttempt = 0; +} + +- (void)bannerView:(GADBannerView *)bannerView didFailToReceiveAdWithError:(NSError *)error { + [self log:@"bannerView:didFailToReceiveAdWithError" withError:error]; + + [self eventBanner:@"load_failed" params:@{ + @"error": [self getGADAdErrorParams:error], + @"error_code": @(error.code) + }]; + + [self retryLoadAd]; +} + +- (void)bannerViewDidRecordImpression:(GADBannerView *)bannerView { + [self log:@"bannerViewDidRecordImpression"]; + + [self eventBanner:@"impression" params:@{}]; +} + +- (void)bannerViewWillPresentScreen:(GADBannerView *)bannerView { + [self log:@"bannerViewWillPresentScreen"]; + + [self eventBanner:@"will_present" params:@{}]; +} + +- (void)bannerViewWillDismissScreen:(GADBannerView *)bannerView { + [self log:@"bannerViewWillDismissScreen"]; + + [self eventBanner:@"will_dismiss" params:@{}]; +} + +- (void)bannerViewDidDismissScreen:(GADBannerView *)bannerView { + [self log:@"bannerViewDidDismissScreen"]; + + [self eventBanner:@"dismissed" params:@{}]; +} + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h new file mode 100644 index 0000000000..609a0d10a1 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h @@ -0,0 +1,39 @@ +#pragma once + +#import "AppleAdMobInterface.h" + +#import "Environment/Apple/AppleIncluder.h" + +#import "Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h" + +#import + +@interface AppleAdMobBaseDelegate : NSObject + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId + advertisement:(id _Nonnull)advertisement; + +- (void) loadAd; +- (void) retryLoadAd; +- (NSInteger) increaseRequestId; +- (NSInteger) getRequestTimeMillisec; + +- (NSDictionary * _Nonnull) getGADResponseInfoParams:(GADResponseInfo * _Nullable) responseInfo; +- (NSDictionary * _Nonnull) getGADAdErrorParams:(NSError * _Nonnull) error; + +- (void) log:(NSString * _Nonnull) callback; +- (void) log:(NSString * _Nonnull) callback withParams:(NSDictionary * _Nonnull) params; +- (void) log:(NSString * _Nonnull) callback withError:(NSError * _Nonnull) error; + +- (void) event:(NSString * _Nonnull)name params:(NSDictionary * _Nonnull)params; + +@property (nonatomic, strong) NSString * _Nonnull m_adUnitId; +@property (nonatomic, strong) id _Nonnull m_advertisement; + +@property (nonatomic, assign) NSInteger m_enumeratorRequest; +@property (nonatomic, assign) NSInteger m_requestId; +@property (nonatomic, assign) NSInteger m_requestAttempt; +@property (nonatomic, assign) NSTimeInterval m_requestTimestamp; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm new file mode 100644 index 0000000000..91bb4bdd05 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -0,0 +1,149 @@ +#import "AppleAdMobBaseDelegate.h" + +#import "Environment/Apple/AppleDetail.h" + +#import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSAnalytics.h" +#import "Environment/iOS/iOSLog.h" + +@implementation AppleAdMobBaseDelegate + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId + advertisement:(id _Nonnull)advertisement { + self = [super init]; + + self.m_adUnitId = adUnitId; + self.m_advertisement = advertisement; + + self.m_requestAttempt = 0; + self.m_enumeratorRequest = 0; + self.m_requestId = 0; + self.m_requestTimestamp = 0.0; + + return self; +} + +- (NSDictionary * _Nonnull) getGADResponseInfoParams:(GADResponseInfo * _Nullable) responseInfo { + NSMutableDictionary * params = [NSMutableDictionary dictionary]; + + if (responseInfo != nil) { + if (responseInfo.adNetworkClassName != nil) { + [params setObject:responseInfo.adNetworkClassName forKey:@"adNetworkClassName"]; + } + if (responseInfo.responseIdentifier != nil) { + [params setObject:responseInfo.responseIdentifier forKey:@"responseIdentifier"]; + } + if (responseInfo.loadedAdNetworkResponseInfo != nil) { + if (responseInfo.loadedAdNetworkResponseInfo.adNetworkClassName != nil) { + [params setObject:responseInfo.loadedAdNetworkResponseInfo.adNetworkClassName forKey:@"networkName"]; + } + if (responseInfo.loadedAdNetworkResponseInfo.credentials != nil) { + [params setObject:responseInfo.loadedAdNetworkResponseInfo.credentials forKey:@"credentials"]; + } + } + } + + return params; +} + +- (NSDictionary * _Nonnull) getGADAdErrorParams:(NSError * _Nonnull) error { + NSMutableDictionary * params = [NSMutableDictionary dictionary]; + + [params setObject:@(error.code) forKey:@"code"]; + + if (error.localizedDescription != nil) { + [params setObject:error.localizedDescription forKey:@"message"]; + } + + if (error.userInfo != nil) { + NSDictionary * userInfo = error.userInfo; + + if (userInfo[@"NSUnderlyingError"] != nil) { + NSError * underlyingError = userInfo[@"NSUnderlyingError"]; + [params setObject:@(underlyingError.code) forKey:@"underlyingErrorCode"]; + if (underlyingError.localizedDescription != nil) { + [params setObject:underlyingError.localizedDescription forKey:@"underlyingErrorMessage"]; + } + } + } + + return params; +} + +- (void) log:(NSString * _Nonnull) method { + IOS_LOGGER_INFO(@"[AdMob] %@: adUnitId: %@ request: %ld" + , method + , self.m_adUnitId + , self.m_requestId + ); +} + +- (void) log:(NSString * _Nonnull) method withParams:(NSDictionary * _Nonnull) params { + IOS_LOGGER_INFO(@"[AdMob] %@: adUnitId: %@ request: %ld %@" + , method + , self.m_adUnitId + , self.m_requestId + , [NSString stringWithFormat:@"%@", params] + ); +} + +- (void) log:(NSString * _Nonnull) method withError:(NSError * _Nonnull) error { + IOS_LOGGER_INFO(@"[AdMob] %@: adUnitId: %@ request: %ld with error: %@" + , method + , self.m_adUnitId + , self.m_requestId + , [NSString stringWithFormat:@"%@", [self getGADAdErrorParams:error]] + ); +} + +- (void) loadAd { + //Empty + + [AppleDetail raisePureVirtualMethodException:[self class] selector:_cmd]; +} + +- (void) retryLoadAd { + self.m_requestAttempt++; + + NSTimeInterval delaySec = pow(2, MIN(6, self.m_requestAttempt)); + + [AppleDetail addMainQueueOperation:^{ + [NSThread sleepForTimeInterval:delaySec]; + + [self loadAd]; + }]; +} + +- (NSInteger) increaseRequestId { + self.m_requestId = self.m_enumeratorRequest++; + self.m_requestTimestamp = [[NSDate date] timeIntervalSince1970]; + + return self.m_requestId; +} + +- (NSInteger) getRequestTimeMillisec { + NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970]; + NSTimeInterval requestTime = timestamp - self.m_requestTimestamp; + + NSInteger requestTimeMillisec = (NSInteger)(requestTime * 1000.0); + + return requestTimeMillisec; +} + +- (void) event:(NSString * _Nonnull)name params:(NSDictionary * _Nonnull)params { + NSInteger requestTimeMillisec = [self getRequestTimeMillisec]; + + NSMutableDictionary * total_params = [@{ + @"ad_unit_id": self.m_adUnitId, + @"request_id": @(self.m_requestId), + @"request_time": @(requestTimeMillisec), + @"request_attempt": @(self.m_requestAttempt) + } mutableCopy]; + + [total_params addEntriesFromDictionary:params]; + + [iOSAnalytics event:name params:total_params]; +} + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterface.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterface.h new file mode 100644 index 0000000000..650abde9cc --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterface.h @@ -0,0 +1,10 @@ +#pragma once + +#import "Environment/Apple/AppleIncluder.h" + +@protocol AppleAdMobInterface + ++ (instancetype)sharedInstance; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.h new file mode 100644 index 0000000000..a88fe01d36 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.h @@ -0,0 +1,26 @@ +#pragma once + +#import "AppleAdMobBaseDelegate.h" + +#import "Environment/Apple/AppleIncluder.h" + +#include "Configuration/Configurations.h" + +#import + +@interface AppleAdMobInterstitialDelegate : AppleAdMobBaseDelegate + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull) adUnitId advertisement:(id _Nonnull)advertisement; + +- (BOOL) canYouShow:(NSString * _Nonnull) placement; +- (BOOL) show:(NSString * _Nonnull) placement; +- (BOOL) isShowing; + +- (void) loadAd; + +@property (nonatomic, strong) GADInterstitialAd * _Nullable m_interstitialAd; + +@property (atomic, assign) BOOL m_showing; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm new file mode 100644 index 0000000000..03bd92dab0 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm @@ -0,0 +1,207 @@ +#import "AppleAdMobInterstitialDelegate.h" + +#include "Interface/PlatformServiceInterface.h" + +#import "Environment/Apple/AppleDetail.h" +#import "Environment/Apple/AppleString.h" + +#import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSLog.h" + +#import "AppleAdMobApplicationDelegate.h" + +@implementation AppleAdMobInterstitialDelegate + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId advertisement:(id _Nonnull)advertisement { + self = [super initWithAdUnitIdentifier:adUnitId advertisement:advertisement]; + + self.m_interstitialAd = nil; + + self.m_showing = NO; + + [self loadAd]; + + return self; +} + +- (void) dealloc { + if (self.m_interstitialAd != nil) { + self.m_interstitialAd.fullScreenContentDelegate = nil; + + self.m_interstitialAd = nil; + } +} + +- (void) eventInterstitial:(NSString * _Nonnull) eventName params:(NSDictionary * _Nullable) params { + [self event:[@"mng_admob_interstitial_" stringByAppendingString:eventName] params:params]; +} + +- (BOOL) canYouShow:(NSString * _Nonnull)placement { + if (self.m_interstitialAd == nil) { + return NO; + } + + BOOL ready = self.m_interstitialAd != nil; + + [self log:@"canYouShow" withParams:@{@"placement":placement, @"ready":@(ready)}]; + + if (ready == NO) { + [self eventInterstitial:@"show" params:@{ + @"placement": placement, + @"ready": @(NO) + }]; + + return NO; + } + + return YES; +} + +- (BOOL) show:(NSString * _Nonnull)placement { + if (self.m_interstitialAd == nil) { + return NO; + } + + BOOL ready = self.m_interstitialAd != nil; + + [self log:@"show" withParams:@{@"placement":placement, @"ready":@(ready)}]; + + [self eventInterstitial:@"show" params:@{ + @"placement": placement, + @"ready": @(ready) + }]; + + if (ready == NO) { + return NO; + } + + self.m_showing = YES; + + UIViewController * viewController = [iOSDetail getRootViewController]; + [self.m_interstitialAd presentFromRootViewController:viewController]; + + return YES; +} + +- (BOOL) isShowing { + return self.m_showing; +} + +- (void) loadAd { + if (self.m_adUnitId == nil) { + return; + } + + [self increaseRequestId]; + + [self log:@"loadAd"]; + + [self eventInterstitial:@"load" params:@{}]; + + GADRequest * request = [GADRequest request]; + + __weak AppleAdMobInterstitialDelegate * weakSelf = self; + + [GADInterstitialAd loadWithAdUnitID:self.m_adUnitId + request:request + completionHandler:^(GADInterstitialAd * _Nullable interstitialAd, NSError * _Nullable error) { + __strong AppleAdMobInterstitialDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + + if (error != nil) { + [strongSelf log:@"loadWithAdUnitID:completionHandler" withError:error]; + + [strongSelf eventInterstitial:@"load_failed" params:@{ + @"error": [strongSelf getGADAdErrorParams:error], + @"error_code": @(error.code) + }]; + + [strongSelf retryLoadAd]; + + return; + } + + if (interstitialAd == nil) { + return; + } + + interstitialAd.fullScreenContentDelegate = strongSelf; + strongSelf.m_interstitialAd = interstitialAd; + + [strongSelf log:@"loadWithAdUnitID:completionHandler" withParams:[strongSelf getGADResponseInfoParams:interstitialAd.responseInfo]]; + + [strongSelf eventInterstitial:@"loaded" params:@{ + @"response": [strongSelf getGADResponseInfoParams:interstitialAd.responseInfo] + }]; + + strongSelf.m_requestAttempt = 0; + }]; +} + +#pragma mark - GADFullScreenContentDelegate + +- (void)adWillPresentFullScreenContent:(id)ad { + [self log:@"adWillPresentFullScreenContent"]; + + [self eventInterstitial:@"will_present" params:@{}]; + + PLATFORM_SERVICE() + ->freezePlatform( true, true ); +} + +- (void)ad:(id)ad didFailToPresentFullScreenContentWithError:(NSError *)error { + [self log:@"ad:didFailToPresentFullScreenContentWithError" withError:error]; + + [self eventInterstitial:@"present_failed" params:@{ + @"error": [self getGADAdErrorParams:error], + @"error_code": @(error.code) + }]; + + self.m_showing = NO; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; + + if (callback != nil) { + [callback onAppleAdvertisementShowFailed:@"unknown" withError:error.code]; + } + + [self loadAd]; +} + +- (void)adDidDismissFullScreenContent:(id)ad { + [self log:@"adDidDismissFullScreenContent"]; + + [self eventInterstitial:@"dismissed" params:@{}]; + + PLATFORM_SERVICE() + ->unfreezePlatform( true, true ); + + self.m_showing = NO; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; + + if (callback != nil) { + [callback onAppleAdvertisementShowSuccess:@"unknown"]; + } + + self.m_interstitialAd = nil; + [self loadAd]; +} + +- (void)adDidRecordImpression:(id)ad { + [self log:@"adDidRecordImpression"]; + + [self eventInterstitial:@"impression" params:@{}]; +} + +- (void)adDidRecordClick:(id)ad { + [self log:@"adDidRecordClick"]; + + [self eventInterstitial:@"clicked" params:@{}]; +} + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.h new file mode 100644 index 0000000000..2b166e2661 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Kernel/PluginBase.h" + +namespace Mengine +{ + class AppleAdMobPlugin + : public PluginBase + { + PLUGIN_DECLARE( "AppleAdMob" ) + + public: + AppleAdMobPlugin(); + ~AppleAdMobPlugin() override; + + protected: + bool _initializePlugin() override; + void _finalizePlugin() override; + }; +} + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.mm new file mode 100644 index 0000000000..d563e3b1bf --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobPlugin.mm @@ -0,0 +1,57 @@ +#include "AppleAdMobPlugin.h" + +#if defined(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) +# include "Interface/ScriptServiceInterface.h" + +# include "AppleAdMobScriptEmbedding.h" +#endif + +#include "Kernel/ConfigHelper.h" +#include "Kernel/OptionHelper.h" +#include "Kernel/FactorableUnique.h" +#include "Kernel/NotificationHelper.h" +#include "Kernel/PluginHelper.h" + +////////////////////////////////////////////////////////////////////////// +PLUGIN_FACTORY( AppleAdMob, Mengine::AppleAdMobPlugin ); +////////////////////////////////////////////////////////////////////////// +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + AppleAdMobPlugin::AppleAdMobPlugin() + { + } + ////////////////////////////////////////////////////////////////////////// + AppleAdMobPlugin::~AppleAdMobPlugin() + { + } + ////////////////////////////////////////////////////////////////////////// + bool AppleAdMobPlugin::_initializePlugin() + { +#if defined(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) + NOTIFICATION_ADDOBSERVERLAMBDA_THIS( NOTIFICATOR_SCRIPT_EMBEDDING, [this]() + { + SCRIPT_SERVICE() + ->addScriptEmbedding( STRINGIZE_STRING_LOCAL( "AppleAdMobScriptEmbedding" ), Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ) ); + }, MENGINE_DOCUMENT_FACTORABLE ); + + NOTIFICATION_ADDOBSERVERLAMBDA_THIS( NOTIFICATOR_SCRIPT_EJECTING, []() + { + SCRIPT_SERVICE() + ->removeScriptEmbedding( STRINGIZE_STRING_LOCAL( "AppleAdMobScriptEmbedding" ) ); + }, MENGINE_DOCUMENT_FACTORABLE ); +#endif + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void AppleAdMobPlugin::_finalizePlugin() + { +#if defined(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) + NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_SCRIPT_EMBEDDING ); + NOTIFICATION_REMOVEOBSERVER_THIS( NOTIFICATOR_SCRIPT_EJECTING ); +#endif + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.h new file mode 100644 index 0000000000..d353eb7bfb --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.h @@ -0,0 +1,27 @@ +#pragma once + +#import "AppleAdMobBaseDelegate.h" + +#import "Environment/Apple/AppleIncluder.h" + +#include "Configuration/Configurations.h" + +#import + +@interface AppleAdMobRewardedDelegate : AppleAdMobBaseDelegate + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId advertisement:(id _Nonnull)advertisement; + +- (BOOL) canOffer:(NSString * _Nonnull)placement; +- (BOOL) canYouShow:(NSString * _Nonnull)placement; +- (BOOL) show:(NSString * _Nonnull)placement; +- (BOOL) isShowing; + +- (void) loadAd; + +@property (nonatomic, strong) GADRewardedAd * _Nullable m_rewardedAd; + +@property (atomic, assign) BOOL m_showing; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm new file mode 100644 index 0000000000..7b43e4fac4 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm @@ -0,0 +1,257 @@ +#import "AppleAdMobRewardedDelegate.h" + +#include "Interface/PlatformServiceInterface.h" + +#import "Environment/Apple/AppleDetail.h" +#import "Environment/Apple/AppleString.h" + +#import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSNetwork.h" + +#import "AppleAdMobApplicationDelegate.h" + +@implementation AppleAdMobRewardedDelegate + +- (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitId advertisement:(id _Nonnull)advertisement { + self = [super initWithAdUnitIdentifier:adUnitId advertisement:advertisement]; + + self.m_rewardedAd = nil; + + self.m_showing = NO; + + [self loadAd]; + + return self; +} + +- (void) dealloc { + if (self.m_rewardedAd != nil) { + self.m_rewardedAd.fullScreenContentDelegate = nil; + + self.m_rewardedAd = nil; + } +} + +- (void) eventRewarded:(NSString * _Nonnull) eventName params:(NSDictionary * _Nullable) params { + [self event:[@"mng_admob_rewarded_" stringByAppendingString:eventName] params:params]; +} + +- (BOOL) canOffer:(NSString * _Nonnull)placement { + if (self.m_rewardedAd == nil) { + return NO; + } + + BOOL ready = self.m_rewardedAd != nil; + + [self log:@"canOffer" withParams:@{@"placement":placement, @"ready":@(ready)}]; + + [self eventRewarded:@"offer" params:@{ + @"placement": placement, + @"ready": @(ready) + }]; + + return ready; +} + +- (BOOL) canYouShow:(NSString * _Nonnull)placement { + if (self.m_rewardedAd == nil) { + return NO; + } + + BOOL ready = self.m_rewardedAd != nil; + + [self log:@"canYouShow" withParams:@{@"placement":placement, @"ready":@(ready)}]; + + if( ready == NO ) { + [self eventRewarded:@"show" params:@{ + @"placement": placement, + @"ready": @(NO) + }]; + + return NO; + } + + if ([[iOSNetwork sharedInstance] isNetworkAvailable] == NO) { + return NO; + } + + return YES; +} + +- (BOOL) show:(NSString * _Nonnull)placement { + if (self.m_rewardedAd == nil) { + return NO; + } + + BOOL ready = self.m_rewardedAd != nil; + + [self log:@"show" withParams:@{@"placement":placement, @"ready":@(ready)}]; + + [self eventRewarded:@"show" params:@{ + @"placement": placement, + @"ready": @(ready) + }]; + + if (ready == NO) { + return NO; + } + + self.m_showing = YES; + + UIViewController * viewController = [iOSDetail getRootViewController]; + + __weak AppleAdMobRewardedDelegate * weakSelf = self; + + [self.m_rewardedAd presentFromRootViewController:viewController + userDidEarnRewardHandler:^{ + __strong AppleAdMobRewardedDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + + GADAdReward * reward = strongSelf.m_rewardedAd.adReward; + + [strongSelf log:@"userDidEarnReward"]; + + [strongSelf eventRewarded:@"rewarded" params:@{ + @"placement": placement, + @"label": reward.type != nil ? reward.type : @"", + @"amount": @(reward.amount.doubleValue) + }]; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; + + if (callback != nil) { + NSString * label = reward.type != nil ? reward.type : @""; + NSInteger amount = (NSInteger)reward.amount.doubleValue; + [callback onAppleAdvertisementUserRewarded:placement withLabel:label withAmount:amount]; + } + }]; + + return YES; +} + +- (BOOL) isShowing { + return self.m_showing; +} + +- (void) loadAd { + if (self.m_adUnitId == nil) { + return; + } + + [self increaseRequestId]; + + [self log:@"loadAd"]; + + [self eventRewarded:@"load" params:@{}]; + + GADRequest * request = [GADRequest request]; + + __weak AppleAdMobRewardedDelegate * weakSelf = self; + + [GADRewardedAd loadWithAdUnitID:self.m_adUnitId + request:request + completionHandler:^(GADRewardedAd * _Nullable rewardedAd, NSError * _Nullable error) { + __strong AppleAdMobRewardedDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + + if (error != nil) { + [strongSelf log:@"loadWithAdUnitID:completionHandler" withError:error]; + + [strongSelf eventRewarded:@"load_failed" params:@{ + @"error": [strongSelf getGADAdErrorParams:error], + @"error_code": @(error.code) + }]; + + [strongSelf retryLoadAd]; + + return; + } + + if (rewardedAd == nil) { + return; + } + + rewardedAd.fullScreenContentDelegate = strongSelf; + strongSelf.m_rewardedAd = rewardedAd; + + [strongSelf log:@"loadWithAdUnitID:completionHandler" withParams:[strongSelf getGADResponseInfoParams:rewardedAd.responseInfo]]; + + [strongSelf eventRewarded:@"loaded" params:@{ + @"response": [strongSelf getGADResponseInfoParams:rewardedAd.responseInfo] + }]; + + strongSelf.m_requestAttempt = 0; + }]; +} + +#pragma mark - GADFullScreenContentDelegate + +- (void)adWillPresentFullScreenContent:(id)ad { + [self log:@"adWillPresentFullScreenContent"]; + + [self eventRewarded:@"will_present" params:@{}]; + + PLATFORM_SERVICE() + ->freezePlatform( true, true ); +} + +- (void)ad:(id)ad didFailToPresentFullScreenContentWithError:(NSError *)error { + [self log:@"ad:didFailToPresentFullScreenContentWithError" withError:error]; + + [self eventRewarded:@"present_failed" params:@{ + @"error": [self getGADAdErrorParams:error], + @"error_code": @(error.code) + }]; + + self.m_showing = NO; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; + + if (callback != nil) { + [callback onAppleAdvertisementShowFailed:@"unknown" withError:error.code]; + } + + [self loadAd]; +} + +- (void)adDidDismissFullScreenContent:(id)ad { + [self log:@"adDidDismissFullScreenContent"]; + + [self eventRewarded:@"dismissed" params:@{}]; + + PLATFORM_SERVICE() + ->unfreezePlatform( true, true ); + + self.m_showing = NO; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; + + if (callback != nil) { + [callback onAppleAdvertisementShowSuccess:@"unknown"]; + } + + self.m_rewardedAd = nil; + [self loadAd]; +} + +- (void)adDidRecordImpression:(id)ad { + [self log:@"adDidRecordImpression"]; + + [self eventRewarded:@"impression" params:@{}]; +} + +- (void)adDidRecordClick:(id)ad { + [self log:@"adDidRecordClick"]; + + [self eventRewarded:@"clicked" params:@{}]; +} + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt new file mode 100644 index 0000000000..c14765e043 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -0,0 +1,37 @@ +MENGINE_PROJECT(AppleAdMobPlugin) + +ADD_PLUGIN_OPTION(MENGINE_PLUGIN_APPLE_ADMOB BANNER OFF "MENGINE_PLUGIN_APPLE_ADMOB_BANNER") +ADD_PLUGIN_OPTION(MENGINE_PLUGIN_APPLE_ADMOB INTERSTITIAL OFF "MENGINE_PLUGIN_APPLE_ADMOB_INTERSTITIAL") +ADD_PLUGIN_OPTION(MENGINE_PLUGIN_APPLE_ADMOB REWARDED OFF "MENGINE_PLUGIN_APPLE_ADMOB_REWARDED") + +ADD_FILTER( +src + AppleAdMobPlugin.h + AppleAdMobPlugin.mm + + AppleAdMobInterface.h + + AppleAdMobBaseDelegate.h + AppleAdMobBaseDelegate.mm + + AppleAdMobInterstitialDelegate.h + AppleAdMobInterstitialDelegate.mm + + AppleAdMobRewardedDelegate.h + AppleAdMobRewardedDelegate.mm + + AppleAdMobBannerDelegate.h + AppleAdMobBannerDelegate.mm + + AppleAdMobApplicationDelegate.h + AppleAdMobApplicationDelegate.mm +) + +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) + +ADD_MENGINE_COCOAPOD("GoogleMobileAds" "NO-GIT" "12.11.0") + +ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleAdvertisementPlugin) + diff --git a/src/Plugins/CMakeLists.txt b/src/Plugins/CMakeLists.txt index afbf172a1f..dd7e74a7af 100644 --- a/src/Plugins/CMakeLists.txt +++ b/src/Plugins/CMakeLists.txt @@ -270,6 +270,10 @@ if(MENGINE_PLUGIN_APPLE_APPLOVIN) ADD_SUBDIRECTORY(AppleAppLovinPlugin) endif() +if(MENGINE_PLUGIN_APPLE_ADMOB) + ADD_SUBDIRECTORY(AppleAdMobPlugin) +endif() + if(MENGINE_PLUGIN_APPLE_FACEBOOK) ADD_SUBDIRECTORY(AppleFacebookPlugin) endif() From 5bc7149d02625b2c7d81a53bebf014ee38616df5 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:17:55 +0200 Subject: [PATCH 097/169] wip --- cmake/Xcode_MacOS/CMakeLists.txt | 1 + cmake/Xcode_iOS/CMakeLists.txt | 1 + cmake/Xcode_iOS_Simulator/CMakeLists.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/cmake/Xcode_MacOS/CMakeLists.txt b/cmake/Xcode_MacOS/CMakeLists.txt index 8804ddffa3..277d4581af 100644 --- a/cmake/Xcode_MacOS/CMakeLists.txt +++ b/cmake/Xcode_MacOS/CMakeLists.txt @@ -119,6 +119,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG OFF OFF "MENGINE_PLUGIN_AP ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV OFF OFF "MENGINE_PLUGIN_APPLE_DEVTODEV") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ONESIGNAL OFF OFF "MENGINE_PLUGIN_APPLE_ONESIGNAL") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB OFF OFF "MENGINE_PLUGIN_APPLE_ADMOB") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_APPLOVIN OFF OFF "MENGINE_PLUGIN_APPLE_APPLOVIN") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_SENTRY OFF OFF "MENGINE_PLUGIN_APPLE_SENTRY") diff --git a/cmake/Xcode_iOS/CMakeLists.txt b/cmake/Xcode_iOS/CMakeLists.txt index b6ed35a4ae..e1449ece99 100644 --- a/cmake/Xcode_iOS/CMakeLists.txt +++ b/cmake/Xcode_iOS/CMakeLists.txt @@ -122,6 +122,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING OFF OFF "MENGINE_ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV OFF OFF "MENGINE_PLUGIN_APPLE_DEVTODEV") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ONESIGNAL OFF OFF "MENGINE_PLUGIN_APPLE_ONESIGNAL") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMAZON OFF OFF "MENGINE_PLUGIN_APPLE_AMAZON") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB OFF OFF "MENGINE_PLUGIN_APPLE_ADMOB") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_APPLOVIN OFF OFF "MENGINE_PLUGIN_APPLE_APPLOVIN") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_SENTRY OFF OFF "MENGINE_PLUGIN_APPLE_SENTRY") diff --git a/cmake/Xcode_iOS_Simulator/CMakeLists.txt b/cmake/Xcode_iOS_Simulator/CMakeLists.txt index 7874fbec65..f601743a35 100644 --- a/cmake/Xcode_iOS_Simulator/CMakeLists.txt +++ b/cmake/Xcode_iOS_Simulator/CMakeLists.txt @@ -115,6 +115,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING OFF OFF "MENGINE_ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV OFF OFF "MENGINE_PLUGIN_APPLE_DEVTODEV") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ONESIGNAL OFF OFF "MENGINE_PLUGIN_APPLE_ONESIGNAL") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMAZON OFF OFF "MENGINE_PLUGIN_APPLE_AMAZON") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB OFF OFF "MENGINE_PLUGIN_APPLE_ADMOB") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_APPLOVIN OFF OFF "MENGINE_PLUGIN_APPLE_APPLOVIN") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_SENTRY OFF OFF "MENGINE_PLUGIN_APPLE_SENTRY") From e0b2aaa9c8261f0a9736834d9f5ca2881d221515 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:22:47 +0200 Subject: [PATCH 098/169] wip --- src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index c14765e043..7c1adbfd48 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -29,7 +29,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) -ADD_MENGINE_COCOAPOD("GoogleMobileAds" "NO-GIT" "12.11.0") +ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.11.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") From 71baf137145c376849862fd6019584c8932bdeb4 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:29:25 +0200 Subject: [PATCH 099/169] fix --- .../AppleAdMobScriptEmbedding.h | 22 +++++++++++ .../AppleAdMobScriptEmbedding.mm | 37 +++++++++++++++++++ src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 14 +++++++ 3 files changed, 73 insertions(+) create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.h create mode 100644 src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.mm diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.h new file mode 100644 index 0000000000..7eae1ede20 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Interface/ScriptEmbeddingInterface.h" + +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class AppleAdMobScriptEmbedding + : public ScriptEmbeddingInterface + , public Factorable + { + public: + AppleAdMobScriptEmbedding(); + ~AppleAdMobScriptEmbedding() override; + + public: + bool embed( pybind::kernel_interface * _kernel ) override; + void eject( pybind::kernel_interface * _kernel ) override; + }; +} + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.mm new file mode 100644 index 0000000000..03b0a046e7 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobScriptEmbedding.mm @@ -0,0 +1,37 @@ +#include "AppleAdMobScriptEmbedding.h" + +#include "Interface/ScriptServiceInterface.h" + +#include "Environment/Python/PythonIncluder.h" +#include "Environment/Python/PythonDocument.h" + +#include "Kernel/FactorableUnique.h" +#include "Kernel/ConstStringHelper.h" +#include "Kernel/DocumentHelper.h" +#include "Kernel/Logger.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + AppleAdMobScriptEmbedding::AppleAdMobScriptEmbedding() + { + } + ////////////////////////////////////////////////////////////////////////// + AppleAdMobScriptEmbedding::~AppleAdMobScriptEmbedding() + { + } + ////////////////////////////////////////////////////////////////////////// + bool AppleAdMobScriptEmbedding::embed( pybind::kernel_interface * _kernel ) + { + // No functions to export to script + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void AppleAdMobScriptEmbedding::eject( pybind::kernel_interface * _kernel ) + { + // No functions to remove from script + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index 7c1adbfd48..3ee3ce1837 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -31,7 +31,21 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.11.0") +if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) + ADD_FILTER( + embedding + AppleAdMobScriptEmbedding.h + AppleAdMobScriptEmbedding.mm + ) + + INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/pybind/include) +endif() + ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") +if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) + TARGET_LINK_LIBRARIES(${PROJECT_NAME} Python) +endif() + TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleAdvertisementPlugin) From 7dfb6ac87477681c4f089998957fd165041c28a6 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:30:23 +0200 Subject: [PATCH 100/169] wip --- src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index 3ee3ce1837..a7d31d3b9d 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -29,7 +29,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) -ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.11.0") +ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.13.0") if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) ADD_FILTER( From 351b6c32efdc99ec632e7d7c7815db4f8e29c1ec Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:33:31 +0200 Subject: [PATCH 101/169] fix ios dispatch main queue --- .../iOSUIApplicationDelegate.mm | 6 +- src/Environment/Apple/AppleDetail.h | 10 +- src/Environment/Apple/AppleDetail.mm | 142 +++++++++++++++++- src/Environment/iOS/iOSDetail.mm | 14 +- .../AppleAppLovinApplicationDelegate.mm | 4 +- .../AppleAppLovinBaseDelegate.mm | 8 +- .../AppleAppTrackingApplicationDelegate.mm | 2 +- src/Plugins/AppleDatadogPlugin/CMakeLists.txt | 4 +- .../CMakeLists.txt | 2 +- .../AppleFirebaseCrashlyticsANRMonitor.mm | 9 +- .../CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../AppleFirebasePlugin/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../AppleGameCenterApplicationDelegate.mm | 34 ++--- .../AppleNativePythonScriptEmbedding.mm | 2 +- .../POSIXThreadProcessor.cpp | 5 +- .../POSIXThreadSystem/POSIXThreadProcessor.h | 4 +- 19 files changed, 200 insertions(+), 56 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 0f24ae51e6..74cc917c05 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -436,7 +436,7 @@ - (void)postFinishLaunch { if( application.bootstrap( argc, argv ) == false ) { [AppleLog withFormat:@"🔴 [ERROR] Mengine application bootstrap [Failed]"]; - [[NSOperationQueue mainQueue] cancelAllOperations]; + [AppleDetail cancelAllQueueOperations]; application.finalize(); @@ -454,7 +454,7 @@ - (void)postFinishLaunch { if( application.initialize() == false ) { [AppleLog withFormat:@"🔴 [ERROR] Mengine application initialize [Failed]"]; - [[NSOperationQueue mainQueue] cancelAllOperations]; + [AppleDetail cancelAllQueueOperations]; application.finalize(); @@ -471,7 +471,7 @@ - (void)postFinishLaunch { application.loop(); - [[NSOperationQueue mainQueue] cancelAllOperations]; + [AppleDetail cancelAllQueueOperations]; application.finalize(); diff --git a/src/Environment/Apple/AppleDetail.h b/src/Environment/Apple/AppleDetail.h index feca99cbe2..7b4a04df70 100644 --- a/src/Environment/Apple/AppleDetail.h +++ b/src/Environment/Apple/AppleDetail.h @@ -25,7 +25,15 @@ + (NSString * _Nonnull)getRandomHexString:(NSUInteger)length; + (void)addMainQueueOperation:(dispatch_block_t _Nonnull)block; -+ (void)dispatchMainQueue:(dispatch_block_t _Nonnull)block; ++ (void)addMainQueueOperation:(dispatch_block_t _Nonnull)block afterSeconds:(NSTimeInterval)seconds; + ++ (void)addDefaultQueueOperation:(dispatch_block_t _Nonnull)block; ++ (void)addBackgroundQueueOperation:(dispatch_block_t _Nonnull)block; ++ (void)addUtilityQueueOperation:(dispatch_block_t _Nonnull)block; ++ (void)addUserInitiatedQueueOperation:(dispatch_block_t _Nonnull)block; ++ (void)addUserInteractiveQueueOperation:(dispatch_block_t _Nonnull)block; + ++ (void)cancelAllQueueOperations; + (BOOL)hasOption:(NSString * _Nonnull)value; diff --git a/src/Environment/Apple/AppleDetail.mm b/src/Environment/Apple/AppleDetail.mm index 9120656c42..7e3273a1da 100644 --- a/src/Environment/Apple/AppleDetail.mm +++ b/src/Environment/Apple/AppleDetail.mm @@ -2,6 +2,8 @@ #import "AppleString.h" #import "AppleFactorablePtr.h" +#import "Environment/Apple/AppleBundle.h" + #include "Kernel/Assertion.h" @implementation AppleDetail @@ -70,16 +72,150 @@ + (NSString * _Nonnull)getRandomHexString:(NSUInteger)length { return randomHexStringTrim; } +static volatile BOOL OPERATION_QUEUES_WORKING = YES; + ++ (NSOperationQueue *)userInteractiveOperationQueue { + static NSOperationQueue *queue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = [[NSOperationQueue alloc] init]; + NSString * bundleId = [AppleBundle getIdentifier]; + queue.name = [NSString stringWithFormat:@"%@.queue.user.interactive", bundleId]; + queue.qualityOfService = NSQualityOfServiceUserInteractive; + }); + return queue; +} + ++ (NSOperationQueue *)userInitiatedOperationQueue { + static NSOperationQueue *queue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = [[NSOperationQueue alloc] init]; + NSString * bundleId = [AppleBundle getIdentifier]; + queue.name = [NSString stringWithFormat:@"%@.queue.user.initiated", bundleId]; + queue.qualityOfService = NSQualityOfServiceUserInitiated; + }); + return queue; +} + ++ (NSOperationQueue *)utilityOperationQueue { + static NSOperationQueue *queue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = [[NSOperationQueue alloc] init]; + NSString * bundleId = [AppleBundle getIdentifier]; + queue.name = [NSString stringWithFormat:@"%@.queue.utility", bundleId]; + queue.qualityOfService = NSQualityOfServiceUtility; + }); + return queue; +} + ++ (NSOperationQueue *)backgroundOperationQueue { + static NSOperationQueue *queue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = [[NSOperationQueue alloc] init]; + NSString * bundleId = [AppleBundle getIdentifier]; + queue.name = [NSString stringWithFormat:@"%@.queue.background", bundleId]; + queue.qualityOfService = NSQualityOfServiceBackground; + }); + return queue; +} + ++ (NSOperationQueue *)defaultOperationQueue { + static NSOperationQueue *queue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + queue = [[NSOperationQueue alloc] init]; + NSString * bundleId = [AppleBundle getIdentifier]; + queue.name = [NSString stringWithFormat:@"%@.queue.default", bundleId]; + queue.qualityOfService = NSQualityOfServiceDefault; + }); + return queue; +} -+ (void)addMainQueueOperation:(dispatch_block_t)block { ++ (void)addMainQueueOperation:(dispatch_block_t _Nonnull)block { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:block]; [[NSOperationQueue mainQueue] addOperation:operation]; } ++ (void)addMainQueueOperation:(dispatch_block_t _Nonnull)block afterSeconds:(NSTimeInterval)seconds { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(seconds * NSEC_PER_SEC)); + + dispatch_after(time, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + [AppleDetail addMainQueueOperation:block]; + }); +} + ++ (void)addDefaultQueueOperation:(dispatch_block_t _Nonnull)block { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + + NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:block]; + + [[AppleDetail defaultOperationQueue] addOperation:operation]; +} + ++ (void)addBackgroundQueueOperation:(dispatch_block_t _Nonnull)block { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + + NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:block]; + + [[AppleDetail backgroundOperationQueue] addOperation:operation]; +} + ++ (void)addUtilityQueueOperation:(dispatch_block_t _Nonnull)block { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + + NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:block]; + + [[AppleDetail utilityOperationQueue] addOperation:operation]; +} + ++ (void)addUserInitiatedQueueOperation:(dispatch_block_t _Nonnull)block { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + + NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:block]; + + [[AppleDetail userInitiatedOperationQueue] addOperation:operation]; +} + ++ (void)addUserInteractiveQueueOperation:(dispatch_block_t _Nonnull)block { + if (OPERATION_QUEUES_WORKING == NO) { + return; + } + + NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:block]; + + [[AppleDetail userInteractiveOperationQueue] addOperation:operation]; +} -+ (void)dispatchMainQueue:(dispatch_block_t _Nonnull)block { - dispatch_async(dispatch_get_main_queue(), block); ++ (void)cancelAllQueueOperations { + OPERATION_QUEUES_WORKING = NO; + + [[AppleDetail defaultOperationQueue] cancelAllOperations]; + [[AppleDetail backgroundOperationQueue] cancelAllOperations]; + [[AppleDetail utilityOperationQueue] cancelAllOperations]; + [[AppleDetail userInitiatedOperationQueue] cancelAllOperations]; + [[AppleDetail userInteractiveOperationQueue] cancelAllOperations]; + + [[NSOperationQueue mainQueue] cancelAllOperations]; } + (BOOL)hasOption:(NSString *)value { diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index de6bd5c33a..3715e81d37 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -224,16 +224,16 @@ + (void) showOkAlertWithViewController:(UIViewController *)viewController UIAlertController * alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ ok(); }]; }]; [alertController addAction:okAction]; - dispatch_async(dispatch_get_main_queue(), ^{ + [AppleDetail addMainQueueOperation:^{ [viewController presentViewController:alertController animated:YES completion:nil]; - }); + }]; } + (void) showAreYouSureAlertDialogWithTitle:(NSString *)title @@ -267,7 +267,7 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController UIAlertAction * yesAction = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ yes(); }]; }]; @@ -275,7 +275,7 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"CANCEL" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ cancel(); }]; }]; @@ -293,9 +293,9 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController }); } - dispatch_async(dispatch_get_main_queue(), ^{ + [AppleDetail addMainQueueOperation:^{ [viewController presentViewController:alert animated:YES completion:nil]; - }); + }]; } @end diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm index 0697adbf83..ce590d4e5e 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm @@ -120,7 +120,7 @@ - (BOOL)loadAndShowCMPFlow:(id)provid , error.cmpMessage ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [provider onAppleAppLovinConsentFlowShowFailed]; }]; @@ -129,7 +129,7 @@ - (BOOL)loadAndShowCMPFlow:(id)provid IOS_LOGGER_MESSAGE( @"AppLovin CMP show success" ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [provider onAppleAppLovinConsentFlowShowSuccess]; }]; }]; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm index 44cd3a3ffa..85f17e0328 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinBaseDelegate.mm @@ -146,13 +146,11 @@ - (void) loadAd { - (void) retryLoadAd { self.m_requestAttempt++; - NSTimeInterval delaySec = pow(2, MIN(6, self.m_requestAttempt)); + NSTimeInterval seconds = pow(2, MIN(6, self.m_requestAttempt)); - [AppleDetail addMainQueueOperation:^{ - [NSThread sleepForTimeInterval:delaySec]; - + [AppleDetail addMainQueueOperation:^{ [self loadAd]; - }]; + } afterSeconds:seconds]; } - (NSInteger) increaseRequestId { diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index c368f09c2b..89b5cf741d 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -65,7 +65,7 @@ - (void)authorization:(void (^)(EAppleAppTrackingAuthorization status, NSString IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ response( self.m_status, self.m_idfa ); }]; }]; diff --git a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt index 9a6c4efa29..11211471f4 100644 --- a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt @@ -11,7 +11,7 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_DATADOG) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleDatadogApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.1.0") -ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.1.0") +ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.2.0") +ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.2.0") target_compile_options(${PROJECT_NAME} PRIVATE -fcxx-modules) diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt index 2013bfec7d..f41c3d418d 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt @@ -17,6 +17,6 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseAnalyticsApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseAnalytics" "NO-GIT" "12.3.0") +ADD_MENGINE_COCOAPOD("FirebaseAnalytics" "NO-GIT" "12.6.0") TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) diff --git a/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm b/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm index 17102a2cd3..3106491e62 100644 --- a/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm +++ b/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm @@ -1,6 +1,7 @@ #import "AppleFirebaseCrashlyticsANRMonitor.h" #import "Environment/iOS/iOSLog.h" +#import "Environment/Apple/AppleDetail.h" #include "Config/StdString.h" @@ -34,11 +35,11 @@ - (instancetype)init { } - (void)runANRMainWatcher { - dispatch_async(dispatch_get_main_queue(), ^{ + [AppleDetail addMainQueueOperation:^{ pthread_t thread = pthread_self(); [self runANRWatcher:thread withName:@"Main"]; - }); + }]; } static void RunLoopObserverCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { @@ -70,7 +71,7 @@ - (void)runANRWatcher:(pthread_t)thread withName:(NSString *)name { CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes); CFRelease(observer); - dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + [AppleDetail addUserInitiatedQueueOperation:^{ while (true) { long result = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC))); @@ -85,7 +86,7 @@ - (void)runANRWatcher:(pthread_t)thread withName:(NSString *)name { [AppleFirebaseCrashlyticsANRMonitor backtraceOfMachPort:thread withName:name]; } - }); + }]; } static size_t my_backtrace_from_fp( _STRUCT_ARM_THREAD_STATE64 _state, void ** _buffer, size_t _size ) { diff --git a/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt index 34e35b5754..e88d2315fb 100644 --- a/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt @@ -18,7 +18,7 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseCrashlyticsApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseCrashlytics" "NO-GIT" "12.3.0") +ADD_MENGINE_COCOAPOD("FirebaseCrashlytics" "NO-GIT" "12.6.0") ADD_MENGINE_SCRIPT_PHASE("Run Firebase Crashlytics" "($){PODS_ROOT}/FirebaseCrashlytics/run" "['($){DWARF_DSYM_FOLDER_PATH}/($){DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/($){TARGET_NAME}', '$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)']") diff --git a/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt index 2af3d3fdc0..9f3b9314f8 100644 --- a/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseMessagingPlugin/CMakeLists.txt @@ -9,7 +9,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseMessaging" "NO-GIT" "12.3.0") +ADD_MENGINE_COCOAPOD("FirebaseMessaging" "NO-GIT" "12.6.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseMessagingApplicationDelegate") diff --git a/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt b/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt index 91f80ab662..1a95580274 100644 --- a/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebasePerformanceMonitoringPlugin/CMakeLists.txt @@ -11,6 +11,6 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebasePerformanceMonitoringApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebasePerformance" "NO-GIT" "12.3.0") +ADD_MENGINE_COCOAPOD("FirebasePerformance" "NO-GIT" "12.6.0") TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) diff --git a/src/Plugins/AppleFirebasePlugin/CMakeLists.txt b/src/Plugins/AppleFirebasePlugin/CMakeLists.txt index 077844104d..6edd90a822 100644 --- a/src/Plugins/AppleFirebasePlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebasePlugin/CMakeLists.txt @@ -9,7 +9,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseCore" "NO-GIT" "12.3.0") +ADD_MENGINE_COCOAPOD("FirebaseCore" "NO-GIT" "12.6.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseApplicationDelegate") diff --git a/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt index 64c5fb35cf..d383a4ac40 100644 --- a/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt @@ -35,7 +35,7 @@ ADD_DEFINITIONS(-DMENGINE_FIREBASE_REMOTECONFIG_PLIST_NAME="${MENGINE_APPLICATIO ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("FirebaseRemoteConfig" "NO-GIT" "12.3.0") +ADD_MENGINE_COCOAPOD("FirebaseRemoteConfig" "NO-GIT" "12.6.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseRemoteConfigApplicationDelegate") diff --git a/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm b/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm index 36284cf168..566b1f23e1 100644 --- a/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm +++ b/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm @@ -42,7 +42,7 @@ - (void)connect:(id)callback { , [AppleDetail getMessageFromNSError:_error] ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [callback onAppleGameCenterAuthenticate:NO]; }]; @@ -54,7 +54,7 @@ - (void)connect:(id)callback { if (self.m_gameCenterAuthenticate == false) { self.m_gameCenterAuthenticate = true; - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [callback onAppleGameCenterAuthenticate:YES]; }]; } @@ -63,7 +63,7 @@ - (void)connect:(id)callback { [self.m_achievementsComplete removeAllObjects]; - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [callback onAppleGameCenterSynchronizate:NO]; }]; @@ -75,7 +75,7 @@ - (void)connect:(id)callback { , [AppleDetail getMessageFromNSError:_error] ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [callback onAppleGameCenterSynchronizate:NO]; }]; @@ -95,7 +95,7 @@ - (void)connect:(id)callback { self.m_achievementsSynchronization = true; if (callback != nil) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [callback onAppleGameCenterSynchronizate:YES]; }]; } @@ -125,7 +125,7 @@ - (BOOL)reportAchievement:(NSString *)identifier percent:(double)percent respons , [AppleDetail getMessageFromNSError:_error] ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( NO ); }]; @@ -141,7 +141,7 @@ - (BOOL)reportAchievement:(NSString *)identifier percent:(double)percent respons [self.m_achievementsComplete addObject:identifier]; } - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( YES ); }]; }]; @@ -189,7 +189,7 @@ - (BOOL)login:(void(^)(NSError *))handler { if (error != nil) { self.m_authenticateSuccess = NO; - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( error ); }]; @@ -198,7 +198,7 @@ - (BOOL)login:(void(^)(NSError *))handler { self.m_authenticateSuccess = YES; - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( nil ); }]; }]; @@ -213,7 +213,7 @@ - (BOOL)loadCompletedAchievements:(void(^)(NSError *, NSArray *))handler { [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray * achievements, NSError * error) { if (error != nil) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( error, nil ); }]; @@ -221,7 +221,7 @@ - (BOOL)loadCompletedAchievements:(void(^)(NSError *, NSArray *))handler { } if (achievements != nil) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( nil, nil ); }]; @@ -236,7 +236,7 @@ - (BOOL)loadCompletedAchievements:(void(^)(NSError *, NSArray *))handler { } } - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( nil, cmpAch ); }]; }]; @@ -259,7 +259,7 @@ - (BOOL)resetAchievements:(void(^)(NSError * error))handler { , [AppleDetail getMessageFromNSError:error] ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( error ); }]; @@ -268,7 +268,7 @@ - (BOOL)resetAchievements:(void(^)(NSError * error))handler { IOS_LOGGER_MESSAGE( @"reset achievement success" ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler( nil ); }]; }]; @@ -313,7 +313,7 @@ - (BOOL)reportScore:(NSString *)identifier score:(int64_t)score response:(void(^ , score , [AppleDetail getMessageFromNSError:error]); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler(error); }]; @@ -325,7 +325,7 @@ - (BOOL)reportScore:(NSString *)identifier score:(int64_t)score response:(void(^ , score ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler(nil); }]; }]; @@ -343,7 +343,7 @@ - (BOOL)reportAchievementIdentifier:(NSString *)identifier percentComplete:(doub [achievement setPercentComplete: percent]; [GKAchievement reportAchievements:@[achievement] withCompletionHandler:^(NSError * error) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler(error); }]; }]; diff --git a/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm b/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm index 91eb9d1634..9999d06bc6 100644 --- a/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm +++ b/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm @@ -325,7 +325,7 @@ void invoke() override { PythonCallbackProviderPtr keep = PythonCallbackProviderPtr::from(this); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ keep->call_cb(); }]; } diff --git a/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp b/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp index 1196d32ad3..2ff33aed38 100644 --- a/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp +++ b/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.cpp @@ -79,7 +79,6 @@ namespace Mengine POSIXThreadProcessor::POSIXThreadProcessor() : m_priority( ETP_NORMAL ) , m_threadId( 0 ) - , m_task( nullptr ) , m_exit( false ) { } @@ -132,6 +131,8 @@ namespace Mengine ::pthread_cond_destroy( &m_conditionVariable ); m_threadId = 0; + + m_task = nullptr; m_mutex = nullptr; } ////////////////////////////////////////////////////////////////////////// @@ -209,7 +210,7 @@ namespace Mengine return (ThreadId)m_threadId; } ////////////////////////////////////////////////////////////////////////// - bool POSIXThreadProcessor::processTask( ThreadTaskInterface * _task ) + bool POSIXThreadProcessor::processTask( const ThreadTaskInterfacePtr & _task ) { if( m_exit == true ) { diff --git a/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.h b/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.h index fb45333616..b33263a7b9 100644 --- a/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.h +++ b/src/Systems/POSIXThreadSystem/POSIXThreadProcessor.h @@ -38,7 +38,7 @@ namespace Mengine ThreadId getThreadId() const override; public: - bool processTask( ThreadTaskInterface * _task ) override; + bool processTask( const ThreadTaskInterfacePtr & _task ) override; void removeTask() override; public: @@ -61,7 +61,7 @@ namespace Mengine pthread_cond_t m_conditionVariable; pthread_mutex_t m_conditionLock; - ThreadTaskInterface * m_task; + ThreadTaskInterfacePtr m_task; AtomicBool m_exit; }; From c72dedee54b74cb9ec67d7f3b875107a8a0092f3 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:36:50 +0200 Subject: [PATCH 102/169] wip --- .../AppleAdMobPlugin/AppleAdMobBaseDelegate.mm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm index 91bb4bdd05..076e76a242 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -27,18 +27,17 @@ - (NSDictionary * _Nonnull) getGADResponseInfoParams:(GADResponseInfo * _Nullabl NSMutableDictionary * params = [NSMutableDictionary dictionary]; if (responseInfo != nil) { - if (responseInfo.adNetworkClassName != nil) { - [params setObject:responseInfo.adNetworkClassName forKey:@"adNetworkClassName"]; - } if (responseInfo.responseIdentifier != nil) { [params setObject:responseInfo.responseIdentifier forKey:@"responseIdentifier"]; } if (responseInfo.loadedAdNetworkResponseInfo != nil) { - if (responseInfo.loadedAdNetworkResponseInfo.adNetworkClassName != nil) { - [params setObject:responseInfo.loadedAdNetworkResponseInfo.adNetworkClassName forKey:@"networkName"]; + GADAdNetworkResponseInfo * loadedInfo = responseInfo.loadedAdNetworkResponseInfo; + if (loadedInfo.adNetworkClassName != nil) { + [params setObject:loadedInfo.adNetworkClassName forKey:@"adNetworkClassName"]; + [params setObject:loadedInfo.adNetworkClassName forKey:@"networkName"]; } - if (responseInfo.loadedAdNetworkResponseInfo.credentials != nil) { - [params setObject:responseInfo.loadedAdNetworkResponseInfo.credentials forKey:@"credentials"]; + if (loadedInfo.credentials != nil) { + [params setObject:loadedInfo.credentials forKey:@"credentials"]; } } } From ea5cd1379dfaedc5bfaf539503ba91dbfc6e786a Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:38:49 +0200 Subject: [PATCH 103/169] wip --- src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm index 076e76a242..2861cad2c9 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -36,8 +36,9 @@ - (NSDictionary * _Nonnull) getGADResponseInfoParams:(GADResponseInfo * _Nullabl [params setObject:loadedInfo.adNetworkClassName forKey:@"adNetworkClassName"]; [params setObject:loadedInfo.adNetworkClassName forKey:@"networkName"]; } - if (loadedInfo.credentials != nil) { - [params setObject:loadedInfo.credentials forKey:@"credentials"]; + NSDictionary * dictionaryRepresentation = loadedInfo.dictionaryRepresentation; + if (dictionaryRepresentation != nil) { + [params setObject:dictionaryRepresentation forKey:@"dictionaryRepresentation"]; } } } From 26aaa621ffd6b526b09edb78e34c3fdda29ad5d0 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:42:55 +0200 Subject: [PATCH 104/169] wip --- src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm | 2 +- src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm index 476b71489b..e6157b8272 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -91,7 +91,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( GADMobileAds * mobileAds = [GADMobileAds sharedInstance]; - GADVersionNumber version = [GADMobileAds versionNumber]; + GADVersionNumber version = [mobileAds versionNumber]; NSString * versionString = [NSString stringWithFormat:@"%lu.%lu.%lu", version.majorVersion, version.minorVersion, version.patchVersion]; IOS_LOGGER_MESSAGE(@"AdMob: %@", versionString); diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm index 2861cad2c9..616eb7648e 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -34,7 +34,6 @@ - (NSDictionary * _Nonnull) getGADResponseInfoParams:(GADResponseInfo * _Nullabl GADAdNetworkResponseInfo * loadedInfo = responseInfo.loadedAdNetworkResponseInfo; if (loadedInfo.adNetworkClassName != nil) { [params setObject:loadedInfo.adNetworkClassName forKey:@"adNetworkClassName"]; - [params setObject:loadedInfo.adNetworkClassName forKey:@"networkName"]; } NSDictionary * dictionaryRepresentation = loadedInfo.dictionaryRepresentation; if (dictionaryRepresentation != nil) { From 699d159a80623ea81afc65eff9dec1b16a7a1485 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 13:43:24 +0200 Subject: [PATCH 105/169] wip --- .../AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm index e6157b8272..092f8253d9 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -96,14 +96,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( IOS_LOGGER_MESSAGE(@"AdMob: %@", versionString); - NSString * MengineAppleAdMobPlugin_AppId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"AppId" withDefault:nil]; - - if (MengineAppleAdMobPlugin_AppId != nil && [MengineAppleAdMobPlugin_AppId length] > 0) { - [GADMobileAds configureWithApplicationID:MengineAppleAdMobPlugin_AppId]; - - IOS_LOGGER_MESSAGE(@"[AdMob] configure with AppId: %@", MengineAppleAdMobPlugin_AppId); - } - BOOL MengineAppleAdMobPlugin_RequestConfigurationTestDeviceIdsEnabled = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"RequestConfigurationTestDeviceIdsEnabled" withDefault:NO]; if (MengineAppleAdMobPlugin_RequestConfigurationTestDeviceIdsEnabled == YES) { From 28e43d99dbfc1191cbf5a285dfd9c16446693c21 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 14:06:26 +0200 Subject: [PATCH 106/169] wip --- .../AppleAdMobApplicationDelegate.mm | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm index 092f8253d9..1bcd07da54 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -131,15 +131,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( MengineAppleAdMobPlugin_RewardedAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"RewardedAdUnitId" withDefault:nil]; #endif - __weak AppleAdMobApplicationDelegate * weakSelf = self; - [mobileAds startWithCompletionHandler:^(GADInitializationStatus * _Nonnull status) { - __strong AppleAdMobApplicationDelegate * strongSelf = weakSelf; - - if (strongSelf == nil) { - return; - } - IOS_LOGGER_MESSAGE(@"[AdMob] plugin initialize complete"); id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; @@ -152,7 +144,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( AppleAdMobBannerDelegate * bannerAd = [[AppleAdMobBannerDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_BannerAdUnitId advertisement:advertisement placement:MengineAppleAdMobPlugin_BannerPlacement adaptive:MengineAppleAdMobPlugin_BannerAdaptive]; - strongSelf.m_bannerAd = bannerAd; + self.m_bannerAd = bannerAd; } #endif @@ -160,7 +152,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (MengineAppleAdMobPlugin_InterstitialAdUnitId != nil) { AppleAdMobInterstitialDelegate * interstitialAd = [[AppleAdMobInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_InterstitialAdUnitId advertisement:advertisement]; - strongSelf.m_interstitialAd = interstitialAd; + self.m_interstitialAd = interstitialAd; } #endif @@ -168,7 +160,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (MengineAppleAdMobPlugin_RewardedAdUnitId != nil) { AppleAdMobRewardedDelegate * rewardedAd = [[AppleAdMobRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_RewardedAdUnitId advertisement:advertisement]; - strongSelf.m_rewardedAd = rewardedAd; + self.m_rewardedAd = rewardedAd; } #endif From d3901a276efeeedfd7f2fe9e0b53e5dc3e2bdb99 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 14:11:12 +0200 Subject: [PATCH 107/169] wip --- .../AppleAdMobApplicationDelegate.mm | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm index 1bcd07da54..137fbd35a9 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -131,40 +131,48 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( MengineAppleAdMobPlugin_RewardedAdUnitId = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"RewardedAdUnitId" withDefault:nil]; #endif + __weak AppleAdMobApplicationDelegate * weakSelf = self; + [mobileAds startWithCompletionHandler:^(GADInitializationStatus * _Nonnull status) { - IOS_LOGGER_MESSAGE(@"[AdMob] plugin initialize complete"); + AppleAdMobApplicationDelegate * strongSelf = weakSelf; - id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; + if (strongSelf == nil) { + return; + } -#if defined(MENGINE_PLUGIN_APPLE_ADMOB_BANNER) - if (MengineAppleAdMobPlugin_BannerAdUnitId != nil) { - NSString * MengineAppleAdMobPlugin_BannerPlacement = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerPlacement" withDefault:@"banner"]; + [AppleDetail addMainQueueOperation:^{ + IOS_LOGGER_MESSAGE(@"[AdMob] plugin initialize complete"); - BOOL MengineAppleAdMobPlugin_BannerAdaptive = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdaptive" withDefault:YES]; - - AppleAdMobBannerDelegate * bannerAd = [[AppleAdMobBannerDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_BannerAdUnitId advertisement:advertisement placement:MengineAppleAdMobPlugin_BannerPlacement adaptive:MengineAppleAdMobPlugin_BannerAdaptive]; - - self.m_bannerAd = bannerAd; - } +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_BANNER) + if (MengineAppleAdMobPlugin_BannerAdUnitId != nil) { + NSString * MengineAppleAdMobPlugin_BannerPlacement = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"BannerPlacement" withDefault:@"banner"]; + + BOOL MengineAppleAdMobPlugin_BannerAdaptive = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"BannerAdaptive" withDefault:YES]; + + AppleAdMobBannerDelegate * bannerAd = [[AppleAdMobBannerDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_BannerAdUnitId advertisement:advertisement placement:MengineAppleAdMobPlugin_BannerPlacement adaptive:MengineAppleAdMobPlugin_BannerAdaptive]; + + strongSelf.m_bannerAd = bannerAd; + } #endif #if defined(MENGINE_PLUGIN_APPLE_ADMOB_INTERSTITIAL) - if (MengineAppleAdMobPlugin_InterstitialAdUnitId != nil) { - AppleAdMobInterstitialDelegate * interstitialAd = [[AppleAdMobInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_InterstitialAdUnitId advertisement:advertisement]; - - self.m_interstitialAd = interstitialAd; - } + if (MengineAppleAdMobPlugin_InterstitialAdUnitId != nil) { + AppleAdMobInterstitialDelegate * interstitialAd = [[AppleAdMobInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_InterstitialAdUnitId advertisement:advertisement]; + + strongSelf.m_interstitialAd = interstitialAd; + } #endif #if defined(MENGINE_PLUGIN_APPLE_ADMOB_REWARDED) - if (MengineAppleAdMobPlugin_RewardedAdUnitId != nil) { - AppleAdMobRewardedDelegate * rewardedAd = [[AppleAdMobRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_RewardedAdUnitId advertisement:advertisement]; - - self.m_rewardedAd = rewardedAd; - } + if (MengineAppleAdMobPlugin_RewardedAdUnitId != nil) { + AppleAdMobRewardedDelegate * rewardedAd = [[AppleAdMobRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAdMobPlugin_RewardedAdUnitId advertisement:advertisement]; + + strongSelf.m_rewardedAd = rewardedAd; + } #endif - [advertisement readyAdProvider]; + [advertisement readyAdProvider]; + }]; }]; return YES; From ed35819d95a70a18d84a7d70b96fcb47ff4b0054 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 17:04:14 +0200 Subject: [PATCH 108/169] fix my_backtrace_from_fp --- .../AppleFirebaseCrashlyticsANRMonitor.mm | 54 +++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm b/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm index 3106491e62..9a2b93582e 100644 --- a/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm +++ b/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm @@ -9,6 +9,7 @@ #import #import +#import #if defined(MENGINE_DEBUG) # import @@ -89,11 +90,32 @@ - (void)runANRWatcher:(pthread_t)thread withName:(NSString *)name { }]; } -static size_t my_backtrace_from_fp( _STRUCT_ARM_THREAD_STATE64 _state, void ** _buffer, size_t _size ) { +static BOOL is_valid_frame_pointer( void ** _frame, uintptr_t _stackLow, uintptr_t _stackHigh ) { + if( _frame == NULL ) + { + return NO; + } + + uintptr_t frameValue = (uintptr_t)_frame; + + if( frameValue < _stackLow || frameValue > _stackHigh ) + { + return NO; + } + + if( (frameValue & 0xF) != 0 ) + { + return NO; + } + + return YES; +} + +static size_t my_backtrace_from_fp( _STRUCT_ARM_THREAD_STATE64 _state, void ** _buffer, size_t _size, uintptr_t _stackLow, uintptr_t _stackHigh ) { void **fp = (void **)(uintptr_t)_state.__fp; void *pc = (void *)(uintptr_t)_state.__pc; - if (fp == NULL || pc == NULL) { + if (is_valid_frame_pointer(fp, _stackLow, _stackHigh) == NO || pc == NULL) { return 0; } @@ -102,6 +124,10 @@ static size_t my_backtrace_from_fp( _STRUCT_ARM_THREAD_STATE64 _state, void ** _ _buffer[i++] = pc; while (fp && i < _size) { + if (is_valid_frame_pointer(fp, _stackLow, _stackHigh) == NO) { + break; + } + void *saved_pc = *(fp + 1); if (saved_pc == NULL) break; @@ -110,7 +136,7 @@ static size_t my_backtrace_from_fp( _STRUCT_ARM_THREAD_STATE64 _state, void ** _ void **next_fp = (void **)(*fp); - if (next_fp <= fp || ((uintptr_t)next_fp & 0xF)) { + if (next_fp <= fp || is_valid_frame_pointer(next_fp, _stackLow, _stackHigh) == NO) { break; } @@ -133,7 +159,27 @@ + (BOOL)backtraceOfMachPort:(pthread_t)thread withName:(NSString *)name { void * buffer[128] = {NULL}; - size_t countFrames = my_backtrace_from_fp(state, buffer, 128); + uintptr_t stackLow = 0; + uintptr_t stackHigh = 0; + + // Try to get stack bounds via pthread API + void * stackAddr = pthread_get_stackaddr_np(thread); + size_t stackSize = pthread_get_stacksize_np(thread); + + if( stackAddr != NULL && stackSize > 0 ) + { + stackHigh = (uintptr_t)stackAddr; + stackLow = stackHigh - (uintptr_t)stackSize; + } + else + { + // Fallback: use heuristic address range for user-space stack + // Typical user-space stack addresses on 64-bit iOS + stackLow = 0x100000000ULL; + stackHigh = 0x7FFFFFFFFFFFF000ULL; + } + + size_t countFrames = my_backtrace_from_fp(state, buffer, 128, stackLow, stackHigh); if (countFrames == 0) { return NO; From bd0c381b7e9bdf7e00385b58155e37fcf4875610 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 18:20:48 +0200 Subject: [PATCH 109/169] fix AppleAdMob --- src/Bootstrapper/Bootstrapper.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index 33d1721d40..4a11692fb1 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -414,6 +414,10 @@ PLUGIN_EXPORT( AppleMARSDK ); PLUGIN_EXPORT( AppleAppLovin ); #endif ////////////////////////////////////////////////////////////////////////// +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_STATIC) +PLUGIN_EXPORT( AppleAdMob ); +#endif +////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS_STATIC) PLUGIN_EXPORT( AppleFirebaseAnalytics ); #endif @@ -1473,6 +1477,10 @@ namespace Mengine MENGINE_ADD_PLUGIN( AppleAppLovin, "plugin AppleAppLovin...", MENGINE_DOCUMENT_FACTORABLE ); #endif +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_STATIC) + MENGINE_ADD_PLUGIN( AppleAdMob, "plugin AppleAdMob...", MENGINE_DOCUMENT_FACTORABLE ); +#endif + #if defined(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS_STATIC) MENGINE_ADD_PLUGIN( AppleFirebaseAnalytics, "plugin AppleFirebaseAnalytics...", MENGINE_DOCUMENT_FACTORABLE ); #endif From 02403b3902775c83cd8f3671d0f30a631ec3adb2 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 18:42:43 +0200 Subject: [PATCH 110/169] fix --- src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index a7d31d3b9d..90fbfef12c 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -27,10 +27,6 @@ src AppleAdMobApplicationDelegate.mm ) -ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) - -ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.13.0") - if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) ADD_FILTER( embedding @@ -41,6 +37,11 @@ if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/pybind/include) endif() +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) + +ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() +ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.13.0") + ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) From 361e3defeba09ede0024be25d7f6a288ddab821c Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 22:52:16 +0200 Subject: [PATCH 111/169] clear code --- src/Bootstrapper/Bootstrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index 4a11692fb1..3ebd405891 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -1338,11 +1338,11 @@ namespace Mengine #endif #if defined(MENGINE_PLUGIN_WAV_STATIC) - MENGINE_ADD_PLUGIN( WAV, "plugin WAVCodec...", MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ADD_PLUGIN( WAV, "plugin WAV...", MENGINE_DOCUMENT_FACTORABLE ); #endif #if defined(MENGINE_PLUGIN_OGG_VORBIS_STATIC) - MENGINE_ADD_PLUGIN( OggVorbis, "plugin OggVorbisCodec...", MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ADD_PLUGIN( OggVorbis, "plugin OggVorbis...", MENGINE_DOCUMENT_FACTORABLE ); #endif #if defined(MENGINE_PLUGIN_PVRTC_STATIC) @@ -1414,7 +1414,7 @@ namespace Mengine #endif #if defined(MENGINE_PLUGIN_SDL2_SOCKET_STATIC) - MENGINE_ADD_PLUGIN( SDL2Socket, "plugin SDLSocket...", MENGINE_DOCUMENT_FACTORABLE ); + MENGINE_ADD_PLUGIN( SDL2Socket, "plugin SDL2Socket...", MENGINE_DOCUMENT_FACTORABLE ); #endif #if defined(MENGINE_PLUGIN_GOAP_STATIC) From f7d719290fe9f05e115b3b9fc251354ed28bbfab Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 17 Nov 2025 23:28:39 +0200 Subject: [PATCH 112/169] fix AppleAdMobPlugin --- .../AppleAdMobBannerDelegate.mm | 28 ++++++++++--------- .../AppleAdMobBaseDelegate.mm | 6 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm index 52bd0e24a7..972c24715a 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm @@ -50,7 +50,20 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI bannerView.delegate = self; - CGSize size = [self getSize]; + CGSize size; + + if (self.m_bannerAdaptive == YES) { + CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); + size = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width).size; + } else { + BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; + + if (isPad == YES) { + size = GADAdSizeLeaderboard.size; + } else { + size = GADAdSizeBanner.size; + } + } CGFloat banner_height = size.height; @@ -115,18 +128,7 @@ - (void) loadAd { - (CGSize) getSize { if (self.m_bannerView == nil) { - if (self.m_bannerAdaptive == YES) { - CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); - return GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width).size; - } else { - BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; - - if (isPad == YES) { - return GADAdSizeLeaderboard.size; - } else { - return GADAdSizeBanner.size; - } - } + return CGSizeZero; } return self.m_bannerView.adSize.size; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm index 616eb7648e..557c60b742 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -106,11 +106,9 @@ - (void) retryLoadAd { NSTimeInterval delaySec = pow(2, MIN(6, self.m_requestAttempt)); - [AppleDetail addMainQueueOperation:^{ - [NSThread sleepForTimeInterval:delaySec]; - + [AppleDetail addMainQueueOperation:^{ [self loadAd]; - }]; + } afterSeconds:delaySec]; } - (NSInteger) increaseRequestId { From ecdf0c2530b28b34765cf1f0f4302155c619fb8f Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 01:26:14 +0200 Subject: [PATCH 113/169] improve PlatformServiceInterface freeze improve SoundService onTurnSound --- src/Interface/PlatformServiceInterface.h | 4 +-- src/Interface/SoundSystemInterface.h | 3 -- .../AndroidPlatformService.cpp | 33 ++++++++++++++++--- .../AndroidPlatform/AndroidPlatformService.h | 12 ++++--- .../Win32Platform/Win32PlatformService.cpp | 31 +++++++++++++++-- .../Win32Platform/Win32PlatformService.h | 9 ++--- .../iOSPlatform/iOSPlatformService.h | 11 ++++--- .../iOSPlatform/iOSPlatformService.mm | 27 +++++++++++++-- .../AppleAdMobInterstitialDelegate.mm | 4 +-- .../AppleAdMobRewardedDelegate.mm | 4 +-- .../AppleAppLovinInterstitialDelegate.mm | 4 +-- .../AppleAppLovinRewardedDelegate.mm | 4 +-- src/Services/SoundService/SoundService.cpp | 3 +- .../OpenALSoundSystem/OpenALSoundSystem.cpp | 7 ---- .../OpenALSoundSystem/OpenALSoundSystem.h | 3 -- .../SilentSoundSystem/SilentSoundSystem.cpp | 5 --- .../SilentSoundSystem/SilentSoundSystem.h | 3 -- 17 files changed, 113 insertions(+), 54 deletions(-) diff --git a/src/Interface/PlatformServiceInterface.h b/src/Interface/PlatformServiceInterface.h index c5923b6b43..60bf5f9432 100644 --- a/src/Interface/PlatformServiceInterface.h +++ b/src/Interface/PlatformServiceInterface.h @@ -42,8 +42,8 @@ namespace Mengine virtual bool updatePlatform() = 0; virtual void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) = 0; virtual void stopPlatform() = 0; - virtual void freezePlatform( bool _tick, bool _render ) = 0; - virtual void unfreezePlatform( bool _tick, bool _render ) = 0; + virtual void freezePlatform( bool _tick, bool _render, bool _sound ) = 0; + virtual void unfreezePlatform( bool _tick, bool _render, bool _sound ) = 0; public: diff --git a/src/Interface/SoundSystemInterface.h b/src/Interface/SoundSystemInterface.h index 29f17756f9..0951232df0 100644 --- a/src/Interface/SoundSystemInterface.h +++ b/src/Interface/SoundSystemInterface.h @@ -28,9 +28,6 @@ namespace Mengine public: virtual bool isSilent() const = 0; - public: - virtual void onTurnSound( bool _turn ) = 0; - public: virtual SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _decoder, bool _streamable, const DocumentInterfacePtr & _doc ) = 0; diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index b8363f497e..f9f4532771 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -581,6 +581,7 @@ namespace Mengine , m_active( false ) , m_freezedTick( 0 ) , m_freezedRender( 0 ) + , m_freezedSound( 0 ) , m_desktop( false ) , m_touchpad( false ) { @@ -1075,7 +1076,7 @@ namespace Mengine this->pushQuitEvent_(); } ////////////////////////////////////////////////////////////////////////// - void AndroidPlatformService::freezePlatform( bool _tick, bool _render ) + void AndroidPlatformService::freezePlatform( bool _tick, bool _render, bool _sound ) { if( _tick == true ) { @@ -1086,9 +1087,20 @@ namespace Mengine { ++m_freezedRender; } + + if( _sound == true ) + { + ++m_freezedSound; + } + + if( m_freezedSound == 1 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), true ); + } } ////////////////////////////////////////////////////////////////////////// - void AndroidPlatformService::unfreezePlatform( bool _tick, bool _render ) + void AndroidPlatformService::unfreezePlatform( bool _tick, bool _render, bool _sound ) { if( _tick == true ) { @@ -1099,6 +1111,17 @@ namespace Mengine { --m_freezedRender; } + + if( _sound == true ) + { + --m_freezedSound; + } + + if( m_freezedSound == 0 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), false ); + } } ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::setSleepMode( bool _sleepMode ) @@ -2540,16 +2563,18 @@ namespace Mengine { bool tick = _event.tick; bool render = _event.render; + bool sound = _event.sound; - this->freezePlatform( tick, render ); + this->freezePlatform( tick, render, sound ); } ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::unfreezeEvent_( const PlatformUnionEvent::PlatformUnfreezeEvent & _event ) { bool tick = _event.tick; bool render = _event.render; + bool sound = _event.sound; - this->unfreezePlatform( tick, render ); + this->unfreezePlatform( tick, render, sound ); } ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::surfaceCreateEvent_( const PlatformUnionEvent::PlatformSurfaceCreateEvent & _event ) diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.h b/src/Platforms/AndroidPlatform/AndroidPlatformService.h index c861c25823..b4758e44c5 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.h +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.h @@ -60,8 +60,8 @@ namespace Mengine bool updatePlatform() override; void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; - void freezePlatform( bool _tick, bool _render ) override; - void unfreezePlatform( bool _tick, bool _render ) override; + void freezePlatform( bool _tick, bool _render, bool _sound ) override; + void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; public: void setSleepMode( bool _sleepMode ) override; @@ -272,12 +272,14 @@ namespace Mengine { bool tick; bool render; + bool sound; }; struct PlatformUnfreezeEvent { bool tick; bool render; + bool sound; }; struct PlatformSurfaceCreateEvent @@ -422,8 +424,10 @@ namespace Mengine float m_pauseUpdatingTime; bool m_active; - int32_t m_freezedTick; - int32_t m_freezedRender; + + AtomicInt32 m_freezedTick; + AtomicInt32 m_freezedRender; + AtomicInt32 m_freezedSound; bool m_desktop; bool m_touchpad; diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index abb21331b0..a005fbe954 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -9,6 +9,7 @@ #include "Interface/DateTimeSystemInterface.h" #include "Interface/ThreadSystemInterface.h" #include "Interface/ThreadServiceInterface.h" +#include "Interface/SoundServiceInterface.h" #include "Interface/PluginInterface.h" #include "Interface/EnvironmentServiceInterface.h" @@ -66,8 +67,8 @@ #include #include +////////////////////////////////////////////////////////////////////////// typedef HRESULT( WINAPI * FGetDpiForMonitor )(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *); - ////////////////////////////////////////////////////////////////////////// #ifndef MENGINE_SETLOCALE #define MENGINE_SETLOCALE 1 @@ -109,6 +110,7 @@ namespace Mengine , m_close( false ) , m_freezedTick( 0 ) , m_freezedRender( 0 ) + , m_freezedSound( 0 ) , m_hIcon( NULL ) , m_sleepMode( true ) , m_windowExposed( false ) @@ -771,7 +773,7 @@ namespace Mengine MENGINE_PROFILER_END_APPLICATION(); } ////////////////////////////////////////////////////////////////////////// - void Win32PlatformService::freezePlatform( bool _tick, bool _render ) + void Win32PlatformService::freezePlatform( bool _tick, bool _render, bool _sound ) { if( _tick == true ) { @@ -782,9 +784,20 @@ namespace Mengine { ++m_freezedRender; } + + if( _sound == true ) + { + ++m_freezedSound; + } + + if( m_freezedSound == 1 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), true ); + } } ////////////////////////////////////////////////////////////////////////// - void Win32PlatformService::unfreezePlatform( bool _tick, bool _render ) + void Win32PlatformService::unfreezePlatform( bool _tick, bool _render, bool _sound ) { if( _tick == true ) { @@ -795,6 +808,17 @@ namespace Mengine { --m_freezedRender; } + + if( _sound == true ) + { + --m_freezedSound; + } + + if( m_freezedSound == 0 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), false ); + } } ////////////////////////////////////////////////////////////////////////// bool Win32PlatformService::setHWNDIcon( const WChar * _iconResource ) @@ -2303,6 +2327,7 @@ namespace Mengine if( shcoreModule != NULL ) { FGetDpiForMonitor GetDpiForMonitor = (FGetDpiForMonitor)::GetProcAddress( shcoreModule, "GetDpiForMonitor" ); + if( GetDpiForMonitor != NULL ) { HMONITOR monitor = ::MonitorFromWindow( (HWND)m_hWnd, MONITOR_DEFAULTTONEAREST ); diff --git a/src/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index 331442c156..4245fc7a22 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.h +++ b/src/Platforms/Win32Platform/Win32PlatformService.h @@ -49,8 +49,8 @@ namespace Mengine bool updatePlatform() override; void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; - void freezePlatform( bool _tick, bool _render ) override; - void unfreezePlatform( bool _tick, bool _render ) override; + void freezePlatform( bool _tick, bool _render, bool _sound ) override; + void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; public: bool setHWNDIcon( const WChar * _iconResource ) override; @@ -240,8 +240,9 @@ namespace Mengine bool m_active; bool m_close; - int32_t m_freezedTick; - int32_t m_freezedRender; + AtomicInt32 m_freezedTick; + AtomicInt32 m_freezedRender; + AtomicInt32 m_freezedSound; bool m_sleepMode; bool m_windowExposed; diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.h b/src/Platforms/iOSPlatform/iOSPlatformService.h index 24599d6254..43686fa1ac 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.h +++ b/src/Platforms/iOSPlatform/iOSPlatformService.h @@ -61,8 +61,10 @@ namespace Mengine bool updatePlatform() override; void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; - void freezePlatform( bool _tick, bool _render ) override; - void unfreezePlatform( bool _tick, bool _render ) override; + + public: + void freezePlatform( bool _tick, bool _render, bool _sound ) override; + void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; public: void setSleepMode( bool _sleepMode ) override; @@ -225,8 +227,9 @@ namespace Mengine bool m_active; bool m_sleepMode; - int32_t m_freezedTick; - int32_t m_freezedRender; + AtomicInt32 m_freezedTick; + AtomicInt32 m_freezedRender; + AtomicInt32 m_freezedSound; bool m_desktop; bool m_touchpad; diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index 75f0e406f1..8816498ed5 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -92,6 +92,7 @@ , m_sleepMode( true ) , m_freezedTick( 0 ) , m_freezedRender( 0 ) + , m_freezedSound( 0 ) , m_desktop( false ) , m_touchpad( false ) , m_glContext( nullptr ) @@ -962,7 +963,7 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit this->pushQuitEvent_(); } ////////////////////////////////////////////////////////////////////////// - void iOSPlatformService::freezePlatform( bool _tick, bool _render ) + void iOSPlatformService::freezePlatform( bool _tick, bool _render, bool _sound ) { if( _tick == true ) { @@ -973,9 +974,20 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit { ++m_freezedRender; } + + if( _sound == true ) + { + ++m_freezedSound; + } + + if( m_freezedSound == 1 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), true ); + } } ////////////////////////////////////////////////////////////////////////// - void iOSPlatformService::unfreezePlatform( bool _tick, bool _render ) + void iOSPlatformService::unfreezePlatform( bool _tick, bool _render, bool _sound ) { if( _tick == true ) { @@ -986,6 +998,17 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit { --m_freezedRender; } + + if( _sound == true ) + { + --m_freezedSound; + } + + if( m_freezedSound == 0 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), false ); + } } ////////////////////////////////////////////////////////////////////////// void iOSPlatformService::setSleepMode( bool _sleepMode ) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm index 03bd92dab0..66f1c22d04 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm @@ -149,7 +149,7 @@ - (void)adWillPresentFullScreenContent:(id)ad { [self eventInterstitial:@"will_present" params:@{}]; PLATFORM_SERVICE() - ->freezePlatform( true, true ); + ->freezePlatform( true, true, true ); } - (void)ad:(id)ad didFailToPresentFullScreenContentWithError:(NSError *)error { @@ -177,7 +177,7 @@ - (void)adDidDismissFullScreenContent:(id)ad { [self eventInterstitial:@"dismissed" params:@{}]; PLATFORM_SERVICE() - ->unfreezePlatform( true, true ); + ->unfreezePlatform( true, true, true ); self.m_showing = NO; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm index 7b43e4fac4..0741395866 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm @@ -199,7 +199,7 @@ - (void)adWillPresentFullScreenContent:(id)ad { [self eventRewarded:@"will_present" params:@{}]; PLATFORM_SERVICE() - ->freezePlatform( true, true ); + ->freezePlatform( true, true, true ); } - (void)ad:(id)ad didFailToPresentFullScreenContentWithError:(NSError *)error { @@ -227,7 +227,7 @@ - (void)adDidDismissFullScreenContent:(id)ad { [self eventRewarded:@"dismissed" params:@{}]; PLATFORM_SERVICE() - ->unfreezePlatform( true, true ); + ->unfreezePlatform( true, true, true ); self.m_showing = NO; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm index fb0482261d..4c09415974 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm @@ -174,7 +174,7 @@ - (void) didDisplayAd:(MAAd *)ad { }]; PLATFORM_SERVICE() - ->freezePlatform( true, true ); + ->freezePlatform( true, true, true ); } - (void) didClickAd:(MAAd *)ad { @@ -195,7 +195,7 @@ - (void) didHideAd:(MAAd *)ad { }]; PLATFORM_SERVICE() - ->unfreezePlatform( true, true ); + ->unfreezePlatform( true, true, true ); self.m_showing = NO; diff --git a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm index 951147370a..98ff6efb0c 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm @@ -193,7 +193,7 @@ - (void) didDisplayAd:(MAAd *)ad { }]; PLATFORM_SERVICE() - ->freezePlatform( true, true ); + ->freezePlatform( true, true, true ); } - (void) didClickAd:(MAAd *)ad { @@ -214,7 +214,7 @@ - (void) didHideAd:(MAAd *)ad { }]; PLATFORM_SERVICE() - ->unfreezePlatform( true, true ); + ->unfreezePlatform( true, true, true ); self.m_showing = NO; diff --git a/src/Services/SoundService/SoundService.cpp b/src/Services/SoundService/SoundService.cpp index 4d2b8bcc12..623469a9f0 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -335,8 +335,7 @@ namespace Mengine m_turnSound = _turn; - SOUND_SYSTEM() - ->onTurnSound( m_turnSound ); + this->updateVolume(); } ////////////////////////////////////////////////////////////////////////// SoundIdentityInterfacePtr SoundService::createSoundIdentity( bool _isHeadMode, const SoundBufferInterfacePtr & _buffer, ESoundSourceCategory _category, bool _streamable, const DocumentInterfacePtr & _doc ) diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp index 4f3e0f2863..b2dd7b80b6 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp @@ -177,13 +177,6 @@ namespace Mengine return false; } ////////////////////////////////////////////////////////////////////////// - void OpenALSoundSystem::onTurnSound( bool _turn ) - { - MENGINE_UNUSED( _turn ); - - // ToDo - } - ////////////////////////////////////////////////////////////////////////// SoundSourceInterfacePtr OpenALSoundSystem::createSoundSource( bool _isHeadMode, const SoundBufferInterfacePtr & _buffer, const DocumentInterfacePtr & _doc ) { OpenALSoundSourcePtr soundSource = m_factoryOpenALSoundSource->createObject( _doc ); diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h index aa040c4299..4fae32052e 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h +++ b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h @@ -35,9 +35,6 @@ namespace Mengine public: bool isSilent() const override; - public: - void onTurnSound( bool _turn ) override; - public: SoundSourceInterfacePtr createSoundSource( bool _isHeadMode, const SoundBufferInterfacePtr & _sample, const DocumentInterfacePtr & _doc ) override; SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _decoder, bool _isStream, const DocumentInterfacePtr & _doc ) override; diff --git a/src/Systems/SilentSoundSystem/SilentSoundSystem.cpp b/src/Systems/SilentSoundSystem/SilentSoundSystem.cpp index cbb04d9bc7..81e9612367 100644 --- a/src/Systems/SilentSoundSystem/SilentSoundSystem.cpp +++ b/src/Systems/SilentSoundSystem/SilentSoundSystem.cpp @@ -49,11 +49,6 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void SilentSoundSystem::onTurnSound( bool _turn ) - { - MENGINE_UNUSED( _turn ); - } - ////////////////////////////////////////////////////////////////////////// SoundSourceInterfacePtr SilentSoundSystem::createSoundSource( bool _isHeadMode, const SoundBufferInterfacePtr & _buffer, const DocumentInterfacePtr & _doc ) { SilentSoundSourcePtr soundSource = m_factorySilentSoundSource->createObject( _doc ); diff --git a/src/Systems/SilentSoundSystem/SilentSoundSystem.h b/src/Systems/SilentSoundSystem/SilentSoundSystem.h index 38fce64f88..e137a5208c 100644 --- a/src/Systems/SilentSoundSystem/SilentSoundSystem.h +++ b/src/Systems/SilentSoundSystem/SilentSoundSystem.h @@ -29,9 +29,6 @@ namespace Mengine public: bool isSilent() const override; - public: - void onTurnSound( bool _turn ) override; - public: SoundSourceInterfacePtr createSoundSource( bool _isHeadMode, const SoundBufferInterfacePtr & _sample, const DocumentInterfacePtr & _doc ) override; SoundBufferInterfacePtr createSoundBuffer( const SoundDecoderInterfacePtr & _soundDecoder, bool _streamable, const DocumentInterfacePtr & _doc ) override; From 441a71674f32a960a1f66ee566c812726e09a816 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 01:48:59 +0200 Subject: [PATCH 114/169] fix iOS AdMob --- .../AppleAdMobBannerDelegate.mm | 43 +++++++------------ .../AppleAdMobInterstitialDelegate.mm | 12 +----- .../AppleAdMobRewardedDelegate.mm | 18 ++------ 3 files changed, 20 insertions(+), 53 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm index 972c24715a..335e13a5e7 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm @@ -19,23 +19,23 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI self.m_bannerAdaptive = adaptive; + GADAdSize adSize; + if (adaptive == YES) { + CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); + adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width); + } else { + BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; + + if (isPad == YES) { + adSize = GADAdSizeLeaderboard; + } else { + adSize = GADAdSizeBanner; + } + } + GADBannerView * bannerView; @try { - GADAdSize adSize; - if (adaptive == YES) { - CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); - adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width); - } else { - BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; - - if (isPad == YES) { - adSize = GADAdSizeLeaderboard; - } else { - adSize = GADAdSizeBanner; - } - } - bannerView = [[GADBannerView alloc] initWithAdSize:adSize]; bannerView.adUnitID = adUnitId; } @catch (NSException * ex) { @@ -50,20 +50,7 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI bannerView.delegate = self; - CGSize size; - - if (self.m_bannerAdaptive == YES) { - CGFloat screen_width = CGRectGetWidth(UIScreen.mainScreen.bounds); - size = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screen_width).size; - } else { - BOOL isPad = UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad; - - if (isPad == YES) { - size = GADAdSizeLeaderboard.size; - } else { - size = GADAdSizeBanner.size; - } - } + CGSize size = adSize.size; CGFloat banner_height = size.height; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm index 66f1c22d04..4677f009e3 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm @@ -37,11 +37,7 @@ - (void) eventInterstitial:(NSString * _Nonnull) eventName params:(NSDictionary< } - (BOOL) canYouShow:(NSString * _Nonnull)placement { - if (self.m_interstitialAd == nil) { - return NO; - } - - BOOL ready = self.m_interstitialAd != nil; + BOOL ready = (self.m_interstitialAd != nil); [self log:@"canYouShow" withParams:@{@"placement":placement, @"ready":@(ready)}]; @@ -58,11 +54,7 @@ - (BOOL) canYouShow:(NSString * _Nonnull)placement { } - (BOOL) show:(NSString * _Nonnull)placement { - if (self.m_interstitialAd == nil) { - return NO; - } - - BOOL ready = self.m_interstitialAd != nil; + BOOL ready = (self.m_interstitialAd != nil); [self log:@"show" withParams:@{@"placement":placement, @"ready":@(ready)}]; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm index 0741395866..fc3ccc54ba 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm @@ -38,11 +38,7 @@ - (void) eventRewarded:(NSString * _Nonnull) eventName params:(NSDictionary Date: Tue, 18 Nov 2025 01:49:50 +0200 Subject: [PATCH 115/169] fix iOS build --- src/Platforms/iOSPlatform/iOSPlatformService.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index 8816498ed5..3c1b984f2b 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -11,6 +11,7 @@ #include "Interface/PluginServiceInterface.h" #include "Interface/DateTimeSystemInterface.h" #include "Interface/ThreadServiceInterface.h" +#include "Interface/SoundServiceInterface.h" #include "Interface/EnvironmentServiceInterface.h" #include "Interface/AccountServiceInterface.h" #include "Interface/AnalyticsServiceInterface.h" From bbd9c8956bcbcdd955ba4d44b385f8ded20b9b87 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 02:00:57 +0200 Subject: [PATCH 116/169] improve iOS AdMob createAdRequest --- src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm | 2 +- src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h | 2 ++ src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm | 7 +++++++ .../AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm | 2 +- src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm index 335e13a5e7..392ff628a7 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm @@ -109,7 +109,7 @@ - (void) loadAd { UIViewController * viewController = [iOSDetail getRootViewController]; self.m_bannerView.rootViewController = viewController; - GADRequest * request = [GADRequest request]; + GADRequest * request = [self createAdRequest]; [self.m_bannerView loadRequest:request]; } diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h index 609a0d10a1..586513f028 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h @@ -27,6 +27,8 @@ - (void) event:(NSString * _Nonnull)name params:(NSDictionary * _Nonnull)params; +- (GADRequest *)createAdRequest; + @property (nonatomic, strong) NSString * _Nonnull m_adUnitId; @property (nonatomic, strong) id _Nonnull m_advertisement; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm index 557c60b742..6e2c712dc0 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -142,5 +142,12 @@ - (void) event:(NSString * _Nonnull)name params:(NSDictionary * _ [iOSAnalytics event:name params:total_params]; } +- (GADRequest *) createAdRequest { + GADRequest * request = [GADRequest request]; + request.requestAgent = @"Mengine"; + + return request; +} + @end diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm index 4677f009e3..108f8ec463 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm @@ -90,7 +90,7 @@ - (void) loadAd { [self eventInterstitial:@"load" params:@{}]; - GADRequest * request = [GADRequest request]; + GADRequest * request = [self createAdRequest]; __weak AppleAdMobInterstitialDelegate * weakSelf = self; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm index fc3ccc54ba..e8fc418074 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm @@ -136,7 +136,7 @@ - (void) loadAd { [self eventRewarded:@"load" params:@{}]; - GADRequest * request = [GADRequest request]; + GADRequest * request = [self createAdRequest]; __weak AppleAdMobRewardedDelegate * weakSelf = self; From f5c370faa622fd45f2a3de28965df6a95f43bae2 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 14:11:34 +0200 Subject: [PATCH 117/169] wip iOS build --- src/Environment/iOS/iOSDetail.mm | 10 +- .../AppleAdMobPlugin/AppleAdMobBaseDelegate.h | 2 +- .../AppleAppTrackingApplicationDelegate.mm | 96 ++++++++----------- ...serMessagingPlatformApplicationDelegate.mm | 83 ++++++++-------- .../CMakeLists.txt | 2 +- ...erNotificationCenterApplicationDelegate.mm | 7 +- 6 files changed, 88 insertions(+), 112 deletions(-) diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index 3715e81d37..cfeb3cc564 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -45,14 +45,8 @@ + (NSString * _Nonnull)getSystemVersion { } + (BOOL) isAppTrackingTransparencyAllowed { - if (@available(iOS 14.5, *)) { - if (ATTrackingManager.trackingAuthorizationStatus == ATTrackingManagerAuthorizationStatusAuthorized) { - return YES; - } - } else { - if ([iOSDetail isValidIDFA] == YES) { - return YES; - } + if (ATTrackingManager.trackingAuthorizationStatus == ATTrackingManagerAuthorizationStatusAuthorized) { + return YES; } return NO; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h index 586513f028..ce6554c2e3 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h @@ -27,7 +27,7 @@ - (void) event:(NSString * _Nonnull)name params:(NSDictionary * _Nonnull)params; -- (GADRequest *)createAdRequest; +- (GADRequest * _Nonnull) createAdRequest; @property (nonatomic, strong) NSString * _Nonnull m_adUnitId; @property (nonatomic, strong) id _Nonnull m_advertisement; diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index 89b5cf741d..29767002e8 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -42,44 +42,32 @@ - (void)makeIDFA { } - (void)authorization:(void (^)(EAppleAppTrackingAuthorization status, NSString *idfa))response { - if (@available(iOS 14.5, *)) { - IOS_LOGGER_MESSAGE( @"request app tracking authorization" ); + IOS_LOGGER_MESSAGE( @"request app tracking authorization" ); + + [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { + switch( status ) { + case ATTrackingManagerAuthorizationStatusAuthorized: { + self.m_status = EAATA_AUTHORIZED; + + [self makeIDFA]; + }break; + case ATTrackingManagerAuthorizationStatusDenied: { + self.m_status = EAATA_DENIED; + }break; + case ATTrackingManagerAuthorizationStatusNotDetermined: { + self.m_status = EAATA_NOT_DETERMINED; + }break; + case ATTrackingManagerAuthorizationStatusRestricted: { + self.m_status = EAATA_RESTRICTED; + }break; + } - [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { - switch( status ) { - case ATTrackingManagerAuthorizationStatusAuthorized: { - self.m_status = EAATA_AUTHORIZED; - - [self makeIDFA]; - }break; - case ATTrackingManagerAuthorizationStatusDenied: { - self.m_status = EAATA_DENIED; - }break; - case ATTrackingManagerAuthorizationStatusNotDetermined: { - self.m_status = EAATA_NOT_DETERMINED; - }break; - case ATTrackingManagerAuthorizationStatusRestricted: { - self.m_status = EAATA_RESTRICTED; - }break; - } - - IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - - [AppleDetail addMainQueueOperation:^{ - response( self.m_status, self.m_idfa ); - }]; - }]; + IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - return; - } - - self.m_status = EAATA_AUTHORIZED; - - [self makeIDFA]; - - IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - - response( self.m_status, self.m_idfa ); + [AppleDetail addMainQueueOperation:^{ + response( self.m_status, self.m_idfa ); + }]; + }]; } - (EAppleAppTrackingAuthorization)getAuthorizationStatus { @@ -91,30 +79,22 @@ - (NSString *)getIDFA { } - (BOOL)isTrackingAllowed { - if (@available(iOS 14.5, *)) { - switch( ATTrackingManager.trackingAuthorizationStatus ) { - case ATTrackingManagerAuthorizationStatusAuthorized: { - return YES; - }break; - case ATTrackingManagerAuthorizationStatusDenied: { - return NO; - }break; - case ATTrackingManagerAuthorizationStatusNotDetermined: { - return NO; - }break; - case ATTrackingManagerAuthorizationStatusRestricted: { - return NO; - }break; - } - - return NO; - } - - if ([iOSDetail isValidIDFA] == NO) { - return NO; + switch( ATTrackingManager.trackingAuthorizationStatus ) { + case ATTrackingManagerAuthorizationStatusAuthorized: { + return YES; + }break; + case ATTrackingManagerAuthorizationStatusDenied: { + return NO; + }break; + case ATTrackingManagerAuthorizationStatusNotDetermined: { + return NO; + }break; + case ATTrackingManagerAuthorizationStatusRestricted: { + return NO; + }break; } - return YES; + return NO; } #pragma mark - iOSPluginApplicationDelegateInterface diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm index 58ea3d5873..0d6ce8a251 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -14,60 +14,65 @@ @implementation AppleUserMessagingPlatformApplicationDelegate - (void)notifyConsentChangedFromDefaults { iOSTransparencyConsentParam * consent = [[iOSTransparencyConsentParam alloc] initFromUserDefaults]; - // Infer geography based on IABTCF_gdprApplies when present - if ([consent isEEA] == YES) { - [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyGDPR]; - } else { - [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; - } - [iOSDetail transparencyConsent:consent]; } -- (void)runUMPFlow { +#pragma mark - iOSPluginApplicationDelegateInterface + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init]; - // Debug settings can be added later via bundle config if needed + parameters.tagForUnderAgeOfConsent = NO; + + // For testing purposes, you can force a UMPDebugGeography of EEA or not EEA. +#if defined(MENGINE_DEBUG) + UMPDebugSettings *debugSettings = [[UMPDebugSettings alloc] init]; + debugSettings.geography = UMPDebugGeographyEEA; + debugSettings.testDeviceIdentifiers = @[@"46D5A6B4-FAE4-4EA3-9D36-94F9A7CEA291"]; + parameters.debugSettings = debugSettings; +#endif [UMPConsentInformation.sharedInstance requestConsentInfoUpdateWithParameters:parameters completionHandler:^(NSError * _Nullable error) { if (error != nil) { IOS_LOGGER_MESSAGE(@"[UMP] requestConsentInfoUpdate error: %@", error); - [self notifyConsentChangedFromDefaults]; + return; } + UMPPrivacyOptionsRequirementStatus privacyOptionsRequirementStatus = UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus; + + if (privacyOptionsRequirementStatus == UMPPrivacyOptionsRequirementStatusNotRequired) { + IOS_LOGGER_MESSAGE(@"[UMP] privacyOptionsRequirementStatus not required"); + + [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; + + return; + } + + [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyGDPR]; + UMPFormStatus formStatus = UMPConsentInformation.sharedInstance.formStatus; - if (formStatus == UMPFormStatusAvailable) { - [UMPConsentForm loadWithCompletionHandler:^(UMPConsentForm * _Nullable form, NSError * _Nullable loadError) { - if (loadError != nil) { - IOS_LOGGER_MESSAGE(@"[UMP] loadWithCompletionHandler error: %@", loadError); - [self notifyConsentChangedFromDefaults]; - return; - } - - UIViewController * rootVC = [iOSDetail getRootViewController]; - [form presentFromViewController:rootVC completionHandler:^(NSError * _Nullable dismissError) { - if (dismissError != nil) { - IOS_LOGGER_MESSAGE(@"[UMP] present dismiss error: %@", dismissError); - } - - // After form dismissal, UMP writes IABTCF_* to NSUserDefaults. Broadcast updated consent. - [self notifyConsentChangedFromDefaults]; - }]; - }]; - } else { - // No form to show; just propagate current consent state from defaults - [self notifyConsentChangedFromDefaults]; + + if (formStatus != UMPFormStatusAvailable) { + IOS_LOGGER_MESSAGE(@"[UMP] formStatus not available: %ld", (long)formStatus); + + return; } - }]; -} - -#pragma mark - iOSPluginApplicationDelegateInterface + + UIViewController * rootVC = [iOSDetail getRootViewController]; + + [UMPConsentForm loadAndPresentIfRequiredFromViewController:rootVC completionHandler:^(NSError * _Nullable loadError) { + if (loadError != nil) { + IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController error: %@", loadError); -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [self runUMPFlow]; + return; + } + + // After form dismissal, UMP writes IABTCF_* to NSUserDefaults. Broadcast updated consent. + [self notifyConsentChangedFromDefaults]; + }]; + }]; + return YES; } @end - - diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt index 639ffdefec..bcde42423b 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt @@ -10,6 +10,6 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleUserMessagingPlatformApplicationDelegate") -ADD_MENGINE_COCOAPOD("GoogleUserMessagingPlatform" "NO-GIT" "2.2.0") +ADD_MENGINE_COCOAPOD("GoogleUserMessagingPlatform" "NO-GIT" "3.1.0") diff --git a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm index e65c2de75a..13c060053e 100644 --- a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm +++ b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm @@ -22,11 +22,8 @@ - (void)scheduleNotification:(NSNumber *)badge withTitle:(NSString *)title withB content.body = body; content.sound = [UNNotificationSound defaultSound]; content.badge = badge; - - if (@available(iOS 15.0, *)) { - content.interruptionLevel = UNNotificationInterruptionLevelTimeSensitive; - content.relevanceScore = relevanceScore; // от 0.0 до 1.0 - } + content.interruptionLevel = UNNotificationInterruptionLevelTimeSensitive; + content.relevanceScore = relevanceScore; // от 0.0 до 1.0 UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:delay repeats:NO]; From 339338897e907c722d559d9a039655da69a87574 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 14:12:23 +0200 Subject: [PATCH 118/169] improve OpenAL buffer --- .../OpenALSoundSystem/OpenALSoundBufferBase.h | 4 +- .../OpenALSoundBufferMemory.cpp | 26 +++++----- .../OpenALSoundBufferMemory.h | 4 +- .../OpenALSoundBufferStream.cpp | 48 ++++++++++--------- .../OpenALSoundBufferStream.h | 4 +- .../OpenALSoundSystem/OpenALSoundSource.cpp | 21 ++++++-- 6 files changed, 63 insertions(+), 44 deletions(-) diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferBase.h b/src/Systems/OpenALSoundSystem/OpenALSoundBufferBase.h index 137aaf5b1f..1a49398642 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferBase.h +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferBase.h @@ -34,9 +34,9 @@ namespace Mengine virtual bool load( const SoundDecoderInterfacePtr & _soundDecoder ) = 0; virtual bool playSource( ALuint _source, bool _looped, float _carriage ) = 0; - virtual bool resumeSource( ALuint _source ) = 0; - virtual void pauseSource( ALuint _source ) = 0; virtual void stopSource( ALuint _source ) = 0; + virtual void pauseSource( ALuint _source ) = 0; + virtual bool resumeSource( ALuint _source ) = 0; public: virtual bool setTimePosition( ALuint _source, float _position ) const = 0; diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.cpp index ddf5c67209..197c00413a 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.cpp @@ -45,7 +45,7 @@ namespace Mengine bool OpenALSoundBufferMemory::updateSoundBuffer() { //Empty - + return false; } ////////////////////////////////////////////////////////////////////////// @@ -192,18 +192,6 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool OpenALSoundBufferMemory::resumeSource( ALuint _sourceId ) - { - MENGINE_OPENAL_CALL( alSourcePlay, (_sourceId) ); - - return true; - } - ////////////////////////////////////////////////////////////////////////// - void OpenALSoundBufferMemory::pauseSource( ALuint _sourceId ) - { - MENGINE_OPENAL_CALL( alSourcePause, (_sourceId) ); - } - ////////////////////////////////////////////////////////////////////////// void OpenALSoundBufferMemory::stopSource( ALuint _sourceId ) { MENGINE_OPENAL_CALL( alSourceStop, (_sourceId) ); @@ -221,6 +209,18 @@ namespace Mengine MENGINE_OPENAL_CALL( alSourcei, (_sourceId, AL_BUFFER, 0) ); } ////////////////////////////////////////////////////////////////////////// + void OpenALSoundBufferMemory::pauseSource( ALuint _sourceId ) + { + MENGINE_OPENAL_CALL( alSourcePause, (_sourceId) ); + } + ////////////////////////////////////////////////////////////////////////// + bool OpenALSoundBufferMemory::resumeSource( ALuint _sourceId ) + { + MENGINE_OPENAL_CALL( alSourcePlay, (_sourceId) ); + + return true; + } + ////////////////////////////////////////////////////////////////////////// bool OpenALSoundBufferMemory::setTimePosition( ALuint _sourceId, float _position ) const { ALfloat al_position = (ALfloat)(_position * 0.001f); diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.h b/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.h index d2481a7b5b..91cd67c9ca 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.h +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferMemory.h @@ -25,9 +25,9 @@ namespace Mengine bool load( const SoundDecoderInterfacePtr & _soundDecoder ) override; bool playSource( ALuint _sourceId, bool _looped, float _position ) override; - bool resumeSource( ALuint _sourceId ) override; - void pauseSource( ALuint _sourceId ) override; void stopSource( ALuint _sourceId ) override; + void pauseSource( ALuint _sourceId ) override; + bool resumeSource( ALuint _sourceId ) override; public: bool setTimePosition( ALuint _sourceId, float _position ) const override; diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp index 16703cfb2b..d6c4713e2c 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.cpp @@ -255,7 +255,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool OpenALSoundBufferStream::resumeSource( ALuint _sourceId ) + void OpenALSoundBufferStream::stopSource( ALuint _sourceId ) { MENGINE_UNUSED( _sourceId ); @@ -263,9 +263,24 @@ namespace Mengine , _sourceId ); - this->setUpdating_( true ); + this->setUpdating_( false ); - return true; + MENGINE_THREAD_MUTEX_SCOPE( m_mutexUpdating ); + + MENGINE_OPENAL_CALL( alSourceStop, (_sourceId) ); + + ALint queued = 0; + MENGINE_OPENAL_CALL( alGetSourcei, (_sourceId, AL_BUFFERS_QUEUED, &queued) ); + + for( ALint i = 0; i != queued; ++i ) + { + ALuint bufferId = 0; + MENGINE_OPENAL_CALL( alSourceUnqueueBuffers, (_sourceId, 1, &bufferId) ); + } + + MENGINE_OPENAL_CALL( alSourcei, (_sourceId, AL_BUFFER, 0) ); + + m_sourceId = 0; } ////////////////////////////////////////////////////////////////////////// void OpenALSoundBufferStream::pauseSource( ALuint _sourceId ) @@ -276,10 +291,12 @@ namespace Mengine , _sourceId ); + MENGINE_OPENAL_CALL( alSourcePause, (_sourceId) ); + this->setUpdating_( false ); } ////////////////////////////////////////////////////////////////////////// - void OpenALSoundBufferStream::stopSource( ALuint _sourceId ) + bool OpenALSoundBufferStream::resumeSource( ALuint _sourceId ) { MENGINE_UNUSED( _sourceId ); @@ -287,24 +304,11 @@ namespace Mengine , _sourceId ); - this->setUpdating_( false ); - - MENGINE_THREAD_MUTEX_SCOPE( m_mutexUpdating ); - - MENGINE_OPENAL_CALL( alSourceStop, (_sourceId) ); - - ALint queued = 0; - MENGINE_OPENAL_CALL( alGetSourcei, (_sourceId, AL_BUFFERS_QUEUED, &queued) ); - - for( ALint i = 0; i != queued; ++i ) - { - ALuint bufferId = 0; - MENGINE_OPENAL_CALL( alSourceUnqueueBuffers, (_sourceId, 1, &bufferId) ); - } + this->setUpdating_( true ); - MENGINE_OPENAL_CALL( alSourcei, (_sourceId, AL_BUFFER, 0) ); + MENGINE_OPENAL_CALL( alSourcePlay, (_sourceId) ); - m_sourceId = 0; + return true; } ////////////////////////////////////////////////////////////////////////// void OpenALSoundBufferStream::setUpdating_( bool _updating ) @@ -439,7 +443,7 @@ namespace Mengine decoder_data_body.size = MENGINE_OPENAL_STREAM_BUFFER_SIZE; size_t bytesWritten = m_soundDecoder->decode( &decoder_data_body ); - + if( m_looped == true && bytesWritten != MENGINE_OPENAL_STREAM_BUFFER_SIZE ) { if( m_soundDecoder->rewind() == false ) @@ -459,7 +463,7 @@ namespace Mengine bytesWritten += bytesWritten2; } - + if( bytesWritten == 0 ) { *_bytes = 0; diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.h b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.h index 0618421f25..aa78c8aac5 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.h +++ b/src/Systems/OpenALSoundSystem/OpenALSoundBufferStream.h @@ -36,9 +36,9 @@ namespace Mengine public: bool playSource( ALuint _sourceId, bool _looped, float _position ) override; - bool resumeSource( ALuint _sourceId ) override; - void pauseSource( ALuint _sourceId ) override; void stopSource( ALuint _sourceId ) override; + void pauseSource( ALuint _sourceId ) override; + bool resumeSource( ALuint _sourceId ) override; public: bool setTimePosition( ALuint _sourceId, float _position ) const override; diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundSource.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundSource.cpp index 68ea508eb1..201442fbcb 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundSource.cpp +++ b/src/Systems/OpenALSoundSystem/OpenALSoundSource.cpp @@ -11,6 +11,18 @@ namespace Mengine { + ////////////////////////////////////////////////////////////////////////// + namespace Detail + { + ////////////////////////////////////////////////////////////////////////// + static ALfloat calcGain( float _volume ) + { + ALfloat gain = (ALfloat)StdMath::powf( _volume, 2.f ); + + return gain; + } + ////////////////////////////////////////////////////////////////////////// + } ////////////////////////////////////////////////////////////////////////// OpenALSoundSource::OpenALSoundSource() : m_volume( 1.f ) @@ -145,7 +157,8 @@ namespace Mengine return false; } - ALfloat gain = (ALfloat)StdMath::powf( m_volume, 2.f ); + ALfloat gain = Detail::calcGain( m_volume ); + MENGINE_OPENAL_CALL( alSourcef, (m_sourceId, AL_GAIN, gain) ); m_soundBuffer->resumeSource( m_sourceId ); @@ -192,7 +205,8 @@ namespace Mengine if( m_playing == true && m_sourceId != 0 ) { - ALfloat gain = (ALfloat)StdMath::powf( m_volume, 2.f ); + ALfloat gain = Detail::calcGain( m_volume ); + MENGINE_OPENAL_CALL( alSourcef, (m_sourceId, AL_GAIN, gain) ); } } @@ -379,7 +393,8 @@ namespace Mengine MENGINE_OPENAL_CALL( alSourcef, (_source, AL_MAX_GAIN, 1.f) ); MENGINE_OPENAL_CALL( alSourcef, (_source, AL_PITCH, 1.f) ); - ALfloat gain = (ALfloat)StdMath::powf( m_volume, 2.f ); + ALfloat gain = Detail::calcGain( m_volume ); + MENGINE_OPENAL_CALL( alSourcef, (_source, AL_GAIN, gain) ); } ////////////////////////////////////////////////////////////////////////// From e71c9084c2c106b6be376533570df3c7833ac73b Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 14:48:32 +0200 Subject: [PATCH 119/169] wip iOS UMP --- ...UserMessagingPlatformApplicationDelegate.h | 2 ++ ...serMessagingPlatformApplicationDelegate.mm | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h index de60ce8df7..13650357a0 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h @@ -2,6 +2,8 @@ @interface AppleUserMessagingPlatformApplicationDelegate : NSObject +@property (atomic, assign) BOOL m_completed; + @end diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm index 0d6ce8a251..ac9a157952 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -9,7 +9,17 @@ @implementation AppleUserMessagingPlatformApplicationDelegate -#pragma mark - helpers +- (instancetype)init { + self = [super init]; + + if (self) { + self.m_completed = NO; + } + + return self; +} + +#pragma mark - Details - (void)notifyConsentChangedFromDefaults { iOSTransparencyConsentParam * consent = [[iOSTransparencyConsentParam alloc] initFromUserDefaults]; @@ -27,7 +37,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #if defined(MENGINE_DEBUG) UMPDebugSettings *debugSettings = [[UMPDebugSettings alloc] init]; debugSettings.geography = UMPDebugGeographyEEA; - debugSettings.testDeviceIdentifiers = @[@"46D5A6B4-FAE4-4EA3-9D36-94F9A7CEA291"]; + //debugSettings.testDeviceIdentifiers = @[@"DB1869F9-B9D0-4D84-B2CB-F63F249E58C9"]; parameters.debugSettings = debugSettings; #endif @@ -35,6 +45,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (error != nil) { IOS_LOGGER_MESSAGE(@"[UMP] requestConsentInfoUpdate error: %@", error); + self.m_completed = YES; + return; } @@ -45,6 +57,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; + self.m_completed = YES; + return; } @@ -55,6 +69,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (formStatus != UMPFormStatusAvailable) { IOS_LOGGER_MESSAGE(@"[UMP] formStatus not available: %ld", (long)formStatus); + self.m_completed = YES; + return; } @@ -63,6 +79,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [UMPConsentForm loadAndPresentIfRequiredFromViewController:rootVC completionHandler:^(NSError * _Nullable loadError) { if (loadError != nil) { IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController error: %@", loadError); + + self.m_completed = YES; return; } From 4ed1348f99b602d552804f620f435208e476a700 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 15:19:55 +0200 Subject: [PATCH 120/169] wip iOSAppTrackingTransparency --- .../iOSUIApplicationDelegate.mm | 8 +++++++ .../iOS/iOSAppTrackingAuthorization.h | 11 ++++++++++ .../iOS/iOSAppTrackingTransparencyParam.h | 12 +++++++++++ .../iOS/iOSAppTrackingTransparencyParam.mm | 5 +++++ src/Environment/iOS/iOSDetail.h | 2 ++ src/Environment/iOS/iOSDetail.mm | 8 +++++++ ...AppTrackingTransparencyDelegateInterface.h | 11 ++++++++++ .../iOSUIMainApplicationDelegateInterface.h | 3 +++ .../AppleAppTrackingApplicationDelegate.mm | 21 ++++++++++++------- .../AppleAppTrackingInterface.h | 12 +++-------- ...serMessagingPlatformApplicationDelegate.mm | 20 ++++++++++++------ .../AppleUserMessagingPlatformInterface.h | 11 ++++++++++ .../CMakeLists.txt | 2 ++ 13 files changed, 103 insertions(+), 23 deletions(-) create mode 100644 src/Environment/iOS/iOSAppTrackingAuthorization.h create mode 100644 src/Environment/iOS/iOSAppTrackingTransparencyParam.h create mode 100644 src/Environment/iOS/iOSAppTrackingTransparencyParam.mm create mode 100644 src/Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h create mode 100644 src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformInterface.h diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 74cc917c05..44793edf8d 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -218,6 +218,14 @@ - (void)eventAdRevenue:(iOSAdRevenueParam *)revenue { } } +- (void)eventAppTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking { + @autoreleasepool { + for (NSObject * delegate in self.m_pluginAppTrackingTransparencyDelegates) { + [delegate onAppTrackingTransparency:tracking]; + } + } +} + - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { @autoreleasepool { for (NSObject * delegate in self.m_pluginTransparencyConsentDelegates) { diff --git a/src/Environment/iOS/iOSAppTrackingAuthorization.h b/src/Environment/iOS/iOSAppTrackingAuthorization.h new file mode 100644 index 0000000000..1eb102ae86 --- /dev/null +++ b/src/Environment/iOS/iOSAppTrackingAuthorization.h @@ -0,0 +1,11 @@ +#pragma once + +#import "Environment/Apple/AppleIncluder.h" + +typedef NS_ENUM( NSInteger, EAppleAppTrackingAuthorization ) +{ + EAATA_AUTHORIZED, + EAATA_DENIED, + EAATA_RESTRICTED, + EAATA_NOT_DETERMINED +}; diff --git a/src/Environment/iOS/iOSAppTrackingTransparencyParam.h b/src/Environment/iOS/iOSAppTrackingTransparencyParam.h new file mode 100644 index 0000000000..9f62878e56 --- /dev/null +++ b/src/Environment/iOS/iOSAppTrackingTransparencyParam.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Config/Config.h" + +#import "Environment/iOS/iOSAppTrackingAuthorization.h" + +@interface iOSAppTrackingTransparencyParam : NSObject + +@property (nonatomic) EAppleAppTrackingAuthorization APPTRACKINGTRANSPARENCY_AUTHORIZATION; +@property (nonatomic) NSString * APPTRACKINGTRANSPARENCY_IDFA; + +@end diff --git a/src/Environment/iOS/iOSAppTrackingTransparencyParam.mm b/src/Environment/iOS/iOSAppTrackingTransparencyParam.mm new file mode 100644 index 0000000000..82fd1816fc --- /dev/null +++ b/src/Environment/iOS/iOSAppTrackingTransparencyParam.mm @@ -0,0 +1,5 @@ +#import "iOSAppTrackingTransparencyParam.h" + +@implementation iOSAppTrackingTransparencyParam + +@end diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index efc4452fab..fa1e37f3fb 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -5,6 +5,7 @@ #import "Environment/Apple/AppleLogRecordParam.h" #import "Environment/iOS/iOSAdRevenueParam.h" +#import "Environment/iOS/iOSAppTrackingTransparencyParam.h" #import "Environment/iOS/iOSTransparencyConsentParam.h" #import "Environment/iOS/iOSUIMainApplicationDelegateInterface.h" @@ -39,6 +40,7 @@ + (void)setUserId:(iOSUserParam * _Nonnull)userId; + (void)removeUserData; + (void)adRevenue:(iOSAdRevenueParam * _Nonnull)revenue; ++ (void)appTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking; + (void)transparencyConsent:(iOSTransparencyConsentParam * _Nonnull)consent; + (void)log:(AppleLogRecordParam * _Nonnull)record; + (void)config:(NSDictionary * _Nonnull)config; diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index cfeb3cc564..82c3cccdd1 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -160,6 +160,14 @@ + (void) adRevenue:(iOSAdRevenueParam *)revenue { }]; } ++ (void) appTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking { + [AppleDetail addMainQueueOperation:^{ + NSObject * delegate = [iOSDetail getUIMainApplicationDelegate]; + + [delegate eventAppTrackingTransparency:tracking]; + }]; +} + + (void) transparencyConsent:(iOSTransparencyConsentParam *)consent { [AppleDetail addMainQueueOperation:^{ NSObject * delegate = [iOSDetail getUIMainApplicationDelegate]; diff --git a/src/Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h b/src/Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h new file mode 100644 index 0000000000..a989224b17 --- /dev/null +++ b/src/Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Config/Config.h" + +#import "Environment/iOS/iOSAppTrackingTransparencyParam.h" + +@protocol iOSPluginAppTrackingTransparencyDelegateInterface + +- (void)onAppTrackingTransparency:(iOSAppTrackingTransparencyParam *)param; + +@end diff --git a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h index 6d785bc285..e110cae64c 100644 --- a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h @@ -6,6 +6,7 @@ #import "Environment/iOS/iOSPluginConfigDelegateInterface.h" #import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" #import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" +#import "Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h" #import "Environment/iOS/iOSPluginTransparencyConsentDelegateInterface.h" @protocol iOSUIMainApplicationDelegateInterface @@ -15,6 +16,7 @@ - (NSArray * _Nonnull)getPluginConfigDelegates; - (NSArray * _Nonnull)getPluginUserIdDelegates; - (NSArray * _Nonnull)getPluginAdRevenueDelegates; +- (NSArray *_Nonnull)getPluginAppTrackingTransparencyDelegates; - (NSArray * _Nonnull)getPluginTransparencyConsentDelegates; - (id _Nullable)getPluginDelegateOfClass:(Class _Nonnull)delegateClass; @@ -35,6 +37,7 @@ - (void)eventRemoveUserData; - (void)eventAdRevenue:(iOSAdRevenueParam * _Nonnull)revenue; +- (void)eventAppTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking; - (void)eventTransparencyConsent:(iOSTransparencyConsentParam * _Nonnull)consent; @end diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index 29767002e8..e1e5e949d6 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -29,19 +29,19 @@ + (instancetype) sharedInstance { return sharedInstance; } -- (void)makeIDFA { ++ (NSString *)makeIDFA { NSUUID * idfa_uuid = [iOSDetail getAdIdentifier]; if (idfa_uuid == nil) { - return; + return @"00000000-0000-0000-0000-000000000000"; } NSString * idfa = [idfa_uuid UUIDString]; - self.m_idfa = idfa; + return idfa; } -- (void)authorization:(void (^)(EAppleAppTrackingAuthorization status, NSString *idfa))response { +- (void)authorization { IOS_LOGGER_MESSAGE( @"request app tracking authorization" ); [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { @@ -49,24 +49,29 @@ - (void)authorization:(void (^)(EAppleAppTrackingAuthorization status, NSString case ATTrackingManagerAuthorizationStatusAuthorized: { self.m_status = EAATA_AUTHORIZED; - [self makeIDFA]; + self.m_idfa = [AppleAppTrackingApplicationDelegate makeIDFA]; }break; case ATTrackingManagerAuthorizationStatusDenied: { self.m_status = EAATA_DENIED; + self.m_idfa = @"00000000-0000-0000-0000-000000000000"; }break; case ATTrackingManagerAuthorizationStatusNotDetermined: { self.m_status = EAATA_NOT_DETERMINED; + self.m_idfa = @"00000000-0000-0000-0000-000000000000"; }break; case ATTrackingManagerAuthorizationStatusRestricted: { self.m_status = EAATA_RESTRICTED; + self.m_idfa = @"00000000-0000-0000-0000-000000000000"; }break; } IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - [AppleDetail addMainQueueOperation:^{ - response( self.m_status, self.m_idfa ); - }]; + iOSAppTrackingTransparencyParam * tracking = [[iOSAppTrackingTransparencyParam alloc] init]; + tracking.APPTRACKINGTRANSPARENCY_AUTHORIZATION = self.m_status; + tracking.APPTRACKINGTRANSPARENCY_IDFA = self.m_idfa; + + [AppleDetail appTrackingTransparency:tracking]; }]; } diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingInterface.h b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingInterface.h index 9e9f536f60..a4977478ff 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingInterface.h +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingInterface.h @@ -1,19 +1,13 @@ #pragma once -#import "Environment/Apple/AppleIncluder.h" - -typedef NS_ENUM(NSInteger, EAppleAppTrackingAuthorization) { - EAATA_AUTHORIZED, - EAATA_DENIED, - EAATA_RESTRICTED, - EAATA_NOT_DETERMINED -}; +#import "Environment/iOS/iOSAppTrackingAuthorization.h" @protocol AppleAppTrackingInterface + (instancetype)sharedInstance; -- (void)authorization:(void (^)(EAppleAppTrackingAuthorization status, NSString *idfa))response; +- (void)authorization; + - (EAppleAppTrackingAuthorization)getAuthorizationStatus; - (NSString *)getIDFA; - (BOOL)isTrackingAllowed; diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm index ac9a157952..e3f1c2a8f0 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -21,7 +21,9 @@ - (instancetype)init { #pragma mark - Details -- (void)notifyConsentChangedFromDefaults { +- (void)completedConsent { + self.m_completed = YES; + iOSTransparencyConsentParam * consent = [[iOSTransparencyConsentParam alloc] initFromUserDefaults]; [iOSDetail transparencyConsent:consent]; @@ -45,7 +47,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (error != nil) { IOS_LOGGER_MESSAGE(@"[UMP] requestConsentInfoUpdate error: %@", error); - self.m_completed = YES; + [self completedConsent]; return; } @@ -57,7 +59,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; - self.m_completed = YES; + [self completedConsent]; return; } @@ -69,7 +71,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (formStatus != UMPFormStatusAvailable) { IOS_LOGGER_MESSAGE(@"[UMP] formStatus not available: %ld", (long)formStatus); - self.m_completed = YES; + [self completedConsent]; return; } @@ -80,17 +82,23 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (loadError != nil) { IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController error: %@", loadError); - self.m_completed = YES; + [self completedConsent]; return; } + + IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController completed"); // After form dismissal, UMP writes IABTCF_* to NSUserDefaults. Broadcast updated consent. - [self notifyConsentChangedFromDefaults]; + [self completedConsent]; }]; }]; return YES; } +- (BOOL)isComplete { + return self.m_completed +} + @end diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformInterface.h b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformInterface.h new file mode 100644 index 0000000000..f26438bb53 --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformInterface.h @@ -0,0 +1,11 @@ +#pragma once + +#import "Environment/Apple/AppleIncluder.h" + +@protocol AppleUserMessagingPlatformInterface + ++ (instancetype)sharedInstance; + +- (BOOL)isComplete; + +@end diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt index bcde42423b..5e78d64d2d 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt @@ -2,6 +2,8 @@ MENGINE_PROJECT(AppleUserMessagingPlatformPlugin) ADD_FILTER( src + AppleUserMessagingPlatformInterface.h + AppleUserMessagingPlatformApplicationDelegate.h AppleUserMessagingPlatformApplicationDelegate.mm ) From b49f38b054e7ff7f0c1d377e5d942f395689248a Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 15:49:47 +0200 Subject: [PATCH 121/169] Fix --- src/Environment/iOS/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Environment/iOS/CMakeLists.txt b/src/Environment/iOS/CMakeLists.txt index 75c76cdd43..12ecfeef19 100644 --- a/src/Environment/iOS/CMakeLists.txt +++ b/src/Environment/iOS/CMakeLists.txt @@ -20,6 +20,10 @@ src iOSEnvironmentService.mm iOSConsentFlowUserGeography.h + + iOSAppTrackingAuthorization.h + iOSAppTrackingTransparencyParam.h + iOSAppTrackingTransparencyParam.mm iOSTransparencyConsentParam.h iOSTransparencyConsentParam.mm @@ -44,6 +48,7 @@ src iOSPluginUserIdDelegateInterface.h iOSPluginAdRevenueDelegateInterface.h iOSPluginApplicationDelegateInterface.h + iOSPluginAppTrackingTransparencyDelegateInterface.h iOSPluginTransparencyConsentDelegateInterface.h iOSPluginLoggerDelegateInterface.h iOSPluginConfigDelegateInterface.h From c2ff04a1b0225b4bcc5bbd640d2663867574f10f Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 18:10:30 +0200 Subject: [PATCH 122/169] wip iOSUIApplicationDelegate --- .../iOSApplication/iOSUIApplicationDelegate.h | 2 ++ .../iOSApplication/iOSUIApplicationDelegate.mm | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index b041aa97d7..1205f62888 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -8,6 +8,7 @@ #import "Environment/iOS/iOSPluginAnalyticDelegateInterface.h" #import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" #import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" +#import "Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h" #import "Environment/iOS/iOSPluginTransparencyConsentDelegateInterface.h" #import @@ -23,6 +24,7 @@ @property (nonatomic, strong) NSMutableArray * m_pluginAnalyticDelegates; @property (nonatomic, strong) NSMutableArray * m_pluginUserIdDelegates; @property (nonatomic, strong) NSMutableArray * m_pluginAdRevenueDelegates; +@property (nonatomic, strong) NSMutableArray * m_pluginAppTrackingTransparencyDelegates; @property (nonatomic, strong) NSMutableArray * m_pluginTransparencyConsentDelegates; @end diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 44793edf8d..632cd479d9 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -27,6 +27,7 @@ - (instancetype)init { self.m_pluginAnalyticDelegates = [NSMutableArray array]; self.m_pluginUserIdDelegates = [NSMutableArray array]; self.m_pluginAdRevenueDelegates = [NSMutableArray array]; + self.m_pluginAppTrackingTransparencyDelegates = [NSMutableArray array]; self.m_pluginTransparencyConsentDelegates = [NSMutableArray array]; NSArray * proxysClassed = [iOSApplicationDelegates getApplicationDelegates]; @@ -66,6 +67,10 @@ - (instancetype)init { [self.m_pluginAdRevenueDelegates addObject:delegate]; } + if ([delegate conformsToProtocol:@protocol(iOSPluginAppTrackingTransparencyDelegateInterface)] == YES) { + [self.m_pluginAppTrackingTransparencyDelegates addObject:delegate]; + } + if ([delegate conformsToProtocol:@protocol(iOSPluginTransparencyConsentDelegateInterface)] == YES) { [self.m_pluginTransparencyConsentDelegates addObject:delegate]; } @@ -101,6 +106,10 @@ - (instancetype)init { return self.m_pluginAdRevenueDelegates; } +- (NSArray *)getPluginAppTrackingTransparencyDelegates { + return self.m_pluginAppTrackingTransparencyDelegates; +} + - (NSArray *)getPluginTransparencyConsentDelegates { return self.m_pluginTransparencyConsentDelegates; } From 0a64d9edca3e4ad078fc7af0a96abdfa16d65a31 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 18:18:17 +0200 Subject: [PATCH 123/169] fix iOS --- .../AppleAppTrackingApplicationDelegate.mm | 2 +- .../AppleAppTrackingScriptEmbedding.mm | 11 +++-------- src/Plugins/AppleDatadogPlugin/CMakeLists.txt | 4 ++-- .../AppleUserMessagingPlatformApplicationDelegate.mm | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index e1e5e949d6..6c155cbb8c 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -71,7 +71,7 @@ - (void)authorization { tracking.APPTRACKINGTRANSPARENCY_AUTHORIZATION = self.m_status; tracking.APPTRACKINGTRANSPARENCY_IDFA = self.m_idfa; - [AppleDetail appTrackingTransparency:tracking]; + [iOSDetail appTrackingTransparency:tracking]; }]; } diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingScriptEmbedding.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingScriptEmbedding.mm index d2ede44027..a57353b14c 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingScriptEmbedding.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingScriptEmbedding.mm @@ -17,14 +17,9 @@ namespace Detail { ////////////////////////////////////////////////////////////////////////// - static void AppleAppTracking_authorization( const pybind::object & _cb, const pybind::args & _args ) + static void AppleAppTracking_authorization() { - pybind::object copy_cb = _cb; - pybind::args copy_args = _args; - - [[AppleAppTrackingApplicationDelegate sharedInstance] authorization:^(EAppleAppTrackingAuthorization status, NSString * idfa) { - copy_cb.call_args( status, idfa, copy_args ); - }]; + [[AppleAppTrackingApplicationDelegate sharedInstance] authorization]; }; ////////////////////////////////////////////////////////////////////////// } @@ -46,7 +41,7 @@ static void AppleAppTracking_authorization( const pybind::object & _cb, const py .def( "EAATA_NOT_DETERMINED", EAATA_NOT_DETERMINED ) ; - pybind::def_function_args( _kernel, "appleAppTrackingAuthorization", &Detail::AppleAppTracking_authorization ); + pybind::def_function( _kernel, "appleAppTrackingAuthorization", &Detail::AppleAppTracking_authorization ); return true; } diff --git a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt index 11211471f4..5fa03b4f91 100644 --- a/src/Plugins/AppleDatadogPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt @@ -11,7 +11,7 @@ ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_DATADOG) ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleDatadogApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.2.0") -ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.2.0") +ADD_MENGINE_COCOAPOD("DatadogCore" "NO-GIT" "3.3.0") +ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.3.0") target_compile_options(${PROJECT_NAME} PRIVATE -fcxx-modules) diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm index e3f1c2a8f0..643414685e 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -98,7 +98,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( } - (BOOL)isComplete { - return self.m_completed + return self.m_completed; } @end From 6e29d37c6d2fd5a40ded66469ba408ad8515c028 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 21:09:25 +0200 Subject: [PATCH 124/169] Wip ATT --- .../AppleAdMobApplicationDelegate.h | 4 +- .../AppleAdMobApplicationDelegate.mm | 28 ++++++- .../AppleAppTrackingApplicationDelegate.h | 3 +- .../AppleAppTrackingApplicationDelegate.mm | 81 ++++++++++++------- 4 files changed, 83 insertions(+), 33 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h index 0c6112f27f..e0ca16f7ee 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h @@ -1,6 +1,7 @@ #pragma once #import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" +#import "Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h" #import "Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterface.h" @@ -14,7 +15,7 @@ #define PLUGIN_BUNDLE_NAME "MengineAppleAdMobPlugin" -@interface AppleAdMobApplicationDelegate : NSObject +@interface AppleAdMobApplicationDelegate : NSObject - (id)getAdvertisementBannerCallback; - (id)getAdvertisementInterstitialCallback; @@ -27,6 +28,7 @@ @property (nonatomic, strong) AppleAdMobBannerDelegate * m_bannerAd; @property (nonatomic, strong) AppleAdMobInterstitialDelegate * m_interstitialAd; @property (nonatomic, strong) AppleAdMobRewardedDelegate * m_rewardedAd; +@property (nonatomic, assign) BOOL m_initialized; @end diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm index 137fbd35a9..402f6de522 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -4,6 +4,7 @@ #import "Environment/Apple/AppleSemaphoreService.h" #import "Environment/Apple/AppleDetail.h" +#import "Environment/iOS/iOSAppTrackingTransparencyParam.h" #import "Environment/iOS/iOSApplication.h" #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSNetwork.h" @@ -28,6 +29,7 @@ - (instancetype)init { self.m_bannerAd = nil; self.m_interstitialAd = nil; self.m_rewardedAd = nil; + self.m_initialized = NO; } return self; @@ -80,6 +82,18 @@ + (instancetype)sharedInstance { return sharedInstance; } +#pragma mark - iOSPluginAppTrackingTransparencyDelegateInterface + +- (void)onAppTrackingTransparency:(iOSAppTrackingTransparencyParam *)param { + if (self.m_initialized == YES) { + return; + } + + IOS_LOGGER_MESSAGE(@"[AdMob] ATT completed, initializing AdMob"); + + [self initializeAdMob]; +} + #pragma mark - iOSPluginApplicationDelegateInterface - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { @@ -87,8 +101,20 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( IOS_LOGGER_ERROR(@"[ERROR] AdMob plugin not found bundle config [%@]", @PLUGIN_BUNDLE_NAME); return NO; + } + + return YES; +} + +- (void)initializeAdMob { + if (self.m_initialized == YES) { + return; } + self.m_initialized = YES; + + IOS_LOGGER_MESSAGE(@"[AdMob] initializing after ATT completion"); + GADMobileAds * mobileAds = [GADMobileAds sharedInstance]; GADVersionNumber version = [mobileAds versionNumber]; @@ -174,8 +200,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [advertisement readyAdProvider]; }]; }]; - - return YES; } #pragma mark - AppleAdvertisementProviderInterface diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.h b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.h index eaac4fe70b..8edaa2b5b4 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.h +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.h @@ -1,12 +1,13 @@ #pragma once #import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" +#import "Environment/iOS/iOSPluginTransparencyConsentDelegateInterface.h" #import "AppleAppTrackingInterface.h" #define PLUGIN_BUNDLE_NAME "MengineAppleAdvertisementPlugin" -@interface AppleAppTrackingApplicationDelegate : NSObject +@interface AppleAppTrackingApplicationDelegate : NSObject @property (nonatomic, assign) EAppleAppTrackingAuthorization m_status; @property (nonatomic, strong) NSString * m_idfa; diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index 6c155cbb8c..586116a5a7 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -3,21 +3,52 @@ #import "Environment/Apple/AppleDetail.h" #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSAppTrackingTransparencyParam.h" #import #import +#define IDFA_NOT_DETERMINED @"00000000-0000-0000-0000-000000000000" + @implementation AppleAppTrackingApplicationDelegate - (instancetype)init { self = [super init]; self.m_status = EAATA_NOT_DETERMINED; - self.m_idfa = @"00000000-0000-0000-0000-000000000000"; + self.m_idfa = IDFA_NOT_DETERMINED; return self; } +- (void)updateTrackingStatus:(ATTrackingManagerAuthorizationStatus)status { + switch(status) { + case ATTrackingManagerAuthorizationStatusAuthorized: { + self.m_status = EAATA_AUTHORIZED; + + self.m_idfa = [AppleAppTrackingApplicationDelegate makeIDFA]; + }break; + case ATTrackingManagerAuthorizationStatusDenied: { + self.m_status = EAATA_DENIED; + self.m_idfa = IDFA_DENIED; + }break; + case ATTrackingManagerAuthorizationStatusNotDetermined: { + self.m_status = EAATA_NOT_DETERMINED; + self.m_idfa = IDFA_NOT_DETERMINED; + }break; + case ATTrackingManagerAuthorizationStatusRestricted: { + self.m_status = EAATA_RESTRICTED; + self.m_idfa = IDFA_RESTRICTED; + }break; + } + + iOSAppTrackingTransparencyParam * tracking = [[iOSAppTrackingTransparencyParam alloc] init]; + tracking.APPTRACKINGTRANSPARENCY_AUTHORIZATION = self.m_status; + tracking.APPTRACKINGTRANSPARENCY_IDFA = self.m_idfa; + + [iOSDetail appTrackingTransparency:tracking]; +} + #pragma mark - AppleAppTrackingInterface + (instancetype) sharedInstance { @@ -33,7 +64,7 @@ + (NSString *)makeIDFA { NSUUID * idfa_uuid = [iOSDetail getAdIdentifier]; if (idfa_uuid == nil) { - return @"00000000-0000-0000-0000-000000000000"; + return IDFA_NOT_DETERMINED; } NSString * idfa = [idfa_uuid UUIDString]; @@ -45,33 +76,9 @@ - (void)authorization { IOS_LOGGER_MESSAGE( @"request app tracking authorization" ); [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { - switch( status ) { - case ATTrackingManagerAuthorizationStatusAuthorized: { - self.m_status = EAATA_AUTHORIZED; - - self.m_idfa = [AppleAppTrackingApplicationDelegate makeIDFA]; - }break; - case ATTrackingManagerAuthorizationStatusDenied: { - self.m_status = EAATA_DENIED; - self.m_idfa = @"00000000-0000-0000-0000-000000000000"; - }break; - case ATTrackingManagerAuthorizationStatusNotDetermined: { - self.m_status = EAATA_NOT_DETERMINED; - self.m_idfa = @"00000000-0000-0000-0000-000000000000"; - }break; - case ATTrackingManagerAuthorizationStatusRestricted: { - self.m_status = EAATA_RESTRICTED; - self.m_idfa = @"00000000-0000-0000-0000-000000000000"; - }break; - } - - IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - - iOSAppTrackingTransparencyParam * tracking = [[iOSAppTrackingTransparencyParam alloc] init]; - tracking.APPTRACKINGTRANSPARENCY_AUTHORIZATION = self.m_status; - tracking.APPTRACKINGTRANSPARENCY_IDFA = self.m_idfa; - - [iOSDetail appTrackingTransparency:tracking]; + IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", status ); + + [self updateTrackingStatus:status]; }]; } @@ -102,6 +109,22 @@ - (BOOL)isTrackingAllowed { return NO; } +#pragma mark - iOSPluginTransparencyConsentDelegateInterface + +- (void)onTransparencyConsent:(iOSTransparencyConsentParam *)consent { + IOS_LOGGER_MESSAGE(@"UMP consent received, requesting ATT authorization"); + + ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus]; + + if (status != ATTrackingManagerAuthorizationStatusNotDetermined) { + [self updateTrackingStatus:status]; + + return; + } + + [self authorization]; +} + #pragma mark - iOSPluginApplicationDelegateInterface - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { From 3471bc9336fab0bd9f50c5fb0bdddc968080d5ab Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 22:30:39 +0200 Subject: [PATCH 125/169] fix iOS --- .../AppleAppTrackingApplicationDelegate.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index 586116a5a7..e86f75a73b 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -30,7 +30,7 @@ - (void)updateTrackingStatus:(ATTrackingManagerAuthorizationStatus)status { }break; case ATTrackingManagerAuthorizationStatusDenied: { self.m_status = EAATA_DENIED; - self.m_idfa = IDFA_DENIED; + self.m_idfa = IDFA_NOT_DETERMINED; }break; case ATTrackingManagerAuthorizationStatusNotDetermined: { self.m_status = EAATA_NOT_DETERMINED; @@ -38,7 +38,7 @@ - (void)updateTrackingStatus:(ATTrackingManagerAuthorizationStatus)status { }break; case ATTrackingManagerAuthorizationStatusRestricted: { self.m_status = EAATA_RESTRICTED; - self.m_idfa = IDFA_RESTRICTED; + self.m_idfa = IDFA_NOT_DETERMINED; }break; } From 0562a7fee9742c478115e6ff5a4d1490fb943526 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 18 Nov 2025 23:18:27 +0200 Subject: [PATCH 126/169] improve iOS ATT --- .../iOSApplication/iOSUIApplicationDelegate.h | 3 ++ .../iOSUIApplicationDelegate.mm | 26 +++++++++++++++ src/Environment/iOS/iOSDetail.h | 2 ++ src/Environment/iOS/iOSDetail.mm | 6 ++++ .../iOSUIMainApplicationDelegateInterface.h | 2 ++ .../AppleAppTrackingApplicationDelegate.mm | 32 +++++++++++++++++++ 6 files changed, 71 insertions(+) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index 1205f62888..c0c0c56b98 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -27,4 +27,7 @@ @property (nonatomic, strong) NSMutableArray * m_pluginAppTrackingTransparencyDelegates; @property (nonatomic, strong) NSMutableArray * m_pluginTransparencyConsentDelegates; +@property (nonatomic, strong) NSMutableArray * m_didBecomeActiveOperations; +@property (nonatomic, assign) BOOL m_didBecomeActiveObserverRegistered; + @end diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 632cd479d9..362bb2fdbf 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -30,6 +30,9 @@ - (instancetype)init { self.m_pluginAppTrackingTransparencyDelegates = [NSMutableArray array]; self.m_pluginTransparencyConsentDelegates = [NSMutableArray array]; + self.m_didBecomeActiveOperations = [NSMutableArray array]; + self.m_didBecomeActiveObserverRegistered = NO; + NSArray * proxysClassed = [iOSApplicationDelegates getApplicationDelegates]; for (id className in proxysClassed) { @@ -243,6 +246,20 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { } } +- (void)addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block { + UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; + + if (appState == UIApplicationStateActive) { + [AppleDetail addMainQueueOperation:block]; + + return; + } + + @synchronized(self) { + [self.m_didBecomeActiveOperations addObject:block]; + } +} + #pragma mark - UIApplicationDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions API_AVAILABLE(ios(3.0)) { @@ -328,6 +345,15 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N - (void)applicationDidBecomeActive:(UIApplication *)application { [AppleLog withFormat:@"Mengine application applicationDidBecomeActive"]; + @synchronized(self) { + NSArray * operations = [self.m_didBecomeActiveOperations copy]; + [self.m_didBecomeActiveOperations removeAllObjects]; + + for (dispatch_block_t operation in operations) { + [AppleDetail addMainQueueOperation:operation]; + } + } + @autoreleasepool { for (id delegate in self.m_pluginApplicationDelegates) { if ([delegate respondsToSelector:@selector(applicationDidBecomeActive:)] == NO) { diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index fa1e37f3fb..1a28c019db 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -45,6 +45,8 @@ + (void)log:(AppleLogRecordParam * _Nonnull)record; + (void)config:(NSDictionary * _Nonnull)config; ++ (void)addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block; + + (NSString * _Nonnull)pathForTemporaryFileWithPrefix:(NSString * _Nonnull)prefix ext:(NSString * _Nonnull)ext; + (void)showOkAlertWithTitle:(NSString * _Nonnull)title diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index 82c3cccdd1..cb604aefef 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -194,6 +194,12 @@ + (void) config:(NSDictionary * _Nonnull)config { }]; } ++ (void) addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block { + NSObject *delegate = [iOSDetail getUIMainApplicationDelegate]; + + [delegate addDidBecomeActiveOperation:block]; +} + + (NSString *) pathForTemporaryFileWithPrefix:(NSString *)prefix ext:(NSString *)ext { NSString * result; CFUUIDRef uuid = CFUUIDCreate(NULL); diff --git a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h index e110cae64c..7e9dfde89b 100644 --- a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h @@ -40,4 +40,6 @@ - (void)eventAppTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking; - (void)eventTransparencyConsent:(iOSTransparencyConsentParam * _Nonnull)consent; +- (void)addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block; + @end diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index e86f75a73b..d67433678c 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -75,6 +75,38 @@ + (NSString *)makeIDFA { - (void)authorization { IOS_LOGGER_MESSAGE( @"request app tracking authorization" ); + ATTrackingManagerAuthorizationStatus currentStatus = [ATTrackingManager trackingAuthorizationStatus]; + + if (currentStatus != ATTrackingManagerAuthorizationStatusNotDetermined) { + [self updateTrackingStatus:currentStatus]; + + return; + } + + __weak AppleAppTrackingApplicationDelegate * weakSelf = self; + + [iOSDetail addDidBecomeActiveOperation:^{ + AppleAppTrackingApplicationDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + + ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus]; + + if (status != ATTrackingManagerAuthorizationStatusNotDetermined) { + [strongSelf updateTrackingStatus:status]; + + return; + } + + [strongSelf requestAuthorization]; + }]; +} + +- (void)requestAuthorization { + IOS_LOGGER_MESSAGE( @"requesting ATT authorization dialog" ); + [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", status ); From 38c63fe666e40f29dde0f4f59194cf855bba5281 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 13:01:15 +0200 Subject: [PATCH 127/169] improve iOS UMP --- .../iOSApplication/iOSUIApplicationDelegate.h | 3 +- .../iOSUIApplicationDelegate.mm | 47 ++++++++++++------ src/Environment/iOS/iOSDetail.h | 4 +- src/Environment/iOS/iOSDetail.mm | 31 +++++++++++- .../iOSUIMainApplicationDelegateInterface.h | 2 +- .../AppleAppTrackingApplicationDelegate.mm | 11 +++-- ...serMessagingPlatformApplicationDelegate.mm | 49 +++++++++++++------ ...erNotificationCenterApplicationDelegate.mm | 36 ++++++++++---- 8 files changed, 132 insertions(+), 51 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index c0c0c56b98..4067517f88 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -27,7 +27,6 @@ @property (nonatomic, strong) NSMutableArray * m_pluginAppTrackingTransparencyDelegates; @property (nonatomic, strong) NSMutableArray * m_pluginTransparencyConsentDelegates; -@property (nonatomic, strong) NSMutableArray * m_didBecomeActiveOperations; -@property (nonatomic, assign) BOOL m_didBecomeActiveObserverRegistered; +@property (nonatomic, strong) NSMutableArray * m_didBecomeActiveOperations; @end diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 362bb2fdbf..97c9a305ff 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -30,8 +30,7 @@ - (instancetype)init { self.m_pluginAppTrackingTransparencyDelegates = [NSMutableArray array]; self.m_pluginTransparencyConsentDelegates = [NSMutableArray array]; - self.m_didBecomeActiveOperations = [NSMutableArray array]; - self.m_didBecomeActiveObserverRegistered = NO; + self.m_didBecomeActiveOperations = [NSMutableArray array]; NSArray * proxysClassed = [iOSApplicationDelegates getApplicationDelegates]; @@ -246,20 +245,42 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { } } -- (void)addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block { +- (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block { UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; - if (appState == UIApplicationStateActive) { - [AppleDetail addMainQueueOperation:block]; + @synchronized(self) { + BOOL wasQueueEmpty = ([self.m_didBecomeActiveOperations count] == 0); + [self.m_didBecomeActiveOperations addObject:block]; - return; + if (appState == UIApplicationStateActive && wasQueueEmpty == YES) { + [self processNextOperation]; + } } - +} + +- (void)processNextOperation { @synchronized(self) { - [self.m_didBecomeActiveOperations addObject:block]; + if ([self.m_didBecomeActiveOperations count] == 0) { + return; + } + + void (^operation)(void (^)(void)) = [self.m_didBecomeActiveOperations firstObject]; + [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; + + [self processOperation:operation]; } } +- (void)processOperation:(void (^)(void (^)(void)))block { + [AppleDetail addMainQueueOperation:^{ + void (^completion)(void) = ^{ + [self processNextOperation]; + }; + + block(completion); + }]; +} + #pragma mark - UIApplicationDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions API_AVAILABLE(ios(3.0)) { @@ -345,14 +366,8 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N - (void)applicationDidBecomeActive:(UIApplication *)application { [AppleLog withFormat:@"Mengine application applicationDidBecomeActive"]; - @synchronized(self) { - NSArray * operations = [self.m_didBecomeActiveOperations copy]; - [self.m_didBecomeActiveOperations removeAllObjects]; - - for (dispatch_block_t operation in operations) { - [AppleDetail addMainQueueOperation:operation]; - } - } + // Начинаем обработку накопленных операций (приложение уже активно) + [self processNextOperation]; @autoreleasepool { for (id delegate in self.m_pluginApplicationDelegates) { diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index 1a28c019db..1ae2d0c1da 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -45,7 +45,9 @@ + (void)log:(AppleLogRecordParam * _Nonnull)record; + (void)config:(NSDictionary * _Nonnull)config; -+ (void)addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block; ++ (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block; + ++ (BOOL)hasSystemWindows; + (NSString * _Nonnull)pathForTemporaryFileWithPrefix:(NSString * _Nonnull)prefix ext:(NSString * _Nonnull)ext; diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index cb604aefef..f7764d6893 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -194,10 +194,37 @@ + (void) config:(NSDictionary * _Nonnull)config { }]; } -+ (void) addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block { ++ (void) addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block { NSObject *delegate = [iOSDetail getUIMainApplicationDelegate]; - [delegate addDidBecomeActiveOperation:block]; + [delegate addDidBecomeActiveOperationWithCompletion:block]; +} + ++ (BOOL)hasSystemWindows { + UIApplication * application = [UIApplication sharedApplication]; + + // Проверяем количество окон - системные диалоги создают дополнительные окна + NSArray * windows = application.windows; + + if (windows.count > 1) { + // Есть дополнительные окна (вероятно системный диалог) + return YES; + } + + // Проверяем наличие модальных view controllers + UIViewController * rootViewController = [iOSDetail getRootViewController]; + + if (rootViewController != nil) { + UIViewController * presented = rootViewController.presentedViewController; + + // Проверяем цепочку модальных view controllers + while (presented != nil) { + // Есть модальный view controller + return YES; + } + } + + return NO; } + (NSString *) pathForTemporaryFileWithPrefix:(NSString *)prefix ext:(NSString *)ext { diff --git a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h index 7e9dfde89b..690a8f9dcd 100644 --- a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h @@ -40,6 +40,6 @@ - (void)eventAppTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking; - (void)eventTransparencyConsent:(iOSTransparencyConsentParam * _Nonnull)consent; -- (void)addDidBecomeActiveOperation:(dispatch_block_t _Nonnull)block; +- (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block; @end diff --git a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm index d67433678c..bb3fde2a94 100644 --- a/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm +++ b/src/Plugins/AppleAppTrackingPlugin/AppleAppTrackingApplicationDelegate.mm @@ -85,10 +85,11 @@ - (void)authorization { __weak AppleAppTrackingApplicationDelegate * weakSelf = self; - [iOSDetail addDidBecomeActiveOperation:^{ + [iOSDetail addDidBecomeActiveOperationWithCompletion:^(void (^ _Nonnull completion)(void)) { AppleAppTrackingApplicationDelegate * strongSelf = weakSelf; if (strongSelf == nil) { + completion(); return; } @@ -96,21 +97,23 @@ - (void)authorization { if (status != ATTrackingManagerAuthorizationStatusNotDetermined) { [strongSelf updateTrackingStatus:status]; - + completion(); return; } - [strongSelf requestAuthorization]; + [strongSelf requestAuthorizationWithCompletion:completion]; }]; } -- (void)requestAuthorization { +- (void)requestAuthorizationWithCompletion:(void (^ _Nonnull)(void))completion { IOS_LOGGER_MESSAGE( @"requesting ATT authorization dialog" ); [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", status ); [self updateTrackingStatus:status]; + + completion(); }]; } diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm index 643414685e..c37ba176e2 100644 --- a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -32,7 +32,7 @@ - (void)completedConsent { #pragma mark - iOSPluginApplicationDelegateInterface - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init]; + UMPRequestParameters * parameters = [[UMPRequestParameters alloc] init]; parameters.tagForUnderAgeOfConsent = NO; // For testing purposes, you can force a UMPDebugGeography of EEA or not EEA. @@ -43,11 +43,19 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( parameters.debugSettings = debugSettings; #endif + __weak AppleUserMessagingPlatformApplicationDelegate * weakSelf = self; + [UMPConsentInformation.sharedInstance requestConsentInfoUpdateWithParameters:parameters completionHandler:^(NSError * _Nullable error) { + AppleUserMessagingPlatformApplicationDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + if (error != nil) { IOS_LOGGER_MESSAGE(@"[UMP] requestConsentInfoUpdate error: %@", error); - [self completedConsent]; + [strongSelf completedConsent]; return; } @@ -59,7 +67,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; - [self completedConsent]; + [strongSelf completedConsent]; return; } @@ -71,26 +79,37 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( if (formStatus != UMPFormStatusAvailable) { IOS_LOGGER_MESSAGE(@"[UMP] formStatus not available: %ld", (long)formStatus); - [self completedConsent]; + [strongSelf completedConsent]; return; } - UIViewController * rootVC = [iOSDetail getRootViewController]; + [iOSDetail addDidBecomeActiveOperationWithCompletion:^(void (^ _Nonnull completion)(void)) { + AppleUserMessagingPlatformApplicationDelegate * strongSelf2 = weakSelf; - [UMPConsentForm loadAndPresentIfRequiredFromViewController:rootVC completionHandler:^(NSError * _Nullable loadError) { - if (loadError != nil) { - IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController error: %@", loadError); - - [self completedConsent]; - + if (strongSelf2 == nil) { + completion(); return; } - IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController completed"); - - // After form dismissal, UMP writes IABTCF_* to NSUserDefaults. Broadcast updated consent. - [self completedConsent]; + UIViewController * rootVC = [iOSDetail getRootViewController]; + + [UMPConsentForm loadAndPresentIfRequiredFromViewController:rootVC completionHandler:^(NSError * _Nullable loadError) { + if (loadError != nil) { + IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController error: %@", loadError); + + [strongSelf2 completedConsent]; + completion(); + + return; + } + + IOS_LOGGER_MESSAGE(@"[UMP] loadAndPresentIfRequiredFromViewController completed"); + + // After form dismissal, UMP writes IABTCF_* to NSUserDefaults. Broadcast updated consent. + [strongSelf2 completedConsent]; + completion(); + }]; }]; }]; diff --git a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm index 13c060053e..2224a0b5aa 100644 --- a/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm +++ b/src/Plugins/AppleUserNotificationCenterPlugin/AppleUserNotificationCenterApplicationDelegate.mm @@ -4,6 +4,7 @@ #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" +#import @implementation AppleUserNotificationCenterApplicationDelegate @@ -55,19 +56,34 @@ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(N center.delegate = self; - [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) - completionHandler:^(BOOL granted, NSError * _Nullable error) { - if (error != nil) { - IOS_LOGGER_MESSAGE(@"Notification permission denied: %@" - , [AppleDetail getMessageFromNSError:error] - ); - - self.m_notificationPermissionGranted = NO; - + __weak AppleUserNotificationCenterApplicationDelegate * weakSelf = self; + + [iOSDetail addDidBecomeActiveOperationWithCompletion:^(void (^ _Nonnull completion)(void)) { + AppleUserNotificationCenterApplicationDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + completion(); return; } - self.m_notificationPermissionGranted = granted; + UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter]; + + [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) + completionHandler:^(BOOL granted, NSError * _Nullable error) { + if (error != nil) { + IOS_LOGGER_MESSAGE(@"Notification permission denied: %@" + , [AppleDetail getMessageFromNSError:error] + ); + + strongSelf.m_notificationPermissionGranted = NO; + completion(); + + return; + } + + strongSelf.m_notificationPermissionGranted = granted; + completion(); + }]; }]; return YES; From 9ea7854793e0545b00ff255d3137d08b8cf479e1 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 13:14:37 +0200 Subject: [PATCH 128/169] Wip --- .../iOSApplication/iOSUIApplicationDelegate.mm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 97c9a305ff..481e20046a 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -246,19 +246,23 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { } - (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block { - UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; - @synchronized(self) { BOOL wasQueueEmpty = ([self.m_didBecomeActiveOperations count] == 0); [self.m_didBecomeActiveOperations addObject:block]; - if (appState == UIApplicationStateActive && wasQueueEmpty == YES) { + if (wasQueueEmpty == YES) { [self processNextOperation]; } } } - (void)processNextOperation { + UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; + + if (appState != UIApplicationStateActive) { + return; + } + @synchronized(self) { if ([self.m_didBecomeActiveOperations count] == 0) { return; From 7ba8fb42ea9314d59f25a66d89795249949a68cc Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 13:39:08 +0200 Subject: [PATCH 129/169] Fix --- .../iOSApplication/iOSUIApplicationDelegate.h | 4 +++- .../iOSApplication/iOSUIApplicationDelegate.mm | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index 4067517f88..473df41aef 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -13,6 +13,8 @@ #import +typedef void (^iOSDidBecomeActiveOperationBlock)(void (^ _Nonnull completion)(void)); + @interface iOSUIApplicationDelegate : NSObject @property (nonatomic, strong) UIWindow * m_window; @@ -27,6 +29,6 @@ @property (nonatomic, strong) NSMutableArray * m_pluginAppTrackingTransparencyDelegates; @property (nonatomic, strong) NSMutableArray * m_pluginTransparencyConsentDelegates; -@property (nonatomic, strong) NSMutableArray * m_didBecomeActiveOperations; +@property (nonatomic, strong) NSMutableArray * m_didBecomeActiveOperations; @end diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 481e20046a..f2a8631e4d 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -30,7 +30,7 @@ - (instancetype)init { self.m_pluginAppTrackingTransparencyDelegates = [NSMutableArray array]; self.m_pluginTransparencyConsentDelegates = [NSMutableArray array]; - self.m_didBecomeActiveOperations = [NSMutableArray array]; + self.m_didBecomeActiveOperations = [NSMutableArray array]; NSArray * proxysClassed = [iOSApplicationDelegates getApplicationDelegates]; @@ -245,7 +245,7 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { } } -- (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block { +- (void)addDidBecomeActiveOperationWithCompletion:(iOSDidBecomeActiveOperationBlock)block { @synchronized(self) { BOOL wasQueueEmpty = ([self.m_didBecomeActiveOperations count] == 0); [self.m_didBecomeActiveOperations addObject:block]; @@ -268,14 +268,14 @@ - (void)processNextOperation { return; } - void (^operation)(void (^)(void)) = [self.m_didBecomeActiveOperations firstObject]; + iOSDidBecomeActiveOperationBlock operation = [self.m_didBecomeActiveOperations firstObject]; [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; [self processOperation:operation]; } } -- (void)processOperation:(void (^)(void (^)(void)))block { +- (void)processOperation:(iOSDidBecomeActiveOperationBlock)block { [AppleDetail addMainQueueOperation:^{ void (^completion)(void) = ^{ [self processNextOperation]; From ff46911d343c1d7d2b637cf797a405e4d8637165 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 14:21:42 +0200 Subject: [PATCH 130/169] wip --- .../iOSApplication/iOSUIApplicationDelegate.h | 2 +- .../iOSUIApplicationDelegate.mm | 5 ++- src/Environment/iOS/iOSDetail.mm | 45 ++++++++++++------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index 473df41aef..612e2a4d7e 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -13,7 +13,7 @@ #import -typedef void (^iOSDidBecomeActiveOperationBlock)(void (^ _Nonnull completion)(void)); +typedef void (^iOSDidBecomeActiveOperationBlock)(void (^completion)(void)); @interface iOSUIApplicationDelegate : NSObject diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index f2a8631e4d..420b437408 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -269,7 +269,6 @@ - (void)processNextOperation { } iOSDidBecomeActiveOperationBlock operation = [self.m_didBecomeActiveOperations firstObject]; - [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; [self processOperation:operation]; } @@ -278,6 +277,10 @@ - (void)processNextOperation { - (void)processOperation:(iOSDidBecomeActiveOperationBlock)block { [AppleDetail addMainQueueOperation:^{ void (^completion)(void) = ^{ + @synchronized(self) { + [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; + } + [self processNextOperation]; }; diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index f7764d6893..217d9402fa 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -203,28 +203,43 @@ + (void) addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _N + (BOOL)hasSystemWindows { UIApplication * application = [UIApplication sharedApplication]; - // Проверяем количество окон - системные диалоги создают дополнительные окна - NSArray * windows = application.windows; + NSMutableArray * all_windows = [NSMutableArray array]; - if (windows.count > 1) { - // Есть дополнительные окна (вероятно системный диалог) + for (UIScene * scene in application.connectedScenes) { + if (scene.activationState != UISceneActivationStateForegroundActive) { + continue; + } + + if ([scene isKindOfClass:[UIWindowScene class]] == NO) { + continue; + } + + UIWindowScene * window_scene = (UIWindowScene *)scene; + + for (UIWindow *window in window_scene.windows) { + if (window.isHidden) { + continue; + } + + [all_windows addObject:window]; + } + } + + if (all_windows.count > 1) { return YES; } - // Проверяем наличие модальных view controllers - UIViewController * rootViewController = [iOSDetail getRootViewController]; + UIViewController * view = [iOSDetail getRootViewController]; - if (rootViewController != nil) { - UIViewController * presented = rootViewController.presentedViewController; - - // Проверяем цепочку модальных view controllers - while (presented != nil) { - // Есть модальный view controller - return YES; - } + if (view == nil) { + return NO; } - return NO; + if (view.presentedViewController == nil) { + return NO; + } + + return YES; } + (NSString *) pathForTemporaryFileWithPrefix:(NSString *)prefix ext:(NSString *)ext { From ed1734f68b5f2e13ca95f1f83fbe569ff8f9c74c Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 14:32:12 +0200 Subject: [PATCH 131/169] wip --- .../iOSApplication/iOSUIApplicationDelegate.h | 1 + .../iOSUIApplicationDelegate.mm | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index 612e2a4d7e..ab93d62461 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -30,5 +30,6 @@ typedef void (^iOSDidBecomeActiveOperationBlock)(void (^completion)(void)); @property (nonatomic, strong) NSMutableArray * m_pluginTransparencyConsentDelegates; @property (nonatomic, strong) NSMutableArray * m_didBecomeActiveOperations; +@property (nonatomic, assign) BOOL m_isProcessingDidBecomeActiveOperation; @end diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 420b437408..64f1b6df5f 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -31,6 +31,7 @@ - (instancetype)init { self.m_pluginTransparencyConsentDelegates = [NSMutableArray array]; self.m_didBecomeActiveOperations = [NSMutableArray array]; + self.m_isProcessingDidBecomeActiveOperation = NO; NSArray * proxysClassed = [iOSApplicationDelegates getApplicationDelegates]; @@ -247,13 +248,10 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { - (void)addDidBecomeActiveOperationWithCompletion:(iOSDidBecomeActiveOperationBlock)block { @synchronized(self) { - BOOL wasQueueEmpty = ([self.m_didBecomeActiveOperations count] == 0); [self.m_didBecomeActiveOperations addObject:block]; - - if (wasQueueEmpty == YES) { - [self processNextOperation]; - } } + + [self processNextOperation]; } - (void)processNextOperation { @@ -263,28 +261,37 @@ - (void)processNextOperation { return; } + iOSDidBecomeActiveOperationBlock operation = nil; + @synchronized(self) { - if ([self.m_didBecomeActiveOperations count] == 0) { + if (self.m_isProcessingDidBecomeActiveOperation == YES) { return; } - iOSDidBecomeActiveOperationBlock operation = [self.m_didBecomeActiveOperations firstObject]; + if ([self.m_didBecomeActiveOperations count] == 0) { + return; + } + operation = [self.m_didBecomeActiveOperations firstObject]; + [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; + + self.m_isProcessingDidBecomeActiveOperation = YES; + } + + if (operation != nil) { [self processOperation:operation]; } } - (void)processOperation:(iOSDidBecomeActiveOperationBlock)block { [AppleDetail addMainQueueOperation:^{ - void (^completion)(void) = ^{ + block(^{ @synchronized(self) { - [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; + self.m_isProcessingDidBecomeActiveOperation = NO; } [self processNextOperation]; - }; - - block(completion); + }); }]; } From 9fc7ab5c9b231653b1580fed33143683d74e15d2 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 19:00:22 +0200 Subject: [PATCH 132/169] fix iOS --- .../iOSApplication/iOSUIApplicationDelegate.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 64f1b6df5f..d50d62d399 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -247,7 +247,7 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { } - (void)addDidBecomeActiveOperationWithCompletion:(iOSDidBecomeActiveOperationBlock)block { - @synchronized(self) { + @synchronized(self.m_didBecomeActiveOperations) { [self.m_didBecomeActiveOperations addObject:block]; } @@ -263,7 +263,7 @@ - (void)processNextOperation { iOSDidBecomeActiveOperationBlock operation = nil; - @synchronized(self) { + @synchronized(self.m_didBecomeActiveOperations) { if (self.m_isProcessingDidBecomeActiveOperation == YES) { return; } @@ -286,7 +286,7 @@ - (void)processNextOperation { - (void)processOperation:(iOSDidBecomeActiveOperationBlock)block { [AppleDetail addMainQueueOperation:^{ block(^{ - @synchronized(self) { + @synchronized(self.m_didBecomeActiveOperations) { self.m_isProcessingDidBecomeActiveOperation = NO; } @@ -380,7 +380,6 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N - (void)applicationDidBecomeActive:(UIApplication *)application { [AppleLog withFormat:@"Mengine application applicationDidBecomeActive"]; - // Начинаем обработку накопленных операций (приложение уже активно) [self processNextOperation]; @autoreleasepool { From 5e70c928236c3f59c496d0eff2b41aea3767a38c Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 19 Nov 2025 19:42:56 +0200 Subject: [PATCH 133/169] Fix Android build --- src/Platforms/AndroidPlatform/AndroidPlatformService.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index f9f4532771..3410f2a0dd 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -10,6 +10,7 @@ #include "Interface/EnumeratorServiceInterface.h" #include "Interface/PluginServiceInterface.h" #include "Interface/DateTimeSystemInterface.h" +#include "Interface/SoundServiceInterface.h" #include "Interface/ThreadServiceInterface.h" #include "Interface/EnvironmentServiceInterface.h" #include "Interface/AccountServiceInterface.h" From 7b076f6cdf8240be5ca2b4b5f006a020360a08ea Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 20 Nov 2025 19:14:49 +0200 Subject: [PATCH 134/169] wip --- cmake/macro_template.cmake | 12 +- src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 2 + .../AppleAdMobPlugin/SKAdNetworkItems.plist | 205 ++++++++++++++++++ 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 src/Plugins/AppleAdMobPlugin/SKAdNetworkItems.plist diff --git a/cmake/macro_template.cmake b/cmake/macro_template.cmake index a7bb2f7731..a5d03d497d 100644 --- a/cmake/macro_template.cmake +++ b/cmake/macro_template.cmake @@ -1039,7 +1039,17 @@ MACRO(ADD_MENGINE_DOWNLOAD_SKADNETWORKITEMS_PLIST URL) message(STATUS "File downloaded successfully: ${URL}") endif() - LIST(APPEND APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS ${SKADNETWORKITEMS_PLIST_DOWNLOAD_FILENAME}) + ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE(${SKADNETWORKITEMS_PLIST_DOWNLOAD_FILENAME}) +ENDMACRO() + +MACRO(ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE FILE_PATH) + if(NOT EXISTS "${FILE_PATH}") + message(FATAL_ERROR "SKAdNetworkItems plist file does not exist: ${FILE_PATH}") + else() + message(STATUS "Using local SKAdNetworkItems plist file: ${FILE_PATH}") + endif() + + LIST(APPEND APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS ${FILE_PATH}) SET(APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS ${APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS} PARENT_SCOPE) ENDMACRO() diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index 90fbfef12c..a505dd54bb 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -44,6 +44,8 @@ ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.13.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") +ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE("SKAdNetworkItems.plist") + if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) TARGET_LINK_LIBRARIES(${PROJECT_NAME} Python) endif() diff --git a/src/Plugins/AppleAdMobPlugin/SKAdNetworkItems.plist b/src/Plugins/AppleAdMobPlugin/SKAdNetworkItems.plist new file mode 100644 index 0000000000..619926a868 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/SKAdNetworkItems.plist @@ -0,0 +1,205 @@ + + + + + SKAdNetworkItems + + + SKAdNetworkIdentifier + cstr6suwn9.skadnetwork + + + SKAdNetworkIdentifier + 4fzdc2evr5.skadnetwork + + + SKAdNetworkIdentifier + 2fnua5tdw4.skadnetwork + + + SKAdNetworkIdentifier + ydx93a7ass.skadnetwork + + + SKAdNetworkIdentifier + p78axxw29g.skadnetwork + + + SKAdNetworkIdentifier + v72qych5uu.skadnetwork + + + SKAdNetworkIdentifier + ludvb6z3bs.skadnetwork + + + SKAdNetworkIdentifier + cp8zw746q7.skadnetwork + + + SKAdNetworkIdentifier + 3sh42y64q3.skadnetwork + + + SKAdNetworkIdentifier + c6k4g5qg8m.skadnetwork + + + SKAdNetworkIdentifier + s39g8k73mm.skadnetwork + + + SKAdNetworkIdentifier + 3qy4746246.skadnetwork + + + SKAdNetworkIdentifier + f38h382jlk.skadnetwork + + + SKAdNetworkIdentifier + hs6bdukanm.skadnetwork + + + SKAdNetworkIdentifier + mlmmfzh3r3.skadnetwork + + + SKAdNetworkIdentifier + v4nxqhlyqp.skadnetwork + + + SKAdNetworkIdentifier + wzmmz9fp6w.skadnetwork + + + SKAdNetworkIdentifier + su67r6k2v3.skadnetwork + + + SKAdNetworkIdentifier + yclnxrl5pm.skadnetwork + + + SKAdNetworkIdentifier + t38b2kh725.skadnetwork + + + SKAdNetworkIdentifier + 7ug5zh24hu.skadnetwork + + + SKAdNetworkIdentifier + gta9lk7p23.skadnetwork + + + SKAdNetworkIdentifier + vutu7akeur.skadnetwork + + + SKAdNetworkIdentifier + y5ghdn5j9k.skadnetwork + + + SKAdNetworkIdentifier + v9wttpbfk9.skadnetwork + + + SKAdNetworkIdentifier + n38lu8286q.skadnetwork + + + SKAdNetworkIdentifier + 47vhws6wlr.skadnetwork + + + SKAdNetworkIdentifier + kbd757ywx3.skadnetwork + + + SKAdNetworkIdentifier + 9t245vhmpl.skadnetwork + + + SKAdNetworkIdentifier + a2p9lx4jpn.skadnetwork + + + SKAdNetworkIdentifier + 22mmun2rn5.skadnetwork + + + SKAdNetworkIdentifier + 44jx6755aq.skadnetwork + + + SKAdNetworkIdentifier + k674qkevps.skadnetwork + + + SKAdNetworkIdentifier + 4468km3ulz.skadnetwork + + + SKAdNetworkIdentifier + 2u9pt9hc89.skadnetwork + + + SKAdNetworkIdentifier + 8s468mfl3y.skadnetwork + + + SKAdNetworkIdentifier + klf5c3l5u5.skadnetwork + + + SKAdNetworkIdentifier + ppxm28t8ap.skadnetwork + + + SKAdNetworkIdentifier + kbmxgpxpgc.skadnetwork + + + SKAdNetworkIdentifier + uw77j35x4d.skadnetwork + + + SKAdNetworkIdentifier + 578prtvx9j.skadnetwork + + + SKAdNetworkIdentifier + 4dzt52r2t5.skadnetwork + + + SKAdNetworkIdentifier + tl55sbb4fm.skadnetwork + + + SKAdNetworkIdentifier + c3frkrj4fj.skadnetwork + + + SKAdNetworkIdentifier + e5fvkxwrpn.skadnetwork + + + SKAdNetworkIdentifier + 8c4e2ghe7u.skadnetwork + + + SKAdNetworkIdentifier + 3rd42ekr43.skadnetwork + + + SKAdNetworkIdentifier + 97r2b46745.skadnetwork + + + SKAdNetworkIdentifier + 3qcr597p9d.skadnetwork + + + + From 2a6df444716f0dbec62e2dd4f71ea1676df02836 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 20 Nov 2025 19:19:40 +0200 Subject: [PATCH 135/169] wip --- cmake/macro_template.cmake | 4 +++- src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/macro_template.cmake b/cmake/macro_template.cmake index a5d03d497d..a5c77ed417 100644 --- a/cmake/macro_template.cmake +++ b/cmake/macro_template.cmake @@ -1049,7 +1049,9 @@ MACRO(ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE FILE_PATH) message(STATUS "Using local SKAdNetworkItems plist file: ${FILE_PATH}") endif() - LIST(APPEND APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS ${FILE_PATH}) + get_filename_component(RESOLVED_FILE_PATH "${FILE_PATH}" ABSOLUTE) + + LIST(APPEND APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS ${RESOLVED_FILE_PATH}) SET(APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS ${APPLICATION_APPLE_SKADNETWORKITEMS_PLISTS} PARENT_SCOPE) ENDMACRO() diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index a505dd54bb..639dae9e85 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -44,7 +44,7 @@ ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.13.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") -ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE("SKAdNetworkItems.plist") +ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE("${CMAKE_CURRENT_SOURCE_DIR}/SKAdNetworkItems.plist") if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) TARGET_LINK_LIBRARIES(${PROJECT_NAME} Python) From fe22b11c66895608a911d19811ea8fa81d5ad2d5 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 20 Nov 2025 19:42:16 +0200 Subject: [PATCH 136/169] wip --- .../iOSUIApplicationDelegate.mm | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index d50d62d399..e2332d11b2 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -255,32 +255,34 @@ - (void)addDidBecomeActiveOperationWithCompletion:(iOSDidBecomeActiveOperationBl } - (void)processNextOperation { - UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; - - if (appState != UIApplicationStateActive) { - return; - } - - iOSDidBecomeActiveOperationBlock operation = nil; - - @synchronized(self.m_didBecomeActiveOperations) { - if (self.m_isProcessingDidBecomeActiveOperation == YES) { - return; - } + [AppleDetail addMainQueueOperation:^{ + UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; - if ([self.m_didBecomeActiveOperations count] == 0) { + if (appState != UIApplicationStateActive) { return; } + + iOSDidBecomeActiveOperationBlock operation = nil; - operation = [self.m_didBecomeActiveOperations firstObject]; - [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; + @synchronized(self.m_didBecomeActiveOperations) { + if (self.m_isProcessingDidBecomeActiveOperation == YES) { + return; + } + + if ([self.m_didBecomeActiveOperations count] == 0) { + return; + } + + operation = [self.m_didBecomeActiveOperations firstObject]; + [self.m_didBecomeActiveOperations removeObjectAtIndex:0]; - self.m_isProcessingDidBecomeActiveOperation = YES; - } - - if (operation != nil) { - [self processOperation:operation]; - } + self.m_isProcessingDidBecomeActiveOperation = YES; + } + + if (operation != nil) { + [self processOperation:operation]; + } + }]; } - (void)processOperation:(iOSDidBecomeActiveOperationBlock)block { From 076b53c2d01be14a368736200752f2c493596b99 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 20 Nov 2025 19:42:35 +0200 Subject: [PATCH 137/169] wip --- src/Plugins/AppleAdMobPlugin/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt index 639dae9e85..d2c0abd858 100644 --- a/src/Plugins/AppleAdMobPlugin/CMakeLists.txt +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -40,7 +40,7 @@ endif() ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB) ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() -ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.13.0") +ADD_MENGINE_COCOAPOD("Google-Mobile-Ads-SDK" "NO-GIT" "12.14.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") From a323e6f6fcb4b6317d8627d7cf6304e27edfcd3e Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 21 Nov 2025 02:29:01 +0200 Subject: [PATCH 138/169] add android AdMob --- gradle/app.gradle | 2 +- .../org/Mengine/Base/MengineAdMediation.java | 1 + .../org/Mengine/Base/MengineAdService.java | 4 +- .../Base/MengineFragmentRemoteConfig.java | 13 +- .../Base/MengineListenerRemoteConfig.java | 2 +- gradle/plugins/AdMob/BannerAd/build.gradle | 11 + .../BannerAd/src/main/AndroidManifest.xml | 7 + .../AdMob/BannerAd/MengineAdMobBannerAd.java | 372 ++++++++++++++ gradle/plugins/AdMob/Core/build.gradle | 11 + .../AdMob/Core/MengineAdMobAdInterface.java | 15 + .../Core/MengineAdMobBannerAdInterface.java | 12 + .../Plugin/AdMob/Core/MengineAdMobBase.java | 303 ++++++++++++ .../MengineAdMobInterstitialAdInterface.java | 12 + .../Core/MengineAdMobPluginInterface.java | 7 + .../Core/MengineAdMobRewardedAdInterface.java | 13 + .../plugins/AdMob/InterstitialAd/build.gradle | 11 + .../src/main/AndroidManifest.xml | 5 + .../MengineAdMobInterstitialAd.java | 312 ++++++++++++ gradle/plugins/AdMob/RewardedAd/build.gradle | 11 + .../RewardedAd/src/main/AndroidManifest.xml | 5 + .../RewardedAd/MengineAdMobRewardedAd.java | 354 ++++++++++++++ gradle/plugins/AdMob/build.gradle | 31 +- .../AdMob/src/main/AndroidManifest.xml | 2 + .../Plugin/AdMob/MengineAdMobPlugin.java | 454 +++++++++++++++++- .../MengineAppLovinMediationInterface.java | 2 +- .../MengineAppLovinNonetBannersInterface.java | 2 +- .../MengineAppLovinMediationAmazon.java | 2 +- .../MengineAppLovinNonetBanners.java | 2 +- .../AppLovin/MengineAppLovinPlugin.java | 6 +- .../Plugin/DataDog/MengineDataDogPlugin.java | 7 +- .../MengineFirebaseRemoteConfigPlugin.java | 7 +- gradle/plugins/GoogleConsent/build.gradle | 4 +- .../MengineGoogleConsentPlugin.java | 26 +- .../src/main/AndroidManifest.xml | 1 - gradle/settings.gradle.kts | 4 + 35 files changed, 2000 insertions(+), 33 deletions(-) create mode 100644 gradle/plugins/AdMob/BannerAd/build.gradle create mode 100644 gradle/plugins/AdMob/BannerAd/src/main/AndroidManifest.xml create mode 100644 gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java create mode 100644 gradle/plugins/AdMob/Core/build.gradle create mode 100644 gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobAdInterface.java create mode 100644 gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBannerAdInterface.java create mode 100644 gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java create mode 100644 gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobInterstitialAdInterface.java create mode 100644 gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobPluginInterface.java create mode 100644 gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobRewardedAdInterface.java create mode 100644 gradle/plugins/AdMob/InterstitialAd/build.gradle create mode 100644 gradle/plugins/AdMob/InterstitialAd/src/main/AndroidManifest.xml create mode 100644 gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java create mode 100644 gradle/plugins/AdMob/RewardedAd/build.gradle create mode 100644 gradle/plugins/AdMob/RewardedAd/src/main/AndroidManifest.xml create mode 100644 gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java diff --git a/gradle/app.gradle b/gradle/app.gradle index eda7369057..da722b2d86 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -769,7 +769,7 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { - buildConfigField "String", "MENGINE_APP_OPTIONS", MENGINE_APP_OPTIONS.empty == false ? "\"MENGINE_APP_OPTIONS\"" : "\"\"" + buildConfigField "String", "MENGINE_APP_OPTIONS", MENGINE_APP_OPTIONS.empty == false ? "\"${MENGINE_APP_OPTIONS}\"" : "\"\"" } } } else { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdMediation.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdMediation.java index 18a2fad6e0..2ac431d49e 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdMediation.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdMediation.java @@ -4,6 +4,7 @@ public class MengineAdMediation { public final static MengineAdMediation ADMEDIATION_APPLOVINMAX = new MengineAdMediation("ADMEDIATION_APPLOVINMAX"); + public final static MengineAdMediation ADMEDIATION_ADMOB = new MengineAdMediation("ADMEDIATION_ADMOB"); private final String m_name; diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java index fc11b511b8..2e79effee2 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdService.java @@ -180,7 +180,7 @@ private void parseAdAppOpenPoint(String adPointName, JSONObject adPointConfig) { } @Override - public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map remoteConfig) { + public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map remoteConfig, @NonNull Map ids) { synchronized (m_syncronizationAdPoints) { m_adInterstitialPoints.clear(); m_adRewardedPoints.clear(); @@ -924,6 +924,8 @@ public void onAdRevenuePaid(@NonNull MengineAdMediation mediation, @NonNull Meng @Override public void onAdShowSuccess(@NonNull MengineAdMediation mediation, @NonNull MengineAdFormat format, String placement) { + placement = Objects.requireNonNullElse(placement, ""); + Map params = Map.of("placement", placement); if (format == MengineAdFormat.ADFORMAT_INTERSTITIAL) { diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentRemoteConfig.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentRemoteConfig.java index 90c2b27c42..977ac05725 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentRemoteConfig.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentRemoteConfig.java @@ -12,6 +12,7 @@ public class MengineFragmentRemoteConfig extends MengineFragment m_configs = new HashMap<>(); + private Map m_ids = new HashMap<>(); private final Object m_syncronizationConfigs = new Object(); MengineFragmentRemoteConfig() { @@ -38,6 +39,12 @@ public Map getRemoteConfigs() { } } + public Map getRemoteConfigIds() { + synchronized (m_syncronizationConfigs) { + return m_ids; + } + } + public JSONObject getRemoteConfigValue(String key) { synchronized (m_syncronizationConfigs) { JSONObject value = m_configs.get(key); @@ -46,15 +53,17 @@ public JSONObject getRemoteConfigValue(String key) { } } - public void remoteConfigFetch(@NonNull Map configs) { + public void remoteConfigFetch(@NonNull Map configs, @NonNull Map ids) { synchronized (m_syncronizationConfigs) { m_configs = configs; + m_ids = ids; } } public void remoteConfigPropagate(boolean updated) { Map configs = this.getRemoteConfigs(); + Map ids = this.getRemoteConfigIds(); - this.propagate(MengineListenerRemoteConfig::onMengineRemoteConfigFetch, updated, configs); + this.propagate(MengineListenerRemoteConfig::onMengineRemoteConfigFetch, updated, configs, ids); } } \ No newline at end of file diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineListenerRemoteConfig.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineListenerRemoteConfig.java index fea05d4a76..e4dde50150 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineListenerRemoteConfig.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineListenerRemoteConfig.java @@ -7,5 +7,5 @@ import java.util.Map; public interface MengineListenerRemoteConfig extends MengineServiceInterface { - void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs); + void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids); } \ No newline at end of file diff --git a/gradle/plugins/AdMob/BannerAd/build.gradle b/gradle/plugins/AdMob/BannerAd/build.gradle new file mode 100644 index 0000000000..93af0c5fa0 --- /dev/null +++ b/gradle/plugins/AdMob/BannerAd/build.gradle @@ -0,0 +1,11 @@ +apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' +apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' + +android { + namespace "org.Mengine.Plugin.AdMob.BannerAd" +} + +dependencies { + implementation project(':plugins:AdMob:Core') +} + diff --git a/gradle/plugins/AdMob/BannerAd/src/main/AndroidManifest.xml b/gradle/plugins/AdMob/BannerAd/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..ed24b4a08c --- /dev/null +++ b/gradle/plugins/AdMob/BannerAd/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java new file mode 100644 index 0000000000..bf3f8f23c7 --- /dev/null +++ b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java @@ -0,0 +1,372 @@ +package org.Mengine.Plugin.AdMob.BannerAd; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.RelativeLayout; +import android.graphics.Color; + +import androidx.annotation.NonNull; +import androidx.annotation.Size; +import androidx.annotation.StringRes; + +import com.google.android.gms.ads.AdError; +import com.google.android.gms.ads.AdListener; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdSize; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.OnPaidEventListener; +import com.google.android.gms.ads.ResponseInfo; + +import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdFormat; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; +import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineNative; +import org.Mengine.Base.MengineNetwork; +import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Base.MengineUtils; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobBannerAdInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobBase; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobPluginInterface; + +import java.util.Map; + +public class MengineAdMobBannerAd extends MengineAdMobBase implements MengineAdMobBannerAdInterface, OnPaidEventListener { + public static final @StringRes int METADATA_BANNER_PLACEMENT = R.string.mengine_admob_banner_placement; + public static final @StringRes int METADATA_BANNER_ADUNITID = R.string.mengine_admob_banner_adunitid; + + protected final String m_placement; + + protected AdView m_adView; + + protected volatile boolean m_visible = false; + protected volatile boolean m_loaded = false; + + public MengineAdMobBannerAd(@NonNull MengineAdService adService, @NonNull MengineAdMobPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin); + + this.setAdUnitId(METADATA_BANNER_ADUNITID, "BannerAdUnitId"); + + String MengineAdMobPlugin_Banner_Placement = plugin.getResourceString(METADATA_BANNER_PLACEMENT); + + m_placement = MengineAdMobPlugin_Banner_Placement; + } + + protected AdSize getBannerSize(@NonNull MengineActivity activity) { + AdSize adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(activity, 320); + + return adSize; + } + + protected MengineAnalyticsEventBuilderInterface buildBannerAdEvent(@Size(min = 1L, max = 40L) String event) { + MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_admob_banner_" + event) + .addParameterString("placement", m_placement); + + return builder; + } + + protected void setBannerState(@NonNull String state) { + this.setState("admob.banner.state." + m_adUnitId, state); + } + + public int getWidthPx() { + MengineActivity activity = m_plugin.getMengineActivity(); + + if (m_adView == null || activity == null) { + return 0; + } + + AdSize adSize = m_adView.getAdSize(); + + if (adSize == null) { + return 0; + } + + int widthPx = adSize.getWidthInPixels(activity); + + return widthPx; + } + + public int getHeightPx() { + MengineActivity activity = m_plugin.getMengineActivity(); + + if (m_adView == null || activity == null) { + return 0; + } + + AdSize adSize = m_adView.getAdSize(); + + if (adSize == null) { + return 0; + } + + int heightPx = adSize.getHeightInPixels(activity); + + return heightPx; + } + + @Override + public void onActivityCreate(@NonNull MengineActivity activity) { + super.onActivityCreate(activity); + + AdSize adSize = this.getBannerSize(activity); + + AdView adView = new AdView(activity); + adView.setAdUnitId(m_adUnitId); + adView.setAdSize(adSize); + + adView.setAdListener(new AdListener() { + @Override + public void onAdLoaded() { + m_loaded = true; + + MengineAdMobBannerAd.this.log("onAdLoaded"); + + MengineAdMobBannerAd.this.buildBannerAdEvent("loaded") + .log(); + + m_requestAttempt = 0; + + MengineAdMobBannerAd.this.setBannerState("loaded." + m_placement); + + if (m_visible == true) { + if (m_adView != null) { + MengineAdMobBannerAd.this.enableAdView(m_adView); + } + } + } + + @Override + public void onAdOpened() { + MengineAdMobBannerAd.this.log("onAdOpened"); + + MengineAdMobBannerAd.this.buildBannerAdEvent("opened") + .log(); + + MengineAdMobBannerAd.this.setBannerState("opened." + m_placement); + } + + @Override + public void onAdClosed() { + MengineAdMobBannerAd.this.log("onAdClosed"); + + MengineAdMobBannerAd.this.buildBannerAdEvent("closed") + .log(); + + MengineAdMobBannerAd.this.setBannerState("closed." + m_placement); + } + + @Override + public void onAdClicked() { + MengineAdMobBannerAd.this.log("onAdClicked"); + + MengineAdMobBannerAd.this.buildBannerAdEvent("clicked") + .log(); + + MengineAdMobBannerAd.this.setBannerState("clicked." + m_placement); + } + + @Override + public void onAdImpression() { + MengineAdMobBannerAd.this.log("onAdImpression"); + + MengineAdMobBannerAd.this.buildBannerAdEvent("impression") + .log(); + + MengineAdMobBannerAd.this.setBannerState("impression." + m_placement); + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError error) { + MengineAdMobBannerAd.this.logLoadAdError("onAdFailedToLoad", error); + + int errorCode = error.getCode(); + + MengineAdMobBannerAd.this.buildBannerAdEvent("load_failed") + .addParameterJSON("error", MengineAdMobBannerAd.this.getLoadAdErrorParams(error)) + .addParameterLong("error_code", errorCode) + .log(); + + m_requestAttempt++; + + MengineAdMobBannerAd.this.setBannerState("load_failed." + m_placement + "." + errorCode); + + if (m_visible == true) { + if (m_adView != null) { + MengineAdMobBannerAd.this.disableAdView(m_adView); + } + } + + MengineAdMobBannerAd.this.retryLoadAd(); + } + }); + adView.setOnPaidEventListener(this); + + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + + adView.setLayoutParams(params); + + adView.setVisibility(View.GONE); + adView.setBackgroundColor(Color.TRANSPARENT); + + m_adView = adView; + + int widthDp = adSize.getWidth(); + int heightDp = adSize.getHeight(); + + this.log("create", Map.of("placement", m_placement, "width", widthDp, "height", heightDp)); + + this.setBannerState("init." + m_placement); + + this.loadAd(); + + ViewGroup viewGroup = activity.getContentViewGroup(); + + viewGroup.addView(m_adView); + } + + @Override + public void onActivityDestroy(@NonNull MengineActivity activity) { + super.onActivityDestroy(activity); + + if (m_adView != null) { + m_adView.setAdListener(null); + m_adView.setOnPaidEventListener(null); + + ViewGroup viewGroup = activity.getContentViewGroup(); + viewGroup.removeView(m_adView); + + m_adView.destroy(); + m_adView = null; + } + } + + @Override + public void loadAd() { + if (m_adView == null) { + return; + } + + if (m_plugin.hasOption("admob.banner.disable") == true || m_plugin.hasOption("admob.ad.disable") == true) { + return; + } + + this.increaseRequestId(); + + this.log("loadAd"); + + this.buildBannerAdEvent("load") + .log(); + + this.setBannerState("load"); + + try { + AdRequest adRequest = new AdRequest.Builder().build(); + m_adView.loadAd(adRequest); + } catch (final Exception e) { + m_plugin.logError("[Banner] loadAd adUnitId: %s exception: %s" + , m_adUnitId + , e.getMessage() + ); + + this.buildBannerAdEvent("load_exception") + .addParameterException("exception", e) + .log(); + + this.setBannerState("load_exception"); + + this.retryLoadAd(); + } + } + + protected void enableAdView(@NonNull AdView adView) { + if (adView.getVisibility() == View.VISIBLE) { + return; + } + + if (m_plugin.hasOption("admob.banner.disable") == true || m_plugin.hasOption("admob.ad.disable") == true) { + return; + } + + m_plugin.logInfo("[Banner] show adView: %s", m_adUnitId); + + adView.setVisibility(View.VISIBLE); + adView.requestLayout(); + } + + protected void disableAdView(@NonNull AdView adView) { + if (adView.getVisibility() == View.GONE) { + return; + } + + if (m_plugin.hasOption("admob.banner.disable") == true || m_plugin.hasOption("admob.ad.disable") == true) { + return; + } + + m_plugin.logInfo("[Banner] hide adView: %s", m_adUnitId); + + adView.setVisibility(View.GONE); + adView.requestLayout(); + } + + private void updateVisible() { + this.log("updateVisible", Map.of("show", m_visible)); + + if (m_visible == true) { + if (m_adView != null && m_loaded == true) { + this.enableAdView(m_adView); + } + } else { + if (m_adView != null) { + this.disableAdView(m_adView); + } + } + } + + public boolean canYouShow() { + return m_loaded; + } + + public void show() { + MengineUtils.performOnMainThread(() -> { + if (m_visible == true) { + return; + } + + m_visible = true; + + this.updateVisible(); + }); + } + + public void hide() { + MengineUtils.performOnMainThread(() -> { + if (m_visible == false) { + return; + } + + m_visible = false; + + this.updateVisible(); + }); + } + + + @Override + public void onPaidEvent(@NonNull com.google.android.gms.ads.AdValue adValue) { + this.log("onPaidEvent"); + + ResponseInfo responseInfo = m_adView.getResponseInfo(); + + if (responseInfo != null) { + long valueMicros = adValue.getValueMicros(); + double value = valueMicros / 1000000.0; + + this.revenuePaid(responseInfo, MengineAdFormat.ADFORMAT_BANNER, m_placement, value); + } + } +} + diff --git a/gradle/plugins/AdMob/Core/build.gradle b/gradle/plugins/AdMob/Core/build.gradle new file mode 100644 index 0000000000..5d7431817f --- /dev/null +++ b/gradle/plugins/AdMob/Core/build.gradle @@ -0,0 +1,11 @@ +apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' +apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' + +android { + namespace "org.Mengine.Plugin.AdMob.Core" +} + +dependencies { + implementation api('com.google.android.gms:play-services-ads:24.7.0') +} + diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobAdInterface.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobAdInterface.java new file mode 100644 index 0000000000..373829fa0e --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobAdInterface.java @@ -0,0 +1,15 @@ +package org.Mengine.Plugin.AdMob.Core; + +import androidx.annotation.NonNull; + +import org.Mengine.Base.MengineActivity; + +public interface MengineAdMobAdInterface { + String getAdUnitId(); + + void onActivityCreate(@NonNull MengineActivity activity); + void onActivityDestroy(@NonNull MengineActivity activity); + + void loadAd(); +} + diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBannerAdInterface.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBannerAdInterface.java new file mode 100644 index 0000000000..ad35688a2b --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBannerAdInterface.java @@ -0,0 +1,12 @@ +package org.Mengine.Plugin.AdMob.Core; + +public interface MengineAdMobBannerAdInterface extends MengineAdMobAdInterface { + int getWidthPx(); + int getHeightPx(); + + boolean canYouShow(); + + void show(); + void hide(); +} + diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java new file mode 100644 index 0000000000..b2b4fb1eca --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java @@ -0,0 +1,303 @@ +package org.Mengine.Plugin.AdMob.Core; + +import androidx.annotation.NonNull; +import androidx.annotation.Size; +import androidx.annotation.StringRes; + +import com.google.android.gms.ads.AdError; +import com.google.android.gms.ads.AdListener; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.ResponseInfo; + +import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdFormat; +import org.Mengine.Base.MengineAdMediation; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; +import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineFragmentAdRevenue; +import org.Mengine.Base.MengineLog; +import org.Mengine.Base.MengineParamAdRevenue; +import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Base.MengineUtils; + +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class MengineAdMobBase extends AdListener implements MengineAdMobAdInterface { + protected final MengineAdService m_adService; + protected final MengineAdMobPluginInterface m_plugin; + + protected String m_adUnitId; + + protected int m_enumeratorRequest; + protected int m_requestId; + protected int m_requestAttempt; + protected long m_requestTimestamp; + + public MengineAdMobBase(@NonNull MengineAdService adService, @NonNull MengineAdMobPluginInterface plugin) { + m_adService = adService; + m_plugin = plugin; + + m_enumeratorRequest = 0; + m_requestId = 0; + m_requestAttempt = 0; + m_requestTimestamp = 0; + } + + @NonNull + public MengineAdMobPluginInterface getPlugin() { + return m_plugin; + } + + protected void setAdUnitId(@StringRes int METADATA_ADUNITID, @NonNull String configAdUnitId) throws MengineServiceInvalidInitializeException { + String metadataAdUnitId = m_plugin.getResourceString(METADATA_ADUNITID); + + if (metadataAdUnitId.isEmpty() == true) { + this.invalidInitialize("meta %s not found" + , m_plugin.getResourceName(METADATA_ADUNITID) + ); + } + + String adUnitId = m_plugin.getServiceConfigOptString(configAdUnitId, metadataAdUnitId); + + if (adUnitId == null) { + this.invalidInitialize("config %s is empty" + , configAdUnitId + ); + } + + m_adUnitId = adUnitId; + } + + @Override + public String getAdUnitId() { + return m_adUnitId; + } + + @Override + public void onActivityCreate(@NonNull MengineActivity activity) { + //Empty + } + + @Override + public void onActivityDestroy(@NonNull MengineActivity activity) { + //Empty + } + + public void loadAd() { + // Empty + } + + protected void retryLoadAd() { + m_requestAttempt++; + + long duration = (long) Math.pow(2, Math.min(6, m_requestAttempt)); + long delayMillis = TimeUnit.SECONDS.toMillis(duration); + + MengineUtils.performOnMainThreadDelayed(() -> { + this.loadAd(); + }, delayMillis); + } + + protected int increaseRequestId() { + m_requestId = m_enumeratorRequest++; + m_requestTimestamp = MengineUtils.getTimestamp(); + + return m_requestId; + } + + protected long getRequestTime() { + long timestamp = MengineUtils.getTimestamp(); + long requestTime = timestamp - m_requestTimestamp; + + return requestTime; + } + + protected String getAdErrorParams(@NonNull AdError error) { + StringBuilder sb = new StringBuilder(512); + + int code = error.getCode(); + String message = error.getMessage(); + String domain = error.getDomain(); + + sb.append("{"); + sb.append(String.format(Locale.US, "\"code\": %d", code)); + sb.append(String.format(Locale.US, ", \"message\": \"%s\"", message)); + sb.append(String.format(Locale.US, ", \"domain\": \"%s\"", domain)); + + sb.append("}"); + + String params = sb.toString(); + + return params; + } + + protected String getLoadAdErrorParams(@NonNull LoadAdError error) { + StringBuilder sb = new StringBuilder(512); + + int code = error.getCode(); + String message = error.getMessage(); + String domain = error.getDomain(); + + sb.append("{"); + sb.append(String.format(Locale.US, "\"code\": %d", code)); + sb.append(String.format(Locale.US, ", \"message\": \"%s\"", message)); + sb.append(String.format(Locale.US, ", \"domain\": \"%s\"", domain)); + + ResponseInfo responseInfo = error.getResponseInfo(); + if (responseInfo != null) { + String responseId = responseInfo.getResponseId(); + if (responseId != null) { + sb.append(String.format(Locale.US, ", \"response_id\": \"%s\"", responseId)); + } + } + + sb.append("}"); + + String params = sb.toString(); + + return params; + } + + protected void setState(@NonNull @Size(min = 1L, max = 1024L) String name, Object value) { + m_plugin.setState(name, value); + } + + protected MengineAnalyticsEventBuilderInterface buildAdEvent(@Size(min = 1L, max = 40L) String name) { + long requestTime = this.getRequestTime(); + + MengineAnalyticsEventBuilderInterface eventBuilder = m_plugin.buildEvent(name); + + eventBuilder.addParameterString("ad_unit_id", m_adUnitId); + eventBuilder.addParameterLong("request_id", m_requestId); + eventBuilder.addParameterLong("request_time", requestTime); + eventBuilder.addParameterLong("request_attempt", m_requestAttempt); + + return eventBuilder; + } + + protected void log(String callback) { + this.log(callback, null); + } + + protected void log(String callback, Map params) { + StringBuilder sb = new StringBuilder(512); + + sb.append(String.format(Locale.US, "[AdMob] %s ", callback)); + + this.writeParams(sb, params); + this.writeBaseInfo(sb); + + sb.setLength(sb.length() - 1); //remove last ' ' + + String message = sb.toString(); + + m_plugin.logInfo("%s", message); + } + + protected void logError(String callback, Exception e) { + StringBuilder sb = new StringBuilder(1024); + + sb.append(String.format(Locale.US, "[AdMob] %s exception: %s ", callback, e.getMessage())); + + this.writeBaseInfo(sb); + + sb.setLength(sb.length() - 1); //remove last ' ' + + String message = sb.toString(); + + m_plugin.logError("%s", message); + } + + protected void logAdError(String callback, @NonNull AdError error) { + StringBuilder sb = new StringBuilder(1024); + + sb.append(String.format(Locale.US, "[AdMob] %s ", callback)); + + this.writeBaseInfo(sb); + + int errorCode = error.getCode(); + String errorMessage = error.getMessage(); + String errorDomain = error.getDomain(); + + sb.append(String.format(Locale.US, "AdError: code: %d message: %s domain: %s ", errorCode, errorMessage, errorDomain)); + + sb.setLength(sb.length() - 1); //remove last ' ' + + String message = sb.toString(); + + m_plugin.logInfo("%s", message); + } + + protected void logLoadAdError(String callback, @NonNull LoadAdError error) { + StringBuilder sb = new StringBuilder(1024); + + sb.append(String.format(Locale.US, "[AdMob] %s ", callback)); + + this.writeBaseInfo(sb); + + int errorCode = error.getCode(); + String errorMessage = error.getMessage(); + String errorDomain = error.getDomain(); + + sb.append(String.format(Locale.US, "LoadAdError: code: %d message: %s domain: %s ", errorCode, errorMessage, errorDomain)); + + sb.setLength(sb.length() - 1); //remove last ' ' + + String message = sb.toString(); + + m_plugin.logInfo("%s", message); + } + + protected void writeParams(StringBuilder sb, Map params) { + if (params == null) { + return; + } + + sb.append(String.format(Locale.US, "%s ", params)); + } + + protected void writeBaseInfo(StringBuilder sb) { + long requestTime = this.getRequestTime(); + + sb.append(String.format(Locale.US, "AdUnitId: %s ", m_adUnitId)); + sb.append(String.format(Locale.US, "RequestId: %d ", m_requestId)); + sb.append(String.format(Locale.US, "RequestTime: %d ", requestTime)); + sb.append(String.format(Locale.US, "RetryAttempt: %d ", m_requestAttempt)); + } + + protected void revenuePaid(@NonNull ResponseInfo responseInfo, @NonNull MengineAdFormat adFormat, String placement, double revenueValue) { + MengineAdMediation mediation = MengineAdMediation.ADMEDIATION_ADMOB; + String networkName = "AdMob"; + String adUnitId = m_adUnitId; + + MengineParamAdRevenue revenue = new MengineParamAdRevenue(); + revenue.ADREVENUE_MEDIATION = mediation; + revenue.ADREVENUE_FORMAT = adFormat; + revenue.ADREVENUE_ADUNITID = adUnitId; + revenue.ADREVENUE_PLACEMENT = placement; + revenue.ADREVENUE_NETWORK = networkName; + revenue.ADREVENUE_REVENUE_PRECISION = "publisher_defined"; + revenue.ADREVENUE_REVENUE_VALUE = revenueValue; + revenue.ADREVENUE_REVENUE_CURRENCY = "USD"; + + MengineFragmentAdRevenue.INSTANCE.adRevenue(revenue); + + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdRevenuePaid(mediation, adFormat, placement, revenueValue); + } + + protected void invalidInitialize(String format, Object ... args) throws MengineServiceInvalidInitializeException { + String serviceName = m_plugin.getServiceName(); + + this.setState("invalid.service", serviceName); + + String message = MengineLog.buildTotalMsg(format, args); + + throw new MengineServiceInvalidInitializeException(message); + } +} + diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobInterstitialAdInterface.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobInterstitialAdInterface.java new file mode 100644 index 0000000000..5f3983a1f2 --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobInterstitialAdInterface.java @@ -0,0 +1,12 @@ +package org.Mengine.Plugin.AdMob.Core; + +import androidx.annotation.NonNull; + +import org.Mengine.Base.MengineActivity; + +public interface MengineAdMobInterstitialAdInterface extends MengineAdMobAdInterface { + boolean canYouShowInterstitial(String placement); + boolean showInterstitial(@NonNull MengineActivity activity, String placement); + boolean isShowingInterstitial(); +} + diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobPluginInterface.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobPluginInterface.java new file mode 100644 index 0000000000..5e29741b1d --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobPluginInterface.java @@ -0,0 +1,7 @@ +package org.Mengine.Plugin.AdMob.Core; + +import org.Mengine.Base.MengineServiceInterface; + +public interface MengineAdMobPluginInterface extends MengineServiceInterface { +} + diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobRewardedAdInterface.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobRewardedAdInterface.java new file mode 100644 index 0000000000..831efabb6e --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobRewardedAdInterface.java @@ -0,0 +1,13 @@ +package org.Mengine.Plugin.AdMob.Core; + +import androidx.annotation.NonNull; + +import org.Mengine.Base.MengineActivity; + +public interface MengineAdMobRewardedAdInterface extends MengineAdMobAdInterface { + boolean canOfferRewarded(String placement); + boolean canYouShowRewarded(String placement); + boolean showRewarded(@NonNull MengineActivity activity, String placement); + boolean isShowingRewarded(); +} + diff --git a/gradle/plugins/AdMob/InterstitialAd/build.gradle b/gradle/plugins/AdMob/InterstitialAd/build.gradle new file mode 100644 index 0000000000..cb7c0ff23a --- /dev/null +++ b/gradle/plugins/AdMob/InterstitialAd/build.gradle @@ -0,0 +1,11 @@ +apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' +apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' + +android { + namespace "org.Mengine.Plugin.AdMob.InterstitialAd" +} + +dependencies { + implementation project(':plugins:AdMob:Core') +} + diff --git a/gradle/plugins/AdMob/InterstitialAd/src/main/AndroidManifest.xml b/gradle/plugins/AdMob/InterstitialAd/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..f9a0d0ddcc --- /dev/null +++ b/gradle/plugins/AdMob/InterstitialAd/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + diff --git a/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java b/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java new file mode 100644 index 0000000000..beb16a0bea --- /dev/null +++ b/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java @@ -0,0 +1,312 @@ +package org.Mengine.Plugin.AdMob.InterstitialAd; + +import androidx.annotation.NonNull; +import androidx.annotation.Size; +import androidx.annotation.StringRes; + +import com.google.android.gms.ads.AdError; +import com.google.android.gms.ads.AdListener; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.FullScreenContentCallback; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.OnPaidEventListener; +import com.google.android.gms.ads.ResponseInfo; +import com.google.android.gms.ads.interstitial.InterstitialAd; +import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback; + +import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdFormat; +import org.Mengine.Base.MengineAdMediation; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; +import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineNative; +import org.Mengine.Base.MengineNetwork; +import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Base.MengineUtils; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobBase; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobInterstitialAdInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobPluginInterface; + +import java.util.Map; + +public class MengineAdMobInterstitialAd extends MengineAdMobBase implements MengineAdMobInterstitialAdInterface { + public static final @StringRes int METADATA_INTERSTITIAL_ADUNITID = R.string.mengine_admob_interstitial_adunitid; + + private InterstitialAd m_interstitialAd; + private OnPaidEventListener m_onPaidEventListener; + + private boolean m_showing = false; + + public MengineAdMobInterstitialAd(@NonNull MengineAdService adService, @NonNull MengineAdMobPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin); + + this.setAdUnitId(METADATA_INTERSTITIAL_ADUNITID, "InterstitialAdUnitId"); + } + + protected MengineAnalyticsEventBuilderInterface buildInterstitialAdEvent(@Size(min = 1L, max = 40L) String event) { + MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_admob_interstitial_" + event); + + return builder; + } + + protected void setInterstitialState(@NonNull String state) { + this.setState("admob.interstitial.state." + m_adUnitId, state); + } + + @Override + public void onActivityCreate(@NonNull MengineActivity activity) { + super.onActivityCreate(activity); + + this.log("create"); + + this.setInterstitialState("init"); + + this.loadAd(); + } + + @Override + public void onActivityDestroy(@NonNull MengineActivity activity) { + super.onActivityDestroy(activity); + + if (m_interstitialAd != null) { + m_interstitialAd.setFullScreenContentCallback(null); + m_interstitialAd.setOnPaidEventListener(null); + + m_interstitialAd = null; + } + } + + @Override + public void loadAd() { + if (m_plugin.hasOption("admob.interstitial.disable") == true || m_plugin.hasOption("admob.ad.disable") == true) { + return; + } + + this.increaseRequestId(); + + this.log("loadAd"); + + this.buildInterstitialAdEvent("load") + .log(); + + this.setInterstitialState("load"); + + MengineActivity activity = m_plugin.getMengineActivity(); + + if (activity == null) { + return; + } + + try { + AdRequest adRequest = new AdRequest.Builder().build(); + + InterstitialAd.load(activity, m_adUnitId, adRequest, new InterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + m_interstitialAd = interstitialAd; + + m_interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() { + @Override + public void onAdDismissedFullScreenContent() { + m_interstitialAd = null; + + MengineAdMobInterstitialAd.this.log("onAdDismissedFullScreenContent"); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("dismissed") + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("dismissed"); + + MengineNative.AndroidPlatform_unfreezeEvent(true, true); + + m_showing = false; + + MengineUtils.performOnMainThread(() -> { + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_INTERSTITIAL, null); + + MengineAdMobInterstitialAd.this.loadAd(); + }); + } + + @Override + public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) { + m_interstitialAd = null; + + MengineAdMobInterstitialAd.this.logAdError("onAdFailedToShowFullScreenContent", adError); + + int errorCode = adError.getCode(); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("show_failed") + .addParameterJSON("error", MengineAdMobInterstitialAd.this.getAdErrorParams(adError)) + .addParameterLong("error_code", errorCode) + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("show_failed." + errorCode); + + m_showing = false; + + MengineUtils.performOnMainThread(() -> { + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_INTERSTITIAL, null, errorCode); + + MengineAdMobInterstitialAd.this.loadAd(); + }); + } + + @Override + public void onAdShowedFullScreenContent() { + MengineAdMobInterstitialAd.this.log("onAdShowedFullScreenContent"); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("showed") + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("showed"); + + MengineNative.AndroidPlatform_freezeEvent(true, true); + } + + @Override + public void onAdClicked() { + MengineAdMobInterstitialAd.this.log("onAdClicked"); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("clicked") + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("clicked"); + } + + @Override + public void onAdImpression() { + MengineAdMobInterstitialAd.this.log("onAdImpression"); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("impression") + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("impression"); + } + }); + + m_interstitialAd.setOnPaidEventListener(adValue -> { + MengineAdMobInterstitialAd.this.log("onPaidEvent"); + + if (m_interstitialAd != null) { + ResponseInfo responseInfo = m_interstitialAd.getResponseInfo(); + + if (responseInfo != null) { + long valueMicros = adValue.getValueMicros(); + double value = valueMicros / 1000000.0; + + MengineAdMobInterstitialAd.this.revenuePaid(responseInfo, MengineAdFormat.ADFORMAT_INTERSTITIAL, null, value); + } + } + }); + + MengineAdMobInterstitialAd.this.log("onAdLoaded"); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("loaded") + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("loaded"); + + m_requestAttempt = 0; + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + m_interstitialAd = null; + + MengineAdMobInterstitialAd.this.logLoadAdError("onAdFailedToLoad", loadAdError); + + int errorCode = loadAdError.getCode(); + + MengineAdMobInterstitialAd.this.buildInterstitialAdEvent("load_failed") + .addParameterJSON("error", MengineAdMobInterstitialAd.this.getLoadAdErrorParams(loadAdError)) + .addParameterLong("error_code", errorCode) + .log(); + + MengineAdMobInterstitialAd.this.setInterstitialState("load_failed." + errorCode); + + MengineAdMobInterstitialAd.this.retryLoadAd(); + } + }); + } catch (final Exception e) { + this.logError("loadAd", e); + + this.buildInterstitialAdEvent("load_exception") + .addParameterException("exception", e) + .log(); + + this.setInterstitialState("load_exception"); + + this.retryLoadAd(); + } + } + + public boolean canYouShowInterstitial(String placement) { + if (m_interstitialAd == null) { + return false; + } + + if (MengineNetwork.isNetworkAvailable() == false) { + return false; + } + + boolean ready = m_interstitialAd != null; + + this.log("canYouShowInterstitial", Map.of("placement", placement, "ready", ready)); + + if (ready == false) { + this.buildInterstitialAdEvent("show") + .addParameterString("placement", placement) + .addParameterBoolean("ready", false) + .log(); + + return false; + } + + return true; + } + + public boolean showInterstitial(@NonNull MengineActivity activity, String placement) { + if (m_interstitialAd == null) { + return false; + } + + if (MengineNetwork.isNetworkAvailable() == false) { + return false; + } + + boolean ready = m_interstitialAd != null; + + this.log("showInterstitial", Map.of("placement", placement, "ready", ready)); + + this.buildInterstitialAdEvent("show") + .addParameterString("placement", placement) + .addParameterBoolean("ready", ready) + .log(); + + if (ready == false) { + return false; + } + + m_showing = true; + + MengineUtils.performOnMainThread(() -> { + if (m_interstitialAd != null) { + m_interstitialAd.show(activity); + } + }); + + return true; + } + + @Override + public boolean isShowingInterstitial() { + return m_showing; + } +} + diff --git a/gradle/plugins/AdMob/RewardedAd/build.gradle b/gradle/plugins/AdMob/RewardedAd/build.gradle new file mode 100644 index 0000000000..d4588bbeb0 --- /dev/null +++ b/gradle/plugins/AdMob/RewardedAd/build.gradle @@ -0,0 +1,11 @@ +apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' +apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' + +android { + namespace "org.Mengine.Plugin.AdMob.RewardedAd" +} + +dependencies { + implementation project(':plugins:AdMob:Core') +} + diff --git a/gradle/plugins/AdMob/RewardedAd/src/main/AndroidManifest.xml b/gradle/plugins/AdMob/RewardedAd/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..f9a0d0ddcc --- /dev/null +++ b/gradle/plugins/AdMob/RewardedAd/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + diff --git a/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java b/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java new file mode 100644 index 0000000000..406f1322dc --- /dev/null +++ b/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java @@ -0,0 +1,354 @@ +package org.Mengine.Plugin.AdMob.RewardedAd; + +import androidx.annotation.NonNull; +import androidx.annotation.Size; +import androidx.annotation.StringRes; + +import com.google.android.gms.ads.AdError; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.FullScreenContentCallback; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.OnPaidEventListener; +import com.google.android.gms.ads.OnUserEarnedRewardListener; +import com.google.android.gms.ads.ResponseInfo; +import com.google.android.gms.ads.rewarded.RewardItem; +import com.google.android.gms.ads.rewarded.RewardedAd; +import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback; + +import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdFormat; +import org.Mengine.Base.MengineAdMediation; +import org.Mengine.Base.MengineAdResponseInterface; +import org.Mengine.Base.MengineAdService; +import org.Mengine.Base.MengineAnalyticsEventBuilderInterface; +import org.Mengine.Base.MengineNative; +import org.Mengine.Base.MengineNetwork; +import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Base.MengineUtils; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobBase; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobPluginInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobRewardedAdInterface; + +import java.util.Map; + +public class MengineAdMobRewardedAd extends MengineAdMobBase implements MengineAdMobRewardedAdInterface { + public static final @StringRes int METADATA_REWARDED_ADUNITID = R.string.mengine_admob_rewarded_adunitid; + + private RewardedAd m_rewardedAd; + + private boolean m_showing = false; + + public MengineAdMobRewardedAd(@NonNull MengineAdService adService, @NonNull MengineAdMobPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin); + + this.setAdUnitId(METADATA_REWARDED_ADUNITID, "RewardedAdUnitId"); + } + + protected MengineAnalyticsEventBuilderInterface buildRewardedAdEvent(@Size(min = 1L, max = 40L) String event) { + MengineAnalyticsEventBuilderInterface builder = this.buildAdEvent("mng_admob_rewarded_" + event); + + return builder; + } + + protected void setRewardedState(@NonNull String state) { + this.setState("admob.rewarded.state." + m_adUnitId, state); + } + + @Override + public void onActivityCreate(@NonNull MengineActivity activity) { + super.onActivityCreate(activity); + + this.log("create"); + + this.setRewardedState("init"); + + this.loadAd(); + } + + @Override + public void onActivityDestroy(@NonNull MengineActivity activity) { + super.onActivityDestroy(activity); + + if (m_rewardedAd != null) { + m_rewardedAd.setFullScreenContentCallback(null); + m_rewardedAd.setOnPaidEventListener(null); + + m_rewardedAd = null; + } + } + + @Override + public void loadAd() { + if (m_plugin.hasOption("admob.rewarded.disable") == true || m_plugin.hasOption("admob.ad.disable") == true) { + return; + } + + this.log("loadAd"); + + this.increaseRequestId(); + + this.buildRewardedAdEvent("load") + .log(); + + this.setRewardedState("load"); + + MengineActivity activity = m_plugin.getMengineActivity(); + + if (activity == null) { + return; + } + + try { + AdRequest adRequest = new AdRequest.Builder().build(); + + RewardedAd.load(activity, m_adUnitId, adRequest, new RewardedAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull RewardedAd rewardedAd) { + m_rewardedAd = rewardedAd; + + m_rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() { + @Override + public void onAdDismissedFullScreenContent() { + m_rewardedAd = null; + + MengineAdMobRewardedAd.this.log("onAdDismissedFullScreenContent"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("dismissed") + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("dismissed"); + + MengineNative.AndroidPlatform_unfreezeEvent(true, true); + + m_showing = false; + + MengineUtils.performOnMainThread(() -> { + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowSuccess(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_REWARDED, null); + + MengineAdMobRewardedAd.this.loadAd(); + }); + } + + @Override + public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) { + m_rewardedAd = null; + + MengineAdMobRewardedAd.this.logAdError("onAdFailedToShowFullScreenContent", adError); + + int errorCode = adError.getCode(); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("show_failed") + .addParameterJSON("error", MengineAdMobRewardedAd.this.getAdErrorParams(adError)) + .addParameterLong("error_code", errorCode) + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("show_failed." + errorCode); + + m_showing = false; + + MengineUtils.performOnMainThread(() -> { + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdShowFailed(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_REWARDED, null, errorCode); + + MengineAdMobRewardedAd.this.loadAd(); + }); + } + + @Override + public void onAdShowedFullScreenContent() { + MengineAdMobRewardedAd.this.log("onAdShowedFullScreenContent"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("showed") + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("showed"); + + MengineNative.AndroidPlatform_freezeEvent(true, true); + } + + @Override + public void onAdClicked() { + MengineAdMobRewardedAd.this.log("onAdClicked"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("clicked") + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("clicked"); + } + + @Override + public void onAdImpression() { + MengineAdMobRewardedAd.this.log("onAdImpression"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("impression") + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("impression"); + } + }); + + m_rewardedAd.setOnPaidEventListener(adValue -> { + MengineAdMobRewardedAd.this.log("onPaidEvent"); + + if (m_rewardedAd != null) { + ResponseInfo responseInfo = m_rewardedAd.getResponseInfo(); + + if (responseInfo != null) { + long valueMicros = adValue.getValueMicros(); + double value = valueMicros / 1000000.0; + + MengineAdMobRewardedAd.this.revenuePaid(responseInfo, MengineAdFormat.ADFORMAT_REWARDED, null, value); + } + } + }); + + MengineAdMobRewardedAd.this.log("onAdLoaded"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("loaded") + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("loaded"); + + m_requestAttempt = 0; + } + + @Override + public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { + m_rewardedAd = null; + + MengineAdMobRewardedAd.this.logLoadAdError("onAdFailedToLoad", loadAdError); + + int errorCode = loadAdError.getCode(); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("load_failed") + .addParameterJSON("error", MengineAdMobRewardedAd.this.getLoadAdErrorParams(loadAdError)) + .addParameterLong("error_code", errorCode) + .log(); + + MengineAdMobRewardedAd.this.setRewardedState("load_failed." + errorCode); + + MengineAdMobRewardedAd.this.retryLoadAd(); + } + }); + } catch (final Exception e) { + this.logError("loadAd", e); + + this.buildRewardedAdEvent("load_exception") + .addParameterException("exception", e) + .log(); + + this.setRewardedState("load_exception"); + + this.retryLoadAd(); + } + } + + public boolean canOfferRewarded(String placement) { + if (m_rewardedAd == null) { + return false; + } + + if (MengineNetwork.isNetworkAvailable() == false) { + return false; + } + + boolean ready = m_rewardedAd != null; + + this.log("canOfferRewarded", Map.of("placement", placement, "ready", ready)); + + this.buildRewardedAdEvent("offer") + .addParameterString("placement", placement) + .addParameterBoolean("ready", ready) + .log(); + + if (ready == false) { + return false; + } + + return true; + } + + public boolean canYouShowRewarded(String placement) { + if (m_rewardedAd == null) { + return false; + } + + if (MengineNetwork.isNetworkAvailable() == false) { + return false; + } + + boolean ready = m_rewardedAd != null; + + this.log("canYouShowRewarded", Map.of("placement", placement, "ready", ready)); + + if (ready == false) { + this.buildRewardedAdEvent("show") + .addParameterString("placement", placement) + .addParameterBoolean("ready", false) + .log(); + + return false; + } + + return true; + } + + public boolean showRewarded(@NonNull MengineActivity activity, String placement) { + if (m_rewardedAd == null) { + return false; + } + + if (MengineNetwork.isNetworkAvailable() == false) { + return false; + } + + boolean ready = m_rewardedAd != null; + + this.log("showRewarded", Map.of("placement", placement, "ready", ready)); + + this.buildRewardedAdEvent("show") + .addParameterString("placement", placement) + .addParameterBoolean("ready", ready) + .log(); + + if (ready == false) { + return false; + } + + m_showing = true; + + MengineUtils.performOnMainThread(() -> { + if (m_rewardedAd != null) { + m_rewardedAd.show(activity, new OnUserEarnedRewardListener() { + @Override + public void onUserEarnedReward(@NonNull RewardItem rewardItem) { + String rewardType = rewardItem.getType(); + int rewardAmount = rewardItem.getAmount(); + + MengineAdMobRewardedAd.this.log("onUserEarnedReward"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("user_rewarded") + .addParameterString("reward_type", rewardType) + .addParameterLong("reward_amount", rewardAmount) + .log(); + + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdUserRewarded(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_REWARDED, placement, rewardType, rewardAmount); + } + }); + } + }); + + return true; + } + + @Override + public boolean isShowingRewarded() { + return m_showing; + } +} + diff --git a/gradle/plugins/AdMob/build.gradle b/gradle/plugins/AdMob/build.gradle index cd381584ab..3b2c7f991f 100644 --- a/gradle/plugins/AdMob/build.gradle +++ b/gradle/plugins/AdMob/build.gradle @@ -1,12 +1,39 @@ apply from: rootProject.projectDir.getAbsolutePath() + '/plugins/plugin.gradle' apply from: rootProject.projectDir.getAbsolutePath() + '/gms.gradle' +final Boolean MENGINE_APP_PLUGIN_ADMOB_BANNERAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_ADMOB_BANNERAD") +final Boolean MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD") +final Boolean MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD = Utils.getBooleanAppPluginProperty("MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD") + +Utils.logAvailable("MENGINE_APP_PLUGIN_ADMOB_BANNERAD", MENGINE_APP_PLUGIN_ADMOB_BANNERAD) +Utils.logAvailable("MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD", MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD) +Utils.logAvailable("MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD", MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD) + android { namespace "org.Mengine.Plugin.AdMob" } dependencies { implementation project(':plugins:GoogleService') + implementation project(':plugins:AdMob:Core') + + if (MENGINE_APP_PLUGIN_ADMOB_BANNERAD == true) { + implementation project(':plugins:AdMob:BannerAd') + } + + if (MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD == true) { + implementation project(':plugins:AdMob:InterstitialAd') + } - implementation api('com.google.android.gms:play-services-ads:24.4.0') -} \ No newline at end of file + if (MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD == true) { + implementation project(':plugins:AdMob:RewardedAd') + } +} + +android { + defaultConfig { + buildConfigField "boolean", "MENGINE_APP_PLUGIN_ADMOB_BANNERAD", "${MENGINE_APP_PLUGIN_ADMOB_BANNERAD}" + buildConfigField "boolean", "MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD", "${MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD}" + buildConfigField "boolean", "MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD", "${MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD}" + } +} diff --git a/gradle/plugins/AdMob/src/main/AndroidManifest.xml b/gradle/plugins/AdMob/src/main/AndroidManifest.xml index 2f5e6aab13..144653c0e2 100644 --- a/gradle/plugins/AdMob/src/main/AndroidManifest.xml +++ b/gradle/plugins/AdMob/src/main/AndroidManifest.xml @@ -3,6 +3,8 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + + diff --git a/gradle/plugins/AdMob/src/main/java/org/Mengine/Plugin/AdMob/MengineAdMobPlugin.java b/gradle/plugins/AdMob/src/main/java/org/Mengine/Plugin/AdMob/MengineAdMobPlugin.java index 6792cf0fc5..162d9fcaf0 100644 --- a/gradle/plugins/AdMob/src/main/java/org/Mengine/Plugin/AdMob/MengineAdMobPlugin.java +++ b/gradle/plugins/AdMob/src/main/java/org/Mengine/Plugin/AdMob/MengineAdMobPlugin.java @@ -1,24 +1,468 @@ package org.Mengine.Plugin.AdMob; +import android.os.Bundle; + +import androidx.annotation.BoolRes; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + +import com.google.android.gms.ads.MobileAds; +import com.google.android.gms.ads.VersionInfo; +import com.google.android.gms.ads.initialization.InitializationStatus; +import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; +import org.Mengine.Base.MengineActivity; +import org.Mengine.Base.MengineAdProviderInterface; +import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineApplication; +import org.Mengine.Base.MengineListenerActivity; +import org.Mengine.Base.MengineListenerTransparencyConsent; +import org.Mengine.Base.MengineParamTransparencyConsent; +import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Base.MengineService; import org.Mengine.Base.MengineListenerApplication; -import org.Mengine.Base.MengineServiceInvalidInitializeException; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobAdInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobBannerAdInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobInterstitialAdInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobPluginInterface; +import org.Mengine.Plugin.AdMob.Core.MengineAdMobRewardedAdInterface; -import com.google.android.gms.ads.MobileAds; -import com.google.android.gms.ads.VersionInfo; +import java.util.ArrayList; +import java.util.List; -public class MengineAdMobPlugin extends MengineService implements MengineListenerApplication { +public class MengineAdMobPlugin extends MengineService implements MengineAdMobPluginInterface, MengineAdProviderInterface, MengineListenerApplication, MengineListenerActivity, MengineListenerTransparencyConsent { public static final String SERVICE_NAME = "AdMob"; + public static final boolean SERVICE_EMBEDDING = true; + + private volatile boolean m_adMobSdkInitialized = false; + + private MengineAdMobBannerAdInterface m_bannerAd; + private MengineAdMobInterstitialAdInterface m_interstitialAd; + private MengineAdMobRewardedAdInterface m_rewardedAd; + + private final List m_ads = new ArrayList<>(); + + @SuppressWarnings("unchecked") + protected T createAd(@NonNull MengineAdService adService, @NonNull String className) throws MengineServiceInvalidInitializeException { + T ad = (T)this.newInstance(className, true, adService, this); + + if (ad == null) { + this.invalidInitialize("not found AdMob extension ad: %s" + , className + ); + } + + return ad; + } @Override public void onAppCreate(@NonNull MengineApplication application) throws MengineServiceInvalidInitializeException { + MengineAdService adService = application.getService(MengineAdService.class); + + boolean noAds = adService.getNoAds(); + + if (BuildConfig.MENGINE_APP_PLUGIN_ADMOB_BANNERAD == true && noAds == false) { + m_bannerAd = this.createAd(adService, "org.Mengine.Plugin.AdMob.BannerAd.MengineAdMobBannerAd"); + + m_ads.add(m_bannerAd); + } + + if (BuildConfig.MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD == true && noAds == false) { + m_interstitialAd = this.createAd(adService, "org.Mengine.Plugin.AdMob.InterstitialAd.MengineAdMobInterstitialAd"); + + m_ads.add(m_interstitialAd); + } + + if (BuildConfig.MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD == true) { + m_rewardedAd = this.createAd(adService, "org.Mengine.Plugin.AdMob.RewardedAd.MengineAdMobRewardedAd"); + + m_ads.add(m_rewardedAd); + } + + adService.setAdProvider(this); + } + + @Override + public void onAppTerminate(@NonNull MengineApplication application) { + m_bannerAd = null; + m_interstitialAd = null; + m_rewardedAd = null; + + m_ads.clear(); + } + + @Override + public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceState) throws MengineServiceInvalidInitializeException { + if (m_adMobSdkInitialized == true) { + for (MengineAdMobAdInterface ad : m_ads) { + ad.onActivityCreate(activity); + } + } + } + + @Override + public void onDestroy(@NonNull MengineActivity activity) { + if (m_adMobSdkInitialized == true) { + for (MengineAdMobAdInterface ad : m_ads) { + ad.onActivityDestroy(activity); + } + } + } + + @Override + public boolean hasBanner() { + if (m_bannerAd == null) { + return false; + } + + return true; + } + + @Override + public boolean canYouShowBanner() { + if (m_bannerAd == null) { + return false; + } + + if (m_bannerAd.canYouShow() == false) { + return false; + } + + return true; + } + + @Override + public void showBanner() { + if (m_bannerAd == null) { + this.logWarning("not found banner"); + + return; + } + + this.logInfo("banner show"); + + m_bannerAd.show(); + } + + @Override + public void hideBanner() { + if (m_bannerAd == null) { + this.logWarning("not found banner"); + + return; + } + + this.logInfo("banner hide"); + + m_bannerAd.hide(); + } + + @Override + public int getBannerWidth() { + if (m_bannerAd == null) { + return 0; + } + + int widthPx = m_bannerAd.getWidthPx(); + + return widthPx; + } + + @Override + public int getBannerHeight() { + if (m_bannerAd == null) { + return 0; + } + + int heightPx = m_bannerAd.getHeightPx(); + + return heightPx; + } + + @Override + public boolean hasInterstitial() { + if (m_interstitialAd == null) { + return false; + } + + return true; + } + + @Override + public boolean canYouShowInterstitial(String placement) { + if (m_interstitialAd == null) { + return false; + } + + if (m_interstitialAd.canYouShowInterstitial(placement) == false) { + return false; + } + + return true; + } + + @Override + public boolean showInterstitial(String placement) { + if (m_interstitialAd == null) { + this.logWarning("invalid show unavailable interstitial placement: %s" + , placement + ); + + return false; + } + + MengineActivity activity = this.getMengineActivity(); + + if (activity == null) { + this.logWarning("invalid show interstitial activity is null"); + + return false; + } + + this.logInfo("showInterstitial placement: %s" + , placement + ); + + if (m_interstitialAd.showInterstitial(activity, placement) == false) { + return false; + } + + return true; + } + + @Override + public boolean isShowingInterstitial() { + if (m_interstitialAd == null) { + return false; + } + + return m_interstitialAd.isShowingInterstitial(); + } + + @Override + public boolean hasRewarded() { + if (m_rewardedAd == null) { + return false; + } + + return true; + } + + @Override + public boolean canOfferRewarded(String placement) { + if (m_rewardedAd == null) { + return false; + } + + if (m_rewardedAd.canOfferRewarded(placement) == false) { + return false; + } + + return true; + } + + @Override + public boolean canYouShowRewarded(String placement) { + if (m_rewardedAd == null) { + return false; + } + + if (m_rewardedAd.canYouShowRewarded(placement) == false) { + return false; + } + + return true; + } + + @Override + public boolean showRewarded(String placement) { + if (m_rewardedAd == null) { + this.logWarning("invalid show unavailable rewarded placement: %s" + , placement + ); + + return false; + } + + MengineActivity activity = this.getMengineActivity(); + + if (activity == null) { + this.logWarning("invalid show rewarded activity is null"); + + return false; + } + + this.logInfo("showRewarded placement: %s" + , placement + ); + + if (m_rewardedAd.showRewarded(activity, placement) == false) { + return false; + } + + return true; + } + + @Override + public boolean isShowingRewarded() { + if (m_rewardedAd == null) { + return false; + } + + return m_rewardedAd.isShowingRewarded(); + } + + @Override + public boolean hasAppOpen() { + //TODO + return false; + } + + @Override + public boolean canYouShowAppOpen(String placement, long timeStop) { + //TODO + return false; + } + + @Override + public boolean showAppOpen(String placement) { + //TODO + return false; + } + + @Override + public boolean hasMREC() { + //TODO + return false; + } + + @Override + public boolean canYouShowMREC() { + //TODO + return false; + } + + @Override + public void showMREC(int leftMargin, int topMargin) { + //TODO + } + + @Override + public void hideMREC() { + //TODO + } + + @Override + public int getMRECLeftMargin() { + //TODO + return 0; + } + + @Override + public int getMRECTopMargin() { + //TODO + return 0; + } + + @Override + public int getMRECWidth() { + //TODO + return 0; + } + + @Override + public int getMRECHeight() { + //TODO + return 0; + } + + @Override + public boolean hasNative() { + //TODO + return false; + } + + @Override + public boolean canYouShowNative() { + //TODO + return false; + } + + @Override + public void showNative() { + //TODO + } + + @Override + public void hideNative() { + //TODO + } + + @Override + public int getNativeLeftMargin() { + //TODO + return 0; + } + + @Override + public int getNativeTopMargin() { + //TODO + return 0; + } + + @Override + public int getNativeWidth() { + //TODO + return 0; + } + + @Override + public int getNativeHeight() { + //TODO + return 0; + } + + protected void initializeAdMob(@NonNull MengineApplication application, @NonNull MengineAdService adService) { + if (m_adMobSdkInitialized == true) { + return; + } + VersionInfo admobSdkVersion = MobileAds.getVersion(); String admobSdkVersionString = String.valueOf(admobSdkVersion); - this.logInfo("AdMob SDK version: " + admobSdkVersionString); + this.logInfo("[AdMob SDK] version: %s", admobSdkVersionString); + + MobileAds.initialize(application, new OnInitializationCompleteListener() { + @Override + public void onInitializationComplete(@NonNull InitializationStatus initializationStatus) { + m_adMobSdkInitialized = true; + + MengineActivity activity = MengineAdMobPlugin.this.getMengineActivity(); + + if (activity != null) { + for (MengineAdMobAdInterface ad : m_ads) { + ad.onActivityCreate(activity); + } + } + + adService.readyAdProvider(); + } + }); + } + + @Override + public void onMengineTransparencyConsent(@NonNull MengineApplication application, @NonNull MengineParamTransparencyConsent tcParam) { + if (m_adMobSdkInitialized == true) { + return; + } + + MengineAdService adService = application.getService(MengineAdService.class); + + if (adService == null) { + return; + } + + this.initializeAdMob(application, adService); } } diff --git a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinMediationInterface.java b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinMediationInterface.java index bb79b5dda3..7a9da1310f 100644 --- a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinMediationInterface.java +++ b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinMediationInterface.java @@ -19,7 +19,7 @@ public interface MengineAppLovinMediationInterface { void onAppCreate(@NonNull MengineApplication application, @NonNull MengineAppLovinPluginInterface plugin); void onAppTerminate(@NonNull MengineApplication application, @NonNull MengineAppLovinPluginInterface plugin); - void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs); + void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids); void loadMediatorBanner(@NonNull MengineActivity activity, @NonNull MengineAppLovinPluginInterface plugin, @NonNull MaxAdView adView, MengineAppLovinMediationLoadedCallback loadAdCallback) throws MengineServiceInvalidInitializeException; void loadMediatorInterstitial(@NonNull MengineActivity activity, @NonNull MengineAppLovinPluginInterface plugin, @NonNull MaxInterstitialAd interstitialAd, MengineAppLovinMediationLoadedCallback loadAdCallback) throws MengineServiceInvalidInitializeException; diff --git a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinNonetBannersInterface.java b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinNonetBannersInterface.java index 6ad94d7833..3c0462b9d6 100644 --- a/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinNonetBannersInterface.java +++ b/gradle/plugins/AppLovin/Core/src/main/java/org/Mengine/Plugin/AppLovin/Core/MengineAppLovinNonetBannersInterface.java @@ -13,7 +13,7 @@ public interface MengineAppLovinNonetBannersInterface { void onAppCreate(@NonNull MengineApplication application, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException; void onAppTerminate(@NonNull MengineApplication application, @NonNull MengineAppLovinPluginInterface plugin); - void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs); + void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids); void onActivityCreate(@NonNull MengineActivity activity); void onActivityDestroy(@NonNull MengineActivity activity); diff --git a/gradle/plugins/AppLovin/MediationAmazon/src/main/java/org/Mengine/Plugin/AppLovin/MediationAmazon/MengineAppLovinMediationAmazon.java b/gradle/plugins/AppLovin/MediationAmazon/src/main/java/org/Mengine/Plugin/AppLovin/MediationAmazon/MengineAppLovinMediationAmazon.java index 2ba31d1d09..69923c3ea1 100644 --- a/gradle/plugins/AppLovin/MediationAmazon/src/main/java/org/Mengine/Plugin/AppLovin/MediationAmazon/MengineAppLovinMediationAmazon.java +++ b/gradle/plugins/AppLovin/MediationAmazon/src/main/java/org/Mengine/Plugin/AppLovin/MediationAmazon/MengineAppLovinMediationAmazon.java @@ -62,7 +62,7 @@ public void onAppTerminate(@NonNull MengineApplication application, @NonNull Men } @Override - public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs) { + public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids) { // ToDo } diff --git a/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java b/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java index 92f8b44f0c..3fdd4dc214 100644 --- a/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java +++ b/gradle/plugins/AppLovin/NonetBanners/src/main/java/org/Mengine/Plugin/AppLovin/NonetBanners/MengineAppLovinNonetBanners.java @@ -136,7 +136,7 @@ public void onAppTerminate(@NonNull MengineApplication application, @NonNull Men } @Override - public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs) { + public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids) { JSONObject applovin_nonetbanner = configs.getOrDefault("applovin_nonetbanner", null); if (applovin_nonetbanner != null) { diff --git a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java index 26928d6bc5..4352e45dfb 100644 --- a/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java +++ b/gradle/plugins/AppLovin/src/main/java/org/Mengine/Plugin/AppLovin/MengineAppLovinPlugin.java @@ -407,7 +407,7 @@ public MengineAppLovinNonetBannersInterface getNonetBanners() { } @Override - public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs) { + public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids) { JSONObject applovin_show_mediation_debugger = configs.getOrDefault("applovin_show_mediation_debugger", null); if (applovin_show_mediation_debugger != null) { @@ -417,11 +417,11 @@ public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, } for (MengineAppLovinMediationInterface mediation : m_mediations) { - mediation.onMengineRemoteConfigFetch(application, updated, configs); + mediation.onMengineRemoteConfigFetch(application, updated, configs, ids); } if (m_nonetBanners != null) { - m_nonetBanners.onMengineRemoteConfigFetch(application, updated, configs); + m_nonetBanners.onMengineRemoteConfigFetch(application, updated, configs, ids); } } diff --git a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java index 629d71cbb8..11c8528e80 100644 --- a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java +++ b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java @@ -17,6 +17,7 @@ import org.Mengine.Base.BuildConfig; import org.Mengine.Base.MengineActivity; import org.Mengine.Base.MengineApplication; +import org.Mengine.Base.MengineFragmentRemoteConfig; import org.Mengine.Base.MengineListenerActivity; import org.Mengine.Base.MengineListenerApplication; import org.Mengine.Base.MengineListenerLogger; @@ -299,7 +300,7 @@ public void onMengineException(@NonNull MengineApplication application, @NonNull } @Override - public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs) { + public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, boolean updated, @NonNull Map configs, @NonNull Map ids) { JSONObject datadog_debug_message = configs.getOrDefault("datadog_debug_message", null); if (datadog_debug_message != null) { @@ -315,6 +316,10 @@ public void onMengineRemoteConfigFetch(@NonNull MengineApplication application, m_enableInfoMessage = enable; } + + if (m_loggerDataDog != null) { + m_loggerDataDog.addAttribute("mng_ids", ids); + } } @Override diff --git a/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java b/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java index f9e52ec859..c940adbf89 100644 --- a/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java +++ b/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java @@ -115,6 +115,7 @@ protected void fetchRemoteConfigValues(@NonNull FirebaseRemoteConfig remoteConfi Map remoteValues = remoteConfig.getAll(); Map configs = new HashMap<>(); + Map ids = new HashMap<>(); for (Map.Entry entry : m_defaults.entrySet()) { String key = entry.getKey(); @@ -148,13 +149,17 @@ protected void fetchRemoteConfigValues(@NonNull FirebaseRemoteConfig remoteConfi } configs.put(key, value_json); + + int id = value_json.optInt("id", 0); + + ids.put(key, id); } this.logInfo("remote config values: %s" , configs ); - MengineFragmentRemoteConfig.INSTANCE.remoteConfigFetch(configs); + MengineFragmentRemoteConfig.INSTANCE.remoteConfigFetch(configs, ids); } protected void propagateRemoteConfigValues(boolean updated) { diff --git a/gradle/plugins/GoogleConsent/build.gradle b/gradle/plugins/GoogleConsent/build.gradle index e47b534d2c..97ad2e2dcc 100644 --- a/gradle/plugins/GoogleConsent/build.gradle +++ b/gradle/plugins/GoogleConsent/build.gradle @@ -12,11 +12,11 @@ android { dependencies { implementation project(':plugins:GoogleService') - implementation 'com.google.android.ump:user-messaging-platform:3.2.0' + implementation 'com.google.android.ump:user-messaging-platform:4.0.0' } android { defaultConfig { - buildConfigField "String", "MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID != null ? "\"MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID\"" : "\"\"" + buildConfigField "String", "MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID", MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID != null ? "\"${MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID}\"" : "\"\"" } } diff --git a/gradle/plugins/GoogleConsent/src/main/java/org/Mengine/Plugin/GoogleConsent/MengineGoogleConsentPlugin.java b/gradle/plugins/GoogleConsent/src/main/java/org/Mengine/Plugin/GoogleConsent/MengineGoogleConsentPlugin.java index 1d47d7b4eb..033a910c1d 100644 --- a/gradle/plugins/GoogleConsent/src/main/java/org/Mengine/Plugin/GoogleConsent/MengineGoogleConsentPlugin.java +++ b/gradle/plugins/GoogleConsent/src/main/java/org/Mengine/Plugin/GoogleConsent/MengineGoogleConsentPlugin.java @@ -24,7 +24,7 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat ConsentRequestParameters.Builder builder = new ConsentRequestParameters.Builder(); if (BuildConfig.DEBUG == true) { - if (BuildConfig.MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID != null) { + if (BuildConfig.MENGINE_APP_PLUGIN_GOOGLE_CONSENT_TEST_DEVICE_HASHED_ID.isEmpty() == false) { ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(activity) .setDebugGeography(ConsentDebugSettings .DebugGeography @@ -42,45 +42,53 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat ConsentInformation consentInformation = UserMessagingPlatform.getConsentInformation(activity); + MengineApplication application = this.getMengineApplication(); + + this.logInfo("Google Consent requestConsentInfoUpdate started"); + consentInformation.requestConsentInfoUpdate(activity, params , () -> { boolean formAvailable = consentInformation.isConsentFormAvailable(); int consentStatus = consentInformation.getConsentStatus(); ConsentInformation.PrivacyOptionsRequirementStatus privacyOptionsRequirementStatus = consentInformation.getPrivacyOptionsRequirementStatus(); - this.logInfo("updated consent info update success status: %d formAvailable: %b privacyOptionsRequirementStatus: %s" + this.logInfo("Google Consent requestConsentInfoUpdate success consentStatus: %d formAvailable: %b privacyOptionsRequirementStatus: %s" , consentStatus , formAvailable - , privacyOptionsRequirementStatus + , privacyOptionsRequirementStatus.toString() ); if (formAvailable == false) { + application.checkTransparencyConsentServices(); + return; } if (privacyOptionsRequirementStatus == ConsentInformation.PrivacyOptionsRequirementStatus.NOT_REQUIRED) { - MengineApplication application = this.getMengineApplication(); - application.checkTransparencyConsentServices(); return; } if (consentStatus != ConsentInformation.ConsentStatus.REQUIRED) { + application.checkTransparencyConsentServices(); + return; } - this.loadForm(activity); + this.loadForm(application, activity); } , (formError) -> { this.logError("consent info update failure: %s [%d]" , formError.getMessage() , formError.getErrorCode() ); + + application.checkTransparencyConsentServices(); }); } - public void loadForm(@NonNull MengineActivity activity) { + public void loadForm(@NonNull MengineApplication application, @NonNull MengineActivity activity) { UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity , (loadAndShowError) -> { if (loadAndShowError != null) { @@ -89,13 +97,13 @@ public void loadForm(@NonNull MengineActivity activity) { , loadAndShowError.getErrorCode() ); + application.checkTransparencyConsentServices(); + return; } this.logInfo("consent form load and show success"); - MengineApplication application = this.getMengineApplication(); - application.checkTransparencyConsentServices(); }); } diff --git a/gradle/plugins/GoogleService/src/main/AndroidManifest.xml b/gradle/plugins/GoogleService/src/main/AndroidManifest.xml index 81f34fa553..8bf7c32593 100644 --- a/gradle/plugins/GoogleService/src/main/AndroidManifest.xml +++ b/gradle/plugins/GoogleService/src/main/AndroidManifest.xml @@ -4,7 +4,6 @@ - diff --git a/gradle/settings.gradle.kts b/gradle/settings.gradle.kts index 23d7e97bc2..87ba49dd6b 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -191,6 +191,10 @@ includePlugin("MENGINE_APP_PLUGIN_APPMETRICA", ":plugins:AppMetrica") includePlugin("MENGINE_APP_PLUGIN_APPSFLYER", ":plugins:AppsFlyer") includePlugin("MENGINE_APP_PLUGIN_FLURRY", ":plugins:Flurry") includePlugin("MENGINE_APP_PLUGIN_ADMOB", ":plugins:AdMob", listOf("MENGINE_APP_PLUGIN_GOOGLE_SERVICE")) +includePlugin("MENGINE_APP_PLUGIN_ADMOB", ":plugins:AdMob:Core", listOf("MENGINE_APP_PLUGIN_ADMOB")) +includePlugin("MENGINE_APP_PLUGIN_ADMOB_BANNERAD", ":plugins:AdMob:BannerAd", listOf("MENGINE_APP_PLUGIN_ADMOB")) +includePlugin("MENGINE_APP_PLUGIN_ADMOB_INTERSTITIALAD", ":plugins:AdMob:InterstitialAd", listOf("MENGINE_APP_PLUGIN_ADMOB")) +includePlugin("MENGINE_APP_PLUGIN_ADMOB_REWARDEDAD", ":plugins:AdMob:RewardedAd", listOf("MENGINE_APP_PLUGIN_ADMOB")) includePlugin("MENGINE_APP_PLUGIN_AMAZON", ":plugins:Amazon") includePlugin("MENGINE_APP_PLUGIN_APPLOVIN", ":plugins:AppLovin") includePlugin("MENGINE_APP_PLUGIN_APPLOVIN", ":plugins:AppLovin:Core") From 115d909b8714b96c50a23d18068a13fe5a4eaff0 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 21 Nov 2025 02:30:15 +0200 Subject: [PATCH 139/169] improve android FirebaseAnalytics --- .../FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java b/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java index a1182ab508..70717bec91 100644 --- a/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java +++ b/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java @@ -179,6 +179,10 @@ private static String getAdMediation(MengineAdMediation adMediation) { return "appLovin"; } + if (adMediation == MengineAdMediation.ADMEDIATION_ADMOB) { + return "adMob"; + } + return "unknown"; } From 8f7c972987d7a9f9ba94dcb5921ad4433bb4acb1 Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 21 Nov 2025 02:37:08 +0200 Subject: [PATCH 140/169] fix circle ci --- gradle/ci/app.properties | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 gradle/ci/app.properties diff --git a/gradle/ci/app.properties b/gradle/ci/app.properties new file mode 100644 index 0000000000..3c3b1d0160 --- /dev/null +++ b/gradle/ci/app.properties @@ -0,0 +1,5 @@ +ANDROID_APP_ID=com.wonderland.ci + +MENGINE_APP_HAS_ADS=0 + +MENGINE_APP_PLUGIN_ENABLE_ALL=0 \ No newline at end of file From 30e53b3eed0094825d6fb84a1ab95e33c8e944ea Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 21 Nov 2025 02:56:20 +0200 Subject: [PATCH 141/169] fix MENGINE_APP_SERVICE_AD and MENGINE_APP_HAS_ADS --- gradle/app.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gradle/app.gradle b/gradle/app.gradle index da722b2d86..37b3afe62b 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -381,11 +381,7 @@ if (MENGINE_APP_LIBRARY_MENGINE == true) { Utils.logAvailable("MENGINE_APP_SERVICE_AD", MENGINE_APP_SERVICE_AD) -if (MENGINE_APP_SERVICE_AD == true) { - if (MENGINE_APP_HAS_ADS == false) { - throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_SERVICE_AD is enabled. Set -PMENGINE_APP_HAS_ADS=true") - } - +if (MENGINE_APP_SERVICE_AD == true && MENGINE_APP_HAS_ADS == true) { android.ext.plugins += 'org.Mengine.Base.MengineAdService' } From 3b9c58fc3e199cd4df2f2515a2a796047d93ec8a Mon Sep 17 00:00:00 2001 From: irov Date: Fri, 21 Nov 2025 03:06:13 +0200 Subject: [PATCH 142/169] add MENGINE_APP_ADMEDIATION_ADDED --- gradle/app.gradle | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gradle/app.gradle b/gradle/app.gradle index 37b3afe62b..2e9cbc8527 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -670,11 +670,19 @@ if (MENGINE_APP_PLUGIN_MAR == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_ADMOB", MENGINE_APP_PLUGIN_ADMOB) +Boolean MENGINE_APP_ADMEDIATION_ADDED = false + if (MENGINE_APP_PLUGIN_ADMOB == true) { + if (MENGINE_APP_ADMEDIATION_ADDED == true) { + throw new GradleException("Cannot enable MENGINE_APP_PLUGIN_ADMOB because another mediation plugin is already enabled. Only one mediation plugin (MENGINE_APP_PLUGIN_ADMOB or MENGINE_APP_PLUGIN_APPLOVIN) can be enabled at a time.") + } + if (MENGINE_APP_HAS_ADS == false) { throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_ADMOB is enabled. Set -PMENGINE_APP_HAS_ADS=true") } + MENGINE_APP_ADMEDIATION_ADDED = true + android.ext.plugins += 'org.Mengine.Plugin.AdMob.MengineAdMobPlugin' dependencies { @@ -699,10 +707,16 @@ if (MENGINE_APP_PLUGIN_AMAZON == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_APPLOVIN", MENGINE_APP_PLUGIN_APPLOVIN) if (MENGINE_APP_PLUGIN_APPLOVIN == true) { + if (MENGINE_APP_ADMEDIATION_ADDED == true) { + throw new GradleException("Cannot enable MENGINE_APP_PLUGIN_APPLOVIN because another mediation plugin is already enabled. Only one mediation plugin (MENGINE_APP_PLUGIN_ADMOB or MENGINE_APP_PLUGIN_APPLOVIN) can be enabled at a time.") + } + if (MENGINE_APP_HAS_ADS == false) { throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_APPLOVIN is enabled. Set -PMENGINE_APP_HAS_ADS=true") } + MENGINE_APP_ADMEDIATION_ADDED = true + android.ext.plugins += 'org.Mengine.Plugin.AppLovin.MengineAppLovinPlugin' dependencies { From 256312cd3431b094038b66c8eb22866b65136247 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 24 Nov 2025 19:01:42 +0200 Subject: [PATCH 143/169] fix android MENGINE_SOLUTIONS_CONFIG_DIR improve android use getResourceName --- cmake/macro_template.cmake | 4 +- gradle/libraries/Mengine/build.gradle | 106 +++++++----------- .../java/org/Mengine/Base/MengineLog.java | 10 -- .../java/org/Mengine/Base/MengineService.java | 8 -- .../Mengine/Base/MengineServiceInterface.java | 1 - gradle/libraries/OpenAL32/build.gradle | 29 +++-- .../Plugin/Adjust/MengineAdjustPlugin.java | 2 +- .../Plugin/Amazon/MengineAmazonPlugin.java | 6 +- .../AppMetrica/MengineAppMetricaPlugin.java | 2 +- .../AppsFlyer/MengineAppsFlyerPlugin.java | 2 +- .../Plugin/DataDog/MengineDataDogPlugin.java | 4 +- .../DevToDev/MengineDevToDevPlugin.java | 2 +- .../MengineFirebaseRemoteConfigPlugin.java | 2 +- .../Plugin/Flurry/MengineFlurryPlugin.java | 2 +- .../MengineGoogleGameSocialAchievement.java | 9 +- .../MengineGoogleGameSocialPlugin.java | 8 +- .../Helpshift/MengineHelpshiftPlugin.java | 4 +- .../Leanplum/MengineLeanplumPlugin.java | 8 +- .../OneSignal/MengineOneSignalPlugin.java | 2 +- .../Plugin/Sentry/MengineSentryPlugin.java | 4 +- 20 files changed, 87 insertions(+), 128 deletions(-) diff --git a/cmake/macro_template.cmake b/cmake/macro_template.cmake index a5c77ed417..c25848c599 100644 --- a/cmake/macro_template.cmake +++ b/cmake/macro_template.cmake @@ -233,9 +233,9 @@ MACRO(SET_MENGINE_SOLUTIONS_OUTPUT_DIRECTORY) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}/${ANDROID_ABI}/${CMAKE_BUILD_TYPE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}/${ANDROID_ABI}/${CMAKE_BUILD_TYPE}) - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) + SET(MENGINE_SOLUTIONS_CONFIG_DIR ${CMAKE_BINARY_DIR}/mengine_config) - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/solutions/${ANDROID_ABI}) + SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/mengine_temp) elseif(MINGW) MESSAGE("Setup MINGW solution output directory") diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index 67ce9eda2c..15655f91f4 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -30,67 +30,65 @@ println("MENGINE_APP_BUILD_DEBUG_DOCUMENT: $MENGINE_APP_BUILD_DEBUG_DOCUMENT") println("MENGINE_APP_ENABLE_STRICT_MODE: $MENGINE_APP_ENABLE_STRICT_MODE") android { + externalNativeBuild { + cmake { + path "../../../cmake/Android/Mengine/CMakeLists.txt" + buildStagingDirectory rootProject.projectDir.getAbsolutePath() + "/../outputs/gradle/.cxx/" + project.getName() + } + } + defaultConfig { manifestPlaceholders = [ - ANDROID_APP_BUILD_NUMBER: ANDROID_APP_BUILD_NUMBER, - ANDROID_APP_BUILD_VERSION: ANDROID_APP_BUILD_VERSION, - ANDROID_APP_SCREEN_ORIENTATION: ANDROID_APP_SCREEN_ORIENTATION, - ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN: ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN, + ANDROID_APP_BUILD_NUMBER : ANDROID_APP_BUILD_NUMBER, + ANDROID_APP_BUILD_VERSION : ANDROID_APP_BUILD_VERSION, + ANDROID_APP_SCREEN_ORIENTATION : ANDROID_APP_SCREEN_ORIENTATION, + ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN : ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN, ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER: ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER ] println "ANDROID_APP_SCREEN_ORIENTATION: $ANDROID_APP_SCREEN_ORIENTATION" println "ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN: $ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN" println "ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER: $ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER" - } - externalNativeBuild { - cmake { - path "../../../cmake/Android/Mengine/CMakeLists.txt" - buildStagingDirectory rootProject.projectDir.getAbsolutePath() + "/../outputs/gradle/.cxx/" + project.getName() + externalNativeBuild { + cmake { + arguments.add("-DANDROID_PLATFORM=android-" + project.minSdkVersion) + arguments.add("-DANDROID_ARM_NEON=TRUE") + arguments.add("-DANDROID_STL=c++_shared") + arguments.add("-DANDROID_TOOLCHAIN=clang") + arguments.add("-DCMAKE_SYSTEM_NAME=Android") + arguments.add("-DCMAKE_SYSTEM_VERSION=${project.minSdkVersion}") + arguments.add("-DMENGINE_BUILD_NUMBER:STRING=${ANDROID_APP_BUILD_NUMBER}") + arguments.add("-DMENGINE_BUILD_VERSION:STRING=${ANDROID_APP_BUILD_VERSION}") + arguments.add("-DMENGINE_DEPENDENCIES_PROJECT:STRING=Depends_Android") + arguments.add("-DMENGINE_BUILD_MENGINE_BUILD_PUBLISH:BOOLEAN=" + (ANDROID_APP_BUILD_PUBLISH ? "ON" : "OFF")) + arguments.add("-DMENGINE_SECURE_VALUE:STRING=${MENGINE_APP_SECURE_VALUE}") + arguments.add("-DMENGINE_DEPLOY_PATH:STRING=${MENGINE_APP_DEPLOY_PATH}") + + if (MENGINE_APP_BUILD_ASSERTION_DEBUG != -1) { + cppFlags.add("-DMENGINE_ASSERTION_DEBUG=${MENGINE_APP_BUILD_ASSERTION_DEBUG}") + } + + if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { + cppFlags.add("-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}") + } + + if (MENGINE_APP_BUILD_DEBUG_FILE_PATH != -1) { + cppFlags.add("-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_BUILD_DEBUG_FILE_PATH}") + } + + if (MENGINE_APP_BUILD_DEBUG_DOCUMENT != -1) { + cppFlags.add("-DMENGINE_DOCUMENT=${MENGINE_APP_BUILD_DEBUG_DOCUMENT}") + } + } } } buildTypes { - final List cmake_arguments = new ArrayList() - cmake_arguments.add("-DANDROID_PLATFORM=android-" + project.minSdkVersion) - cmake_arguments.add("-DANDROID_ARM_NEON=TRUE") - cmake_arguments.add("-DANDROID_STL=c++_shared") - cmake_arguments.add("-DANDROID_TOOLCHAIN=clang") - cmake_arguments.add("-DCMAKE_SYSTEM_NAME=Android") - cmake_arguments.add("-DCMAKE_SYSTEM_VERSION=${project.minSdkVersion}") - - cmake_arguments.add("-DMENGINE_BUILD_NUMBER:STRING=${ANDROID_APP_BUILD_NUMBER}") - cmake_arguments.add("-DMENGINE_BUILD_VERSION:STRING=${ANDROID_APP_BUILD_VERSION}") - cmake_arguments.add("-DMENGINE_DEPENDENCIES_PROJECT:STRING=Depends_Android") - cmake_arguments.add("-DMENGINE_BUILD_MENGINE_BUILD_PUBLISH:BOOLEAN=" + (ANDROID_APP_BUILD_PUBLISH ? "ON" : "OFF")) - cmake_arguments.add("-DMENGINE_SECURE_VALUE:STRING=${MENGINE_APP_SECURE_VALUE}") - cmake_arguments.add("-DMENGINE_DEPLOY_PATH:STRING=${MENGINE_APP_DEPLOY_PATH}") - debug { externalNativeBuild { cmake { - for (final String argument : cmake_arguments) { - arguments.add(argument) - } - arguments.add("-DCMAKE_BUILD_TYPE:STRING=Debug") - - if (MENGINE_APP_BUILD_ASSERTION_DEBUG != -1) { - cppFlags += ["-DMENGINE_ASSERTION_DEBUG=${MENGINE_APP_BUILD_ASSERTION_DEBUG}"] - } - - if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { - cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] - } - - if (MENGINE_APP_BUILD_DEBUG_FILE_PATH != -1) { - cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_BUILD_DEBUG_FILE_PATH}"] - } - - if (MENGINE_APP_BUILD_DEBUG_DOCUMENT != -1) { - cppFlags += ["-DMENGINE_DOCUMENT=${MENGINE_APP_BUILD_DEBUG_DOCUMENT}"] - } } } } @@ -98,27 +96,7 @@ android { release { externalNativeBuild { cmake { - for (final String argument : cmake_arguments) { - arguments.add(argument) - } - arguments.add("-DCMAKE_BUILD_TYPE:STRING=Release") - - if (MENGINE_APP_BUILD_ASSERTION_DEBUG != -1) { - cppFlags += ["-DMENGINE_ASSERTION_DEBUG=${MENGINE_APP_BUILD_ASSERTION_DEBUG}"] - } - - if (MENGINE_APP_BUILD_LOGGER_INFO != -1) { - cppFlags += ["-DMENGINE_LOGGER_INFO=${MENGINE_APP_BUILD_LOGGER_INFO}"] - } - - if (MENGINE_APP_BUILD_DEBUG_FILE_PATH != -1) { - cppFlags += ["-DMENGINE_DEBUG_FILE_PATH=${MENGINE_APP_BUILD_DEBUG_FILE_PATH}"] - } - - if (MENGINE_APP_BUILD_DEBUG_DOCUMENT != -1) { - cppFlags += ["-DMENGINE_DOCUMENT=${MENGINE_APP_BUILD_DEBUG_DOCUMENT}"] - } } } } diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java index e9e3ec3e28..5f6bc0c592 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java @@ -129,16 +129,6 @@ public static String logMessage(@NonNull MengineTag category, @NonNull String fo return m; } - public static String logMessageProtected(@NonNull MengineTag category, @NonNull String format, Object ... args) { - if (BuildConfig.DEBUG == false) { - return ""; - } - - String m = MengineLog.log(LM_MESSAGE, category, MengineLog.LFILTER_PROTECTED, format, args); - - return m; - } - public static String logMessageRelease(@NonNull MengineTag category, @NonNull String format, Object ... args) { String m = MengineLog.log(LM_MESSAGE_RELEASE, category, MengineLog.LFILTER_NONE, format, args); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java index 9d8b98d139..d7aa874cb2 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java @@ -230,14 +230,6 @@ public String logMessage(@NonNull String format, Object ... args) { return m; } - @Override - public String logMessageProtected(@NonNull String format, Object ... args) { - MengineTag t = this.getServiceTag(); - String m = MengineLog.logMessageProtected(t, format, args); - - return m; - } - @Override public String logMessageRelease(@NonNull String format, Object ... args) { MengineTag t = this.getServiceTag(); diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java index 4a658fd6a0..c49ecd1e8c 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineServiceInterface.java @@ -71,7 +71,6 @@ default Bundle onSave(@NonNull MengineApplication application) { String logDebug(@NonNull String format, Object ... args); String logInfo(@NonNull String format, Object ... args); String logMessage(@NonNull String format, Object ... args); - String logMessageProtected(@NonNull String format, Object ... args); String logMessageRelease(@NonNull String format, Object ... args); String logWarning(@NonNull String format, Object ... args); String logError(@NonNull String format, Object ... args); diff --git a/gradle/libraries/OpenAL32/build.gradle b/gradle/libraries/OpenAL32/build.gradle index 05bcc26a05..f9f2db54bf 100644 --- a/gradle/libraries/OpenAL32/build.gradle +++ b/gradle/libraries/OpenAL32/build.gradle @@ -8,22 +8,23 @@ android { } } - buildTypes { - final List cmake_arguments = new ArrayList() - cmake_arguments.add("-DANDROID_PLATFORM=android-" + project.minSdkVersion) - cmake_arguments.add("-DANDROID_ARM_NEON=TRUE") - cmake_arguments.add("-DANDROID_STL=c++_shared") - cmake_arguments.add("-DANDROID_TOOLCHAIN=clang") - cmake_arguments.add("-DCMAKE_SYSTEM_NAME=Android") - cmake_arguments.add("-DCMAKE_SYSTEM_VERSION=${project.minSdkVersion}") + defaultConfig { + externalNativeBuild { + cmake { + arguments.add("-DANDROID_PLATFORM=android-" + project.minSdkVersion) + arguments.add("-DANDROID_ARM_NEON=TRUE") + arguments.add("-DANDROID_STL=c++_shared") + arguments.add("-DANDROID_TOOLCHAIN=clang") + arguments.add("-DCMAKE_SYSTEM_NAME=Android") + arguments.add("-DCMAKE_SYSTEM_VERSION=${project.minSdkVersion}") + } + } + } + buildTypes { debug { externalNativeBuild { cmake { - for (final String argument : cmake_arguments) { - arguments.add(argument) - } - arguments.add("-DCMAKE_BUILD_TYPE:STRING=Debug") } } @@ -32,10 +33,6 @@ android { release { externalNativeBuild { cmake { - for (final String argument : cmake_arguments) { - arguments.add(argument) - } - arguments.add("-DCMAKE_BUILD_TYPE:STRING=Release") } } diff --git a/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java b/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java index c773d57392..d596f5494a 100644 --- a/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java +++ b/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java @@ -87,7 +87,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS String MengineAdjustPlugin_AppToken = this.getResourceString(METADATA_APP_TOKEN); this.logInfo("%s: %s" - , METADATA_APP_TOKEN + , this.getResourceName(METADATA_APP_TOKEN) , MengineUtils.getRedactedValue(MengineAdjustPlugin_AppToken) ); diff --git a/gradle/plugins/Amazon/src/main/java/org/Mengine/Plugin/Amazon/MengineAmazonPlugin.java b/gradle/plugins/Amazon/src/main/java/org/Mengine/Plugin/Amazon/MengineAmazonPlugin.java index 9d251da793..14b36c206b 100644 --- a/gradle/plugins/Amazon/src/main/java/org/Mengine/Plugin/Amazon/MengineAmazonPlugin.java +++ b/gradle/plugins/Amazon/src/main/java/org/Mengine/Plugin/Amazon/MengineAmazonPlugin.java @@ -26,7 +26,7 @@ public void onAppCreate(MengineApplication application) throws MengineServiceInv String MengineAmazonPlugin_AppId = this.getResourceString(METADATA_APP_ID); this.logInfo("%s: %s" - , METADATA_APP_ID + , this.getResourceName(METADATA_APP_ID) , MengineUtils.getRedactedValue(MengineAmazonPlugin_AppId) ); @@ -50,7 +50,7 @@ public void onAppCreate(MengineApplication application) throws MengineServiceInv } this.logInfo("%s: %b" - , METADATA_ENABLE_TESTING + , this.getResourceName(METADATA_ENABLE_TESTING) , MengineAmazonPlugin_EnableTesting ); @@ -61,7 +61,7 @@ public void onAppCreate(MengineApplication application) throws MengineServiceInv } this.logInfo("%s: %b" - , METADATA_ENABLE_LOGGING + , this.getResourceName(METADATA_ENABLE_LOGGING) , MengineAmazonPlugin_EnableLogging ); } diff --git a/gradle/plugins/AppMetrica/src/main/java/org/Mengine/Plugin/AppMetrica/MengineAppMetricaPlugin.java b/gradle/plugins/AppMetrica/src/main/java/org/Mengine/Plugin/AppMetrica/MengineAppMetricaPlugin.java index a8547f268a..a86799c5e4 100644 --- a/gradle/plugins/AppMetrica/src/main/java/org/Mengine/Plugin/AppMetrica/MengineAppMetricaPlugin.java +++ b/gradle/plugins/AppMetrica/src/main/java/org/Mengine/Plugin/AppMetrica/MengineAppMetricaPlugin.java @@ -53,7 +53,7 @@ public void onAppInit(@NonNull MengineApplication application, boolean isMainPro String MengineAppMetricaPlugin_ApiKey = this.getResourceString(METADATA_API_KEY); this.logInfo("%s: %s" - , METADATA_API_KEY + , this.getResourceName(METADATA_API_KEY) , MengineUtils.getRedactedValue(MengineAppMetricaPlugin_ApiKey) ); diff --git a/gradle/plugins/AppsFlyer/src/main/java/org/Mengine/Plugin/AppsFlyer/MengineAppsFlyerPlugin.java b/gradle/plugins/AppsFlyer/src/main/java/org/Mengine/Plugin/AppsFlyer/MengineAppsFlyerPlugin.java index cf2332819d..744bef04fb 100644 --- a/gradle/plugins/AppsFlyer/src/main/java/org/Mengine/Plugin/AppsFlyer/MengineAppsFlyerPlugin.java +++ b/gradle/plugins/AppsFlyer/src/main/java/org/Mengine/Plugin/AppsFlyer/MengineAppsFlyerPlugin.java @@ -42,7 +42,7 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine String MengineAppsFlyerPlugin_ApiKey = application.getResourceString(METADATA_API_KEY); this.logInfo("%s: %s" - , METADATA_API_KEY + , this.getResourceName(METADATA_API_KEY) , MengineUtils.getRedactedValue(MengineAppsFlyerPlugin_ApiKey) ); diff --git a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java index 11c8528e80..686d524d3b 100644 --- a/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java +++ b/gradle/plugins/DataDog/src/main/java/org/Mengine/Plugin/DataDog/MengineDataDogPlugin.java @@ -78,7 +78,7 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine String MengineDataDogPlugin_Site = this.getResourceString(METADATA_SITE); this.logInfo("%s: %s" - , METADATA_SITE + , this.getResourceName(METADATA_SITE) , MengineUtils.getRedactedValue(MengineDataDogPlugin_Site) ); @@ -105,7 +105,7 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine String MengineDataDogPlugin_ClientToken = this.getResourceString(METADATA_CLIENT_TOKEN); this.logInfo("%s: %s" - , METADATA_CLIENT_TOKEN + , this.getResourceName(METADATA_CLIENT_TOKEN) , MengineUtils.getRedactedValue(MengineDataDogPlugin_ClientToken) ); diff --git a/gradle/plugins/DevToDev/src/main/java/org/Mengine/Plugin/DevToDev/MengineDevToDevPlugin.java b/gradle/plugins/DevToDev/src/main/java/org/Mengine/Plugin/DevToDev/MengineDevToDevPlugin.java index 2d677b4a4f..d40c5689a5 100644 --- a/gradle/plugins/DevToDev/src/main/java/org/Mengine/Plugin/DevToDev/MengineDevToDevPlugin.java +++ b/gradle/plugins/DevToDev/src/main/java/org/Mengine/Plugin/DevToDev/MengineDevToDevPlugin.java @@ -52,7 +52,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS String MengineDevToDevPlugin_AppId = this.getResourceString(METADATA_APP_ID); this.logInfo("%s: %s" - , METADATA_APP_ID + , this.getResourceName(METADATA_APP_ID) , MengineUtils.getRedactedValue(MengineDevToDevPlugin_AppId) ); diff --git a/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java b/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java index c940adbf89..9c84be6031 100644 --- a/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java +++ b/gradle/plugins/FirebaseRemoteConfig/src/main/java/org/Mengine/Plugin/FirebaseRemoteConfig/MengineFirebaseRemoteConfigPlugin.java @@ -42,7 +42,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS int MengineFirebaseRemoteConfigPlugin_MinimumFetchInterval = this.getResourceInteger(METADATA_MINIMUM_FETCH_INTERVAL); this.logInfo("%s: %d" - , METADATA_MINIMUM_FETCH_INTERVAL + , this.getResourceName(METADATA_MINIMUM_FETCH_INTERVAL) , MengineFirebaseRemoteConfigPlugin_MinimumFetchInterval ); diff --git a/gradle/plugins/Flurry/src/main/java/org/Mengine/Plugin/Flurry/MengineFlurryPlugin.java b/gradle/plugins/Flurry/src/main/java/org/Mengine/Plugin/Flurry/MengineFlurryPlugin.java index 65d5eb070f..792662e82f 100644 --- a/gradle/plugins/Flurry/src/main/java/org/Mengine/Plugin/Flurry/MengineFlurryPlugin.java +++ b/gradle/plugins/Flurry/src/main/java/org/Mengine/Plugin/Flurry/MengineFlurryPlugin.java @@ -36,7 +36,7 @@ public void onAppPrepare(MengineApplication application) throws MengineServiceIn String MengineFlurryPlugin_ApiKey = this.getResourceString(METADATA_API_KEY); this.logInfo("%s: %s" - , METADATA_API_KEY + , this.getResourceName(METADATA_API_KEY) , MengineUtils.getRedactedValue(MengineFlurryPlugin_ApiKey) ); diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java index 765f2deca2..f8fdd31936 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java @@ -74,7 +74,7 @@ public void markUnlocked(long timestamp) { m_state = Achievement.STATE_UNLOCKED; m_lastUpdatedTimestamp = timestamp; - if (this.isIncremental()) { + if (this.isIncremental() == true) { m_currentSteps = m_totalSteps; } } @@ -107,6 +107,9 @@ public void incrementSteps(int numSteps, long timestamp) { public JSONObject toJSONObject() throws JSONException { JSONObject achievementJSON = new JSONObject(); + boolean unlocked = this.isUnlocked(); + boolean incremental = this.isIncremental(); + achievementJSON.put("name", m_name); achievementJSON.put("description", m_description); achievementJSON.put("state", m_state); @@ -115,8 +118,8 @@ public JSONObject toJSONObject() throws JSONException { achievementJSON.put("lastUpdatedTimestamp", m_lastUpdatedTimestamp); achievementJSON.put("currentSteps", m_currentSteps); achievementJSON.put("totalSteps", m_totalSteps); - achievementJSON.put("isUnlocked", this.isUnlocked()); - achievementJSON.put("isIncremental", this.isIncremental()); + achievementJSON.put("isUnlocked", unlocked); + achievementJSON.put("isIncremental", incremental); return achievementJSON; } diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java index 50dcc1668b..70c0bc2e3e 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java @@ -168,14 +168,14 @@ public boolean isAuthenticated() { } private void signInSilently() { - if (m_isAuthenticated == true) { - this.logInfo("signInSilently already authenticated"); + if (MengineNetwork.isNetworkAvailable() == false) { + this.logInfo("signInSilently network not available"); return; } - if (MengineNetwork.isNetworkAvailable() == false) { - this.logInfo("signInSilently network not available"); + if (m_isAuthenticated == true) { + this.logInfo("signInSilently already authenticated"); return; } diff --git a/gradle/plugins/Helpshift/src/main/java/org/Mengine/Plugin/Helpshift/MengineHelpshiftPlugin.java b/gradle/plugins/Helpshift/src/main/java/org/Mengine/Plugin/Helpshift/MengineHelpshiftPlugin.java index fc069623fb..db6ea92dab 100644 --- a/gradle/plugins/Helpshift/src/main/java/org/Mengine/Plugin/Helpshift/MengineHelpshiftPlugin.java +++ b/gradle/plugins/Helpshift/src/main/java/org/Mengine/Plugin/Helpshift/MengineHelpshiftPlugin.java @@ -47,14 +47,14 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS String MengineHelpshiftPlugin_PlatformId = this.getResourceString(METADATA_PLATFORM_ID); this.logInfo("%s: %s" - , METADATA_PLATFORM_ID + , this.getResourceName(METADATA_PLATFORM_ID) , MengineUtils.getRedactedValue(MengineHelpshiftPlugin_PlatformId) ); String MengineHelpshiftPlugin_Domain = this.getResourceString(METADATA_DOMAIN); this.logInfo("%s: %s" - , METADATA_DOMAIN + , this.getResourceName(METADATA_DOMAIN) , MengineUtils.getRedactedValue(MengineHelpshiftPlugin_Domain) ); diff --git a/gradle/plugins/Leanplum/src/main/java/org/Mengine/Plugin/Leanplum/MengineLeanplumPlugin.java b/gradle/plugins/Leanplum/src/main/java/org/Mengine/Plugin/Leanplum/MengineLeanplumPlugin.java index 3eee7ef216..b7ca1532b8 100644 --- a/gradle/plugins/Leanplum/src/main/java/org/Mengine/Plugin/Leanplum/MengineLeanplumPlugin.java +++ b/gradle/plugins/Leanplum/src/main/java/org/Mengine/Plugin/Leanplum/MengineLeanplumPlugin.java @@ -30,24 +30,24 @@ public void onAppCreate(MengineApplication application) throws MengineServiceInv String Environment = this.getResourceString(METADATA_ENVIRONMENT); this.logInfo("%s: %s" - , METADATA_APP_ID + , this.getResourceName(METADATA_APP_ID) , MengineUtils.getRedactedValue(AppId) ); if (BuildConfig.DEBUG == true) { this.logInfo("%s: %s" - , METADATA_DEV_KEY + , this.getResourceName(METADATA_DEV_KEY) , MengineUtils.getRedactedValue(DevKey) ); } else { this.logInfo("%s: %s" - , METADATA_PROD_KEY + , this.getResourceName(METADATA_PROD_KEY) , MengineUtils.getRedactedValue(ProdKey) ); } this.logInfo("%s: %s" - , METADATA_ENVIRONMENT + , this.getResourceName(METADATA_ENVIRONMENT) , Environment ); diff --git a/gradle/plugins/OneSignal/src/main/java/org/Mengine/Plugin/OneSignal/MengineOneSignalPlugin.java b/gradle/plugins/OneSignal/src/main/java/org/Mengine/Plugin/OneSignal/MengineOneSignalPlugin.java index 3aad305103..73c130582a 100644 --- a/gradle/plugins/OneSignal/src/main/java/org/Mengine/Plugin/OneSignal/MengineOneSignalPlugin.java +++ b/gradle/plugins/OneSignal/src/main/java/org/Mengine/Plugin/OneSignal/MengineOneSignalPlugin.java @@ -27,7 +27,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS String MengineOneSignalPlugin_AppId = this.getResourceString(METADATA_APP_ID); this.logInfo("%s: %s" - , METADATA_APP_ID + , this.getResourceName(METADATA_APP_ID) , MengineUtils.getRedactedValue(MengineOneSignalPlugin_AppId) ); diff --git a/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java b/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java index 2116c1878d..6ceb2dc8d8 100644 --- a/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java +++ b/gradle/plugins/Sentry/src/main/java/org/Mengine/Plugin/Sentry/MengineSentryPlugin.java @@ -50,14 +50,14 @@ public void onAppInit(MengineApplication application, boolean isMainProcess) thr String MengineSentryPlugin_DSN = this.getResourceString(METADATA_DSN); this.logInfo("%s: %s" - , METADATA_DSN + , this.getResourceName(METADATA_DSN) , MengineUtils.getRedactedValue(MengineSentryPlugin_DSN) ); boolean MengineSentryPlugin_EnableUncaughtExceptionHandler = this.getResourceBoolean(METADATA_ENABLE_UNCAUGHT_EXCEPTION_HANDLER); this.logInfo("%s: %b" - , METADATA_ENABLE_UNCAUGHT_EXCEPTION_HANDLER + , this.getResourceName(METADATA_ENABLE_UNCAUGHT_EXCEPTION_HANDLER) , MengineSentryPlugin_EnableUncaughtExceptionHandler ); From 5c8f8b41533ba7cbef11585a7d646a5e51a6c2d1 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 24 Nov 2025 19:28:37 +0200 Subject: [PATCH 144/169] fix android AdMob InterstitialAd&RewardedAd --- .../AdMob/BannerAd/MengineAdMobBannerAd.java | 4 +- .../Plugin/AdMob/Core/MengineAdMobBase.java | 3 +- .../MengineAdMobInterstitialAd.java | 22 ++++--- .../RewardedAd/MengineAdMobRewardedAd.java | 60 +++++++++---------- 4 files changed, 41 insertions(+), 48 deletions(-) diff --git a/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java index bf3f8f23c7..2aa2bdfa67 100644 --- a/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java +++ b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java @@ -264,7 +264,9 @@ public void loadAd() { this.setBannerState("load"); try { - AdRequest adRequest = new AdRequest.Builder().build(); + AdRequest adRequest = new AdRequest.Builder() + .build(); + m_adView.loadAd(adRequest); } catch (final Exception e) { m_plugin.logError("[Banner] loadAd adUnitId: %s exception: %s" diff --git a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java index b2b4fb1eca..cf7147db58 100644 --- a/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java @@ -299,5 +299,4 @@ protected void invalidInitialize(String format, Object ... args) throws MengineS throw new MengineServiceInvalidInitializeException(message); } -} - +} \ No newline at end of file diff --git a/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java b/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java index beb16a0bea..9ae81be56d 100644 --- a/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java +++ b/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java @@ -69,6 +69,10 @@ public void onActivityCreate(@NonNull MengineActivity activity) { public void onActivityDestroy(@NonNull MengineActivity activity) { super.onActivityDestroy(activity); + this.destroyInterstitialAd(); + } + + private void destroyInterstitialAd() { if (m_interstitialAd != null) { m_interstitialAd.setFullScreenContentCallback(null); m_interstitialAd.setOnPaidEventListener(null); @@ -104,6 +108,8 @@ public void loadAd() { InterstitialAd.load(activity, m_adUnitId, adRequest, new InterstitialAdLoadCallback() { @Override public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { + MengineAdMobInterstitialAd.this.destroyInterstitialAd(); + m_interstitialAd = interstitialAd; m_interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() { @@ -217,7 +223,7 @@ public void onAdImpression() { @Override public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { - m_interstitialAd = null; + MengineAdMobInterstitialAd.this.destroyInterstitialAd(); MengineAdMobInterstitialAd.this.logLoadAdError("onAdFailedToLoad", loadAdError); @@ -247,10 +253,6 @@ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { } public boolean canYouShowInterstitial(String placement) { - if (m_interstitialAd == null) { - return false; - } - if (MengineNetwork.isNetworkAvailable() == false) { return false; } @@ -272,10 +274,6 @@ public boolean canYouShowInterstitial(String placement) { } public boolean showInterstitial(@NonNull MengineActivity activity, String placement) { - if (m_interstitialAd == null) { - return false; - } - if (MengineNetwork.isNetworkAvailable() == false) { return false; } @@ -295,10 +293,10 @@ public boolean showInterstitial(@NonNull MengineActivity activity, String placem m_showing = true; + InterstitialAd show_interstitialAd = m_interstitialAd; + MengineUtils.performOnMainThread(() -> { - if (m_interstitialAd != null) { - m_interstitialAd.show(activity); - } + show_interstitialAd.show(activity); }); return true; diff --git a/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java b/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java index 406f1322dc..a1a15d5cc1 100644 --- a/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java +++ b/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java @@ -69,6 +69,10 @@ public void onActivityCreate(@NonNull MengineActivity activity) { public void onActivityDestroy(@NonNull MengineActivity activity) { super.onActivityDestroy(activity); + this.destroyRewardedAd(); + } + + private void destroyRewardedAd() { if (m_rewardedAd != null) { m_rewardedAd.setFullScreenContentCallback(null); m_rewardedAd.setOnPaidEventListener(null); @@ -104,6 +108,8 @@ public void loadAd() { RewardedAd.load(activity, m_adUnitId, adRequest, new RewardedAdLoadCallback() { @Override public void onAdLoaded(@NonNull RewardedAd rewardedAd) { + MengineAdMobRewardedAd.this.destroyRewardedAd(); + m_rewardedAd = rewardedAd; m_rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() { @@ -217,7 +223,7 @@ public void onAdImpression() { @Override public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { - m_rewardedAd = null; + MengineAdMobRewardedAd.this.destroyRewardedAd(); MengineAdMobRewardedAd.this.logLoadAdError("onAdFailedToLoad", loadAdError); @@ -247,10 +253,6 @@ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { } public boolean canOfferRewarded(String placement) { - if (m_rewardedAd == null) { - return false; - } - if (MengineNetwork.isNetworkAvailable() == false) { return false; } @@ -272,10 +274,6 @@ public boolean canOfferRewarded(String placement) { } public boolean canYouShowRewarded(String placement) { - if (m_rewardedAd == null) { - return false; - } - if (MengineNetwork.isNetworkAvailable() == false) { return false; } @@ -297,10 +295,6 @@ public boolean canYouShowRewarded(String placement) { } public boolean showRewarded(@NonNull MengineActivity activity, String placement) { - if (m_rewardedAd == null) { - return false; - } - if (MengineNetwork.isNetworkAvailable() == false) { return false; } @@ -320,27 +314,27 @@ public boolean showRewarded(@NonNull MengineActivity activity, String placement) m_showing = true; + RewardedAd show_rewardedAd = m_rewardedAd; + MengineUtils.performOnMainThread(() -> { - if (m_rewardedAd != null) { - m_rewardedAd.show(activity, new OnUserEarnedRewardListener() { - @Override - public void onUserEarnedReward(@NonNull RewardItem rewardItem) { - String rewardType = rewardItem.getType(); - int rewardAmount = rewardItem.getAmount(); - - MengineAdMobRewardedAd.this.log("onUserEarnedReward"); - - MengineAdMobRewardedAd.this.buildRewardedAdEvent("user_rewarded") - .addParameterString("reward_type", rewardType) - .addParameterLong("reward_amount", rewardAmount) - .log(); - - MengineAdResponseInterface adResponse = m_adService.getAdResponse(); - - adResponse.onAdUserRewarded(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_REWARDED, placement, rewardType, rewardAmount); - } - }); - } + show_rewardedAd.show(activity, new OnUserEarnedRewardListener() { + @Override + public void onUserEarnedReward(@NonNull RewardItem rewardItem) { + String rewardType = rewardItem.getType(); + int rewardAmount = rewardItem.getAmount(); + + MengineAdMobRewardedAd.this.log("onUserEarnedReward"); + + MengineAdMobRewardedAd.this.buildRewardedAdEvent("user_rewarded") + .addParameterString("reward_type", rewardType) + .addParameterLong("reward_amount", rewardAmount) + .log(); + + MengineAdResponseInterface adResponse = m_adService.getAdResponse(); + + adResponse.onAdUserRewarded(MengineAdMediation.ADMEDIATION_ADMOB, MengineAdFormat.ADFORMAT_REWARDED, placement, rewardType, rewardAmount); + } + }); }); return true; From 28cedbfeee0f44897110ec1cabefc9ded96ffe23 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 24 Nov 2025 22:15:00 +0200 Subject: [PATCH 145/169] improve android MenginePreferences improve android MengineGoogleGameSocialPlugin --- .../org/Mengine/Base/MenginePreferences.java | 25 +++++++++++ .../MengineGoogleGameSocialPlugin.java | 42 +++++++++++++------ 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java index b9c31f034c..2ea1e64cc2 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MenginePreferences.java @@ -11,6 +11,7 @@ import java.util.Collection; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import java.util.function.Supplier; import java.util.HashMap; @@ -58,6 +59,12 @@ static public boolean getPreferenceBoolean(@NonNull String name, boolean default static public void setPreferenceBoolean(@NonNull String name, boolean value) { synchronized (MenginePreferences.SETTINGS_SYNC) { + Boolean currentValue = (Boolean)MenginePreferences.SETTINGS.getOrDefault(name, null); + + if (Objects.equals(currentValue, value) == true) { + return; + } + MenginePreferences.SETTINGS.put(name, value); } @@ -76,6 +83,12 @@ static public long getPreferenceLong(@NonNull String name, long defaultValue) { static public void setPreferenceLong(@NonNull String name, long value) { synchronized (MenginePreferences.SETTINGS_SYNC) { + Long currentValue = (Long)MenginePreferences.SETTINGS.getOrDefault(name, null); + + if (Objects.equals(currentValue, value) == true) { + return; + } + MenginePreferences.SETTINGS.put(name, value); } @@ -94,6 +107,12 @@ static public String getPreferenceString(@NonNull String name, String defaultVal static public void setPreferenceString(@NonNull String name, String value) { synchronized (MenginePreferences.SETTINGS_SYNC) { + String currentValue = (String)MenginePreferences.SETTINGS.getOrDefault(name, null); + + if (Objects.equals(currentValue, value) == true) { + return; + } + MenginePreferences.SETTINGS.put(name, value); } @@ -114,6 +133,12 @@ static public Set getPreferenceStrings(@NonNull String name, Set static public void setPreferenceStrings(@NonNull String name, Set value) { synchronized (MenginePreferences.SETTINGS_SYNC) { + Set currentValue = (Set)MenginePreferences.SETTINGS.getOrDefault(name, null); + + if (Objects.equals(currentValue, value) == true) { + return; + } + MenginePreferences.SETTINGS.put(name, value); } diff --git a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java index 70c0bc2e3e..cc1d8e3e64 100644 --- a/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialPlugin.java @@ -26,13 +26,13 @@ import org.Mengine.Base.MengineApplication; import org.Mengine.Base.MengineFragmentGame; import org.Mengine.Base.MengineNetwork; +import org.Mengine.Base.MenginePreferences; import org.Mengine.Base.MengineService; import org.Mengine.Base.MengineListenerActivity; import org.Mengine.Base.MengineListenerApplication; import org.Mengine.Base.MengineServiceInvalidInitializeException; import org.Mengine.Plugin.GoogleService.MengineGoogleServicePlugin; -import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -43,6 +43,8 @@ public class MengineGoogleGameSocialPlugin extends MengineService implements Men public static final String SERVICE_NAME = "GGameSocial"; public static final boolean SERVICE_EMBEDDING = true; + private static final String PREFERENCE_KEY_TRYING_SIGN_IN_INTENT = "mengine.googlegamesocial.trying_sign_in_intent"; + private ActivityResultLauncher m_achievementLauncher; private ActivityResultLauncher m_leaderboardLauncher; private ActivityResultLauncher m_gamesResolutionLauncher; @@ -105,19 +107,23 @@ public void onCreate(@NonNull MengineActivity activity, Bundle savedInstanceStat m_leaderboardLauncher = leaderboardLauncher; ActivityResultLauncher gamesResolutionLauncher = activity.registerForActivityResultIntentSender(result -> { - if (result.getResultCode() == Activity.RESULT_OK) { - Intent data = result.getData(); - - this.logInfo("gamesResolutionLauncher onActivityResult intent: %s", - data - ); - - this.signInIntent(); - } else { + if (result.getResultCode() != Activity.RESULT_OK) { this.logInfo("gamesResolutionLauncher onActivityResult resultCode: %d", result.getResultCode() ); + + MenginePreferences.setPreferenceBoolean(PREFERENCE_KEY_TRYING_SIGN_IN_INTENT, false); + + return; } + + Intent data = result.getData(); + + this.logInfo("gamesResolutionLauncher onActivityResult intent: %s", + data + ); + + this.signInIntent(); }); m_gamesResolutionLauncher = gamesResolutionLauncher; @@ -204,7 +210,7 @@ private void signInSilently() { AuthenticationResult result = isAuthenticatedTask.getResult(); if (result.isAuthenticated() == false) { - this.logInfo("google game social isAuthenticated failed"); + this.logInfo("signInSilently isAuthenticated failed, trying signInIntent"); m_isAuthenticated = false; @@ -212,13 +218,23 @@ private void signInSilently() { m_cachedAchievements.clear(); } + if (MenginePreferences.getPreferenceBoolean(PREFERENCE_KEY_TRYING_SIGN_IN_INTENT, false) == false) { + MenginePreferences.setPreferenceBoolean(PREFERENCE_KEY_TRYING_SIGN_IN_INTENT, true); + + this.logInfo("signInSilently trying signInIntent"); + + this.signInIntent(); + } + return; } - this.logInfo("google game social isAuthenticated success"); + this.logInfo("signInSilently isAuthenticated success"); m_isAuthenticated = true; + MenginePreferences.setPreferenceBoolean(PREFERENCE_KEY_TRYING_SIGN_IN_INTENT, false); + this.activateSemaphore("GoogleGameSocialAuthenticated"); }); } @@ -291,6 +307,8 @@ public void signInIntent() { m_isAuthenticated = true; + MenginePreferences.setPreferenceBoolean(PREFERENCE_KEY_TRYING_SIGN_IN_INTENT, false); + this.activateSemaphore("GoogleGameSocialAuthenticated"); }); } From 31fe09522f25df36c1439719831a15314c78b94b Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 24 Nov 2025 22:59:31 +0200 Subject: [PATCH 146/169] wip apple build --- src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm | 4 ++-- .../AppleGameCenterApplicationDelegate.mm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm index 402f6de522..b5f4c00131 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -122,20 +122,20 @@ - (void)initializeAdMob { IOS_LOGGER_MESSAGE(@"AdMob: %@", versionString); +#if defined(MENGINE_DEBUG) BOOL MengineAppleAdMobPlugin_RequestConfigurationTestDeviceIdsEnabled = [AppleBundle getPluginConfigBoolean:@PLUGIN_BUNDLE_NAME withKey:@"RequestConfigurationTestDeviceIdsEnabled" withDefault:NO]; if (MengineAppleAdMobPlugin_RequestConfigurationTestDeviceIdsEnabled == YES) { GADRequestConfiguration * requestConfiguration = mobileAds.requestConfiguration; -#if defined(MENGINE_DEBUG) if ([AppleDetail hasOption:@"admob.test_device_advertising"] == YES) { NSString * testDeviceId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; requestConfiguration.testDeviceIdentifiers = @[testDeviceId]; IOS_LOGGER_MESSAGE(@"[AdMob] test device id: %@", testDeviceId); } -#endif } +#endif id advertisement = [iOSDetail getPluginDelegateOfProtocol:@protocol(AppleAdvertisementInterface)]; diff --git a/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm b/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm index 566b1f23e1..18f115829e 100644 --- a/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm +++ b/src/Plugins/AppleGameCenterPlugin/AppleGameCenterApplicationDelegate.mm @@ -179,7 +179,7 @@ - (BOOL)resetAchievements { IOS_LOGGER_MESSAGE( @"reset achievement success" ); }] ; - return YES; + return result; } - (BOOL)login:(void(^)(NSError *))handler { From c66d3d2fb63eed1c5a9b548b2483091fe6ab476b Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 25 Nov 2025 20:55:39 +0200 Subject: [PATCH 147/169] add iOS Amplitude add visitAnalyticsParameter --- cmake/Xcode_MacOS/CMakeLists.txt | 1 + cmake/Xcode_iOS/CMakeLists.txt | 1 + cmake/Xcode_iOS_Simulator/CMakeLists.txt | 1 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/plugins/Amplitude/build.gradle | 2 +- gradle/plugins/DataDog/build.gradle | 2 +- src/Bootstrapper/Bootstrapper.cpp | 8 + .../PythonGameEventReceiver.cpp | 60 +++---- src/Kernel/AnalyticsHelper.h | 70 +++++++- .../AndroidAnalyticsEventProvider.cpp | 58 +++---- .../iOSPlatform/iOSAnalyticsEventProvider.mm | 68 +++----- .../AppleAmplitudeAnalyticsEventProvider.h | 26 +++ .../AppleAmplitudeAnalyticsEventProvider.mm | 75 ++++++++ .../AppleAmplitudeApplicationDelegate.h | 10 ++ .../AppleAmplitudeApplicationDelegate.mm | 162 ++++++++++++++++++ .../AppleAmplitudePlugin.h | 26 +++ .../AppleAmplitudePlugin.mm | 48 ++++++ .../AppleAmplitudePlugin/CMakeLists.txt | 20 +++ .../AppleDevToDevAnalyticsEventProvider.mm | 64 +++---- .../AppleFirebaseAnalyticsEventProvider.mm | 88 ++++------ src/Plugins/CMakeLists.txt | 4 + 21 files changed, 569 insertions(+), 227 deletions(-) create mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h create mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm create mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h create mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm create mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h create mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm create mode 100644 src/Plugins/AppleAmplitudePlugin/CMakeLists.txt diff --git a/cmake/Xcode_MacOS/CMakeLists.txt b/cmake/Xcode_MacOS/CMakeLists.txt index 277d4581af..63997d301f 100644 --- a/cmake/Xcode_MacOS/CMakeLists.txt +++ b/cmake/Xcode_MacOS/CMakeLists.txt @@ -117,6 +117,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS OFF OFF "MENGINE_PLUGIN_APP ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE OFF OFF "MENGINE_PLUGIN_APPLE_AMPLITUDE") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV OFF OFF "MENGINE_PLUGIN_APPLE_DEVTODEV") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ONESIGNAL OFF OFF "MENGINE_PLUGIN_APPLE_ONESIGNAL") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ADMOB OFF OFF "MENGINE_PLUGIN_APPLE_ADMOB") diff --git a/cmake/Xcode_iOS/CMakeLists.txt b/cmake/Xcode_iOS/CMakeLists.txt index e1449ece99..6db4f9129b 100644 --- a/cmake/Xcode_iOS/CMakeLists.txt +++ b/cmake/Xcode_iOS/CMakeLists.txt @@ -119,6 +119,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS OFF OFF "MENGINE_PLUGIN_APP ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE OFF OFF "MENGINE_PLUGIN_APPLE_AMPLITUDE") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV OFF OFF "MENGINE_PLUGIN_APPLE_DEVTODEV") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ONESIGNAL OFF OFF "MENGINE_PLUGIN_APPLE_ONESIGNAL") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMAZON OFF OFF "MENGINE_PLUGIN_APPLE_AMAZON") diff --git a/cmake/Xcode_iOS_Simulator/CMakeLists.txt b/cmake/Xcode_iOS_Simulator/CMakeLists.txt index f601743a35..639b1ed69f 100644 --- a/cmake/Xcode_iOS_Simulator/CMakeLists.txt +++ b/cmake/Xcode_iOS_Simulator/CMakeLists.txt @@ -112,6 +112,7 @@ ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS OFF OFF "MENGINE_PLUGIN_APP ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_REMOTECONFIG") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING OFF OFF "MENGINE_PLUGIN_APPLE_FIREBASE_PERFORMANCEMONITORING") +ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE OFF OFF "MENGINE_PLUGIN_APPLE_AMPLITUDE") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV OFF OFF "MENGINE_PLUGIN_APPLE_DEVTODEV") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_ONESIGNAL OFF OFF "MENGINE_PLUGIN_APPLE_ONESIGNAL") ADD_PLUGIN(MENGINE_PLUGIN_APPLE_AMAZON OFF OFF "MENGINE_PLUGIN_APPLE_AMAZON") diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index a302e1d920..1c41947bf5 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Sep 24 12:58:29 EEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle/plugins/Amplitude/build.gradle b/gradle/plugins/Amplitude/build.gradle index a5484031f1..30fb766d09 100644 --- a/gradle/plugins/Amplitude/build.gradle +++ b/gradle/plugins/Amplitude/build.gradle @@ -6,7 +6,7 @@ android { } dependencies { - implementation 'com.squareup.okhttp3:okhttp:5.3.0' + implementation 'com.squareup.okhttp3:okhttp:5.3.2' implementation 'com.amplitude:analytics-android:1.22.4' } \ No newline at end of file diff --git a/gradle/plugins/DataDog/build.gradle b/gradle/plugins/DataDog/build.gradle index 5622a412a7..644e4feb0c 100644 --- a/gradle/plugins/DataDog/build.gradle +++ b/gradle/plugins/DataDog/build.gradle @@ -15,5 +15,5 @@ android { } dependencies { - implementation 'com.datadoghq:dd-sdk-android-logs:3.2.0' + implementation 'com.datadoghq:dd-sdk-android-logs:3.3.0' } \ No newline at end of file diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index 3ebd405891..bec2c8cad1 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -458,6 +458,10 @@ PLUGIN_EXPORT( AppleStoreInAppPurchase ); PLUGIN_EXPORT( AppleAdjust ); #endif ////////////////////////////////////////////////////////////////////////// +#if defined(MENGINE_PLUGIN_APPLE_AMPLITUDE_STATIC) +PLUGIN_EXPORT( AppleAmplitude ); +#endif +////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_PLUGIN_APPLE_DEVTODEV_STATIC) PLUGIN_EXPORT( AppleDevToDev ); #endif @@ -1513,6 +1517,10 @@ namespace Mengine MENGINE_ADD_PLUGIN( AppleAdjust, "plugin AppleAdjust...", MENGINE_DOCUMENT_FACTORABLE ); #endif +#if defined(MENGINE_PLUGIN_APPLE_AMPLITUDE_STATIC) + MENGINE_ADD_PLUGIN( AppleAmplitude, "plugin AppleAmplitude...", MENGINE_DOCUMENT_FACTORABLE ); +#endif + #if defined(MENGINE_PLUGIN_APPLE_DEVTODEV_STATIC) MENGINE_ADD_PLUGIN( AppleDevToDev, "plugin AppleDevToDev...", MENGINE_DOCUMENT_FACTORABLE ); #endif diff --git a/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp b/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp index cf2eb0d73d..33ddd90fc7 100644 --- a/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp +++ b/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp @@ -1,6 +1,7 @@ #include "PythonGameEventReceiver.h" #include "Interface/PlayerServiceInterface.h" +#include "Kernel/AnalyticsHelper.h" namespace Mengine { @@ -317,46 +318,27 @@ namespace Mengine _event->foreachParameters( [¶ms]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) { - EAnalyticsEventParameterType parameterType = _parameter->getType(); - - switch( parameterType ) + Helper::visitAnalyticsParameter( _parameter + , [¶ms, &_name]( bool _value ) { - case EAEPT_BOOLEAN: - { - AnalyticsEventParameterBooleanInterfacePtr parameter_boolean = AnalyticsEventParameterBooleanInterfacePtr::from( _parameter ); - bool parameter_value = parameter_boolean->resolveValue(); - - params.set( _name, parameter_value ); - }break; - case EAEPT_INTEGER: - { - AnalyticsEventParameterIntegerInterfacePtr parameter_integer = AnalyticsEventParameterIntegerInterfacePtr::from( _parameter ); - int64_t parameter_value = parameter_integer->resolveValue(); - - params.set( _name, parameter_value ); - }break; - case EAEPT_DOUBLE: - { - AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); - double parameter_value = parameter_double->resolveValue(); - - params.set( _name, parameter_value ); - }break; - case EAEPT_STRING: - { - AnalyticsEventParameterStringInterfacePtr parameter_string = AnalyticsEventParameterStringInterfacePtr::from( _parameter ); - const String & parameter_value = parameter_string->resolveValue(); - - params.set( _name, parameter_value ); - }break; - case EAEPT_CONSTSTRING: - { - AnalyticsEventParameterConstStringInterfacePtr parameter_string = AnalyticsEventParameterConstStringInterfacePtr::from( _parameter ); - const ConstString & parameter_value = parameter_string->resolveValue(); - - params.set( _name, parameter_value ); - }break; - } + params.set( _name, _value ); + } + , [¶ms, &_name]( int64_t _value ) + { + params.set( _name, _value ); + } + , [¶ms, &_name]( double _value ) + { + params.set( _name, _value ); + } + , [¶ms, &_name]( const String & _value ) + { + params.set( _name, _value ); + } + , [¶ms, &_name]( const ConstString & _value ) + { + params.set( _name, _value ); + } ); }); const ConstString & name = _event->getName(); diff --git a/src/Kernel/AnalyticsHelper.h b/src/Kernel/AnalyticsHelper.h index 9f959689e3..bfccb6aac7 100644 --- a/src/Kernel/AnalyticsHelper.h +++ b/src/Kernel/AnalyticsHelper.h @@ -1,11 +1,63 @@ #pragma once -#include "Interface/AnalyticsServiceInterface.h" - -#define ANALYTICS_EVENT(Event) ANALYTICS_SERVICE()->buildEvent(STRINGIZE_STRING_LOCAL_I(Event)) -#define ANALYTICS_PARAMETER_BOOLEAN(Name, Value) ->addParameterBoolean(STRINGIZE_STRING_LOCAL_I(Name), (Value)) -#define ANALYTICS_PARAMETER_INTEGER(Name, Value) ->addParameterInteger(STRINGIZE_STRING_LOCAL_I(Name), (Value)) -#define ANALYTICS_PARAMETER_DOUBLE(Name, Value) ->addParameterDouble(STRINGIZE_STRING_LOCAL_I(Name), (Value)) -#define ANALYTICS_PARAMETER_STRING(Name, Value) ->addParameterString(STRINGIZE_STRING_LOCAL_I(Name), (Value)) -#define ANALYTICS_PARAMETER_CONSTSTRING(Name, Value) ->addParameterConstString(STRINGIZE_STRING_LOCAL_I(Name), (Value)) -#define ANALYTICS_LOG() ->log() +#include "Interface/AnalyticsEventParameterInterface.h" + +#include "Config/Variant.h" + +namespace Mengine +{ + namespace Helper + { + template + void visitAnalyticsParameter( const AnalyticsEventParameterInterfacePtr & _parameter, Fn && ... fn ) + { + auto dispatcher = Mengine::Helper::Overloaded{std::forward( fn ) ...}; + + EAnalyticsEventParameterType type = _parameter->getType(); + + switch( type ) + { + case EAEPT_BOOLEAN: + { + AnalyticsEventParameterBooleanInterfacePtr parameter_boolean = AnalyticsEventParameterBooleanInterfacePtr::from( _parameter ); + + bool value = parameter_boolean->resolveValue(); + + dispatcher( value ); + }break; + case EAEPT_INTEGER: + { + AnalyticsEventParameterIntegerInterfacePtr parameter_integer = AnalyticsEventParameterIntegerInterfacePtr::from( _parameter ); + + int64_t value = parameter_integer->resolveValue(); + + dispatcher( value ); + }break; + case EAEPT_DOUBLE: + { + AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); + + double value = parameter_double->resolveValue(); + + dispatcher( value ); + }break; + case EAEPT_STRING: + { + AnalyticsEventParameterStringInterfacePtr parameter_string = AnalyticsEventParameterStringInterfacePtr::from( _parameter ); + + const String & value = parameter_string->resolveValue(); + + dispatcher( value ); + }break; + case EAEPT_CONSTSTRING: + { + AnalyticsEventParameterConstStringInterfacePtr parameter_conststring = AnalyticsEventParameterConstStringInterfacePtr::from( _parameter ); + + const ConstString & value = parameter_conststring->resolveValue(); + + dispatcher( value ); + }break; + } + } + } +} \ No newline at end of file diff --git a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp index e850e87a0b..2850a9e3f2 100644 --- a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp +++ b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp @@ -5,6 +5,7 @@ #include "Environment/Android/AndroidFragmentHelper.h" #include "Kernel/AssertionMemoryPanic.h" +#include "Kernel/AnalyticsHelper.h" namespace Mengine { @@ -42,48 +43,29 @@ namespace Mengine { jobject jobject_name = Helper::AndroidMakeJObjectString( jenv, _name); - EAnalyticsEventParameterType parameterType = _parameter->getType(); - jobject jobject_parameter = nullptr; - switch( parameterType ) + Helper::visitAnalyticsParameter( _parameter + , [jenv, &jobject_parameter]( bool _value ) + { + jobject_parameter = Helper::AndroidMakeJObjectBoolean( jenv, _value ); + } + , [jenv, &jobject_parameter]( int64_t _value ) + { + jobject_parameter = Helper::AndroidMakeJObjectLong( jenv, _value ); + } + , [jenv, &jobject_parameter]( double _value ) + { + jobject_parameter = Helper::AndroidMakeJObjectDouble( jenv, _value ); + } + , [jenv, &jobject_parameter]( const String & _value ) { - case EAEPT_BOOLEAN: - { - AnalyticsEventParameterBooleanInterfacePtr parameter_boolean = AnalyticsEventParameterBooleanInterfacePtr::from( _parameter ); - bool parameter_value = parameter_boolean->resolveValue(); - - jobject_parameter = Helper::AndroidMakeJObjectBoolean( jenv, parameter_value ); - }break; - case EAEPT_INTEGER: - { - AnalyticsEventParameterIntegerInterfacePtr parameter_integer = AnalyticsEventParameterIntegerInterfacePtr::from( _parameter ); - int64_t parameter_value = parameter_integer->resolveValue(); - - jobject_parameter = Helper::AndroidMakeJObjectLong( jenv, parameter_value ); - }break; - case EAEPT_DOUBLE: - { - AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); - double parameter_value = parameter_double->resolveValue(); - - jobject_parameter = Helper::AndroidMakeJObjectDouble( jenv, parameter_value ); - }break; - case EAEPT_STRING: - { - AnalyticsEventParameterStringInterfacePtr parameter_string = AnalyticsEventParameterStringInterfacePtr::from( _parameter ); - const String & parameter_value = parameter_string->resolveValue(); - - jobject_parameter = Helper::AndroidMakeJObjectString( jenv, parameter_value ); - }break; - case EAEPT_CONSTSTRING: - { - AnalyticsEventParameterConstStringInterfacePtr parameter_conststring = AnalyticsEventParameterConstStringInterfacePtr::from( _parameter ); - const ConstString & parameter_value = parameter_conststring->resolveValue(); - - jobject_parameter = Helper::AndroidMakeJObjectString( jenv, parameter_value ); - }break; + jobject_parameter = Helper::AndroidMakeJObjectString( jenv, _value ); } + , [jenv, &jobject_parameter]( const ConstString & _value ) + { + jobject_parameter = Helper::AndroidMakeJObjectString( jenv, _value ); + } ); Helper::AndroidPutJObjectMap( jenv, jobject_parameters, jobject_name, jobject_parameter ); diff --git a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm index 69d59657ec..4de8417c50 100644 --- a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm +++ b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm @@ -4,6 +4,7 @@ #import "Environment/iOS/iOSAnalytics.h" #include "Kernel/AssertionMemoryPanic.h" +#include "Kernel/AnalyticsHelper.h" namespace Mengine { @@ -28,54 +29,33 @@ const Char * name_str = _name.c_str(); ConstString::size_type name_size = _name.size(); - EAnalyticsEventParameterType parameterType = _parameter->getType(); + MENGINE_UNUSED( name_size ); - switch( parameterType ) + Helper::visitAnalyticsParameter( _parameter + , [parameters, name_str]( bool _value ) { - case EAEPT_BOOLEAN: - { - AnalyticsEventParameterBooleanInterfacePtr parameter_boolean = AnalyticsEventParameterBooleanInterfacePtr::from( _parameter ); - bool parameter_value = parameter_boolean->resolveValue(); - - [parameters setValue:@(parameter_value) forKey:@(name_str)]; - }break; - case EAEPT_INTEGER: - { - AnalyticsEventParameterIntegerInterfacePtr parameter_integer = AnalyticsEventParameterIntegerInterfacePtr::from( _parameter ); - int64_t parameter_value = parameter_integer->resolveValue(); - - [parameters setValue:@(parameter_value) forKey:@(name_str)]; - }break; - case EAEPT_DOUBLE: - { - AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); - double parameter_value = parameter_double->resolveValue(); - - [parameters setValue:@(parameter_value) forKey:@(name_str)]; - }break; - case EAEPT_STRING: - { - AnalyticsEventParameterStringInterfacePtr parameter_string = AnalyticsEventParameterStringInterfacePtr::from( _parameter ); - const String & parameter_value = parameter_string->resolveValue(); - - String::size_type parameter_value_size = parameter_value.size(); - - const Char * parameter_value_str = parameter_value.c_str(); - - [parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - }break; - case EAEPT_CONSTSTRING: - { - AnalyticsEventParameterConstStringInterfacePtr parameter_string = AnalyticsEventParameterConstStringInterfacePtr::from( _parameter ); - const ConstString & parameter_value = parameter_string->resolveValue(); - - ConstString::size_type parameter_value_size = parameter_value.size(); - - const Char * parameter_value_str = parameter_value.c_str(); + [parameters setValue:@(_value) forKey:@(name_str)]; + } + , [parameters, name_str]( int64_t _value ) + { + [parameters setValue:@(_value) forKey:@(name_str)]; + } + , [parameters, name_str]( double _value ) + { + [parameters setValue:@(_value) forKey:@(name_str)]; + } + , [parameters, name_str]( const String & _value ) + { + const Char * parameter_value_str = _value.c_str(); - [parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - }break; + [parameters setValue:@(parameter_value_str) forKey:@(name_str)]; } + , [parameters, name_str]( const ConstString & _value ) + { + const Char * parameter_value_str = _value.c_str(); + + [parameters setValue:@(parameter_value_str) forKey:@(name_str)]; + } ); } ); [iOSAnalytics event:@(eventName_str) params:parameters]; diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h new file mode 100644 index 0000000000..1347fd8fb5 --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Interface/AnalyticsEventProviderInterface.h" + +#include "Kernel/ConstString.h" +#include "Kernel/Factorable.h" + +namespace Mengine +{ + class AppleAmplitudeAnalyticsEventProvider + : public AnalyticsEventProviderInterface + , public Factorable + { + DECLARE_FACTORABLE( AppleAmplitudeAnalyticsEventProvider ); + + public: + AppleAmplitudeAnalyticsEventProvider(); + ~AppleAmplitudeAnalyticsEventProvider() override; + + protected: + void onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) override; + void onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) override; + void onAnalyticsFlush() override; + }; +} + diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm new file mode 100644 index 0000000000..d095b0af8f --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm @@ -0,0 +1,75 @@ +#include "AppleAmplitudeAnalyticsEventProvider.h" + +#include "Kernel/AnalyticsHelper.h" + +#import + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + AppleAmplitudeAnalyticsEventProvider::AppleAmplitudeAnalyticsEventProvider() + { + } + ////////////////////////////////////////////////////////////////////////// + AppleAmplitudeAnalyticsEventProvider::~AppleAmplitudeAnalyticsEventProvider() + { + } + ////////////////////////////////////////////////////////////////////////// + void AppleAmplitudeAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) + { + const ConstString & eventName = _event->getName(); + const Char * eventName_str = eventName.c_str(); + + NSMutableDictionary * properties = [[NSMutableDictionary alloc] init]; + + _event->foreachParameters( [properties]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) + { + const Char * name_str = _name.c_str(); + + Helper::visitAnalyticsParameter( _parameter + , [properties, name_str]( bool _value ) + { + [properties setValue:@(_value) forKey:@(name_str)]; + } + , [properties, name_str]( int64_t _value ) + { + [properties setValue:@(_value) forKey:@(name_str)]; + } + , [properties, name_str]( double _value ) + { + [properties setValue:@(_value) forKey:@(name_str)]; + } + , [properties, name_str]( const String & _value ) + { + const Char * value_str = _value.c_str(); + + [properties setValue:@(value_str) forKey:@(name_str)]; + } + , [properties, name_str]( const ConstString & _value ) + { + const Char * value_str = _value.c_str(); + + [properties setValue:@(value_str) forKey:@(name_str)]; + } ); + } ); + + [[Amplitude instance] logEvent:@(eventName_str) withEventProperties:properties]; + } + ////////////////////////////////////////////////////////////////////////// + void AppleAmplitudeAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) + { + const Char * screenType_str = _screenType.c_str(); + const Char * screenName_str = _screenName.c_str(); + + [[Amplitude instance] logEvent:@"screen_view" + withEventProperties:@{@"screen_type": @(screenType_str), + @"screen_name": @(screenName_str)}]; + } + ////////////////////////////////////////////////////////////////////////// + void AppleAmplitudeAnalyticsEventProvider::onAnalyticsFlush() + { + [[Amplitude instance] uploadEvents]; + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h new file mode 100644 index 0000000000..fb5493537b --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h @@ -0,0 +1,10 @@ +#pragma once + +#import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" +#import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" +#import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" + +@interface AppleAmplitudeApplicationDelegate : NSObject + +@end + diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm new file mode 100644 index 0000000000..9be0d1a130 --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm @@ -0,0 +1,162 @@ +#import "AppleAmplitudeApplicationDelegate.h" + +#import "Environment/Apple/AppleBundle.h" +#import "Environment/Apple/AppleDetail.h" + +#import "Environment/iOS/iOSApplication.h" +#import "Environment/iOS/iOSAdRevenueParam.h" +#import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSUserParam.h" + +#import + +#define PLUGIN_BUNDLE_NAME "MengineAppleAmplitudePlugin" + +@implementation AppleAmplitudeApplicationDelegate + +#pragma mark - UIApplicationDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + MENGINE_UNUSED( application ); + MENGINE_UNUSED( launchOptions ); + + if( [AppleBundle hasPluginConfig:@PLUGIN_BUNDLE_NAME] == NO ) + { + IOS_LOGGER_ERROR( @"[AppleAmplitude] plugin config '%s' not found", PLUGIN_BUNDLE_NAME ); + return NO; + } + + NSString * apiKey = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"ApiKey" withDefault:nil]; + + if( apiKey == nil || apiKey.length == 0 ) + { + IOS_LOGGER_ERROR( @"[AppleAmplitude] plugin config '%s.ApiKey' is not specified", PLUGIN_BUNDLE_NAME ); + return NO; + } + + [[Amplitude instance] initializeApiKey:apiKey]; + + NSString * userId = [iOSApplication.sharedInstance getUserId]; + + if( userId.length != 0 ) + { + [[Amplitude instance] setUserId:userId]; + } + + NSString * installId = [iOSApplication.sharedInstance getInstallId]; + + if( installId.length != 0 ) + { + [[Amplitude instance] setDeviceId:installId]; + } + + NSInteger installTimestamp = [iOSApplication.sharedInstance getInstallTimestamp]; + NSString * installVersion = [iOSApplication.sharedInstance getInstallVersion]; + NSInteger installRND = [iOSApplication.sharedInstance getInstallRND]; + NSInteger sessionIndex = [iOSApplication.sharedInstance getSessionIndex]; + NSInteger sessionTimestamp = [iOSApplication.sharedInstance getSessionTimestamp]; + + AMPIdentify * identify = [AMPIdentify identify]; + + [identify set:@"is_publish" value:MENGINE_BUILD_PUBLISH_VALUE(@(YES), @(NO))]; + [identify set:@"is_debug" value:MENGINE_DEBUG_VALUE(@(YES), @(NO))]; + [identify set:@"install_id" value:installId]; + [identify set:@"install_timestamp" value:@(installTimestamp)]; + [identify set:@"install_version" value:installVersion]; + [identify set:@"install_rnd" value:@(installRND)]; + [identify set:@"session_index" value:@(sessionIndex)]; + [identify set:@"session_timestamp" value:@(sessionTimestamp)]; + + NSInteger currentTimestamp = [AppleDetail getTimestamp]; + NSInteger lifeTime = currentTimestamp - installTimestamp; + + [identify set:@"life_time" value:@(lifeTime)]; + + [[Amplitude instance] identify:identify]; + + return YES; +} + +#pragma mark - iOSPluginUserIdDelegateInterface + +- (void)onUserId:(iOSUserParam *)user { + [[Amplitude instance] setUserId:user.USER_ID]; +} + +- (void)onRemoveUserData { + Amplitude * amplitude = [Amplitude instance]; + + if( [amplitude respondsToSelector:@selector(reset)] == YES ) + { + [amplitude reset]; + return; + } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + if( [amplitude respondsToSelector:@selector(regenerateDeviceId)] == YES ) + { + [amplitude performSelector:@selector(regenerateDeviceId)]; + } +#pragma clang diagnostic pop + + [amplitude setUserId:nil]; + [amplitude setDeviceId:[iOSApplication.sharedInstance getInstallId]]; +} + +#pragma mark - iOSPluginAdRevenueDelegateInterface + +- (void)onAdRevenue:(iOSAdRevenueParam *)revenue { + AMPRevenue * ampRevenue = [AMPRevenue revenue]; + [ampRevenue setQuantity:1]; + [ampRevenue setPrice:revenue.REVENUE_VALUE]; + + if( revenue.REVENUE_FORMAT != nil ) + { + [ampRevenue setRevenueType:revenue.REVENUE_FORMAT]; + } + + NSMutableDictionary * properties = [NSMutableDictionary dictionary]; + + if( revenue.REVENUE_PLATFORM != nil ) { + properties[@"ad_platform"] = revenue.REVENUE_PLATFORM; + } + + if( revenue.REVENUE_SOURCE != nil ) { + properties[@"ad_source"] = revenue.REVENUE_SOURCE; + } + + if( revenue.REVENUE_FORMAT != nil ) { + properties[@"ad_format"] = revenue.REVENUE_FORMAT; + } + + if( revenue.REVENUE_UNIT != nil ) { + properties[@"ad_unit_id"] = revenue.REVENUE_UNIT; + } + + if( revenue.REVENUE_PLACEMENT != nil ) { + properties[@"placement"] = revenue.REVENUE_PLACEMENT; + } + + if( revenue.REVENUE_NETWORK_PLACEMENT != nil ) { + properties[@"network_placement"] = revenue.REVENUE_NETWORK_PLACEMENT; + } + + if( revenue.REVENUE_COUNTRY_CODE != nil ) { + properties[@"country_code"] = revenue.REVENUE_COUNTRY_CODE; + } + + if( revenue.REVENUE_CURRENCY != nil ) { + properties[@"currency"] = revenue.REVENUE_CURRENCY; + } + + if( properties.count != 0 ) + { + [ampRevenue setEventProperties:properties]; + } + + [[Amplitude instance] logRevenueV2:ampRevenue]; +} + +@end + diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h new file mode 100644 index 0000000000..5dda5f971b --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Interface/AnalyticsEventProviderInterface.h" + +#include "Kernel/PluginBase.h" + +namespace Mengine +{ + class AppleAmplitudePlugin + : public PluginBase + { + PLUGIN_DECLARE( "AppleAmplitude" ) + + public: + AppleAmplitudePlugin(); + ~AppleAmplitudePlugin() override; + + protected: + bool _initializePlugin() override; + void _finalizePlugin() override; + + protected: + AnalyticsEventProviderInterfacePtr m_provider; + }; +} + diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm new file mode 100644 index 0000000000..a240856514 --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm @@ -0,0 +1,48 @@ +#include "AppleAmplitudePlugin.h" + +#include "Interface/AnalyticsServiceInterface.h" + +#include "AppleAmplitudeAnalyticsEventProvider.h" + +#include "Kernel/FactorableUnique.h" +#include "Kernel/PluginHelper.h" + +////////////////////////////////////////////////////////////////////////// +PLUGIN_FACTORY( AppleAmplitude, Mengine::AppleAmplitudePlugin ); +////////////////////////////////////////////////////////////////////////// +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + AppleAmplitudePlugin::AppleAmplitudePlugin() + { + } + ////////////////////////////////////////////////////////////////////////// + AppleAmplitudePlugin::~AppleAmplitudePlugin() + { + } + ////////////////////////////////////////////////////////////////////////// + bool AppleAmplitudePlugin::_initializePlugin() + { + AnalyticsEventProviderInterfacePtr provider = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); + + ANALYTICS_SERVICE() + ->addEventProvider( provider ); + + m_provider = provider; + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void AppleAmplitudePlugin::_finalizePlugin() + { + if( m_provider != nullptr ) + { + ANALYTICS_SERVICE() + ->removeEventProvider( m_provider ); + + m_provider = nullptr; + } + } + ////////////////////////////////////////////////////////////////////////// +} + diff --git a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt new file mode 100644 index 0000000000..f90c94f48b --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt @@ -0,0 +1,20 @@ +MENGINE_PROJECT(AppleAmplitudePlugin) + +ADD_FILTER( +src + AppleAmplitudePlugin.h + AppleAmplitudePlugin.mm + + AppleAmplitudeAnalyticsEventProvider.h + AppleAmplitudeAnalyticsEventProvider.mm + + AppleAmplitudeApplicationDelegate.h + AppleAmplitudeApplicationDelegate.mm +) + +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE) + +ADD_MENGINE_COCOAPOD("Amplitude" "NO-GIT" "8.20.0") + +ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAmplitudeApplicationDelegate") + diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm index ad6e30d683..53c5546332 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm @@ -2,6 +2,7 @@ #include "Kernel/Logger.h" #include "Kernel/ConfigHelper.h" +#include "Kernel/AnalyticsHelper.h" #include "Config/StdString.h" @@ -29,51 +30,32 @@ _event->foreachParameters( [devtodev_parameters]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) { const Char * name_str = _name.c_str(); - - EAnalyticsEventParameterType parameterType = _parameter->getType(); - switch( parameterType ) + Helper::visitAnalyticsParameter( _parameter + , [devtodev_parameters, name_str]( bool _value ) { - case EAEPT_BOOLEAN: - { - AnalyticsEventParameterBooleanInterfacePtr parameter_boolean = AnalyticsEventParameterBooleanInterfacePtr::from( _parameter ); - bool parameter_value = parameter_boolean->resolveValue(); - - [devtodev_parameters addBool:@(name_str) value:@(parameter_value)]; - }break; - case EAEPT_INTEGER: - { - AnalyticsEventParameterIntegerInterfacePtr parameter_integer = AnalyticsEventParameterIntegerInterfacePtr::from( _parameter ); - int64_t parameter_value = parameter_integer->resolveValue(); - - [devtodev_parameters addInt:@(name_str) value:parameter_value]; - }break; - case EAEPT_DOUBLE: - { - AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); - double parameter_value = parameter_double->resolveValue(); - - [devtodev_parameters addDouble:@(name_str) value:parameter_value]; - }break; - case EAEPT_STRING: - { - AnalyticsEventParameterStringInterfacePtr parameter_string = AnalyticsEventParameterStringInterfacePtr::from( _parameter ); - const String & parameter_value = parameter_string->resolveValue(); - - const Char * parameter_value_str = parameter_value.c_str(); - - [devtodev_parameters addString:@(name_str) value:@(parameter_value_str)]; - }break; - case EAEPT_CONSTSTRING: - { - AnalyticsEventParameterConstStringInterfacePtr parameter_string = AnalyticsEventParameterConstStringInterfacePtr::from( _parameter ); - const ConstString & parameter_value = parameter_string->resolveValue(); - - const Char * parameter_value_str = parameter_value.c_str(); + [devtodev_parameters addBool:@(name_str) value:@(_value)]; + } + , [devtodev_parameters, name_str]( int64_t _value ) + { + [devtodev_parameters addInt:@(name_str) value:_value]; + } + , [devtodev_parameters, name_str]( double _value ) + { + [devtodev_parameters addDouble:@(name_str) value:_value]; + } + , [devtodev_parameters, name_str]( const String & _value ) + { + const Char * parameter_value_str = _value.c_str(); - [devtodev_parameters addString:@(name_str) value:@(parameter_value_str)]; - }break; + [devtodev_parameters addString:@(name_str) value:@(parameter_value_str)]; } + , [devtodev_parameters, name_str]( const ConstString & _value ) + { + const Char * parameter_value_str = _value.c_str(); + + [devtodev_parameters addString:@(name_str) value:@(parameter_value_str)]; + } ); } ); [DTDAnalytics customEvent:@(eventName_str) withParameters:devtodev_parameters]; diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm index d2ad3c0636..8795138cc3 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm @@ -3,6 +3,7 @@ #import "Environment/Apple/AppleString.h" #include "Kernel/Logger.h" +#include "Kernel/AnalyticsHelper.h" #include "Config/StdAlgorithm.h" @@ -51,65 +52,46 @@ } const Char * name_str = _name.c_str(); - - EAnalyticsEventParameterType parameterType = _parameter->getType(); - switch( parameterType ) + Helper::visitAnalyticsParameter( _parameter + , [firebase_parameters, name_str]( bool _value ) { - case EAEPT_BOOLEAN: - { - AnalyticsEventParameterBooleanInterfacePtr parameter_boolean = AnalyticsEventParameterBooleanInterfacePtr::from( _parameter ); - bool parameter_value = parameter_boolean->resolveValue(); - - [firebase_parameters setValue:@(parameter_value) forKey:@(name_str)]; - }break; - case EAEPT_INTEGER: - { - AnalyticsEventParameterIntegerInterfacePtr parameter_integer = AnalyticsEventParameterIntegerInterfacePtr::from( _parameter ); - int64_t parameter_value = parameter_integer->resolveValue(); - - [firebase_parameters setValue:@(parameter_value) forKey:@(name_str)]; - }break; - case EAEPT_DOUBLE: - { - AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); - double parameter_value = parameter_double->resolveValue(); - - [firebase_parameters setValue:@(parameter_value) forKey:@(name_str)]; - }break; - case EAEPT_STRING: + [firebase_parameters setValue:@(_value) forKey:@(name_str)]; + } + , [firebase_parameters, name_str]( int64_t _value ) + { + [firebase_parameters setValue:@(_value) forKey:@(name_str)]; + } + , [firebase_parameters, name_str]( double _value ) + { + [firebase_parameters setValue:@(_value) forKey:@(name_str)]; + } + , [firebase_parameters, name_str]( const String & _value ) + { + String::size_type parameter_value_size = _value.size(); + + if( parameter_value_size > 100 ) { - AnalyticsEventParameterStringInterfacePtr parameter_string = AnalyticsEventParameterStringInterfacePtr::from( _parameter ); - const String & parameter_value = parameter_string->resolveValue(); - - String::size_type parameter_value_size = parameter_value.size(); - - if( parameter_value_size > 100 ) - { - return; - } - - const Char * parameter_value_str = parameter_value.c_str(); + return; + } + + const Char * parameter_value_str = _value.c_str(); - [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - }break; - case EAEPT_CONSTSTRING: + [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; + } + , [firebase_parameters, name_str]( const ConstString & _value ) + { + ConstString::size_type parameter_value_size = _value.size(); + + if( parameter_value_size > 100 ) { - AnalyticsEventParameterConstStringInterfacePtr parameter_string = AnalyticsEventParameterConstStringInterfacePtr::from( _parameter ); - const ConstString & parameter_value = parameter_string->resolveValue(); - - ConstString::size_type parameter_value_size = parameter_value.size(); - - if( parameter_value_size > 100 ) - { - return; - } - - const Char * parameter_value_str = parameter_value.c_str(); + return; + } + + const Char * parameter_value_str = _value.c_str(); - [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - }break; - } + [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; + } ); } ); [FIRAnalytics logEventWithName:@(eventName_str) diff --git a/src/Plugins/CMakeLists.txt b/src/Plugins/CMakeLists.txt index dd7e74a7af..d8d676acdc 100644 --- a/src/Plugins/CMakeLists.txt +++ b/src/Plugins/CMakeLists.txt @@ -338,6 +338,10 @@ if(MENGINE_PLUGIN_APPLE_DEVTODEV) ADD_SUBDIRECTORY(AppleDevToDevPlugin) endif() +if(MENGINE_PLUGIN_APPLE_AMPLITUDE) + ADD_SUBDIRECTORY(AppleAmplitudePlugin) +endif() + if(MENGINE_PLUGIN_APPLE_ONESIGNAL) ADD_SUBDIRECTORY(AppleOneSignalPlugin) endif() From c9d573326e44d6f66cb6c3dceeea25f166941f50 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 25 Nov 2025 22:27:54 +0200 Subject: [PATCH 148/169] fix AppleAdMobInterstitialDelegate improve iOS Amplitude --- .../AppleAdMobInterstitialDelegate.mm | 9 ++- .../AppleAdMobRewardedDelegate.mm | 15 +++-- .../AppleAmplitudeAnalyticsEventProvider.mm | 2 +- .../AppleAmplitudeApplicationDelegate.mm | 61 ++++++------------- .../AppleAmplitudePlugin/CMakeLists.txt | 2 +- 5 files changed, 40 insertions(+), 49 deletions(-) diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm index 108f8ec463..dfdd8ddf4e 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm @@ -25,6 +25,10 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI } - (void) dealloc { + [self destroyInterstitialAd]; +} + +- (void) destroyInterstitialAd { if (self.m_interstitialAd != nil) { self.m_interstitialAd.fullScreenContentDelegate = nil; @@ -154,6 +158,8 @@ - (void)ad:(id)ad didFailToPresentFullScreenContentWi self.m_showing = NO; + [self destroyInterstitialAd]; + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; if (callback != nil) { @@ -173,13 +179,14 @@ - (void)adDidDismissFullScreenContent:(id)ad { self.m_showing = NO; + [self destroyInterstitialAd]; + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; if (callback != nil) { [callback onAppleAdvertisementShowSuccess:@"unknown"]; } - self.m_interstitialAd = nil; [self loadAd]; } diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm index e8fc418074..2ce021daa3 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm @@ -26,6 +26,10 @@ - (instancetype _Nullable) initWithAdUnitIdentifier:(NSString * _Nonnull)adUnitI } - (void) dealloc { + [self destroyRewardedAd]; +} + +- (void) destroyRewardedAd { if (self.m_rewardedAd != nil) { self.m_rewardedAd.fullScreenContentDelegate = nil; @@ -52,9 +56,9 @@ - (BOOL) canOffer:(NSString * _Nonnull)placement { - (BOOL) canYouShow:(NSString * _Nonnull)placement { BOOL ready = (self.m_rewardedAd != nil); - + [self log:@"canYouShow" withParams:@{@"placement":placement, @"ready":@(ready)}]; - + if( ready == NO ) { [self eventRewarded:@"show" params:@{ @"placement": placement, @@ -73,7 +77,7 @@ - (BOOL) canYouShow:(NSString * _Nonnull)placement { - (BOOL) show:(NSString * _Nonnull)placement { BOOL ready = (self.m_rewardedAd != nil); - + [self log:@"show" withParams:@{@"placement":placement, @"ready":@(ready)}]; [self eventRewarded:@"show" params:@{ @@ -198,6 +202,8 @@ - (void)ad:(id)ad didFailToPresentFullScreenContentWi @"error_code": @(error.code) }]; + [self destroyRewardedAd]; + self.m_showing = NO; id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; @@ -217,6 +223,8 @@ - (void)adDidDismissFullScreenContent:(id)ad { PLATFORM_SERVICE() ->unfreezePlatform( true, true, true ); + [self destroyRewardedAd]; + self.m_showing = NO; id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; @@ -225,7 +233,6 @@ - (void)adDidDismissFullScreenContent:(id)ad { [callback onAppleAdvertisementShowSuccess:@"unknown"]; } - self.m_rewardedAd = nil; [self loadAd]; } diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm index d095b0af8f..1ba983a111 100644 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm @@ -16,7 +16,7 @@ } ////////////////////////////////////////////////////////////////////////// void AppleAmplitudeAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) - { + { const ConstString & eventName = _event->getName(); const Char * eventName_str = eventName.c_str(); diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm index 9be0d1a130..44915e9c80 100644 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm @@ -20,35 +20,27 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( MENGINE_UNUSED( application ); MENGINE_UNUSED( launchOptions ); - if( [AppleBundle hasPluginConfig:@PLUGIN_BUNDLE_NAME] == NO ) - { + if ([AppleBundle hasPluginConfig:@PLUGIN_BUNDLE_NAME] == NO) { IOS_LOGGER_ERROR( @"[AppleAmplitude] plugin config '%s' not found", PLUGIN_BUNDLE_NAME ); + return NO; } NSString * apiKey = [AppleBundle getPluginConfigString:@PLUGIN_BUNDLE_NAME withKey:@"ApiKey" withDefault:nil]; - if( apiKey == nil || apiKey.length == 0 ) - { + if (apiKey == nil || apiKey.length == 0) { IOS_LOGGER_ERROR( @"[AppleAmplitude] plugin config '%s.ApiKey' is not specified", PLUGIN_BUNDLE_NAME ); + return NO; } - - [[Amplitude instance] initializeApiKey:apiKey]; - + NSString * userId = [iOSApplication.sharedInstance getUserId]; - if( userId.length != 0 ) - { - [[Amplitude instance] setUserId:userId]; - } + [[Amplitude instance] initializeApiKey:apiKey userId:userId]; NSString * installId = [iOSApplication.sharedInstance getInstallId]; - if( installId.length != 0 ) - { - [[Amplitude instance] setDeviceId:installId]; - } + [[Amplitude instance] setDeviceId:installId]; NSInteger installTimestamp = [iOSApplication.sharedInstance getInstallTimestamp]; NSString * installVersion = [iOSApplication.sharedInstance getInstallVersion]; @@ -85,21 +77,7 @@ - (void)onUserId:(iOSUserParam *)user { - (void)onRemoveUserData { Amplitude * amplitude = [Amplitude instance]; - - if( [amplitude respondsToSelector:@selector(reset)] == YES ) - { - [amplitude reset]; - return; - } - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if( [amplitude respondsToSelector:@selector(regenerateDeviceId)] == YES ) - { - [amplitude performSelector:@selector(regenerateDeviceId)]; - } -#pragma clang diagnostic pop - + [amplitude setUserId:nil]; [amplitude setDeviceId:[iOSApplication.sharedInstance getInstallId]]; } @@ -108,50 +86,49 @@ - (void)onRemoveUserData { - (void)onAdRevenue:(iOSAdRevenueParam *)revenue { AMPRevenue * ampRevenue = [AMPRevenue revenue]; + [ampRevenue setQuantity:1]; [ampRevenue setPrice:revenue.REVENUE_VALUE]; - if( revenue.REVENUE_FORMAT != nil ) - { + if (revenue.REVENUE_FORMAT != nil) { [ampRevenue setRevenueType:revenue.REVENUE_FORMAT]; } NSMutableDictionary * properties = [NSMutableDictionary dictionary]; - if( revenue.REVENUE_PLATFORM != nil ) { + if (revenue.REVENUE_PLATFORM != nil) { properties[@"ad_platform"] = revenue.REVENUE_PLATFORM; } - if( revenue.REVENUE_SOURCE != nil ) { + if (revenue.REVENUE_SOURCE != nil) { properties[@"ad_source"] = revenue.REVENUE_SOURCE; } - if( revenue.REVENUE_FORMAT != nil ) { + if (revenue.REVENUE_FORMAT != nil) { properties[@"ad_format"] = revenue.REVENUE_FORMAT; } - if( revenue.REVENUE_UNIT != nil ) { + if (revenue.REVENUE_UNIT != nil) { properties[@"ad_unit_id"] = revenue.REVENUE_UNIT; } - if( revenue.REVENUE_PLACEMENT != nil ) { + if (revenue.REVENUE_PLACEMENT != nil) { properties[@"placement"] = revenue.REVENUE_PLACEMENT; } - if( revenue.REVENUE_NETWORK_PLACEMENT != nil ) { + if (revenue.REVENUE_NETWORK_PLACEMENT != nil) { properties[@"network_placement"] = revenue.REVENUE_NETWORK_PLACEMENT; } - if( revenue.REVENUE_COUNTRY_CODE != nil ) { + if (revenue.REVENUE_COUNTRY_CODE != nil) { properties[@"country_code"] = revenue.REVENUE_COUNTRY_CODE; } - if( revenue.REVENUE_CURRENCY != nil ) { + if (revenue.REVENUE_CURRENCY != nil) { properties[@"currency"] = revenue.REVENUE_CURRENCY; } - if( properties.count != 0 ) - { + if (properties.count != 0) { [ampRevenue setEventProperties:properties]; } diff --git a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt index f90c94f48b..89b8536dec 100644 --- a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt +++ b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt @@ -14,7 +14,7 @@ src ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE) -ADD_MENGINE_COCOAPOD("Amplitude" "NO-GIT" "8.20.0") +ADD_MENGINE_COCOAPOD("Amplitude" "NO-GIT" "8.22.2") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAmplitudeApplicationDelegate") From 39642037598867f374a5dacfe295707e14bc8d2f Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 25 Nov 2025 22:42:49 +0200 Subject: [PATCH 149/169] clear iOS analytics --- .../Amplitude/MengineAmplitudePlugin.java | 31 ++--- .../MengineFirebaseAnalyticsPlugin.java | 45 +------- .../AppleAmplitudeAnalyticsEventProvider.h | 26 ----- .../AppleAmplitudeAnalyticsEventProvider.mm | 75 ------------- .../AppleAmplitudeApplicationDelegate.h | 3 +- .../AppleAmplitudeApplicationDelegate.mm | 17 +++ .../AppleAmplitudePlugin.h | 26 ----- .../AppleAmplitudePlugin.mm | 48 -------- .../AppleAmplitudePlugin/CMakeLists.txt | 8 -- .../AppleDevToDevAnalyticsEventProvider.h | 24 ---- .../AppleDevToDevAnalyticsEventProvider.mm | 77 ------------- .../AppleDevToDevApplicationDelegate.h | 3 +- .../AppleDevToDevApplicationDelegate.mm | 19 ++++ .../AppleDevToDevPlugin/AppleDevToDevPlugin.h | 25 ----- .../AppleDevToDevPlugin.mm | 50 --------- .../AppleDevToDevPlugin/CMakeLists.txt | 8 -- ...ppleFirebaseAnalyticsApplicationDelegate.h | 3 +- ...pleFirebaseAnalyticsApplicationDelegate.mm | 18 +++ .../AppleFirebaseAnalyticsEventProvider.h | 26 ----- .../AppleFirebaseAnalyticsEventProvider.mm | 106 ------------------ .../AppleFirebaseAnalyticsPlugin.h | 25 ----- .../AppleFirebaseAnalyticsPlugin.mm | 50 --------- .../CMakeLists.txt | 8 -- 23 files changed, 74 insertions(+), 647 deletions(-) delete mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h delete mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm delete mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h delete mode 100644 src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm delete mode 100644 src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.h delete mode 100644 src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm delete mode 100644 src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.h delete mode 100644 src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.mm delete mode 100644 src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.h delete mode 100644 src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm delete mode 100644 src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.h delete mode 100644 src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.mm diff --git a/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java b/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java index 172431f59a..80c8b49b25 100644 --- a/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java +++ b/gradle/plugins/Amplitude/src/main/java/org/Mengine/Plugin/Amplitude/MengineAmplitudePlugin.java @@ -10,6 +10,7 @@ import com.amplitude.core.network.NetworkTrackingPlugin; import com.amplitude.core.events.Identify; +import org.Mengine.Base.MengineAnalyticsEventCategory; import org.Mengine.Base.MengineApplication; import org.Mengine.Base.MengineListenerAdRevenue; import org.Mengine.Base.MengineListenerAnalytics; @@ -37,7 +38,7 @@ public class MengineAmplitudePlugin extends MengineService implements MengineLis protected Amplitude m_amplitude; @Override - public void onAppCreate(@NonNull MengineApplication application) throws MengineServiceInvalidInitializeException { + public void onAppPrepare(@NonNull MengineApplication application) throws MengineServiceInvalidInitializeException { String MengineAmplitudePlugin_ApiKey = this.getResourceString(METADATA_API_KEY); Configuration configuration = new Configuration(MengineAmplitudePlugin_ApiKey, application); @@ -102,26 +103,24 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS } @Override - public void onMengineChangeUserId(@NonNull MengineApplication application, String oldUserId, String newUserId) { - if (m_amplitude == null) { - return; - } + public void onAppTerminate(@NonNull MengineApplication application) { + m_amplitude.flush(); + m_amplitude = null; + } + @Override + public void onMengineChangeUserId(@NonNull MengineApplication application, String oldUserId, String newUserId) { m_amplitude.setUserId(newUserId); } @Override public void onMengineRemoveUserData(@NonNull MengineApplication application) { - if (m_amplitude == null) { - return; - } - m_amplitude.reset(); } @Override public void onMengineAnalyticsEvent(@NonNull MengineApplication application, @NonNull MengineParamAnalyticsEvent param) { - if (m_amplitude == null) { + if (param.ANALYTICS_CATEGORY == MengineAnalyticsEventCategory.MengineAnalyticsEventCategory_System) { return; } @@ -134,10 +133,6 @@ public void onMengineAnalyticsEvent(@NonNull MengineApplication application, @No @Override public void onMengineAnalyticsScreenView(@NonNull MengineApplication application, @NonNull String screenType, @NonNull String screenName) { - if (m_amplitude == null) { - return; - } - Map eventProperties = new HashMap<>(); eventProperties.put("screen_type", screenType); eventProperties.put("screen_name", screenName); @@ -147,19 +142,11 @@ public void onMengineAnalyticsScreenView(@NonNull MengineApplication application @Override public void onMengineAnalyticsFlush(@NonNull MengineApplication application) { - if (m_amplitude == null) { - return; - } - m_amplitude.flush(); } @Override public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull MengineParamAdRevenue revenue) { - if (m_amplitude == null) { - return; - } - Revenue r = new Revenue(); r.setCurrency(revenue.ADREVENUE_REVENUE_CURRENCY); r.setPrice(revenue.ADREVENUE_REVENUE_VALUE); diff --git a/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java b/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java index 70717bec91..89fc8cdada 100644 --- a/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java +++ b/gradle/plugins/FirebaseAnalytics/src/main/java/org/Mengine/Plugin/FirebaseAnalytics/MengineFirebaseAnalyticsPlugin.java @@ -75,20 +75,17 @@ public void onAppPrepare(@NonNull MengineApplication application) throws Mengine } @Override - public void onMengineChangeUserId(@NonNull MengineApplication application, String oldUserId, String newUserId) { - if (m_firebaseAnalytics == null) { - return; - } + public void onAppTerminate(@NonNull MengineApplication application) { + m_firebaseAnalytics = null; + } + @Override + public void onMengineChangeUserId(@NonNull MengineApplication application, String oldUserId, String newUserId) { m_firebaseAnalytics.setUserId(newUserId); } @Override public void onMengineRemoveUserData(@NonNull MengineApplication application) { - if (m_firebaseAnalytics == null) { - return; - } - m_firebaseAnalytics.resetAnalyticsData(); m_firebaseAnalytics.setUserId(null); } @@ -128,10 +125,6 @@ private void updateBundle(@NonNull Bundle bundle, @NonNull Map p @Override public void onMengineAnalyticsEvent(@NonNull MengineApplication application, @NonNull MengineParamAnalyticsEvent param) { - if (m_firebaseAnalytics == null) { - return; - } - Bundle bundle = new Bundle(); this.updateBundle(bundle, param.ANALYTICS_BASES); @@ -142,10 +135,6 @@ public void onMengineAnalyticsEvent(@NonNull MengineApplication application, @No @Override public void onMengineAnalyticsScreenView(@NonNull MengineApplication application, @NonNull String screenType, @NonNull String screenName) { - if (m_firebaseAnalytics == null) { - return; - } - Bundle params = new Bundle(); params.putString(FirebaseAnalytics.Param.SCREEN_CLASS, screenType); @@ -188,10 +177,6 @@ private static String getAdMediation(MengineAdMediation adMediation) { @Override public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull MengineParamAdRevenue revenue) { - if (m_firebaseAnalytics == null) { - return; - } - MengineAdMediation adMediation = revenue.ADREVENUE_MEDIATION; String adFirebaseMediation = MengineFirebaseAnalyticsPlugin.getAdMediation(adMediation); String networkName = revenue.ADREVENUE_NETWORK; @@ -214,10 +199,6 @@ public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull @Override public void onMengineTransparencyConsent(@NonNull MengineApplication application, @NonNull MengineParamTransparencyConsent tcParam) { - if (m_firebaseAnalytics == null) { - return; - } - boolean AD_STORAGE = tcParam.getConsentAdStorage(); boolean ANALYTICS_STORAGE = tcParam.getConsentAnalyticsStorage(); boolean AD_USER_DATA = tcParam.getConsentAdUserData(); @@ -241,10 +222,6 @@ public void onMengineTransparencyConsent(@NonNull MengineApplication application @Override public void onMengineUnlockAchievement(@NonNull MengineApplication application, String achievementId) { - if (m_firebaseAnalytics == null) { - return; - } - Bundle params = new Bundle(); params.putString(FirebaseAnalytics.Param.ACHIEVEMENT_ID, achievementId); @@ -253,28 +230,16 @@ public void onMengineUnlockAchievement(@NonNull MengineApplication application, @Override public void onMengineIncrementAchievement(@NonNull MengineApplication application, String achievementId, int numSteps) { - if (m_firebaseAnalytics == null) { - return; - } - //Todo: implement increment achievement } @Override public void onMengineRevealAchievement(@NonNull MengineApplication application, String achievementId) { - if (m_firebaseAnalytics == null) { - return; - } - //Todo: implement reveal achievement } @Override public void onMengineSubmitLeaderboardScore(@NonNull MengineApplication application, String leaderboardId, long score) { - if (m_firebaseAnalytics == null) { - return; - } - Bundle params = new Bundle(); params.putLong(FirebaseAnalytics.Param.SCORE, score); params.putString(FirebaseAnalytics.Param.CHARACTER, "LEADERBOARD_" + leaderboardId); diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h deleted file mode 100644 index 1347fd8fb5..0000000000 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Interface/AnalyticsEventProviderInterface.h" - -#include "Kernel/ConstString.h" -#include "Kernel/Factorable.h" - -namespace Mengine -{ - class AppleAmplitudeAnalyticsEventProvider - : public AnalyticsEventProviderInterface - , public Factorable - { - DECLARE_FACTORABLE( AppleAmplitudeAnalyticsEventProvider ); - - public: - AppleAmplitudeAnalyticsEventProvider(); - ~AppleAmplitudeAnalyticsEventProvider() override; - - protected: - void onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) override; - void onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) override; - void onAnalyticsFlush() override; - }; -} - diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm deleted file mode 100644 index 1ba983a111..0000000000 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeAnalyticsEventProvider.mm +++ /dev/null @@ -1,75 +0,0 @@ -#include "AppleAmplitudeAnalyticsEventProvider.h" - -#include "Kernel/AnalyticsHelper.h" - -#import - -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - AppleAmplitudeAnalyticsEventProvider::AppleAmplitudeAnalyticsEventProvider() - { - } - ////////////////////////////////////////////////////////////////////////// - AppleAmplitudeAnalyticsEventProvider::~AppleAmplitudeAnalyticsEventProvider() - { - } - ////////////////////////////////////////////////////////////////////////// - void AppleAmplitudeAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) - { - const ConstString & eventName = _event->getName(); - const Char * eventName_str = eventName.c_str(); - - NSMutableDictionary * properties = [[NSMutableDictionary alloc] init]; - - _event->foreachParameters( [properties]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) - { - const Char * name_str = _name.c_str(); - - Helper::visitAnalyticsParameter( _parameter - , [properties, name_str]( bool _value ) - { - [properties setValue:@(_value) forKey:@(name_str)]; - } - , [properties, name_str]( int64_t _value ) - { - [properties setValue:@(_value) forKey:@(name_str)]; - } - , [properties, name_str]( double _value ) - { - [properties setValue:@(_value) forKey:@(name_str)]; - } - , [properties, name_str]( const String & _value ) - { - const Char * value_str = _value.c_str(); - - [properties setValue:@(value_str) forKey:@(name_str)]; - } - , [properties, name_str]( const ConstString & _value ) - { - const Char * value_str = _value.c_str(); - - [properties setValue:@(value_str) forKey:@(name_str)]; - } ); - } ); - - [[Amplitude instance] logEvent:@(eventName_str) withEventProperties:properties]; - } - ////////////////////////////////////////////////////////////////////////// - void AppleAmplitudeAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) - { - const Char * screenType_str = _screenType.c_str(); - const Char * screenName_str = _screenName.c_str(); - - [[Amplitude instance] logEvent:@"screen_view" - withEventProperties:@{@"screen_type": @(screenType_str), - @"screen_name": @(screenName_str)}]; - } - ////////////////////////////////////////////////////////////////////////// - void AppleAmplitudeAnalyticsEventProvider::onAnalyticsFlush() - { - [[Amplitude instance] uploadEvents]; - } - ////////////////////////////////////////////////////////////////////////// -} - diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h index fb5493537b..6c1dd0c73c 100644 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h @@ -3,8 +3,9 @@ #import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" #import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" #import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" +#import "Environment/iOS/iOSPluginAnalyticDelegateInterface.h" -@interface AppleAmplitudeApplicationDelegate : NSObject +@interface AppleAmplitudeApplicationDelegate : NSObject @end diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm index 44915e9c80..55bfe1ce2a 100644 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm @@ -135,5 +135,22 @@ - (void)onAdRevenue:(iOSAdRevenueParam *)revenue { [[Amplitude instance] logRevenueV2:ampRevenue]; } +#pragma mark - iOSPluginAnalyticDelegateInterface + +- (void)onAnalyticEvent:(NSString *)event params:(NSDictionary *)params { + [[Amplitude instance] logEvent:event withEventProperties:params]; +} + +- (void)onAnalyticScreen:(NSString *)screen type:(NSString *)type { + [[Amplitude instance] logEvent:@"screen_view" withEventProperties:@{ + @"screen_name": screen, + @"screen_type": type + }]; +} + +- (void)onAnalyticFlush { + [[Amplitude instance] uploadEvents]; +} + @end diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h deleted file mode 100644 index 5dda5f971b..0000000000 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Interface/AnalyticsEventProviderInterface.h" - -#include "Kernel/PluginBase.h" - -namespace Mengine -{ - class AppleAmplitudePlugin - : public PluginBase - { - PLUGIN_DECLARE( "AppleAmplitude" ) - - public: - AppleAmplitudePlugin(); - ~AppleAmplitudePlugin() override; - - protected: - bool _initializePlugin() override; - void _finalizePlugin() override; - - protected: - AnalyticsEventProviderInterfacePtr m_provider; - }; -} - diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm deleted file mode 100644 index a240856514..0000000000 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudePlugin.mm +++ /dev/null @@ -1,48 +0,0 @@ -#include "AppleAmplitudePlugin.h" - -#include "Interface/AnalyticsServiceInterface.h" - -#include "AppleAmplitudeAnalyticsEventProvider.h" - -#include "Kernel/FactorableUnique.h" -#include "Kernel/PluginHelper.h" - -////////////////////////////////////////////////////////////////////////// -PLUGIN_FACTORY( AppleAmplitude, Mengine::AppleAmplitudePlugin ); -////////////////////////////////////////////////////////////////////////// -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - AppleAmplitudePlugin::AppleAmplitudePlugin() - { - } - ////////////////////////////////////////////////////////////////////////// - AppleAmplitudePlugin::~AppleAmplitudePlugin() - { - } - ////////////////////////////////////////////////////////////////////////// - bool AppleAmplitudePlugin::_initializePlugin() - { - AnalyticsEventProviderInterfacePtr provider = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); - - ANALYTICS_SERVICE() - ->addEventProvider( provider ); - - m_provider = provider; - - return true; - } - ////////////////////////////////////////////////////////////////////////// - void AppleAmplitudePlugin::_finalizePlugin() - { - if( m_provider != nullptr ) - { - ANALYTICS_SERVICE() - ->removeEventProvider( m_provider ); - - m_provider = nullptr; - } - } - ////////////////////////////////////////////////////////////////////////// -} - diff --git a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt index 89b8536dec..2dbdd158cf 100644 --- a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt +++ b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt @@ -2,18 +2,10 @@ MENGINE_PROJECT(AppleAmplitudePlugin) ADD_FILTER( src - AppleAmplitudePlugin.h - AppleAmplitudePlugin.mm - - AppleAmplitudeAnalyticsEventProvider.h - AppleAmplitudeAnalyticsEventProvider.mm - AppleAmplitudeApplicationDelegate.h AppleAmplitudeApplicationDelegate.mm ) -ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE) - ADD_MENGINE_COCOAPOD("Amplitude" "NO-GIT" "8.22.2") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAmplitudeApplicationDelegate") diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.h b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.h deleted file mode 100644 index f1de5a7160..0000000000 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "Interface/AnalyticsEventProviderInterface.h" - -#include "Kernel/Factorable.h" - -namespace Mengine -{ - class AppleDevToDevAnalyticsEventProvider - : public AnalyticsEventProviderInterface - , public Factorable - { - public: - AppleDevToDevAnalyticsEventProvider(); - ~AppleDevToDevAnalyticsEventProvider() override; - - protected: - void onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) override; - void onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) override; - - protected: - void onAnalyticsFlush() override; - }; -} diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm deleted file mode 100644 index 53c5546332..0000000000 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm +++ /dev/null @@ -1,77 +0,0 @@ -#include "AppleDevToDevAnalyticsEventProvider.h" - -#include "Kernel/Logger.h" -#include "Kernel/ConfigHelper.h" -#include "Kernel/AnalyticsHelper.h" - -#include "Config/StdString.h" - -#import - -////////////////////////////////////////////////////////////////////////// -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - AppleDevToDevAnalyticsEventProvider::AppleDevToDevAnalyticsEventProvider() - { - } - ////////////////////////////////////////////////////////////////////////// - AppleDevToDevAnalyticsEventProvider::~AppleDevToDevAnalyticsEventProvider() - { - } - ////////////////////////////////////////////////////////////////////////// - void AppleDevToDevAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) - { - const ConstString & eventName = _event->getName(); - const Char * eventName_str = eventName.c_str(); - - DTDCustomEventParameters * devtodev_parameters = [[DTDCustomEventParameters alloc] init]; - - _event->foreachParameters( [devtodev_parameters]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) - { - const Char * name_str = _name.c_str(); - - Helper::visitAnalyticsParameter( _parameter - , [devtodev_parameters, name_str]( bool _value ) - { - [devtodev_parameters addBool:@(name_str) value:@(_value)]; - } - , [devtodev_parameters, name_str]( int64_t _value ) - { - [devtodev_parameters addInt:@(name_str) value:_value]; - } - , [devtodev_parameters, name_str]( double _value ) - { - [devtodev_parameters addDouble:@(name_str) value:_value]; - } - , [devtodev_parameters, name_str]( const String & _value ) - { - const Char * parameter_value_str = _value.c_str(); - - [devtodev_parameters addString:@(name_str) value:@(parameter_value_str)]; - } - , [devtodev_parameters, name_str]( const ConstString & _value ) - { - const Char * parameter_value_str = _value.c_str(); - - [devtodev_parameters addString:@(name_str) value:@(parameter_value_str)]; - } ); - } ); - - [DTDAnalytics customEvent:@(eventName_str) withParameters:devtodev_parameters]; - } - ////////////////////////////////////////////////////////////////////////// - void AppleDevToDevAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) - { - MENGINE_UNUSED( _screenType ); - MENGINE_UNUSED( _screenName ); - - //ToDo - } - ////////////////////////////////////////////////////////////////////////// - void AppleDevToDevAnalyticsEventProvider::onAnalyticsFlush() - { - //ToDo - } - ////////////////////////////////////////////////////////////////////////// -} diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.h b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.h index 2ea606a13a..537d470d67 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.h +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.h @@ -2,8 +2,9 @@ #import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" #import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" +#import "Environment/iOS/iOSPluginAnalyticDelegateInterface.h" -@interface AppleDevToDevApplicationDelegate : NSObject +@interface AppleDevToDevApplicationDelegate : NSObject - (void)sendEvent:(NSString *)eventName parameters:(NSDictionary *)parameters; diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm index b3526a417e..1d738f84ce 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm @@ -72,4 +72,23 @@ - (void)onRemoveUserData { //Empty } +#pragma mark - iOSPluginAnalyticDelegateInterface + +- (void)onAnalyticEvent:(NSString *)event params:(NSDictionary *)params { + [self sendEvent:event parameters:params]; +} + +- (void)onAnalyticScreen:(NSString *)screen type:(NSString *)type { + DTDCustomEventParameters * devtodev_parameters = [[DTDCustomEventParameters alloc] init]; + + [devtodev_parameters addString:@"screen_type" value:type]; + [devtodev_parameters addString:@"screen_name" value:screen]; + + [DTDAnalytics customEvent:@"screen_view" withParameters:devtodev_parameters]; +} + +- (void)onAnalyticFlush { + // DevToDev automatically flushes events, no manual flush needed +} + @end diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.h b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.h deleted file mode 100644 index edd060d453..0000000000 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "Interface/AnalyticsEventProviderInterface.h" - -#include "Kernel/PluginBase.h" - -namespace Mengine -{ - class AppleDevToDevPlugin - : public PluginBase - { - PLUGIN_DECLARE( "AppleDevToDev" ) - - public: - AppleDevToDevPlugin(); - ~AppleDevToDevPlugin() override; - - protected: - bool _initializePlugin() override; - void _finalizePlugin() override; - - protected: - AnalyticsEventProviderInterfacePtr m_provider; - }; -} diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.mm deleted file mode 100644 index 1e6d520801..0000000000 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevPlugin.mm +++ /dev/null @@ -1,50 +0,0 @@ -#include "AppleDevToDevPlugin.h" - -#include "Interface/AnalyticsServiceInterface.h" - -#include "AppleDevToDevAnalyticsEventProvider.h" - -#include "Kernel/ConfigHelper.h" -#include "Kernel/OptionHelper.h" -#include "Kernel/ConstStringHelper.h" -#include "Kernel/NotificationHelper.h" -#include "Kernel/PluginHelper.h" - -////////////////////////////////////////////////////////////////////////// -PLUGIN_FACTORY( AppleDevToDev, Mengine::AppleDevToDevPlugin ); -////////////////////////////////////////////////////////////////////////// -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - AppleDevToDevPlugin::AppleDevToDevPlugin() - { - } - ////////////////////////////////////////////////////////////////////////// - AppleDevToDevPlugin::~AppleDevToDevPlugin() - { - } - ////////////////////////////////////////////////////////////////////////// - bool AppleDevToDevPlugin::_initializePlugin() - { - AnalyticsEventProviderInterfacePtr provider = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); - - ANALYTICS_SERVICE() - ->addEventProvider( provider ); - - m_provider = provider; - - return true; - } - ////////////////////////////////////////////////////////////////////////// - void AppleDevToDevPlugin::_finalizePlugin() - { - if( m_provider != nullptr ) - { - ANALYTICS_SERVICE() - ->removeEventProvider( m_provider ); - - m_provider = nullptr; - } - } - ////////////////////////////////////////////////////////////////////////// -} diff --git a/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt b/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt index 8cc218fe26..f6db2211a9 100644 --- a/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt @@ -2,18 +2,10 @@ MENGINE_PROJECT(AppleDevToDevPlugin) ADD_FILTER( src - AppleDevToDevPlugin.h - AppleDevToDevPlugin.mm - - AppleDevToDevAnalyticsEventProvider.h - AppleDevToDevAnalyticsEventProvider.mm - AppleDevToDevApplicationDelegate.h AppleDevToDevApplicationDelegate.mm ) -ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV) - ADD_MENGINE_COCOAPOD("DTDAnalytics" "NO-GIT" "2.5.1") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleDevToDevApplicationDelegate") \ No newline at end of file diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.h b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.h index 19e76c052d..93f5a44d41 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.h +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.h @@ -4,8 +4,9 @@ #import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" #import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" #import "Environment/iOS/iOSPluginTransparencyConsentDelegateInterface.h" +#import "Environment/iOS/iOSPluginAnalyticDelegateInterface.h" -@interface AppleFirebaseAnalyticsApplicationDelegate : NSObject +@interface AppleFirebaseAnalyticsApplicationDelegate : NSObject + (instancetype)sharedInstance; diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm index 284e485680..e03b8a7d3e 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm @@ -94,4 +94,22 @@ - (void)onTransparencyConsent:(iOSTransparencyConsentParam *)consent { }]; } +#pragma mark - iOSPluginAnalyticDelegateInterface + +- (void)onAnalyticEvent:(NSString *)event params:(NSDictionary *)params { + [FIRAnalytics logEventWithName:event parameters:params]; +} + +- (void)onAnalyticScreen:(NSString *)screen type:(NSString *)type { + [FIRAnalytics logEventWithName:kFIREventScreenView + parameters:@{ + kFIRParameterScreenClass: type, + kFIRParameterScreenName: screen + }]; +} + +- (void)onAnalyticFlush { + // Firebase Analytics automatically flushes events, no manual flush needed +} + @end diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.h b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.h deleted file mode 100644 index a068cdfba1..0000000000 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Interface/AnalyticsEventProviderInterface.h" - -#include "Kernel/ConstString.h" -#include "Kernel/Factorable.h" - -namespace Mengine -{ - class AppleFirebaseAnalyticsEventProvider - : public AnalyticsEventProviderInterface - , public Factorable - { - DECLARE_FACTORABLE( AppleFirebaseAnalyticsEventProvider ); - - public: - AppleFirebaseAnalyticsEventProvider(); - ~AppleFirebaseAnalyticsEventProvider() override; - - protected: - void onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) override; - void onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) override; - - void onAnalyticsFlush() override; - }; -} diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm deleted file mode 100644 index 8795138cc3..0000000000 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm +++ /dev/null @@ -1,106 +0,0 @@ -#include "AppleFirebaseAnalyticsEventProvider.h" - -#import "Environment/Apple/AppleString.h" - -#include "Kernel/Logger.h" -#include "Kernel/AnalyticsHelper.h" - -#include "Config/StdAlgorithm.h" - -#import - -////////////////////////////////////////////////////////////////////////// -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - AppleFirebaseAnalyticsEventProvider::AppleFirebaseAnalyticsEventProvider() - { - } - ////////////////////////////////////////////////////////////////////////// - AppleFirebaseAnalyticsEventProvider::~AppleFirebaseAnalyticsEventProvider() - { - } - ////////////////////////////////////////////////////////////////////////// - void AppleFirebaseAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) - { - [FIRAnalytics logEventWithName:kFIREventScreenView - parameters:@{kFIRParameterScreenClass: [AppleString NSStringFromConstString:_screenType], - kFIRParameterScreenName: [AppleString NSStringFromConstString:_screenName]}]; - } - ////////////////////////////////////////////////////////////////////////// - void AppleFirebaseAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) - { - const ConstString & eventName = _event->getName(); - const Char * eventName_str = eventName.c_str(); - - uint32_t countParameters = _event->getCountParameters(); - - if( countParameters > 25 ) - { - return; - } - - NSMutableDictionary * firebase_parameters = [[NSMutableDictionary alloc] init]; - - _event->foreachParameters( [firebase_parameters]( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) - { - ConstString::size_type name_size = _name.size(); - - if( name_size > 40 ) - { - return; - } - - const Char * name_str = _name.c_str(); - - Helper::visitAnalyticsParameter( _parameter - , [firebase_parameters, name_str]( bool _value ) - { - [firebase_parameters setValue:@(_value) forKey:@(name_str)]; - } - , [firebase_parameters, name_str]( int64_t _value ) - { - [firebase_parameters setValue:@(_value) forKey:@(name_str)]; - } - , [firebase_parameters, name_str]( double _value ) - { - [firebase_parameters setValue:@(_value) forKey:@(name_str)]; - } - , [firebase_parameters, name_str]( const String & _value ) - { - String::size_type parameter_value_size = _value.size(); - - if( parameter_value_size > 100 ) - { - return; - } - - const Char * parameter_value_str = _value.c_str(); - - [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - } - , [firebase_parameters, name_str]( const ConstString & _value ) - { - ConstString::size_type parameter_value_size = _value.size(); - - if( parameter_value_size > 100 ) - { - return; - } - - const Char * parameter_value_str = _value.c_str(); - - [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - } ); - } ); - - [FIRAnalytics logEventWithName:@(eventName_str) - parameters:firebase_parameters]; - } - ////////////////////////////////////////////////////////////////////////// - void AppleFirebaseAnalyticsEventProvider::onAnalyticsFlush() - { - //ToDo - } - ////////////////////////////////////////////////////////////////////////// -} diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.h b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.h deleted file mode 100644 index e6393062ec..0000000000 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "Interface/AnalyticsEventProviderInterface.h" - -#include "Kernel/PluginBase.h" - -namespace Mengine -{ - class AppleFirebaseAnalyticsPlugin - : public PluginBase - { - PLUGIN_DECLARE( "AppleFirebaseAnalytics" ) - - public: - AppleFirebaseAnalyticsPlugin(); - ~AppleFirebaseAnalyticsPlugin() override; - - protected: - bool _initializePlugin() override; - void _finalizePlugin() override; - - protected: - AnalyticsEventProviderInterfacePtr m_provider; - }; -} diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.mm deleted file mode 100644 index 8bab870d76..0000000000 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsPlugin.mm +++ /dev/null @@ -1,50 +0,0 @@ -#include "AppleFirebaseAnalyticsPlugin.h" - -#include "Interface/AnalyticsServiceInterface.h" - -#import "AppleFirebaseAnalyticsEventProvider.h" - -#include "Kernel/ConfigHelper.h" -#include "Kernel/OptionHelper.h" -#include "Kernel/FactorableUnique.h" -#include "Kernel/NotificationHelper.h" -#include "Kernel/PluginHelper.h" - -////////////////////////////////////////////////////////////////////////// -PLUGIN_FACTORY( AppleFirebaseAnalytics, Mengine::AppleFirebaseAnalyticsPlugin ); -////////////////////////////////////////////////////////////////////////// -namespace Mengine -{ - ////////////////////////////////////////////////////////////////////////// - AppleFirebaseAnalyticsPlugin::AppleFirebaseAnalyticsPlugin() - { - } - ////////////////////////////////////////////////////////////////////////// - AppleFirebaseAnalyticsPlugin::~AppleFirebaseAnalyticsPlugin() - { - } - ////////////////////////////////////////////////////////////////////////// - bool AppleFirebaseAnalyticsPlugin::_initializePlugin() - { - AnalyticsEventProviderInterfacePtr provider = Helper::makeFactorableUnique( MENGINE_DOCUMENT_FACTORABLE ); - - ANALYTICS_SERVICE() - ->addEventProvider( provider ); - - m_provider = provider; - - return true; - } - ////////////////////////////////////////////////////////////////////////// - void AppleFirebaseAnalyticsPlugin::_finalizePlugin() - { - if( m_provider != nullptr ) - { - ANALYTICS_SERVICE() - ->removeEventProvider( m_provider ); - - m_provider = nullptr; - } - } - ////////////////////////////////////////////////////////////////////////// -} diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt index f41c3d418d..7b0a1301f9 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt @@ -2,18 +2,10 @@ MENGINE_PROJECT(AppleFirebaseAnalyticsPlugin) ADD_FILTER( src - AppleFirebaseAnalyticsPlugin.h - AppleFirebaseAnalyticsPlugin.mm - - AppleFirebaseAnalyticsEventProvider.h - AppleFirebaseAnalyticsEventProvider.mm - AppleFirebaseAnalyticsApplicationDelegate.h AppleFirebaseAnalyticsApplicationDelegate.mm ) -ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS) - ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseAnalyticsApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() From feef43a446ba2e279295771764e3d63b864fe050 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 25 Nov 2025 22:50:42 +0200 Subject: [PATCH 150/169] fix AI --- src/Plugins/AppleAmplitudePlugin/CMakeLists.txt | 2 ++ src/Plugins/AppleDevToDevPlugin/CMakeLists.txt | 2 ++ src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt index 2dbdd158cf..212901d22b 100644 --- a/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt +++ b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt @@ -6,6 +6,8 @@ src AppleAmplitudeApplicationDelegate.mm ) +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_AMPLITUDE) + ADD_MENGINE_COCOAPOD("Amplitude" "NO-GIT" "8.22.2") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAmplitudeApplicationDelegate") diff --git a/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt b/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt index f6db2211a9..99e848fec0 100644 --- a/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt @@ -6,6 +6,8 @@ src AppleDevToDevApplicationDelegate.mm ) +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_DEVTODEV) + ADD_MENGINE_COCOAPOD("DTDAnalytics" "NO-GIT" "2.5.1") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleDevToDevApplicationDelegate") \ No newline at end of file diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt index 7b0a1301f9..b7ff50464e 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt @@ -6,9 +6,12 @@ src AppleFirebaseAnalyticsApplicationDelegate.mm ) +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS) + ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseAnalyticsApplicationDelegate") ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() ADD_MENGINE_COCOAPOD("FirebaseAnalytics" "NO-GIT" "12.6.0") TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) + From 928d92261f47de23d9421d743e508e90b9111003 Mon Sep 17 00:00:00 2001 From: irov Date: Tue, 25 Nov 2025 23:09:15 +0200 Subject: [PATCH 151/169] wip --- src/Bootstrapper/Bootstrapper.cpp | 24 ------------------- .../CMakeLists.txt | 3 +-- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index bec2c8cad1..c01bbdd932 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -418,10 +418,6 @@ PLUGIN_EXPORT( AppleAppLovin ); PLUGIN_EXPORT( AppleAdMob ); #endif ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS_STATIC) -PLUGIN_EXPORT( AppleFirebaseAnalytics ); -#endif -////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS_STATIC) PLUGIN_EXPORT( AppleFirebaseCrashlytics ); #endif @@ -458,14 +454,6 @@ PLUGIN_EXPORT( AppleStoreInAppPurchase ); PLUGIN_EXPORT( AppleAdjust ); #endif ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLUGIN_APPLE_AMPLITUDE_STATIC) -PLUGIN_EXPORT( AppleAmplitude ); -#endif -////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLUGIN_APPLE_DEVTODEV_STATIC) -PLUGIN_EXPORT( AppleDevToDev ); -#endif -////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_PLUGIN_APPLE_SENTRY_STATIC) PLUGIN_EXPORT( AppleSentry ); #endif @@ -1485,10 +1473,6 @@ namespace Mengine MENGINE_ADD_PLUGIN( AppleAdMob, "plugin AppleAdMob...", MENGINE_DOCUMENT_FACTORABLE ); #endif -#if defined(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS_STATIC) - MENGINE_ADD_PLUGIN( AppleFirebaseAnalytics, "plugin AppleFirebaseAnalytics...", MENGINE_DOCUMENT_FACTORABLE ); -#endif - #if defined(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING_STATIC) MENGINE_ADD_PLUGIN( AppleFirebaseMessaging, "plugin AppleFirebaseMessaging...", MENGINE_DOCUMENT_FACTORABLE ); #endif @@ -1517,14 +1501,6 @@ namespace Mengine MENGINE_ADD_PLUGIN( AppleAdjust, "plugin AppleAdjust...", MENGINE_DOCUMENT_FACTORABLE ); #endif -#if defined(MENGINE_PLUGIN_APPLE_AMPLITUDE_STATIC) - MENGINE_ADD_PLUGIN( AppleAmplitude, "plugin AppleAmplitude...", MENGINE_DOCUMENT_FACTORABLE ); -#endif - -#if defined(MENGINE_PLUGIN_APPLE_DEVTODEV_STATIC) - MENGINE_ADD_PLUGIN( AppleDevToDev, "plugin AppleDevToDev...", MENGINE_DOCUMENT_FACTORABLE ); -#endif - #if defined(MENGINE_PLUGIN_XMLTOBIN_STATIC) MENGINE_ADD_PLUGIN( XmlToBin, "plugin XmlToBin...", MENGINE_DOCUMENT_FACTORABLE ); #endif diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt index b7ff50464e..b37b717e99 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt @@ -13,5 +13,4 @@ ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseAnalyticsApplicationDelegat ADD_MENGINE_COCOAPOD_GOOGLE_UTILITIES() ADD_MENGINE_COCOAPOD("FirebaseAnalytics" "NO-GIT" "12.6.0") -TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) - +TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) \ No newline at end of file From f4da75ba04a6eaa53b2bdce22035b4ab92e4e437 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 26 Nov 2025 01:25:22 +0200 Subject: [PATCH 152/169] fix circle.ci --- gradle/gradle.properties.ci | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gradle/gradle.properties.ci b/gradle/gradle.properties.ci index 04bd2939cf..9037c71415 100644 --- a/gradle/gradle.properties.ci +++ b/gradle/gradle.properties.ci @@ -15,4 +15,16 @@ ANDROID_APP_MAIN_PROJECT=ci android.useAndroidX=true android.useFullClasspathForDexingTransform=true -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true + +# Explicitly disable split APK to avoid IncrementalSplitterRunnable issues +ANDROID_APP_SPLIT_ENABLE=false + +# Increase memory for Gradle to handle large builds +org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# Disable build cache to avoid issues with incremental builds in CI +org.gradle.caching=false + +# Configure daemon settings for CI +org.gradle.daemon=false \ No newline at end of file From c3c611fc9f75bb7c05b46dc151587e1fcf6c86a4 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 26 Nov 2025 02:19:29 +0200 Subject: [PATCH 153/169] wip CI --- gradle/ci/app.properties | 5 ----- gradle/ci/res/drawable/ic_launchscreen.png | Bin 52485 -> 0 bytes 2 files changed, 5 deletions(-) delete mode 100644 gradle/ci/app.properties delete mode 100644 gradle/ci/res/drawable/ic_launchscreen.png diff --git a/gradle/ci/app.properties b/gradle/ci/app.properties deleted file mode 100644 index 3c3b1d0160..0000000000 --- a/gradle/ci/app.properties +++ /dev/null @@ -1,5 +0,0 @@ -ANDROID_APP_ID=com.wonderland.ci - -MENGINE_APP_HAS_ADS=0 - -MENGINE_APP_PLUGIN_ENABLE_ALL=0 \ No newline at end of file diff --git a/gradle/ci/res/drawable/ic_launchscreen.png b/gradle/ci/res/drawable/ic_launchscreen.png deleted file mode 100644 index 80530c81335b6aedaf47a2d18b332091adbf5246..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52485 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 From 0be9b78c8893bb602dff587e0f2f2c9ae9650611 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 26 Nov 2025 13:21:39 +0200 Subject: [PATCH 154/169] add iOS iOSAnalyticsEventCategory --- .../iOSApplication/iOSUIApplicationDelegate.mm | 4 ++-- src/Environment/iOS/CMakeLists.txt | 2 ++ src/Environment/iOS/iOSAnalytics.h | 5 +++-- src/Environment/iOS/iOSAnalytics.mm | 4 ++-- src/Environment/iOS/iOSAnalyticsEventCategory.h | 10 ++++++++++ .../iOS/iOSPluginAnalyticDelegateInterface.h | 3 ++- .../iOS/iOSUIMainApplicationDelegateInterface.h | 3 ++- src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm | 3 ++- .../AppleAmplitudeApplicationDelegate.mm | 7 ++++++- .../AppleDevToDevApplicationDelegate.mm | 7 ++++++- .../AppleFirebaseAnalyticsApplicationDelegate.mm | 7 ++++++- 11 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 src/Environment/iOS/iOSAnalyticsEventCategory.h diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index e2332d11b2..9822ba68a0 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -182,10 +182,10 @@ - (void)eventConfig:(NSDictionary *)config { } } -- (void)eventAnalytic:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params { +- (void)eventAnalytic:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params { @autoreleasepool { for (NSObject * delegate in self.m_pluginAnalyticDelegates) { - [delegate onAnalyticEvent:event params:params]; + [delegate onAnalyticEvent:event category:category params:params]; } } } diff --git a/src/Environment/iOS/CMakeLists.txt b/src/Environment/iOS/CMakeLists.txt index 12ecfeef19..c064b2fce8 100644 --- a/src/Environment/iOS/CMakeLists.txt +++ b/src/Environment/iOS/CMakeLists.txt @@ -40,6 +40,8 @@ src iOSAnalytics.h iOSAnalytics.mm + iOSAnalyticsEventCategory.h + iOSNetwork.h iOSNetwork.mm diff --git a/src/Environment/iOS/iOSAnalytics.h b/src/Environment/iOS/iOSAnalytics.h index 93b34d4e0c..6a1567e973 100644 --- a/src/Environment/iOS/iOSAnalytics.h +++ b/src/Environment/iOS/iOSAnalytics.h @@ -1,11 +1,12 @@ #pragma once #import "Environment/Apple/AppleIncluder.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" @interface iOSAnalytics : NSObject -+(void)event:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params; ++(void)event:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params; +(void)screen:(NSString * _Nonnull)name type:(NSString * _Nonnull)type; +(void)flush; -@end +@end \ No newline at end of file diff --git a/src/Environment/iOS/iOSAnalytics.mm b/src/Environment/iOS/iOSAnalytics.mm index 050d3ec0f2..35f8334683 100644 --- a/src/Environment/iOS/iOSAnalytics.mm +++ b/src/Environment/iOS/iOSAnalytics.mm @@ -6,11 +6,11 @@ @implementation iOSAnalytics -+ (void)event:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params { ++ (void)event:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params { [AppleDetail addMainQueueOperation:^{ NSObject * delegate = [iOSDetail getUIMainApplicationDelegate]; - [delegate eventAnalytic:event params:params]; + [delegate eventAnalytic:event category:category params:params]; }]; } diff --git a/src/Environment/iOS/iOSAnalyticsEventCategory.h b/src/Environment/iOS/iOSAnalyticsEventCategory.h new file mode 100644 index 0000000000..33abb80e2c --- /dev/null +++ b/src/Environment/iOS/iOSAnalyticsEventCategory.h @@ -0,0 +1,10 @@ +#pragma once + +#import "Environment/Apple/AppleIncluder.h" + +typedef NS_ENUM(NSInteger, iOSAnalyticsEventCategory) +{ + iOSAnalyticsEventCategory_System, + iOSAnalyticsEventCategory_Custom +}; + diff --git a/src/Environment/iOS/iOSPluginAnalyticDelegateInterface.h b/src/Environment/iOS/iOSPluginAnalyticDelegateInterface.h index 3246df5f04..a6b0ec3cb5 100644 --- a/src/Environment/iOS/iOSPluginAnalyticDelegateInterface.h +++ b/src/Environment/iOS/iOSPluginAnalyticDelegateInterface.h @@ -1,10 +1,11 @@ #pragma once #import "Environment/Apple/AppleIncluder.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" @protocol iOSPluginAnalyticDelegateInterface -- (void)onAnalyticEvent:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params; +- (void)onAnalyticEvent:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params; - (void)onAnalyticScreen:(NSString * _Nonnull)screen type:(NSString * _Nonnull)type; - (void)onAnalyticFlush; diff --git a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h index 690a8f9dcd..270a15b295 100644 --- a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h @@ -8,6 +8,7 @@ #import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" #import "Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.h" #import "Environment/iOS/iOSPluginTransparencyConsentDelegateInterface.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" @protocol iOSUIMainApplicationDelegateInterface @@ -29,7 +30,7 @@ - (void)eventConfig:(NSDictionary * _Nonnull)config; -- (void)eventAnalytic:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params; +- (void)eventAnalytic:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params; - (void)eventAnalyticScreen:(NSString * _Nonnull)name type:(NSString * _Nonnull)type; - (void)eventAnalyticFlush; diff --git a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm index 4de8417c50..e510469bf8 100644 --- a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm +++ b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm @@ -2,6 +2,7 @@ #import "Environment/Apple/AppleIncluder.h" #import "Environment/iOS/iOSAnalytics.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" #include "Kernel/AssertionMemoryPanic.h" #include "Kernel/AnalyticsHelper.h" @@ -58,7 +59,7 @@ } ); } ); - [iOSAnalytics event:@(eventName_str) params:parameters]; + [iOSAnalytics event:@(eventName_str) category:iOSAnalyticsEventCategory_Custom params:parameters]; } ////////////////////////////////////////////////////////////////////////// void iOSAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) diff --git a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm index 55bfe1ce2a..009abf4aa0 100644 --- a/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm @@ -7,6 +7,7 @@ #import "Environment/iOS/iOSAdRevenueParam.h" #import "Environment/iOS/iOSLog.h" #import "Environment/iOS/iOSUserParam.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" #import @@ -137,7 +138,11 @@ - (void)onAdRevenue:(iOSAdRevenueParam *)revenue { #pragma mark - iOSPluginAnalyticDelegateInterface -- (void)onAnalyticEvent:(NSString *)event params:(NSDictionary *)params { +- (void)onAnalyticEvent:(NSString *)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary *)params { + if (category == iOSAnalyticsEventCategory_System) { + return; + } + [[Amplitude instance] logEvent:event withEventProperties:params]; } diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm index 1d738f84ce..2e0183982f 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm @@ -5,6 +5,7 @@ #import "Environment/iOS/iOSApplication.h" #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" #import @@ -74,7 +75,11 @@ - (void)onRemoveUserData { #pragma mark - iOSPluginAnalyticDelegateInterface -- (void)onAnalyticEvent:(NSString *)event params:(NSDictionary *)params { +- (void)onAnalyticEvent:(NSString *)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary *)params { + if (category == iOSAnalyticsEventCategory_System) { + return; + } + [self sendEvent:event parameters:params]; } diff --git a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm index e03b8a7d3e..9f39b3f8f6 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsApplicationDelegate.mm @@ -5,6 +5,7 @@ #import "Environment/iOS/iOSApplication.h" #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSAdRevenueParam.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" #import @@ -96,7 +97,11 @@ - (void)onTransparencyConsent:(iOSTransparencyConsentParam *)consent { #pragma mark - iOSPluginAnalyticDelegateInterface -- (void)onAnalyticEvent:(NSString *)event params:(NSDictionary *)params { +- (void)onAnalyticEvent:(NSString *)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary *)params { + if (category == iOSAnalyticsEventCategory_System) { + return; + } + [FIRAnalytics logEventWithName:event parameters:params]; } From 6b5201f67e9e4a149e6b2bed270fd7d72f742153 Mon Sep 17 00:00:00 2001 From: irov Date: Wed, 26 Nov 2025 13:52:53 +0200 Subject: [PATCH 155/169] wip iOS analytics --- src/Environment/iOS/iOSAnalytics.h | 4 +++- src/Environment/iOS/iOSAnalytics.mm | 9 +++++++++ src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm | 2 +- .../AppleAdvertisementInterstitialPoint.mm | 6 +++--- .../AppleSKAdNetworkApplicationDelegate.mm | 8 ++++---- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Environment/iOS/iOSAnalytics.h b/src/Environment/iOS/iOSAnalytics.h index 6a1567e973..b4dba1f627 100644 --- a/src/Environment/iOS/iOSAnalytics.h +++ b/src/Environment/iOS/iOSAnalytics.h @@ -6,7 +6,9 @@ @interface iOSAnalytics : NSObject +(void)event:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params; ++(void)eventSystem:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params; ++(void)eventCustom:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params; +(void)screen:(NSString * _Nonnull)name type:(NSString * _Nonnull)type; +(void)flush; -@end \ No newline at end of file +@end diff --git a/src/Environment/iOS/iOSAnalytics.mm b/src/Environment/iOS/iOSAnalytics.mm index 35f8334683..441ff4f177 100644 --- a/src/Environment/iOS/iOSAnalytics.mm +++ b/src/Environment/iOS/iOSAnalytics.mm @@ -3,6 +3,7 @@ #import "Environment/Apple/AppleDetail.h" #import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" @implementation iOSAnalytics @@ -14,6 +15,14 @@ + (void)event:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)cat }]; } ++(void)eventSystem:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params { + [iOSAnalytics event:event category:iOSAnalyticsEventCategory_System params:params]; +} + ++(void)eventCustom:(NSString * _Nonnull)event params:(NSDictionary * _Nonnull)params { + [iOSAnalytics event:event category:iOSAnalyticsEventCategory_Custom params:params]; +} + + (void)screen:(NSString * _Nonnull)name type:(NSString * _Nonnull)type { [AppleDetail addMainQueueOperation:^{ NSObject * delegate = [iOSDetail getUIMainApplicationDelegate]; diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm index 6e2c712dc0..db2b9eb619 100644 --- a/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -139,7 +139,7 @@ - (void) event:(NSString * _Nonnull)name params:(NSDictionary * _ [total_params addEntriesFromDictionary:params]; - [iOSAnalytics event:name params:total_params]; + [iOSAnalytics eventSystem:name params:total_params]; } - (GADRequest *) createAdRequest { diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterstitialPoint.mm b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterstitialPoint.mm index 19941bb7a7..d2ef405d36 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterstitialPoint.mm +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementInterstitialPoint.mm @@ -11,9 +11,9 @@ - (instancetype)initWithName:(NSString *)name withJson:(NSDictionary *)json { if (self != nil) { self.m_actionOffset = [self parseAdPointInteger:json key:@"trigger_action_offset" required:NO defaultValue:-1]; self.m_actionCooldown = [self parseAdPointInteger:json key:@"trigger_action_cooldown" required:NO defaultValue:-1]; - self.m_timeOffset = [self parseAdPointTimeInterval:json key:@"trigger_time_offset" required:NO defaultValue:-1.0]; - self.m_timeCooldown = [self parseAdPointTimeInterval:json key:@"trigger_time_cooldown" required:NO defaultValue:-1.0]; - self.m_installTimeOffset = [self parseAdPointTimeInterval:json key:@"trigger_install_time_offset" required:NO defaultValue:600.0]; + self.m_timeOffset = [self parseAdPointTimeInterval:json key:@"trigger_time_offset" required:NO defaultValue:600]; + self.m_timeCooldown = [self parseAdPointTimeInterval:json key:@"trigger_time_cooldown" required:NO defaultValue:-1]; + self.m_installTimeOffset = [self parseAdPointTimeInterval:json key:@"trigger_install_time_offset" required:NO defaultValue:600]; self.m_sessionOffset = [self parseAdPointInteger:json key:@"trigger_session_offset" required:NO defaultValue:-1]; } diff --git a/src/Plugins/AppleSKAdNetworkPlugin/AppleSKAdNetworkApplicationDelegate.mm b/src/Plugins/AppleSKAdNetworkPlugin/AppleSKAdNetworkApplicationDelegate.mm index 4c8df58cf3..2b9acf25b5 100644 --- a/src/Plugins/AppleSKAdNetworkPlugin/AppleSKAdNetworkApplicationDelegate.mm +++ b/src/Plugins/AppleSKAdNetworkPlugin/AppleSKAdNetworkApplicationDelegate.mm @@ -238,7 +238,7 @@ - (void)recordInstallation { , [AppleDetail getMessageFromNSError:error] ); - [iOSAnalytics event:@"mng_skadnetwork_installation_error" params:@{ + [iOSAnalytics eventSystem:@"mng_skadnetwork_installation_error" params:@{ @"error": error, @"error_code": @(error.code) }]; @@ -256,7 +256,7 @@ - (void)recordInstallation { [AppleKeyChain setTimeIntervalForKey:@"mengine.skadnetwork.time" value:self.m_time]; [AppleKeyChain setIntegerForKey:@"mengine.skadnetwork.fine" value:0]; - [iOSAnalytics event:@"mng_skadnetwork_installation" params:@{}]; + [iOSAnalytics eventSystem:@"mng_skadnetwork_installation" params:@{}]; }]; } @@ -387,7 +387,7 @@ - (void)onAdRevenue:(iOSAdRevenueParam *)revenue { , [AppleDetail getMessageFromNSError:error] ); - [iOSAnalytics event:@"mng_skadnetwork_conversion_error" params:@{ + [iOSAnalytics eventSystem:@"mng_skadnetwork_conversion_error" params:@{ @"error": error, @"error_code": @(error.code), @"fine": @(fine), @@ -410,7 +410,7 @@ - (void)onAdRevenue:(iOSAdRevenueParam *)revenue { [AppleKeyChain setIntegerForKey:@"mengine.skadnetwork.fine" value:fine]; - [iOSAnalytics event:@"mng_skadnetwork_conversion" params:@{ + [iOSAnalytics eventSystem:@"mng_skadnetwork_conversion" params:@{ @"fine": @(fine), @"coarse": coarse, @"window": window_id, From 0eb432a91194e823006429067a45eae470b0a9b5 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 27 Nov 2025 20:12:43 +0200 Subject: [PATCH 156/169] improve AnalyticsService --- .../Mengine/Base/MengineAdPointAppOpen.java | 2 +- .../Base/MengineAdPointInterstitial.java | 2 +- .../MengineGoogleAdvertisingPlugin.java | 16 ++++++------- src/Bootstrapper/Bootstrapper.cpp | 4 ++-- .../PythonFramework/EngineScriptEmbedding.cpp | 2 +- src/Interface/AnalyticsContextInterface.h | 7 +++--- .../AnalyticsEventBuilderInterface.h | 3 ++- src/Interface/AnalyticsEventInterface.h | 12 +++++++++- src/Interface/AnalyticsServiceInterface.h | 2 +- .../AndroidAnalyticsEventProvider.cpp | 20 +++++++++++++++- .../iOSPlatform/iOSAnalyticsEventProvider.mm | 20 +++++++++++++++- .../AnalyticsService/AnalyticsContext.cpp | 6 ++--- .../AnalyticsService/AnalyticsContext.h | 5 ++-- .../AnalyticsService/AnalyticsEvent.cpp | 23 ++++++++++++++----- .../AnalyticsService/AnalyticsEvent.h | 7 +++++- .../AnalyticsEventBuilder.cpp | 14 ++++++++++- .../AnalyticsService/AnalyticsEventBuilder.h | 8 ++++++- .../AnalyticsService/AnalyticsService.cpp | 5 ++-- .../AnalyticsService/AnalyticsService.h | 2 +- 19 files changed, 122 insertions(+), 38 deletions(-) diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointAppOpen.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointAppOpen.java index 266daabb96..cf5c8134f6 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointAppOpen.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointAppOpen.java @@ -22,7 +22,7 @@ public class MengineAdPointAppOpen extends MengineAdPointBase { m_actionOffset = this.parseAdPointInteger(values, "trigger_action_offset", false, -1); m_actionCooldown = this.parseAdPointInteger(values, "trigger_action_cooldown", false, -1); m_timeOffset = this.parseAdPointTime(values, "trigger_time_offset", false, -1); - m_timeCooldown = this.parseAdPointTime(values, "trigger_time_cooldown", false, -1); + m_timeCooldown = this.parseAdPointTime(values, "trigger_time_cooldown", false, 600); m_installTimeOffset = this.parseAdPointTime(values, "trigger_install_time_offset", false, 600); m_sessionOffset = this.parseAdPointLong(values, "trigger_session_offset", false, -1); } diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointInterstitial.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointInterstitial.java index a85de7b755..f787869666 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointInterstitial.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAdPointInterstitial.java @@ -20,7 +20,7 @@ public class MengineAdPointInterstitial extends MengineAdPointBase { m_actionOffset = this.parseAdPointInteger(values, "trigger_action_offset", false, -1); m_actionCooldown = this.parseAdPointInteger(values, "trigger_action_cooldown", false, -1); m_timeOffset = this.parseAdPointTime(values, "trigger_time_offset", false, -1); - m_timeCooldown = this.parseAdPointTime(values, "trigger_time_cooldown", false, -1); + m_timeCooldown = this.parseAdPointTime(values, "trigger_time_cooldown", false, 600); m_installTimeOffset = this.parseAdPointTime(values, "trigger_install_time_offset", false, 600); m_sessionOffset = this.parseAdPointLong(values, "trigger_session_offset", false, -1); } diff --git a/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java b/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java index 8bc1d959dd..da48966270 100644 --- a/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java +++ b/gradle/plugins/GoogleAdvertising/src/main/java/org/Mengine/Plugin/GoogleAdvertising/MengineGoogleAdvertisingPlugin.java @@ -29,7 +29,7 @@ public class MengineGoogleAdvertisingPlugin extends MengineService implements Me protected boolean m_advertisingLimitTrackingEnabled = false; protected boolean m_advertisingLimitTrackingFetch = false; - protected final Object m_syncronizationAdvertising = new Object(); + protected final Object m_synchronizationAdvertising = new Object(); private Thread m_advertisingThread; @@ -48,7 +48,7 @@ public Bundle onSave(@NonNull MengineApplication application) { bundle.putInt("version", SAVE_VERSION); - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { bundle.putString("advertisingId", m_advertisingId); bundle.putBoolean("advertisingLimitTrackingEnabled", m_advertisingLimitTrackingEnabled); bundle.putBoolean("advertisingLimitTrackingFetch", m_advertisingLimitTrackingFetch); @@ -61,7 +61,7 @@ public Bundle onSave(@NonNull MengineApplication application) { public void onLoad(@NonNull MengineApplication application, @NonNull Bundle bundle) { int version = bundle.getInt("version", 0); - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { m_advertisingId = bundle.getString("advertisingId", MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID); m_advertisingLimitTrackingEnabled = bundle.getBoolean("advertisingLimitTrackingEnabled", true); m_advertisingLimitTrackingFetch = bundle.getBoolean("advertisingLimitTrackingFetch", false); @@ -75,7 +75,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS if (tcParam.getConsentAdStorage() == false) { this.logInfo("AdvertisingId disabled by consent ad storage"); - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { m_advertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; m_advertisingLimitTrackingEnabled = true; m_advertisingLimitTrackingFetch = true; @@ -86,7 +86,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS return; } - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { if (m_advertisingLimitTrackingFetch == true) { this.logInfo("AdvertisingId: %s limit: %s" , MengineUtils.getRedactedValue(m_advertisingId) @@ -125,7 +125,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS this.postAdInfo(adInfo); }; - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { m_advertisingThread = new Thread(task, "MengineGAID"); m_advertisingThread.start(); } @@ -133,7 +133,7 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS @Override public void onAppTerminate(@NonNull MengineApplication application) { - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { if (m_advertisingThread != null) { m_advertisingThread.interrupt(); m_advertisingThread = null; @@ -142,7 +142,7 @@ public void onAppTerminate(@NonNull MengineApplication application) { } private void postAdInfo(AdvertisingIdClient.Info adInfo) { - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { String newAdvertisingId; boolean newAdvertisingLimitTrackingEnabled; diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index c01bbdd932..a747054c5e 100644 --- a/src/Bootstrapper/Bootstrapper.cpp +++ b/src/Bootstrapper/Bootstrapper.cpp @@ -1745,7 +1745,7 @@ namespace Mengine LOGGER_INFO( "bootstrapper", "create application..." ); Timestamp mengine_create_application_timestamp = ANALYTICS_SERVICE() - ->buildEvent( STRINGIZE_STRING_LOCAL( "mng_create_application_start" ), MENGINE_DOCUMENT_FACTORABLE ) + ->buildEvent( AEEC_SYSTEM, STRINGIZE_STRING_LOCAL( "mng_create_application_start" ), MENGINE_DOCUMENT_FACTORABLE ) ->log(); if( SERVICE_CREATE_SAFE( Application, MENGINE_DOCUMENT_FACTORABLE ) == false ) @@ -1756,7 +1756,7 @@ namespace Mengine NOTIFICATION_NOTIFY( NOTIFICATOR_BOOTSTRAPPER_CREATE_APPLICATION ); ANALYTICS_SERVICE() - ->buildEvent( STRINGIZE_STRING_LOCAL( "mng_create_application_completed" ), MENGINE_DOCUMENT_FACTORABLE ) + ->buildEvent( AEEC_SYSTEM, STRINGIZE_STRING_LOCAL( "mng_create_application_completed" ), MENGINE_DOCUMENT_FACTORABLE ) ->addParameterInteger( STRINGIZE_STRING_LOCAL( "time" ), Helper::getSystemDurationTimestamp( mengine_create_application_timestamp ) ) ->log(); diff --git a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index 5cc4225f75..bc73624aa6 100644 --- a/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp +++ b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp @@ -1818,7 +1818,7 @@ namespace Mengine void s_analyticsEvent( const ConstString & _eventName, const AnalyticsContextInterfacePtr & _context, const pybind::dict & _parameters ) { AnalyticsEventBuilderInterfacePtr builder = ANALYTICS_SERVICE() - ->buildEvent( _eventName, MENGINE_DOCUMENT_PYTHON ); + ->buildEvent( AEEC_CUSTOM, _eventName, MENGINE_DOCUMENT_PYTHON ); builder->setLocalContext( _context ); diff --git a/src/Interface/AnalyticsContextInterface.h b/src/Interface/AnalyticsContextInterface.h index 51f2e84ac8..9aa4fca984 100644 --- a/src/Interface/AnalyticsContextInterface.h +++ b/src/Interface/AnalyticsContextInterface.h @@ -27,10 +27,11 @@ namespace Mengine virtual void addParameter( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) = 0; public: - virtual uint32_t getCountParameters() const = 0; + virtual size_t getCountParameters() const = 0; - typedef Lambda LambdaForeachParameters; - virtual void foreachParameters( const LambdaForeachParameters & _lambda ) const = 0; + public: + typedef Lambda LambdaEventParameter; + virtual void foreachParameters( const LambdaEventParameter & _lambda ) const = 0; public: virtual void addParameterBoolean( const ConstString & _name, bool _value, const DocumentInterfacePtr & _doc ) = 0; diff --git a/src/Interface/AnalyticsEventBuilderInterface.h b/src/Interface/AnalyticsEventBuilderInterface.h index 0326313e92..dff1521a1c 100644 --- a/src/Interface/AnalyticsEventBuilderInterface.h +++ b/src/Interface/AnalyticsEventBuilderInterface.h @@ -2,6 +2,7 @@ #include "Interface/ServantInterface.h" #include "Interface/AnalyticsContextInterface.h" +#include "Interface/AnalyticsEventInterface.h" #include "Kernel/ConstString.h" #include "Kernel/String.h" @@ -26,7 +27,7 @@ namespace Mengine virtual AnalyticsEventBuilderInterface * addParameterConstString( const ConstString & _name, const ConstString & _value ) = 0; public: - virtual Timestamp log() = 0; + virtual Timestamp log() const = 0; }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr AnalyticsEventBuilderInterfacePtr; diff --git a/src/Interface/AnalyticsEventInterface.h b/src/Interface/AnalyticsEventInterface.h index 0545abe6af..256b1eb6d5 100644 --- a/src/Interface/AnalyticsEventInterface.h +++ b/src/Interface/AnalyticsEventInterface.h @@ -9,6 +9,12 @@ namespace Mengine { + ////////////////////////////////////////////////////////////////////////// + enum EAnalyticsEventCategory + { + AEEC_SYSTEM = 0, + AEEC_CUSTOM = 1 + }; ////////////////////////////////////////////////////////////////////////// class AnalyticsEventInterface : public ServantInterface @@ -16,6 +22,10 @@ namespace Mengine public: virtual const ConstString & getName() const = 0; + public: + virtual void setCategory( EAnalyticsEventCategory _category ) = 0; + virtual EAnalyticsEventCategory getCategory() const = 0; + public: virtual void setTimestamp( Timestamp _time ) = 0; virtual Timestamp getTimestamp() const = 0; @@ -33,7 +43,7 @@ namespace Mengine virtual const AnalyticsContextInterfacePtr & getGlobalContext() const = 0; public: - virtual uint32_t getCountParameters() const = 0; + virtual size_t getCountParameters() const = 0; typedef Lambda LambdaEventParameter; virtual void foreachParameters( const LambdaEventParameter & _lambda ) const = 0; diff --git a/src/Interface/AnalyticsServiceInterface.h b/src/Interface/AnalyticsServiceInterface.h index 43ede336cb..b36e4600cd 100644 --- a/src/Interface/AnalyticsServiceInterface.h +++ b/src/Interface/AnalyticsServiceInterface.h @@ -30,7 +30,7 @@ namespace Mengine virtual void logFlush() = 0; public: - virtual AnalyticsEventBuilderInterfacePtr buildEvent( const ConstString & _eventName, const DocumentInterfacePtr & _doc ) = 0; + virtual AnalyticsEventBuilderInterfacePtr buildEvent( EAnalyticsEventCategory _category, const ConstString & _eventName, const DocumentInterfacePtr & _doc ) = 0; public: virtual AnalyticsContextInterfacePtr makeContext( const DocumentInterfacePtr & _doc ) = 0; diff --git a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp index 2850a9e3f2..c338165216 100644 --- a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp +++ b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp @@ -9,6 +9,20 @@ namespace Mengine { + namespace Detail + { + static const Char * getAndroidAnalyticsCategoryEnumName( EAnalyticsEventCategory _category ) + { + switch( _category ) + { + case AEEC_SYSTEM: + return "MengineAnalyticsEventCategory_System"; + default: + return "MengineAnalyticsEventCategory_Custom"; + } + } + } + ////////////////////////////////////////////////////////////////////////// AndroidAnalyticsEventProvider::AndroidAnalyticsEventProvider() { @@ -73,7 +87,11 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( jenv, jobject_parameter ); }); - jobject jobject_category = Helper::AndroidGetJObjectEnum( jenv, "org/Mengine/Base/MengineAnalyticsEventCategory", "MengineAnalyticsEventCategory_Custom" ); + EAnalyticsEventCategory eventCategory = _event->getCategory(); + + const Char * categoryEnumName = Detail::getAndroidAnalyticsCategoryEnumName( eventCategory ); + + jobject jobject_category = Helper::AndroidGetJObjectEnum( jenv, "org/Mengine/Base/MengineAnalyticsEventCategory", categoryEnumName ); jclass jclass_MengineAnalyticsEventParam = Helper::AndroidEnvFindClass( jenv, "org/Mengine/Base/MengineParamAnalyticsEvent" ); diff --git a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm index e510469bf8..6dcf28ad10 100644 --- a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm +++ b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm @@ -9,6 +9,20 @@ namespace Mengine { + ////////////////////////////////////////////////////////////////////////// + namespace Detail + { + static iOSAnalyticsEventCategory getIOSAnalyticsCategory( EAnalyticsEventCategory _category ) + { + switch( _category ) + { + case AEEC_SYSTEM: + return iOSAnalyticsEventCategory_System; + default: + return iOSAnalyticsEventCategory_Custom; + } + } + } ////////////////////////////////////////////////////////////////////////// iOSAnalyticsEventProvider::iOSAnalyticsEventProvider() { @@ -58,8 +72,12 @@ [parameters setValue:@(parameter_value_str) forKey:@(name_str)]; } ); } ); + + EAnalyticsEventCategory eventCategory = _event->getCategory(); + + iOSAnalyticsEventCategory iosCategory = Detail::getIOSAnalyticsCategory( eventCategory ); - [iOSAnalytics event:@(eventName_str) category:iOSAnalyticsEventCategory_Custom params:parameters]; + [iOSAnalytics event:@(eventName_str) category:iosCategory params:parameters]; } ////////////////////////////////////////////////////////////////////////// void iOSAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) diff --git a/src/Services/AnalyticsService/AnalyticsContext.cpp b/src/Services/AnalyticsService/AnalyticsContext.cpp index ea2d44705e..a019a42553 100644 --- a/src/Services/AnalyticsService/AnalyticsContext.cpp +++ b/src/Services/AnalyticsService/AnalyticsContext.cpp @@ -30,14 +30,14 @@ namespace Mengine m_parameters.emplace_back( desc ); } ////////////////////////////////////////////////////////////////////////// - uint32_t AnalyticsContext::getCountParameters() const + size_t AnalyticsContext::getCountParameters() const { VectorAnalyticsEventParameter::size_type parameters_count = m_parameters.size(); - return (uint32_t)parameters_count; + return (size_t)parameters_count; } ////////////////////////////////////////////////////////////////////////// - void AnalyticsContext::foreachParameters( const LambdaForeachParameters & _lambda ) const + void AnalyticsContext::foreachParameters( const LambdaEventParameter & _lambda ) const { for( const AnalyticsEventParameterDesc & desc : m_parameters ) { diff --git a/src/Services/AnalyticsService/AnalyticsContext.h b/src/Services/AnalyticsService/AnalyticsContext.h index 99f4c2d4bb..830e3cf01a 100644 --- a/src/Services/AnalyticsService/AnalyticsContext.h +++ b/src/Services/AnalyticsService/AnalyticsContext.h @@ -26,9 +26,10 @@ namespace Mengine void addParameter( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) override; public: - uint32_t getCountParameters() const override; + size_t getCountParameters() const override; - void foreachParameters( const LambdaForeachParameters & _lambda ) const override; + public: + void foreachParameters( const LambdaEventParameter & _lambda ) const override; public: void addParameterBoolean( const ConstString & _name, bool _value, const DocumentInterfacePtr & _doc ) override; diff --git a/src/Services/AnalyticsService/AnalyticsEvent.cpp b/src/Services/AnalyticsService/AnalyticsEvent.cpp index ae8d38ef03..af50ca063d 100644 --- a/src/Services/AnalyticsService/AnalyticsEvent.cpp +++ b/src/Services/AnalyticsService/AnalyticsEvent.cpp @@ -4,7 +4,8 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// AnalyticsEvent::AnalyticsEvent() - : m_timestamp( 0 ) + : m_category( AEEC_CUSTOM ) + , m_timestamp( 0 ) { } ////////////////////////////////////////////////////////////////////////// @@ -22,6 +23,16 @@ namespace Mengine return m_name; } ////////////////////////////////////////////////////////////////////////// + void AnalyticsEvent::setCategory( EAnalyticsEventCategory _category ) + { + m_category = _category; + } + ////////////////////////////////////////////////////////////////////////// + EAnalyticsEventCategory AnalyticsEvent::getCategory() const + { + return m_category; + } + ////////////////////////////////////////////////////////////////////////// void AnalyticsEvent::setTimestamp( Timestamp _timestamp ) { m_timestamp = _timestamp; @@ -62,22 +73,22 @@ namespace Mengine return m_globalContext; } ////////////////////////////////////////////////////////////////////////// - uint32_t AnalyticsEvent::getCountParameters() const + size_t AnalyticsEvent::getCountParameters() const { - uint32_t parametersCount = 0; + size_t parametersCount = 0; - uint32_t selfParametersCount = m_context->getCountParameters(); + size_t selfParametersCount = m_context->getCountParameters(); parametersCount += selfParametersCount; if( m_localContext != nullptr ) { - uint32_t localParametersCount = m_localContext->getCountParameters(); + size_t localParametersCount = m_localContext->getCountParameters(); parametersCount += localParametersCount; } if( m_globalContext != nullptr ) { - uint32_t globalParametersCount = m_globalContext->getCountParameters(); + size_t globalParametersCount = m_globalContext->getCountParameters(); parametersCount += globalParametersCount; } diff --git a/src/Services/AnalyticsService/AnalyticsEvent.h b/src/Services/AnalyticsService/AnalyticsEvent.h index 218f957be8..2b77663593 100644 --- a/src/Services/AnalyticsService/AnalyticsEvent.h +++ b/src/Services/AnalyticsService/AnalyticsEvent.h @@ -21,6 +21,10 @@ namespace Mengine void setName( const ConstString & _name ); const ConstString & getName() const override; + public: + void setCategory( EAnalyticsEventCategory _category ) override; + EAnalyticsEventCategory getCategory() const override; + public: void setTimestamp( Timestamp _timestamp ) override; Timestamp getTimestamp() const override; @@ -38,11 +42,12 @@ namespace Mengine const AnalyticsContextInterfacePtr & getGlobalContext() const override; public: - uint32_t getCountParameters() const override; + size_t getCountParameters() const override; void foreachParameters( const LambdaEventParameter & _lambda ) const override; protected: ConstString m_name; + EAnalyticsEventCategory m_category; Timestamp m_timestamp; diff --git a/src/Services/AnalyticsService/AnalyticsEventBuilder.cpp b/src/Services/AnalyticsService/AnalyticsEventBuilder.cpp index 156370db3a..0908cca01c 100644 --- a/src/Services/AnalyticsService/AnalyticsEventBuilder.cpp +++ b/src/Services/AnalyticsService/AnalyticsEventBuilder.cpp @@ -7,6 +7,7 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// AnalyticsEventBuilder::AnalyticsEventBuilder() + : m_category( AEEC_CUSTOM ) { } ////////////////////////////////////////////////////////////////////////// @@ -64,6 +65,16 @@ namespace Mengine return m_localContext; } ////////////////////////////////////////////////////////////////////////// + void AnalyticsEventBuilder::setEventCategory( EAnalyticsEventCategory _category ) + { + m_category = _category; + } + ////////////////////////////////////////////////////////////////////////// + EAnalyticsEventCategory AnalyticsEventBuilder::getEventCategory() const + { + return m_category; + } + ////////////////////////////////////////////////////////////////////////// void AnalyticsEventBuilder::addParameter( const ConstString & _name, const AnalyticsEventParameterInterfacePtr & _parameter ) { m_context->addParameter( _name, _parameter ); @@ -104,11 +115,12 @@ namespace Mengine return this; } ////////////////////////////////////////////////////////////////////////// - Timestamp AnalyticsEventBuilder::log() + Timestamp AnalyticsEventBuilder::log() const { AnalyticsEventInterfacePtr event = m_analyticsFactory->makeEvent( m_eventName, MENGINE_DOCUMENT_FACTORABLE ); event->setContext( m_context ); + event->setCategory( m_category ); AnalyticsContextInterfacePtr resolve_globalContext = m_globalContext->resolveContext( MENGINE_DOCUMENT_FACTORABLE ); event->setGlobalContext( resolve_globalContext ); diff --git a/src/Services/AnalyticsService/AnalyticsEventBuilder.h b/src/Services/AnalyticsService/AnalyticsEventBuilder.h index f1074cbeb4..4bb68fe108 100644 --- a/src/Services/AnalyticsService/AnalyticsEventBuilder.h +++ b/src/Services/AnalyticsService/AnalyticsEventBuilder.h @@ -29,6 +29,10 @@ namespace Mengine void setGlobalContext( const AnalyticsContextInterfacePtr & _globalContext ); const AnalyticsContextInterfacePtr & getGlobalContext() const; + public: + void setEventCategory( EAnalyticsEventCategory _category ); + EAnalyticsEventCategory getEventCategory() const; + public: void setEventName( const ConstString & _eventName ); const ConstString & getEventName() const; @@ -48,7 +52,7 @@ namespace Mengine AnalyticsEventBuilderInterface * addParameterConstString( const ConstString & _name, const ConstString & _value ) override; public: - Timestamp log() override; + Timestamp log() const override; protected: AnalyticsFactoryInterfacePtr m_analyticsFactory; @@ -57,6 +61,8 @@ namespace Mengine ConstString m_eventName; + EAnalyticsEventCategory m_category; + AnalyticsContextInterfacePtr m_localContext; struct AnalyticsEventParameterDesc diff --git a/src/Services/AnalyticsService/AnalyticsService.cpp b/src/Services/AnalyticsService/AnalyticsService.cpp index d3a53bd2fb..0dfa18f85a 100644 --- a/src/Services/AnalyticsService/AnalyticsService.cpp +++ b/src/Services/AnalyticsService/AnalyticsService.cpp @@ -87,13 +87,14 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - AnalyticsEventBuilderInterfacePtr AnalyticsService::buildEvent( const ConstString & _eventName, const DocumentInterfacePtr & _doc ) + AnalyticsEventBuilderInterfacePtr AnalyticsService::buildEvent( EAnalyticsEventCategory _category, const ConstString & _eventName, const DocumentInterfacePtr & _doc ) { AnalyticsEventBuilderPtr builder = m_analyticsFactory->makeEventBuilder( _doc ); builder->setAnalyticsFactory( m_analyticsFactory ); builder->setGlobalContext( m_analyticsGlobalContext ); - builder->setEventName( _eventName ); + builder->setEventCategory( _category ); + builder->setEventName( _eventName ); return builder; } diff --git a/src/Services/AnalyticsService/AnalyticsService.h b/src/Services/AnalyticsService/AnalyticsService.h index fa68b7fc4b..c79826d6c0 100644 --- a/src/Services/AnalyticsService/AnalyticsService.h +++ b/src/Services/AnalyticsService/AnalyticsService.h @@ -31,7 +31,7 @@ namespace Mengine void logFlush() override; public: - AnalyticsEventBuilderInterfacePtr buildEvent( const ConstString & _eventName, const DocumentInterfacePtr & _doc ) override; + AnalyticsEventBuilderInterfacePtr buildEvent( EAnalyticsEventCategory _category, const ConstString & _eventName, const DocumentInterfacePtr & _doc ) override; public: AnalyticsContextInterfacePtr makeContext( const DocumentInterfacePtr & _doc ) override; From c449cdebac54e6dc9e947aa6e3ec38393b0d133c Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 27 Nov 2025 22:47:15 +0200 Subject: [PATCH 157/169] remove MENGINE_APP_HAS_ADS fix CMake MENGINE_SOLUTIONS_CONFIG_DIR --- cmake/macro_template.cmake | 36 +++++-------------- gradle/app.gradle | 26 ++------------ .../org/Mengine/Project/FinalApplication.java | 5 --- .../org/Mengine/Project/FinalApplication.java | 5 --- .../org/Mengine/Base/MengineApplication.java | 1 - .../Plugin/Adjust/MengineAdjustPlugin.java | 30 ++++------------ src/Plugins/JPEGPlugin/CMakeLists.txt | 2 +- 7 files changed, 19 insertions(+), 86 deletions(-) diff --git a/cmake/macro_template.cmake b/cmake/macro_template.cmake index c25848c599..1962c331a3 100644 --- a/cmake/macro_template.cmake +++ b/cmake/macro_template.cmake @@ -97,9 +97,9 @@ MACRO(SET_MENGINE_ENVIRONMENT MENGINE_TARGET MENGINE_RENDER MENGINE_PLATFORM MEN MESSAGE(FATAL_ERROR "miss MENGINE_DEPENDENCIES_PROJECT") ENDIF() - SET(MENGINE_DEPENDENCIES_ARCHIVE_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/depends/archive/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) - SET(MENGINE_DEPENDENCIES_LIBRARY_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/depends/library/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) - SET(MENGINE_DEPENDENCIES_RUNTIME_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/depends/runtime/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) + SET(MENGINE_DEPENDENCIES_ARCHIVE_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/dependencies/archive/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) + SET(MENGINE_DEPENDENCIES_LIBRARY_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/dependencies/library/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) + SET(MENGINE_DEPENDENCIES_RUNTIME_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/dependencies/runtime/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) SET(MENGINE_DEPENDENCIES_TEMP_DIR_BASE ${CMAKE_BINARY_DIR}/dependencies/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_CMAKE_GENERATOR}) @@ -161,7 +161,7 @@ MACRO(SET_MENGINE_ENVIRONMENT MENGINE_TARGET MENGINE_RENDER MENGINE_PLATFORM MEN endif() SET(THIRDPARTY_LIB_DIR ${MENGINE_DEPENDENCIES_ARCHIVE_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) - SET(THIRDPARTY_CONFIG_DIR ${MENGINE_REPOSITORY}/outputs/depends/config/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_OUTPUT_SUFFIX}) + SET(THIRDPARTY_CONFIG_DIR ${MENGINE_REPOSITORY}/outputs/dependencies/config/${MENGINE_DEPENDENCIES_PROJECT}/${MENGINE_OUTPUT_SUFFIX}) MESSAGE("THIRDPARTY_LIB_DIR: ${THIRDPARTY_LIB_DIR}") MESSAGE("THIRDPARTY_CONFIG_DIR: ${THIRDPARTY_CONFIG_DIR}") @@ -223,19 +223,11 @@ MACRO(SET_MENGINE_SOLUTIONS_OUTPUT_DIRECTORY) SET(MENGINE_SOLUTIONS_ARCHIVE_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/solutions/archive/${PROJECT_NAME}/${MENGINE_CMAKE_GENERATOR}) SET(MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/solutions/library/${PROJECT_NAME}/${MENGINE_CMAKE_GENERATOR}) SET(MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE ${MENGINE_INSTALL_PATH}/${PROJECT_NAME}/${MENGINE_CMAKE_GENERATOR}) - SET(MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE ${MENGINE_REPOSITORY}/outputs/solutions/config/${PROJECT_NAME}/${MENGINE_CMAKE_GENERATOR}) - + if(ANDROID) MESSAGE("Setup ANDROID solution output directory") - # output paths - SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_ARCHIVE_OUTPUT_BASE}/${ANDROID_ABI}/${CMAKE_BUILD_TYPE}) - SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}/${ANDROID_ABI}/${CMAKE_BUILD_TYPE}) - SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}/${ANDROID_ABI}/${CMAKE_BUILD_TYPE}) - - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${CMAKE_BINARY_DIR}/mengine_config) - - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/mengine_temp) + SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/mengine_solution_temp) elseif(MINGW) MESSAGE("Setup MINGW solution output directory") @@ -244,8 +236,6 @@ MACRO(SET_MENGINE_SOLUTIONS_OUTPUT_DIRECTORY) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/solutions) elseif(APPLE) # output paths @@ -255,24 +245,18 @@ MACRO(SET_MENGINE_SOLUTIONS_OUTPUT_DIRECTORY) SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_ARCHIVE_OUTPUT_BASE}) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}) - - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) elseif(MENGINE_TARGET_IOS) MESSAGE("Setup IOS solution output directory") SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_ARCHIVE_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) - - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) elseif(MENGINE_TARGET_IOS_SIMULATOR) MESSAGE("Setup IOS_SIMULATOR solution output directory") SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_ARCHIVE_OUTPUT_BASE}) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}) - - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) else() MESSAGE(FATAL_ERROR "unsupported target") endif() @@ -286,8 +270,6 @@ MACRO(SET_MENGINE_SOLUTIONS_OUTPUT_DIRECTORY) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}/${CMAKE_BUILD_TYPE}) - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/solutions) else() MESSAGE("Setup OTHER solution output directory") @@ -298,20 +280,18 @@ MACRO(SET_MENGINE_SOLUTIONS_OUTPUT_DIRECTORY) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}/${CMAKE_GENERATOR_PLATFORM}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}/${CMAKE_GENERATOR_PLATFORM}) - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${CMAKE_GENERATOR_PLATFORM}/${MENGINE_OUTPUT_SUFFIX}) - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/solutions/${CMAKE_GENERATOR_PLATFORM}) else() SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_ARCHIVE_OUTPUT_BASE}) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_LIBRARY_OUTPUT_BASE}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MENGINE_SOLUTIONS_RUNTIME_OUTPUT_BASE}) - SET(MENGINE_SOLUTIONS_CONFIG_DIR ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/solutions) endif() endif() + SET(MENGINE_SOLUTIONS_CONFIG_DIR ${CMAKE_BINARY_DIR}/mengine_solution_config) + INCLUDE_DIRECTORIES(${MENGINE_SOLUTIONS_CONFIG_DIR}/include) INCLUDE_DIRECTORIES(${MENGINE_SOURCE_DIR}) INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/libmath/include) diff --git a/gradle/app.gradle b/gradle/app.gradle index 2e9cbc8527..c2f4550839 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -58,15 +58,12 @@ final Boolean MENGINE_APP_PLUGIN_DATADOG = Utils.existAppPlugin("MENGINE_APP_PLU final Boolean MENGINE_APP_PLUGIN_VIBRATOR = Utils.existAppPlugin("MENGINE_APP_PLUGIN_VIBRATOR") final Boolean MENGINE_APP_PLUGIN_AMPLITUDE = Utils.existAppPlugin("MENGINE_APP_PLUGIN_AMPLITUDE") -final Boolean MENGINE_APP_HAS_ADS = Utils.getBooleanProperty("MENGINE_APP_HAS_ADS", false) - Utils.logString("ANDROID_APP_DELIVERY_PACKAGES", ANDROID_APP_DELIVERY_PACKAGES) Utils.logAvailable("ANDROID_APP_BUILD_PUBLISH", ANDROID_APP_BUILD_PUBLISH) Utils.logAvailable("ANDROID_APP_SPLIT_ENABLE", ANDROID_APP_SPLIT_ENABLE) Utils.logAvailable("ANDROID_APP_BUNDLE_ENABLE", ANDROID_APP_BUNDLE_ENABLE) Utils.logInteger("ANDROID_APP_BUILD_NUMBER", ANDROID_APP_BUILD_NUMBER) Utils.logString("ANDROID_APP_BUILD_VERSION", ANDROID_APP_BUILD_VERSION) -Utils.logAvailable("MENGINE_APP_HAS_ADS", MENGINE_APP_HAS_ADS) if (MENGINE_APP_PLUGIN_GOOGLE_SERVICE == true) { apply plugin: 'com.google.gms.google-services' @@ -381,7 +378,7 @@ if (MENGINE_APP_LIBRARY_MENGINE == true) { Utils.logAvailable("MENGINE_APP_SERVICE_AD", MENGINE_APP_SERVICE_AD) -if (MENGINE_APP_SERVICE_AD == true && MENGINE_APP_HAS_ADS == true) { +if (MENGINE_APP_SERVICE_AD == true) { android.ext.plugins += 'org.Mengine.Base.MengineAdService' } @@ -420,10 +417,6 @@ if (MENGINE_APP_PLUGIN_GOOGLE_SERVICE == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING", MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING) if (MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING == true) { - if (MENGINE_APP_HAS_ADS == false) { - throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_GOOGLE_ADVERTISING is enabled. Set -PMENGINE_APP_HAS_ADS=true") - } - android.ext.plugins += 'org.Mengine.Plugin.GoogleAdvertising.MengineGoogleAdvertisingPlugin' dependencies { @@ -676,11 +669,7 @@ if (MENGINE_APP_PLUGIN_ADMOB == true) { if (MENGINE_APP_ADMEDIATION_ADDED == true) { throw new GradleException("Cannot enable MENGINE_APP_PLUGIN_ADMOB because another mediation plugin is already enabled. Only one mediation plugin (MENGINE_APP_PLUGIN_ADMOB or MENGINE_APP_PLUGIN_APPLOVIN) can be enabled at a time.") } - - if (MENGINE_APP_HAS_ADS == false) { - throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_ADMOB is enabled. Set -PMENGINE_APP_HAS_ADS=true") - } - + MENGINE_APP_ADMEDIATION_ADDED = true android.ext.plugins += 'org.Mengine.Plugin.AdMob.MengineAdMobPlugin' @@ -693,10 +682,6 @@ if (MENGINE_APP_PLUGIN_ADMOB == true) { Utils.logAvailable("MENGINE_APP_PLUGIN_AMAZON", MENGINE_APP_PLUGIN_AMAZON) if (MENGINE_APP_PLUGIN_AMAZON == true) { - if (MENGINE_APP_HAS_ADS == false) { - throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_AMAZON is enabled. Set -PMENGINE_APP_HAS_ADS=true") - } - android.ext.plugins += 'org.Mengine.Plugin.Amazon.MengineAmazonPlugin' dependencies { @@ -710,11 +695,7 @@ if (MENGINE_APP_PLUGIN_APPLOVIN == true) { if (MENGINE_APP_ADMEDIATION_ADDED == true) { throw new GradleException("Cannot enable MENGINE_APP_PLUGIN_APPLOVIN because another mediation plugin is already enabled. Only one mediation plugin (MENGINE_APP_PLUGIN_ADMOB or MENGINE_APP_PLUGIN_APPLOVIN) can be enabled at a time.") } - - if (MENGINE_APP_HAS_ADS == false) { - throw new GradleException("MENGINE_APP_HAS_ADS must be set to true when MENGINE_APP_PLUGIN_APPLOVIN is enabled. Set -PMENGINE_APP_HAS_ADS=true") - } - + MENGINE_APP_ADMEDIATION_ADDED = true android.ext.plugins += 'org.Mengine.Plugin.AppLovin.MengineAppLovinPlugin' @@ -795,7 +776,6 @@ if (project.hasProperty("MENGINE_APP_OPTIONS") == true) { android { defaultConfig { buildConfigField "boolean", "ANDROID_APP_BUILD_PUBLISH", "${ANDROID_APP_BUILD_PUBLISH}" - buildConfigField "boolean", "MENGINE_APP_HAS_ADS", "${MENGINE_APP_HAS_ADS}" } } diff --git a/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java b/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java index 3c617d2ed4..4b5aa8c85c 100644 --- a/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java +++ b/gradle/app/src/main/java/org/Mengine/Project/FinalApplication.java @@ -35,9 +35,4 @@ public boolean isBuildPublish() { public String getApplicationOptions() { return BuildConfig.MENGINE_APP_OPTIONS; } - - @Override - public boolean hasAds() { - return BuildConfig.MENGINE_APP_HAS_ADS; - } } \ No newline at end of file diff --git a/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java b/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java index 3c617d2ed4..4b5aa8c85c 100644 --- a/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java +++ b/gradle/ci/src/main/java/org/Mengine/Project/FinalApplication.java @@ -35,9 +35,4 @@ public boolean isBuildPublish() { public String getApplicationOptions() { return BuildConfig.MENGINE_APP_OPTIONS; } - - @Override - public boolean hasAds() { - return BuildConfig.MENGINE_APP_HAS_ADS; - } } \ No newline at end of file diff --git a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java index 84771508c4..375dd806e6 100644 --- a/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineApplication.java @@ -103,7 +103,6 @@ public static String getBuildUsername() { public abstract String getVersionName(); public abstract boolean isBuildPublish(); public abstract String getApplicationOptions(); - public abstract boolean hasAds(); public void createFragment(Class cls) { MengineFragmentInterface fragment = (MengineFragmentInterface) MengineUtils.newInstance(TAG, cls, true); diff --git a/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java b/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java index d596f5494a..f50975cb8b 100644 --- a/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java +++ b/gradle/plugins/Adjust/src/main/java/org/Mengine/Plugin/Adjust/MengineAdjustPlugin.java @@ -97,19 +97,13 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS config.setLogLevel(LogLevel.INFO); } - boolean hasAds = application.hasAds(); - - if (hasAds == true) { - Adjust.getAdid(adid -> { - this.logInfo("Adjust adid: %s" - , MengineUtils.getRedactedValue(adid) - ); - - application.setADID(adid); - }); - } else { - this.logInfo("Skip Adjust AdID request, ads disabled"); - } + Adjust.getAdid(adid -> { + this.logInfo("Adjust adid: %s" + , MengineUtils.getRedactedValue(adid) + ); + + application.setADID(adid); + }); config.setOnAttributionChangedListener(attribution -> { this.logInfo("Adjust attribution changed: %s" @@ -207,11 +201,6 @@ public void onMengineChangePushToken(@NonNull MengineApplication application, St @Override public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull MengineParamAdRevenue revenue) { - if (application.hasAds() == false) { - this.logInfo("Skip Adjust AdRevenue, ads disabled"); - return; - } - MengineAdMediation mediation = revenue.ADREVENUE_MEDIATION; String AdjustMediation = MengineAdjustPlugin.getAdjustMediation(mediation); String network = revenue.ADREVENUE_NETWORK; @@ -233,11 +222,6 @@ public void onMengineAdRevenue(@NonNull MengineApplication application, @NonNull @Override public void onMengineTransparencyConsent(@NonNull MengineApplication application, @NonNull MengineParamTransparencyConsent tcParam) { - if (application.hasAds() == false) { - this.logInfo("Skip Adjust third-party sharing, ads disabled"); - return; - } - boolean EEA = tcParam.isEEA(); boolean AD_PERSONALIZATION = tcParam.getConsentAdPersonalization(); boolean AD_USER_DATA = tcParam.getConsentAdUserData(); diff --git a/src/Plugins/JPEGPlugin/CMakeLists.txt b/src/Plugins/JPEGPlugin/CMakeLists.txt index 6329f431e6..e686548e4a 100644 --- a/src/Plugins/JPEGPlugin/CMakeLists.txt +++ b/src/Plugins/JPEGPlugin/CMakeLists.txt @@ -11,7 +11,7 @@ src ImageDecoderJPEG.cpp ImageDecoderJPEG.h ImageEncoderJPEG.cpp - ImageEncoderJPEG.h + ImageEncoderJPEG.h ) INCLUDE_DIRECTORIES(${THIRDPARTY_CONFIG_DIR}/libjpeg) From 5d60d9a3acb859c844d9e41e623974ea7f8a855a Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 27 Nov 2025 23:03:51 +0200 Subject: [PATCH 158/169] clear code --- .../Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java index 2aa2bdfa67..d2e8a871de 100644 --- a/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java +++ b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java @@ -212,6 +212,9 @@ public void onAdFailedToLoad(@NonNull LoadAdError error) { adView.setVisibility(View.GONE); adView.setBackgroundColor(Color.TRANSPARENT); + ViewGroup viewGroup = activity.getContentViewGroup(); + viewGroup.addView(adView); + m_adView = adView; int widthDp = adSize.getWidth(); @@ -222,10 +225,6 @@ public void onAdFailedToLoad(@NonNull LoadAdError error) { this.setBannerState("init." + m_placement); this.loadAd(); - - ViewGroup viewGroup = activity.getContentViewGroup(); - - viewGroup.addView(m_adView); } @Override From 66ed2cf9568ac233bb78cce54cf0e0ad086d95a1 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 27 Nov 2025 23:38:34 +0200 Subject: [PATCH 159/169] add iOS visitParameters --- src/Environment/iOS/iOSDetail.h | 8 ++++ src/Environment/iOS/iOSDetail.mm | 77 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index 1ae2d0c1da..6fc41691f9 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -73,4 +73,12 @@ yes:(void (^ _Nonnull)(void) _Nonnull)yes cancel:(void (^ _Nonnull)(void) _Nonnull)cancel; ++ (void)visitParameters:(NSDictionary * _Nonnull)parameters + onBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))onBool + onInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))onInteger + onDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))onDouble + onString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))onString + onNull:(void (^ _Nonnull)(NSString * _Nonnull key))onNull + onUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))onUnknown; + @end diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index 217d9402fa..7c0eaf460d 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -348,4 +348,81 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController }]; } ++ (void)visitParameters:(NSDictionary * _Nonnull)parameters + onBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))onBool + onInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))onInteger + onDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))onDouble + onString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))onString + onNull:(void (^ _Nonnull)(NSString * _Nonnull key))onNull + onUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))onUnknown { + if (parameters == nil) { + return; + } + + CFTypeID boolenTypeId = CFBooleanGetTypeID(); + CFTypeID numberTypeId = CFNumberGetTypeID(); + + for (NSString * key in parameters) { + id value = [parameters objectForKey:key]; + + if (value == nil) { + onNull(key); + } else if ([value isKindOfClass:[NSNumber class]] == YES) { + CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); + + if (valueTypeId == boolenTypeId) { + BOOL b = [value boolValue]; + onBool(key, b); + } else if (valueTypeId == numberTypeId) { + CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); + + switch (numberType) { + case kCFNumberSInt8Type: + case kCFNumberSInt16Type: + case kCFNumberSInt32Type: + case kCFNumberSInt64Type: + case kCFNumberCharType: + case kCFNumberShortType: + case kCFNumberIntType: + case kCFNumberLongType: + case kCFNumberLongLongType: { + int64_t n = [value longLongValue]; + onInteger(key, n); + } break; + + case kCFNumberFloat32Type: + case kCFNumberFloat64Type: + case kCFNumberFloatType: + case kCFNumberDoubleType: { + double d = [value doubleValue]; + onDouble(key, d); + } break; + + case kCFNumberCFIndexType: + case kCFNumberNSIntegerType: + case kCFNumberCGFloatType: { + double d = [value doubleValue]; + onDouble(key, d); + } break; + } + } else { + BOOL handled = onUnknown(key, value); + if (handled == NO) { + // Skip unsupported type + } + } + } else if ([value isKindOfClass:[NSString class]] == YES) { + NSString * s = (NSString *)value; + onString(key, s); + } else if ([value isKindOfClass:[NSNull class]]) { + onNull(key); + } else { + BOOL handled = onUnknown(key, value); + if (handled == NO) { + // Skip unsupported type + } + } + } +} + @end From 42ea05494dac4902f051c19edc2df9a359ab3f83 Mon Sep 17 00:00:00 2001 From: irov Date: Thu, 27 Nov 2025 23:46:22 +0200 Subject: [PATCH 160/169] wip --- src/Environment/iOS/iOSDetail.h | 12 ++++++------ src/Environment/iOS/iOSDetail.mm | 30 +++++++++++++++--------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index 6fc41691f9..eb87b67352 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -74,11 +74,11 @@ cancel:(void (^ _Nonnull)(void) _Nonnull)cancel; + (void)visitParameters:(NSDictionary * _Nonnull)parameters - onBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))onBool - onInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))onInteger - onDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))onDouble - onString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))onString - onNull:(void (^ _Nonnull)(NSString * _Nonnull key))onNull - onUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))onUnknown; + forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool + forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger + forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull + forUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown; @end diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index 7c0eaf460d..a54c95d5f6 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -349,12 +349,12 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController } + (void)visitParameters:(NSDictionary * _Nonnull)parameters - onBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))onBool - onInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))onInteger - onDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))onDouble - onString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))onString - onNull:(void (^ _Nonnull)(NSString * _Nonnull key))onNull - onUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))onUnknown { + forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool + forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger + forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull + forUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown { if (parameters == nil) { return; } @@ -366,13 +366,13 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters id value = [parameters objectForKey:key]; if (value == nil) { - onNull(key); + forNull(key); } else if ([value isKindOfClass:[NSNumber class]] == YES) { CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); if (valueTypeId == boolenTypeId) { BOOL b = [value boolValue]; - onBool(key, b); + forBool(key, b); } else if (valueTypeId == numberTypeId) { CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); @@ -387,7 +387,7 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters case kCFNumberLongType: case kCFNumberLongLongType: { int64_t n = [value longLongValue]; - onInteger(key, n); + forInteger(key, n); } break; case kCFNumberFloat32Type: @@ -395,29 +395,29 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters case kCFNumberFloatType: case kCFNumberDoubleType: { double d = [value doubleValue]; - onDouble(key, d); + forDouble(key, d); } break; case kCFNumberCFIndexType: case kCFNumberNSIntegerType: case kCFNumberCGFloatType: { double d = [value doubleValue]; - onDouble(key, d); + forDouble(key, d); } break; } } else { - BOOL handled = onUnknown(key, value); + BOOL handled = forUnknown(key, value); if (handled == NO) { // Skip unsupported type } } } else if ([value isKindOfClass:[NSString class]] == YES) { NSString * s = (NSString *)value; - onString(key, s); + forString(key, s); } else if ([value isKindOfClass:[NSNull class]]) { - onNull(key); + forNull(key); } else { - BOOL handled = onUnknown(key, value); + BOOL handled = forUnknown(key, value); if (handled == NO) { // Skip unsupported type } From 3daafe52c185cac99f9e6903509f4e3df242abfc Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 29 Nov 2025 00:48:33 +0200 Subject: [PATCH 161/169] fix android Manifest required --- gradle/libraries/Mengine/build.gradle | 10 +++++++++- gradle/libraries/Mengine/src/main/AndroidManifest.xml | 11 ++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/gradle/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index 15655f91f4..94eada408b 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -16,6 +16,8 @@ final Boolean MENGINE_APP_ENABLE_STRICT_MODE = Utils.getBooleanProperty("MENGINE final String ANDROID_APP_SCREEN_ORIENTATION = Utils.getStringProperty("ANDROID_APP_SCREEN_ORIENTATION", "sensorPortrait") final Boolean ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN", false) final Boolean ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER", false) +final Boolean ANDROID_APP_REQUIRED_HARDWARE_CAMERA = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_CAMERA", false) +final Boolean ANDROID_APP_REQUIRED_HARDWARE_WIFI = Utils.getBooleanProperty("ANDROID_APP_REQUIRED_HARDWARE_WIFI", false) final Boolean MENGINE_APP_LIBRARY_OPENAL32 = Utils.existAppLibrary("MENGINE_APP_LIBRARY_OPENAL32") @@ -43,12 +45,16 @@ android { ANDROID_APP_BUILD_VERSION : ANDROID_APP_BUILD_VERSION, ANDROID_APP_SCREEN_ORIENTATION : ANDROID_APP_SCREEN_ORIENTATION, ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN : ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN, - ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER: ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER + ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER: ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER, + ANDROID_APP_REQUIRED_HARDWARE_CAMERA : ANDROID_APP_REQUIRED_HARDWARE_CAMERA, + ANDROID_APP_REQUIRED_HARDWARE_WIFI : ANDROID_APP_REQUIRED_HARDWARE_WIFI ] println "ANDROID_APP_SCREEN_ORIENTATION: $ANDROID_APP_SCREEN_ORIENTATION" println "ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN: $ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN" println "ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER: $ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER" + println "ANDROID_APP_REQUIRED_HARDWARE_CAMERA: $ANDROID_APP_REQUIRED_HARDWARE_CAMERA" + println "ANDROID_APP_REQUIRED_HARDWARE_WIFI: $ANDROID_APP_REQUIRED_HARDWARE_WIFI" externalNativeBuild { cmake { @@ -129,5 +135,7 @@ android { buildConfigField "boolean", "ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN", "${ANDROID_APP_REQUIRED_HARDWARE_TOUCHSCREEN}" buildConfigField "boolean", "ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER", "${ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER}" + buildConfigField "boolean", "ANDROID_APP_REQUIRED_HARDWARE_CAMERA", "${ANDROID_APP_REQUIRED_HARDWARE_CAMERA}" + buildConfigField "boolean", "ANDROID_APP_REQUIRED_HARDWARE_WIFI", "${ANDROID_APP_REQUIRED_HARDWARE_WIFI}" } } \ No newline at end of file diff --git a/gradle/libraries/Mengine/src/main/AndroidManifest.xml b/gradle/libraries/Mengine/src/main/AndroidManifest.xml index 9f3c23e39a..eeebd93380 100644 --- a/gradle/libraries/Mengine/src/main/AndroidManifest.xml +++ b/gradle/libraries/Mengine/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ @@ -9,11 +10,11 @@ - - - - - + + + + + From 575e45ff16b3daaf607918e229804ca1cc935af8 Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 29 Nov 2025 01:20:38 +0200 Subject: [PATCH 162/169] fix AppleDevToDevApplicationDelegate --- src/Environment/iOS/iOSDetail.h | 10 +++---- src/Environment/iOS/iOSDetail.mm | 27 +++++++++---------- .../AppleDevToDevApplicationDelegate.mm | 17 ++++++++---- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index eb87b67352..9a704b78d7 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -75,10 +75,10 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool - forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger - forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble - forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString - forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull - forUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown; + forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger + forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull + forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown; @end diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index a54c95d5f6..33b5c72519 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -350,11 +350,11 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController + (void)visitParameters:(NSDictionary * _Nonnull)parameters forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool - forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger - forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble - forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString - forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull - forUnknown:(BOOL (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown { + forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger + forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull + forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown { if (parameters == nil) { return; } @@ -372,6 +372,7 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters if (valueTypeId == boolenTypeId) { BOOL b = [value boolValue]; + forBool(key, b); } else if (valueTypeId == numberTypeId) { CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); @@ -387,40 +388,36 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters case kCFNumberLongType: case kCFNumberLongLongType: { int64_t n = [value longLongValue]; + forInteger(key, n); } break; - case kCFNumberFloat32Type: case kCFNumberFloat64Type: case kCFNumberFloatType: case kCFNumberDoubleType: { double d = [value doubleValue]; + forDouble(key, d); } break; - case kCFNumberCFIndexType: case kCFNumberNSIntegerType: case kCFNumberCGFloatType: { double d = [value doubleValue]; + forDouble(key, d); } break; } } else { - BOOL handled = forUnknown(key, value); - if (handled == NO) { - // Skip unsupported type - } + forUnknown(key, value); } } else if ([value isKindOfClass:[NSString class]] == YES) { NSString * s = (NSString *)value; + forString(key, s); } else if ([value isKindOfClass:[NSNull class]]) { forNull(key); } else { - BOOL handled = forUnknown(key, value); - if (handled == NO) { - // Skip unsupported type - } + forUnknown(key, value); } } } diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm index 2e0183982f..faca6cfe71 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm @@ -19,12 +19,19 @@ - (void)sendEvent:(NSString *)eventName parameters:(NSDictionary DTDCustomEventParameters * devtodev_parameters = [[DTDCustomEventParameters alloc] init]; - for (NSString * key in parameters) - { - id value = parameters[key]; - + [iOSDetail visitParameters:parameters forBool:^(NSString * key, bool value) { + [devtodev_parameters addBool:key value:value]; + } forInteger:^(NSString * key, int64_t value) { + [devtodev_parameters addInt:key value:value]; + } forDouble:^(NSString * key, double value) { + [devtodev_parameters addDouble:key value:value]; + } forString:^(NSString * key, NSString * value) { [devtodev_parameters addString:key value:value]; - } + } forNull:^(NSString * key) { + // DevToDev does not have a specific null type, so we can skip or add as empty string + } forUnknown:^(NSString * key, id value) { + // Handle unknown types if necessary + }]; [DTDAnalytics customEvent:eventName withParameters:devtodev_parameters]; } From e40a0d18432ba3e529d6e7b345986de3b7e44b04 Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 29 Nov 2025 02:13:11 +0200 Subject: [PATCH 163/169] wip visitParameters --- src/Environment/Apple/AppleDetail.h | 24 ++ src/Environment/Apple/AppleDetail.mm | 220 ++++++++++++++++-- src/Environment/iOS/iOSDetail.h | 8 - src/Environment/iOS/iOSDetail.mm | 74 ------ .../AppleDevToDevApplicationDelegate.mm | 5 +- .../AppleNativePythonScriptEmbedding.mm | 149 ++++-------- 6 files changed, 264 insertions(+), 216 deletions(-) diff --git a/src/Environment/Apple/AppleDetail.h b/src/Environment/Apple/AppleDetail.h index 7b4a04df70..168a8862d9 100644 --- a/src/Environment/Apple/AppleDetail.h +++ b/src/Environment/Apple/AppleDetail.h @@ -51,4 +51,28 @@ + (void)raisePureVirtualMethodException:(Class _Nonnull)klass selector:(SEL _Nonnull)selector; ++ (void)visitParameters:(NSDictionary * _Nonnull)parameters + forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool + forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger + forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull + forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown; + ++ (void)visitValues:(NSSet * _Nonnull)values + forBool:(void (^ _Nonnull)(BOOL value))forBool + forInteger:(void (^ _Nonnull)(int64_t value))forInteger + forDouble:(void (^ _Nonnull)(double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(void))forNull + forUnknown:(void (^ _Nonnull)(id _Nonnull value))forUnknown; + ++ (void)visitValues:(NSArray * _Nonnull)values + forBool:(void (^ _Nonnull)(BOOL value))forBool + forInteger:(void (^ _Nonnull)(int64_t value))forInteger + forDouble:(void (^ _Nonnull)(double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(void))forNull + forUnknown:(void (^ _Nonnull)(id _Nonnull value))forUnknown; + @end diff --git a/src/Environment/Apple/AppleDetail.mm b/src/Environment/Apple/AppleDetail.mm index 7e3273a1da..dabe237073 100644 --- a/src/Environment/Apple/AppleDetail.mm +++ b/src/Environment/Apple/AppleDetail.mm @@ -272,26 +272,32 @@ + (BOOL)getParamsFromJSON:(NSString * _Nonnull)_in outParams:(Mengine::Params * return YES; } -+ (void)getParamsFromNSDictionary:(NSDictionary *)_in outParams:(Mengine::Params * const)_out { - if (_in == nil) { ++ (void)visitParameters:(NSDictionary * _Nonnull)parameters + forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool + forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger + forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull + forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown { + if (parameters == nil) { return; } CFTypeID boolenTypeId = CFBooleanGetTypeID(); CFTypeID numberTypeId = CFNumberGetTypeID(); - [_in enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) { - Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; - - Mengine::ParamVariant variant; + for (NSString * key in parameters) { + id value = [parameters objectForKey:key]; - if ([value isKindOfClass:[NSNumber class]] == YES) { + if (value == nil) { + forNull(key); + } else if ([value isKindOfClass:[NSNumber class]] == YES) { CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); if (valueTypeId == boolenTypeId) { - bool b = [value boolValue]; + BOOL b = [value boolValue]; - variant = Mengine::ParamBool(b); + forBool(key, b); } else if (valueTypeId == numberTypeId) { CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); @@ -307,38 +313,208 @@ + (void)getParamsFromNSDictionary:(NSDictionary *)_in outParams:(Mengine::Params case kCFNumberLongLongType: { int64_t n = [value longLongValue]; - variant = Mengine::ParamInteger(n); - }break; - + forInteger(key, n); + } break; case kCFNumberFloat32Type: case kCFNumberFloat64Type: case kCFNumberFloatType: case kCFNumberDoubleType: { double d = [value doubleValue]; - variant = Mengine::ParamDouble(d); - }break; - + forDouble(key, d); + } break; case kCFNumberCFIndexType: case kCFNumberNSIntegerType: case kCFNumberCGFloatType: { + double d = [value doubleValue]; - }break; + forDouble(key, d); + } break; } + } else { + forUnknown(key, value); } } else if ([value isKindOfClass:[NSString class]] == YES) { - Mengine::ConstString s = [AppleString NSStringToConstString:value]; + NSString * s = (NSString *)value; - variant = Mengine::ParamConstString(s); + forString(key, s); } else if ([value isKindOfClass:[NSNull class]]) { - variant = Mengine::ParamNull(); + forNull(key); + } else { + forUnknown(key, value); + } + } +} + ++ (void)visitValues:(NSSet * _Nonnull)values + forBool:(void (^ _Nonnull)(BOOL value))forBool + forInteger:(void (^ _Nonnull)(int64_t value))forInteger + forDouble:(void (^ _Nonnull)(double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(void))forNull + forUnknown:(void (^ _Nonnull)(id _Nonnull value))forUnknown { + if (values == nil) { + return; + } + + CFTypeID boolenTypeId = CFBooleanGetTypeID(); + CFTypeID numberTypeId = CFNumberGetTypeID(); + + for (id value in values) { + if (value == nil || [value isKindOfClass:[NSNull class]]) { + forNull(); + } else if ([value isKindOfClass:[NSNumber class]] == YES) { + CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); + + if (valueTypeId == boolenTypeId) { + BOOL b = [value boolValue]; + + forBool(b); + } else if (valueTypeId == numberTypeId) { + CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); + + switch (numberType) { + case kCFNumberSInt8Type: + case kCFNumberSInt16Type: + case kCFNumberSInt32Type: + case kCFNumberSInt64Type: + case kCFNumberCharType: + case kCFNumberShortType: + case kCFNumberIntType: + case kCFNumberLongType: + case kCFNumberLongLongType: { + int64_t n = [value longLongValue]; + + forInteger(n); + } break; + case kCFNumberFloat32Type: + case kCFNumberFloat64Type: + case kCFNumberFloatType: + case kCFNumberDoubleType: + case kCFNumberCFIndexType: + case kCFNumberNSIntegerType: + case kCFNumberCGFloatType: { + double d = [value doubleValue]; + + forDouble(d); + } break; + } + } else { + forUnknown(value); + } + } else if ([value isKindOfClass:[NSString class]] == YES) { + NSString * s = (NSString *)value; + + forString(s); } else { - const Mengine::Char * value_str = [[NSString stringWithFormat:@"%@", value] UTF8String]; + forUnknown(value); + } + } +} + ++ (void)visitValues:(NSArray * _Nonnull)values + forBool:(void (^ _Nonnull)(BOOL value))forBool + forInteger:(void (^ _Nonnull)(int64_t value))forInteger + forDouble:(void (^ _Nonnull)(double value))forDouble + forString:(void (^ _Nonnull)(NSString * _Nonnull value))forString + forNull:(void (^ _Nonnull)(void))forNull + forUnknown:(void (^ _Nonnull)(id _Nonnull value))forUnknown { + if (values == nil) { + return; + } + + CFTypeID boolenTypeId = CFBooleanGetTypeID(); + CFTypeID numberTypeId = CFNumberGetTypeID(); + + for (id value in values) { + if (value == nil || [value isKindOfClass:[NSNull class]]) { + forNull(); + } else if ([value isKindOfClass:[NSNumber class]] == YES) { + CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); + + if (valueTypeId == boolenTypeId) { + BOOL b = [value boolValue]; + + forBool(b); + } else if (valueTypeId == numberTypeId) { + CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); + + switch (numberType) { + case kCFNumberSInt8Type: + case kCFNumberSInt16Type: + case kCFNumberSInt32Type: + case kCFNumberSInt64Type: + case kCFNumberCharType: + case kCFNumberShortType: + case kCFNumberIntType: + case kCFNumberLongType: + case kCFNumberLongLongType: { + int64_t n = [value longLongValue]; + + forInteger(n); + } break; + case kCFNumberFloat32Type: + case kCFNumberFloat64Type: + case kCFNumberFloatType: + case kCFNumberDoubleType: + case kCFNumberCFIndexType: + case kCFNumberNSIntegerType: + case kCFNumberCGFloatType: { + double d = [value doubleValue]; + + forDouble(d); + } break; + } + } else { + forUnknown(value); + } + } else if ([value isKindOfClass:[NSString class]] == YES) { + NSString * s = (NSString *)value; - variant = Mengine::ParamString(value_str); + forString(s); + } else { + forUnknown(value); } + } +} + ++ (void)getParamsFromNSDictionary:(NSDictionary *)_in outParams:(Mengine::Params * const)_out { + if (_in == nil) { + return; + } + + [AppleDetail visitParameters:_in forBool:^(NSString * key, BOOL value) { + Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; + Mengine::ParamVariant variant = Mengine::ParamBool(value); + + _out->emplace(key_cstr, variant); + } forInteger:^(NSString * key, int64_t value) { + Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; + Mengine::ParamVariant variant = Mengine::ParamInteger(value); + + _out->emplace(key_cstr, variant); + } forDouble:^(NSString * key, double value) { + Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; + Mengine::ParamVariant variant = Mengine::ParamDouble(value); + + _out->emplace(key_cstr, variant); + } forString:^(NSString * key, NSString * value) { + Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; + Mengine::ConstString s = [AppleString NSStringToConstString:value]; + Mengine::ParamVariant variant = Mengine::ParamConstString(s); + + _out->emplace(key_cstr, variant); + } forNull:^(NSString * key) { + Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; + Mengine::ParamVariant variant = Mengine::ParamNull(); + + _out->emplace(key_cstr, variant); + } forUnknown:^(NSString * key, id value) { + Mengine::ConstString key_cstr = [AppleString NSStringToConstString:key]; + const Mengine::Char * value_str = [[NSString stringWithFormat:@"%@", value] UTF8String]; + Mengine::ParamVariant variant = Mengine::ParamString(value_str); - _out->emplace( key_cstr, variant ); + _out->emplace(key_cstr, variant); }]; } diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index 9a704b78d7..1ae2d0c1da 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -73,12 +73,4 @@ yes:(void (^ _Nonnull)(void) _Nonnull)yes cancel:(void (^ _Nonnull)(void) _Nonnull)cancel; -+ (void)visitParameters:(NSDictionary * _Nonnull)parameters - forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool - forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger - forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble - forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString - forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull - forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown; - @end diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index 33b5c72519..217d9402fa 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -348,78 +348,4 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController }]; } -+ (void)visitParameters:(NSDictionary * _Nonnull)parameters - forBool:(void (^ _Nonnull)(NSString * _Nonnull key, BOOL value))forBool - forInteger:(void (^ _Nonnull)(NSString * _Nonnull key, int64_t value))forInteger - forDouble:(void (^ _Nonnull)(NSString * _Nonnull key, double value))forDouble - forString:(void (^ _Nonnull)(NSString * _Nonnull key, NSString * _Nonnull value))forString - forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull - forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown { - if (parameters == nil) { - return; - } - - CFTypeID boolenTypeId = CFBooleanGetTypeID(); - CFTypeID numberTypeId = CFNumberGetTypeID(); - - for (NSString * key in parameters) { - id value = [parameters objectForKey:key]; - - if (value == nil) { - forNull(key); - } else if ([value isKindOfClass:[NSNumber class]] == YES) { - CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); - - if (valueTypeId == boolenTypeId) { - BOOL b = [value boolValue]; - - forBool(key, b); - } else if (valueTypeId == numberTypeId) { - CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); - - switch (numberType) { - case kCFNumberSInt8Type: - case kCFNumberSInt16Type: - case kCFNumberSInt32Type: - case kCFNumberSInt64Type: - case kCFNumberCharType: - case kCFNumberShortType: - case kCFNumberIntType: - case kCFNumberLongType: - case kCFNumberLongLongType: { - int64_t n = [value longLongValue]; - - forInteger(key, n); - } break; - case kCFNumberFloat32Type: - case kCFNumberFloat64Type: - case kCFNumberFloatType: - case kCFNumberDoubleType: { - double d = [value doubleValue]; - - forDouble(key, d); - } break; - case kCFNumberCFIndexType: - case kCFNumberNSIntegerType: - case kCFNumberCGFloatType: { - double d = [value doubleValue]; - - forDouble(key, d); - } break; - } - } else { - forUnknown(key, value); - } - } else if ([value isKindOfClass:[NSString class]] == YES) { - NSString * s = (NSString *)value; - - forString(key, s); - } else if ([value isKindOfClass:[NSNull class]]) { - forNull(key); - } else { - forUnknown(key, value); - } - } -} - @end diff --git a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm index faca6cfe71..d5cb20b821 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm @@ -2,8 +2,9 @@ #import "Environment/Apple/AppleBundle.h" +#import "Environment/Apple/AppleDetail.h" + #import "Environment/iOS/iOSApplication.h" -#import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" #import "Environment/iOS/iOSAnalyticsEventCategory.h" @@ -19,7 +20,7 @@ - (void)sendEvent:(NSString *)eventName parameters:(NSDictionary DTDCustomEventParameters * devtodev_parameters = [[DTDCustomEventParameters alloc] init]; - [iOSDetail visitParameters:parameters forBool:^(NSString * key, bool value) { + [AppleDetail visitParameters:parameters forBool:^(NSString * key, BOOL value) { [devtodev_parameters addBool:key value:value]; } forInteger:^(NSString * key, int64_t value) { [devtodev_parameters addInt:key value:value]; diff --git a/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm b/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm index 9999d06bc6..af7b94dc18 100644 --- a/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm +++ b/src/Plugins/AppleNativePythonPlugin/AppleNativePythonScriptEmbedding.mm @@ -118,65 +118,30 @@ bool apply( pybind::kernel_interface * _kernel, PyObject * _obj, value_type & _v PyObject * wrap( pybind::kernel_interface * _kernel, pybind::type_cast_result::TCastRef _value ) override { PyObject * py_dict = _kernel->dict_new(); + __block bool error = false; - CFTypeID boolenTypeId = CFBooleanGetTypeID(); - CFTypeID numberTypeId = CFNumberGetTypeID(); - - for (NSString * key in _value) { - id value = [_value objectForKey:key]; - + [AppleDetail visitParameters:_value forBool:^(NSString * key, BOOL value) { PyObject * py_key = pybind::ptr( _kernel, key ); - - if ([value isKindOfClass:[NSNumber class]] == YES) { - CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); - - if (valueTypeId == boolenTypeId) { - bool b = [value boolValue]; - - pybind::dict_setobject_t( _kernel, py_dict, py_key, b ); - } else if (valueTypeId == numberTypeId) { - CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); - - switch (numberType) { - case kCFNumberSInt8Type: - case kCFNumberSInt16Type: - case kCFNumberSInt32Type: - case kCFNumberSInt64Type: - case kCFNumberCharType: - case kCFNumberShortType: - case kCFNumberIntType: - case kCFNumberLongType: - case kCFNumberLongLongType: { - int64_t n = [value longLongValue]; - - pybind::dict_setobject_t( _kernel, py_dict, py_key, n ); - }break; - - case kCFNumberFloat32Type: - case kCFNumberFloat64Type: - case kCFNumberFloatType: - case kCFNumberDoubleType: { - double d = [value doubleValue]; - - pybind::dict_setobject_t( _kernel, py_dict, py_key, d ); - }break; - - case kCFNumberCFIndexType: - case kCFNumberNSIntegerType: - case kCFNumberCGFloatType: { - - }break; - } - } - } else if ([value isKindOfClass:[NSString class]] == YES) { - NSString * s = (NSString *)value; - - pybind::dict_setobject_t( _kernel, py_dict, py_key, s ); - } else if ([value isKindOfClass:[NSNull class]]) { - //Empty (???) - } else { - return nullptr; - } + pybind::dict_setobject_t( _kernel, py_dict, py_key, (bool)value ); + } forInteger:^(NSString * key, int64_t value) { + PyObject * py_key = pybind::ptr( _kernel, key ); + pybind::dict_setobject_t( _kernel, py_dict, py_key, value ); + } forDouble:^(NSString * key, double value) { + PyObject * py_key = pybind::ptr( _kernel, key ); + pybind::dict_setobject_t( _kernel, py_dict, py_key, value ); + } forString:^(NSString * key, NSString * value) { + PyObject * py_key = pybind::ptr( _kernel, key ); + pybind::dict_setobject_t( _kernel, py_dict, py_key, value ); + } forNull:^(NSString * key) { + PyObject * py_key = pybind::ptr( _kernel, key ); + PyObject * py_none = _kernel->ret_none(); + pybind::dict_setobject_t( _kernel, py_dict, py_key, py_none ); + } forUnknown:^(NSString * key, id value) { + error = true; + }]; + + if (error == true) { + return nullptr; } return py_dict; @@ -247,61 +212,25 @@ bool apply( pybind::kernel_interface * _kernel, PyObject * _obj, value_type & _v PyObject * wrap( pybind::kernel_interface * _kernel, pybind::type_cast_result::TCastRef _value ) override { PyObject * py_set = _kernel->set_new(); + __block bool error = false; - CFTypeID boolenTypeId = CFBooleanGetTypeID(); - CFTypeID numberTypeId = CFNumberGetTypeID(); + [AppleDetail visitValues:_value forBool:^(BOOL value) { + pybind::set_set_t( _kernel, py_set, (bool)value ); + } forInteger:^(int64_t value) { + pybind::set_set_t( _kernel, py_set, value ); + } forDouble:^(double value) { + pybind::set_set_t( _kernel, py_set, value ); + } forString:^(NSString * value) { + pybind::set_set_t( _kernel, py_set, value ); + } forNull:^(void) { + PyObject * py_none = _kernel->ret_none(); + pybind::set_set_t( _kernel, py_set, py_none ); + } forUnknown:^(id value) { + error = true; + }]; - for (id value in _value) { - if ([value isKindOfClass:[NSNumber class]] == YES) { - CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); - - if (valueTypeId == boolenTypeId) { - bool b = [value boolValue]; - - pybind::set_set_t( _kernel, py_set, b ); - } else if (valueTypeId == numberTypeId) { - CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); - - switch (numberType) { - case kCFNumberSInt8Type: - case kCFNumberSInt16Type: - case kCFNumberSInt32Type: - case kCFNumberSInt64Type: - case kCFNumberCharType: - case kCFNumberShortType: - case kCFNumberIntType: - case kCFNumberLongType: - case kCFNumberLongLongType: { - int64_t n = [value longLongValue]; - - pybind::set_set_t( _kernel, py_set, n ); - }break; - - case kCFNumberFloat32Type: - case kCFNumberFloat64Type: - case kCFNumberFloatType: - case kCFNumberDoubleType: { - double d = [value doubleValue]; - - pybind::set_set_t( _kernel, py_set, d ); - }break; - - case kCFNumberCFIndexType: - case kCFNumberNSIntegerType: - case kCFNumberCGFloatType: { - - }break; - } - } - } else if ([value isKindOfClass:[NSString class]] == YES) { - NSString * s = (NSString *)value; - - pybind::set_set_t( _kernel, py_set, s ); - } else if ([value isKindOfClass:[NSNull class]]) { - //Empty (???) - } else { - return nullptr; - } + if (error == true) { + return nullptr; } return py_set; From 2338d08385d28733c0378101240bc92fa57823fa Mon Sep 17 00:00:00 2001 From: irov Date: Sat, 29 Nov 2025 02:21:18 +0200 Subject: [PATCH 164/169] fix visitValues --- src/Environment/Apple/AppleDetail.h | 10 +--- src/Environment/Apple/AppleDetail.mm | 68 +--------------------------- 2 files changed, 2 insertions(+), 76 deletions(-) diff --git a/src/Environment/Apple/AppleDetail.h b/src/Environment/Apple/AppleDetail.h index 168a8862d9..8c94a3e864 100644 --- a/src/Environment/Apple/AppleDetail.h +++ b/src/Environment/Apple/AppleDetail.h @@ -59,15 +59,7 @@ forNull:(void (^ _Nonnull)(NSString * _Nonnull key))forNull forUnknown:(void (^ _Nonnull)(NSString * _Nonnull key, id _Nonnull value))forUnknown; -+ (void)visitValues:(NSSet * _Nonnull)values - forBool:(void (^ _Nonnull)(BOOL value))forBool - forInteger:(void (^ _Nonnull)(int64_t value))forInteger - forDouble:(void (^ _Nonnull)(double value))forDouble - forString:(void (^ _Nonnull)(NSString * _Nonnull value))forString - forNull:(void (^ _Nonnull)(void))forNull - forUnknown:(void (^ _Nonnull)(id _Nonnull value))forUnknown; - -+ (void)visitValues:(NSArray * _Nonnull)values ++ (void)visitValues:(id _Nonnull)values forBool:(void (^ _Nonnull)(BOOL value))forBool forInteger:(void (^ _Nonnull)(int64_t value))forInteger forDouble:(void (^ _Nonnull)(double value))forDouble diff --git a/src/Environment/Apple/AppleDetail.mm b/src/Environment/Apple/AppleDetail.mm index dabe237073..6ec6db7071 100644 --- a/src/Environment/Apple/AppleDetail.mm +++ b/src/Environment/Apple/AppleDetail.mm @@ -346,73 +346,7 @@ + (void)visitParameters:(NSDictionary * _Nonnull)parameters } } -+ (void)visitValues:(NSSet * _Nonnull)values - forBool:(void (^ _Nonnull)(BOOL value))forBool - forInteger:(void (^ _Nonnull)(int64_t value))forInteger - forDouble:(void (^ _Nonnull)(double value))forDouble - forString:(void (^ _Nonnull)(NSString * _Nonnull value))forString - forNull:(void (^ _Nonnull)(void))forNull - forUnknown:(void (^ _Nonnull)(id _Nonnull value))forUnknown { - if (values == nil) { - return; - } - - CFTypeID boolenTypeId = CFBooleanGetTypeID(); - CFTypeID numberTypeId = CFNumberGetTypeID(); - - for (id value in values) { - if (value == nil || [value isKindOfClass:[NSNull class]]) { - forNull(); - } else if ([value isKindOfClass:[NSNumber class]] == YES) { - CFTypeID valueTypeId = CFGetTypeID((__bridge CFTypeRef)(value)); - - if (valueTypeId == boolenTypeId) { - BOOL b = [value boolValue]; - - forBool(b); - } else if (valueTypeId == numberTypeId) { - CFNumberType numberType = CFNumberGetType((__bridge CFNumberRef)value); - - switch (numberType) { - case kCFNumberSInt8Type: - case kCFNumberSInt16Type: - case kCFNumberSInt32Type: - case kCFNumberSInt64Type: - case kCFNumberCharType: - case kCFNumberShortType: - case kCFNumberIntType: - case kCFNumberLongType: - case kCFNumberLongLongType: { - int64_t n = [value longLongValue]; - - forInteger(n); - } break; - case kCFNumberFloat32Type: - case kCFNumberFloat64Type: - case kCFNumberFloatType: - case kCFNumberDoubleType: - case kCFNumberCFIndexType: - case kCFNumberNSIntegerType: - case kCFNumberCGFloatType: { - double d = [value doubleValue]; - - forDouble(d); - } break; - } - } else { - forUnknown(value); - } - } else if ([value isKindOfClass:[NSString class]] == YES) { - NSString * s = (NSString *)value; - - forString(s); - } else { - forUnknown(value); - } - } -} - -+ (void)visitValues:(NSArray * _Nonnull)values ++ (void)visitValues:(id _Nonnull)values forBool:(void (^ _Nonnull)(BOOL value))forBool forInteger:(void (^ _Nonnull)(int64_t value))forInteger forDouble:(void (^ _Nonnull)(double value))forDouble From c933211e709b2b7700889e56d829b2223d1fd8c3 Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 30 Nov 2025 00:46:21 +0200 Subject: [PATCH 165/169] improve PlatformServiceInterface tickPlatform improve iOS config ids --- .../iOSUIApplicationDelegate.mm | 4 ++-- src/Environment/iOS/iOSDetail.h | 2 +- src/Environment/iOS/iOSDetail.mm | 4 ++-- .../iOS/iOSPluginConfigDelegateInterface.h | 2 +- .../iOSUIMainApplicationDelegateInterface.h | 2 +- src/Interface/PlatformServiceInterface.h | 2 +- .../AndroidPlatformService.cpp | 22 ++++++++++------- .../AndroidPlatform/AndroidPlatformService.h | 2 +- .../Win32Platform/Win32PlatformService.cpp | 6 +++-- .../Win32Platform/Win32PlatformService.h | 2 +- .../AppleAdvertisementApplicationDelegate.mm | 2 +- .../AppleDatadogApplicationDelegate.mm | 24 +++++++++++++++---- ...FirebaseRemoteConfigApplicationDelegate.mm | 9 ++++++- 13 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm index 9822ba68a0..4a5b85bec6 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -174,10 +174,10 @@ - (void)eventLog:(AppleLogRecordParam *)record { } } -- (void)eventConfig:(NSDictionary *)config { +- (void)eventConfig:(NSDictionary *)config ids:(NSDictionary *)ids { @autoreleasepool { for (NSObject * delegate in self.m_pluginConfigDelegates) { - [delegate onConfig:config]; + [delegate onConfig:config ids:ids]; } } } diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index 1ae2d0c1da..0f3a4769a9 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -43,7 +43,7 @@ + (void)appTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking; + (void)transparencyConsent:(iOSTransparencyConsentParam * _Nonnull)consent; + (void)log:(AppleLogRecordParam * _Nonnull)record; -+ (void)config:(NSDictionary * _Nonnull)config; ++ (void)config:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids; + (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block; diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index 217d9402fa..7b5d7ed4ab 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -186,11 +186,11 @@ + (void) log:(AppleLogRecordParam *)record { }]; } -+ (void) config:(NSDictionary * _Nonnull)config { ++ (void) config:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids { [AppleDetail addMainQueueOperation:^{ NSObject *delegate = [iOSDetail getUIMainApplicationDelegate]; - [delegate eventConfig:config]; + [delegate eventConfig:config ids:ids]; }]; } diff --git a/src/Environment/iOS/iOSPluginConfigDelegateInterface.h b/src/Environment/iOS/iOSPluginConfigDelegateInterface.h index 10bed96a50..ced6ccec2c 100644 --- a/src/Environment/iOS/iOSPluginConfigDelegateInterface.h +++ b/src/Environment/iOS/iOSPluginConfigDelegateInterface.h @@ -4,6 +4,6 @@ @protocol iOSPluginConfigDelegateInterface -- (void)onConfig:(NSDictionary * _Nonnull)config; +- (void)onConfig:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids; @end diff --git a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h index 270a15b295..091c679083 100644 --- a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h @@ -28,7 +28,7 @@ - (void)eventLog:(AppleLogRecordParam * _Nonnull)record; -- (void)eventConfig:(NSDictionary * _Nonnull)config; +- (void)eventConfig:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids; - (void)eventAnalytic:(NSString * _Nonnull)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary * _Nonnull)params; - (void)eventAnalyticScreen:(NSString * _Nonnull)name type:(NSString * _Nonnull)type; diff --git a/src/Interface/PlatformServiceInterface.h b/src/Interface/PlatformServiceInterface.h index 60bf5f9432..e95e59cd0e 100644 --- a/src/Interface/PlatformServiceInterface.h +++ b/src/Interface/PlatformServiceInterface.h @@ -40,7 +40,7 @@ namespace Mengine virtual bool runPlatform() = 0; virtual void loopPlatform() = 0; virtual bool updatePlatform() = 0; - virtual void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) = 0; + virtual bool tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) = 0; virtual void stopPlatform() = 0; virtual void freezePlatform( bool _tick, bool _render, bool _sound ) = 0; virtual void unfreezePlatform( bool _tick, bool _render, bool _sound ) = 0; diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index 3410f2a0dd..1f04c96682 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -70,6 +70,7 @@ #include #include +#include ////////////////////////////////////////////////////////////////////////// #ifndef MENGINE_SETLOCALE_ENABLE @@ -882,7 +883,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void AndroidPlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) + bool AndroidPlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) { MENGINE_UNUSED( _pause ); MENGINE_UNUSED( _flush ); @@ -907,17 +908,17 @@ namespace Mengine if( m_active == false ) { - return; + return false; } if( m_activityState != EAS_RESUME && m_activityState != EAS_START ) { - return; + return false; } if( m_freezedRender != 0 || _render == false ) { - return; + return false; } MENGINE_THREAD_MUTEX_SCOPE( m_nativeWindowMutex ); @@ -925,7 +926,7 @@ namespace Mengine if( m_nativeWindow == nullptr || m_eglSurface == EGL_NO_SURFACE || m_eglContext == EGL_NO_CONTEXT ) { - return; + return false; } bool sucessful = APPLICATION_SERVICE() @@ -943,7 +944,7 @@ namespace Mengine , ::eglGetError() ); - return; + return false; } if( ::eglSwapBuffers( m_eglDisplay, m_eglSurface ) == EGL_FALSE ) @@ -952,8 +953,10 @@ namespace Mengine , ::eglGetError() ); - return; + return false; } + + return true; } ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::loopPlatform() @@ -973,7 +976,10 @@ namespace Mengine m_prevTime = currentTime; - this->tickPlatform( frameTime, true, true, true ); + if( this->tickPlatform( frameTime, true, true, true ) == false ) + { + usleep( 100000 ); + } } } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.h b/src/Platforms/AndroidPlatform/AndroidPlatformService.h index b4758e44c5..5f9562b559 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.h +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.h @@ -58,7 +58,7 @@ namespace Mengine bool runPlatform() override; void loopPlatform() override; bool updatePlatform() override; - void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; + bool tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; void freezePlatform( bool _tick, bool _render, bool _sound ) override; void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index a005fbe954..49af21a13a 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -641,7 +641,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void Win32PlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) + bool Win32PlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) { MENGINE_UNUSED( _frameTime ); @@ -650,7 +650,7 @@ namespace Mengine { ::Sleep( 200 ); - return; + return false; } #endif @@ -715,6 +715,8 @@ namespace Mengine } } } + + return true; } ////////////////////////////////////////////////////////////////////////// void Win32PlatformService::loopPlatform() diff --git a/src/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index 4245fc7a22..097e825a35 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.h +++ b/src/Platforms/Win32Platform/Win32PlatformService.h @@ -47,7 +47,7 @@ namespace Mengine bool runPlatform() override; void loopPlatform() override; bool updatePlatform() override; - void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; + bool tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; void stopPlatform() override; void freezePlatform( bool _tick, bool _render, bool _sound ) override; void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm index 0ac1c9807a..9e5d58cdf0 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm @@ -434,7 +434,7 @@ - (void)parseAdRewardedAdPoint:(NSMutableDictionary *)points withName:(NSString [points setObject:point forKey:name]; } -- (void)onConfig:(NSDictionary * _Nonnull)config { +- (void)onConfig:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids { @synchronized (self) { NSMutableDictionary * interstitialPoints = [NSMutableDictionary dictionary]; NSMutableDictionary * rewardedPoints = [NSMutableDictionary dictionary]; diff --git a/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm b/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm index 179c44f0e0..63fc2646e0 100644 --- a/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm +++ b/src/Plugins/AppleDatadogPlugin/AppleDatadogApplicationDelegate.mm @@ -214,12 +214,26 @@ - (void)onLogger:(AppleLogRecordParam * _Nonnull)record { #pragma mark - iOSPluginConfigDelegateInterface -- (void)onConfig:(NSDictionary * _Nonnull)config { -#ifdef MENGINE_RELEASE - self.m_enableDebugMessage = [[config objectForKey:@"datadog_debug_message"] boolValue]; -#endif +- (void)onConfig:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids { + NSDictionary * datadog_debug_message = [config objectForKey:@"datadog_debug_message"]; + + if (datadog_debug_message != nil) { + BOOL enable = [[datadog_debug_message objectForKey:@"enable"] boolValue]; + + self.m_enableDebugMessage = enable; + } + + NSDictionary * datadog_info_message = [config objectForKey:@"datadog_info_message"]; - self.m_enableInfoMessage = [[config objectForKey:@"datadog_info_message"] boolValue]; + if (datadog_info_message != nil) { + BOOL enable = [[datadog_info_message objectForKey:@"enable"] boolValue]; + + self.m_enableInfoMessage = enable; + } + + if (self.m_logger != nil) { + [self.m_logger addAttributeForKey:@"mng_ids" value:ids]; + } } #pragma mark - iOSPluginTransparencyConsentDelegateInterface diff --git a/src/Plugins/AppleFirebaseRemoteConfigPlugin/AppleFirebaseRemoteConfigApplicationDelegate.mm b/src/Plugins/AppleFirebaseRemoteConfigPlugin/AppleFirebaseRemoteConfigApplicationDelegate.mm index 21b15449df..e7b011eb37 100644 --- a/src/Plugins/AppleFirebaseRemoteConfigPlugin/AppleFirebaseRemoteConfigApplicationDelegate.mm +++ b/src/Plugins/AppleFirebaseRemoteConfigPlugin/AppleFirebaseRemoteConfigApplicationDelegate.mm @@ -111,6 +111,7 @@ - (void)updateRemoteConfigValues:(FIRRemoteConfig *)remoteConfig { NSArray * remoteKeys = [remoteConfig allKeysFromSource:FIRRemoteConfigSourceDefault]; NSMutableDictionary * configs = [NSMutableDictionary dictionary]; + NSMutableDictionary * ids = [NSMutableDictionary dictionary]; for( NSString * key in remoteKeys ) { FIRRemoteConfigValue * value = [remoteConfig configValueForKey:key]; @@ -130,13 +131,19 @@ - (void)updateRemoteConfigValues:(FIRRemoteConfig *)remoteConfig { } [configs setObject:json forKey:key]; + + id idValueObj = [json objectForKey:@"id"]; + + if (idValueObj != nil && [idValueObj isKindOfClass:[NSNumber class]] == YES) { + [ids setObject:(NSNumber *)idValueObj forKey:key]; + } } @synchronized (self) { self.m_configs = configs; } - [iOSDetail config:configs]; + [iOSDetail config:configs ids:ids]; } - (BOOL)hasRemoteConfig:(NSString *)key { From a574a462becd93ae48c2736e4ae090335f80ea6d Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 30 Nov 2025 01:23:43 +0200 Subject: [PATCH 166/169] wip PlatformServiceInterface --- src/Interface/PlatformServiceInterface.h | 8 +- .../AndroidPlatformService.cpp | 48 ++++---- .../AndroidPlatform/AndroidPlatformService.h | 7 +- .../Win32Platform/Win32PlatformService.cpp | 115 +++++++++--------- .../Win32Platform/Win32PlatformService.h | 7 +- .../iOSPlatform/iOSPlatformService.h | 8 +- .../iOSPlatform/iOSPlatformService.mm | 89 +++++++++----- 7 files changed, 148 insertions(+), 134 deletions(-) diff --git a/src/Interface/PlatformServiceInterface.h b/src/Interface/PlatformServiceInterface.h index e95e59cd0e..f56752e926 100644 --- a/src/Interface/PlatformServiceInterface.h +++ b/src/Interface/PlatformServiceInterface.h @@ -40,16 +40,12 @@ namespace Mengine virtual bool runPlatform() = 0; virtual void loopPlatform() = 0; virtual bool updatePlatform() = 0; - virtual bool tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) = 0; + virtual void tickPlatform( float _frameTime ) = 0; + virtual bool renderPlatform() = 0; virtual void stopPlatform() = 0; virtual void freezePlatform( bool _tick, bool _render, bool _sound ) = 0; virtual void unfreezePlatform( bool _tick, bool _render, bool _sound ) = 0; - - public: - virtual void setSleepMode( bool _sleepMode ) = 0; - virtual bool getSleepMode() const = 0; - public: virtual Timestamp getPlatfomTime() const = 0; diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index 1f04c96682..bca7395d65 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -870,7 +870,7 @@ namespace Mengine return false; } - this->tickPlatform( 0.f, false, false, false ); + this->tickPlatform( 0.f ); NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_RUN ); @@ -883,11 +883,8 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidPlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) + void AndroidPlatformService::tickPlatform( float _frameTime ) { - MENGINE_UNUSED( _pause ); - MENGINE_UNUSED( _flush ); - bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); @@ -906,17 +903,23 @@ namespace Mengine APPLICATION_SERVICE() ->endUpdate(); - if( m_active == false ) + if( updating == false ) { - return false; + if( m_pauseUpdatingTime < 0.f ) + { + m_pauseUpdatingTime = _frameTime; + } } - + } + ////////////////////////////////////////////////////////////////////////// + bool AndroidPlatformService::renderPlatform() + { if( m_activityState != EAS_RESUME && m_activityState != EAS_START ) { return false; } - if( m_freezedRender != 0 || _render == false ) + if( m_freezedRender != 0 ) { return false; } @@ -932,7 +935,7 @@ namespace Mengine bool sucessful = APPLICATION_SERVICE() ->render(); - if( sucessful == true && _flush == true ) + if( sucessful == true ) { APPLICATION_SERVICE() ->flush(); @@ -976,9 +979,20 @@ namespace Mengine m_prevTime = currentTime; - if( this->tickPlatform( frameTime, true, true, true ) == false ) + if( m_active == false ) { usleep( 100000 ); + + continue; + } + + this->tickPlatform( frameTime ); + + if( this->renderPlatform() == false ) + { + usleep( 100000 ); + + continue; } } } @@ -1131,18 +1145,6 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void AndroidPlatformService::setSleepMode( bool _sleepMode ) - { - MENGINE_UNUSED( _sleepMode ); - - //Empty - } - ////////////////////////////////////////////////////////////////////////// - bool AndroidPlatformService::getSleepMode() const - { - return true; - } - ////////////////////////////////////////////////////////////////////////// Timestamp AndroidPlatformService::getPlatfomTime() const { Timestamp currentTime = Helper::getSystemTimestamp(); diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.h b/src/Platforms/AndroidPlatform/AndroidPlatformService.h index 5f9562b559..9ca105ab21 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.h +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.h @@ -58,15 +58,12 @@ namespace Mengine bool runPlatform() override; void loopPlatform() override; bool updatePlatform() override; - bool tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; + void tickPlatform( float _frameTime ) override; + bool renderPlatform() override; void stopPlatform() override; void freezePlatform( bool _tick, bool _render, bool _sound ) override; void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; - public: - void setSleepMode( bool _sleepMode ) override; - bool getSleepMode() const override; - public: Timestamp getPlatfomTime() const override; diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index 49af21a13a..345e80562d 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.cpp +++ b/src/Platforms/Win32Platform/Win32PlatformService.cpp @@ -112,7 +112,6 @@ namespace Mengine , m_freezedRender( 0 ) , m_freezedSound( 0 ) , m_hIcon( NULL ) - , m_sleepMode( true ) , m_windowExposed( false ) , m_pauseUpdatingTime( -1.f ) , m_prevTime( 0.0 ) @@ -585,16 +584,6 @@ namespace Mengine ::DebugBreak(); } ////////////////////////////////////////////////////////////////////////// - void Win32PlatformService::setSleepMode( bool _sleepMode ) - { - m_sleepMode = _sleepMode; - } - ////////////////////////////////////////////////////////////////////////// - bool Win32PlatformService::getSleepMode() const - { - return m_sleepMode; - } - ////////////////////////////////////////////////////////////////////////// Timestamp Win32PlatformService::getPlatfomTime() const { Timestamp currentTime = Helper::getSystemTimestamp(); @@ -618,7 +607,7 @@ namespace Mengine return false; } - this->tickPlatform( 0.f, false, false, false ); + this->tickPlatform( 0.f ); NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_RUN ); @@ -641,19 +630,10 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - bool Win32PlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) + void Win32PlatformService::tickPlatform( float _frameTime ) { MENGINE_UNUSED( _frameTime ); -#if defined(MENGINE_WINDOWS_SUPPORT_MIN_VERSION_VISTA) - if( m_sessionLock == true ) - { - ::Sleep( 200 ); - - return false; - } -#endif - bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); @@ -672,50 +652,40 @@ namespace Mengine APPLICATION_SERVICE() ->endUpdate(); - if( m_freezedRender == false && this->isNeedWindowRender() == true && _render == true ) + if( updating == false ) { - bool sucessful = APPLICATION_SERVICE() - ->render(); - - if( sucessful == true && _flush == true ) + if( m_pauseUpdatingTime < 0.f ) { - APPLICATION_SERVICE() - ->flush(); + m_pauseUpdatingTime = _frameTime; } - - m_windowExposed = false; + } + } + ////////////////////////////////////////////////////////////////////////// + bool Win32PlatformService::renderPlatform() + { + if( m_freezedRender != 0 ) + { + return false; } - if( _pause == true ) + if( this->isNeedWindowRender() == false ) { - if( updating == false ) - { - if( m_pauseUpdatingTime < 0.f ) - { - m_pauseUpdatingTime = _frameTime; - } + return false; + } - if( m_freezedTick != 0 || m_freezedRender != 0 || m_sleepMode == true ) - { - ::Sleep( 100 ); - } - else - { - ::Sleep( 1 ); - } - } - else - { - bool OPTION_maxfps = HAS_OPTION( "maxfps" ); + bool sucessful = APPLICATION_SERVICE() + ->render(); - if( APPLICATION_SERVICE() - ->getVSync() == false && OPTION_maxfps == false ) - { - ::Sleep( 1 ); - } - } + if( sucessful == false ) + { + return false; } + APPLICATION_SERVICE() + ->flush(); + + m_windowExposed = false; + return true; } ////////////////////////////////////////////////////////////////////////// @@ -740,7 +710,38 @@ namespace Mengine m_prevTime = currentTime; - this->tickPlatform( frameTime, true, true, true ); +#if defined(MENGINE_WINDOWS_SUPPORT_MIN_VERSION_VISTA) + if( m_sessionLock == true ) + { + ::Sleep( 200 ); + + continue; + } +#endif + + if( m_active == false ) + { + ::Sleep( 100 ); + + continue; + } + + this->tickPlatform( frameTime ); + + if( this->renderPlatform() == false ) + { + ::Sleep( 100 ); + + continue; + } + + bool OPTION_maxfps = HAS_OPTION( "maxfps" ); + + if( APPLICATION_SERVICE() + ->getVSync() == false && OPTION_maxfps == false ) + { + ::Sleep( 1 ); + } } } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index 097e825a35..76d1bd25b7 100644 --- a/src/Platforms/Win32Platform/Win32PlatformService.h +++ b/src/Platforms/Win32Platform/Win32PlatformService.h @@ -36,10 +36,6 @@ namespace Mengine bool _runService() override; void _stopService() override; - public: - void setSleepMode( bool _sleepMode ) override; - bool getSleepMode() const override; - public: Timestamp getPlatfomTime() const override; @@ -47,7 +43,8 @@ namespace Mengine bool runPlatform() override; void loopPlatform() override; bool updatePlatform() override; - bool tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; + void tickPlatform( float _frameTime ) override; + bool renderPlatform() override; void stopPlatform() override; void freezePlatform( bool _tick, bool _render, bool _sound ) override; void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.h b/src/Platforms/iOSPlatform/iOSPlatformService.h index 43686fa1ac..9fc3c48edf 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.h +++ b/src/Platforms/iOSPlatform/iOSPlatformService.h @@ -59,17 +59,14 @@ namespace Mengine bool runPlatform() override; void loopPlatform() override; bool updatePlatform() override; - void tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) override; + void tickPlatform( float _frameTime ) override; + bool renderPlatform() override; void stopPlatform() override; public: void freezePlatform( bool _tick, bool _render, bool _sound ) override; void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; - public: - void setSleepMode( bool _sleepMode ) override; - bool getSleepMode() const override; - public: Timestamp getPlatfomTime() const override; @@ -225,7 +222,6 @@ namespace Mengine float m_pauseUpdatingTime; bool m_active; - bool m_sleepMode; AtomicInt32 m_freezedTick; AtomicInt32 m_freezedRender; diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index 3c1b984f2b..7f48257a7e 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -90,7 +90,6 @@ , m_prevTime( 0.0 ) , m_pauseUpdatingTime( -1.f ) , m_active( false ) - , m_sleepMode( true ) , m_freezedTick( 0 ) , m_freezedRender( 0 ) , m_freezedSound( 0 ) @@ -772,17 +771,15 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit return false; } - this->tickPlatform( 0.f, false, false, false ); + this->tickPlatform( 0.f ); NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_RUN ); return true; } ////////////////////////////////////////////////////////////////////////// - void iOSPlatformService::tickPlatform( float _frameTime, bool _render, bool _flush, bool _pause ) + void iOSPlatformService::tickPlatform( float _frameTime ) { - MENGINE_UNUSED( _pause ); - bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); @@ -801,27 +798,51 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit APPLICATION_SERVICE() ->endUpdate(); - if( m_freezedRender == 0 && this->isNeedWindowRender() == true && _render == true ) + if( updating == false ) { - bool sucessful = APPLICATION_SERVICE() - ->render(); - - if( sucessful == true && _flush == true ) + if( m_pauseUpdatingTime < 0.f ) { - APPLICATION_SERVICE() - ->flush(); + m_pauseUpdatingTime = _frameTime; + } + } + } + ////////////////////////////////////////////////////////////////////////// + bool iOSPlatformService::renderPlatform() + { + if( m_freezedRender != 0 ) + { + return false; + } - if( m_sdlWindow != nullptr ) - { - SDL_ShowWindow( m_sdlWindow ); + if( this->isNeedWindowRender() == false ) + { + return false; + } - if( SDL_GetWindowFlags( m_sdlWindow ) & SDL_WINDOW_OPENGL ) - { - SDL_GL_SwapWindow( m_sdlWindow ); - } - } - } + bool sucessful = APPLICATION_SERVICE() + ->render(); + + if( sucessful == false ) + { + return false; + } + + APPLICATION_SERVICE() + ->flush(); + + if( m_sdlWindow == nullptr ) + { + return false; } + + SDL_ShowWindow( m_sdlWindow ); + + if( SDL_GetWindowFlags( m_sdlWindow ) & SDL_WINDOW_OPENGL ) + { + SDL_GL_SwapWindow( m_sdlWindow ); + } + + return true; } ////////////////////////////////////////////////////////////////////////// void iOSPlatformService::loopPlatform() @@ -840,8 +861,22 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit float frameTime = (float)(currentTime - m_prevTime); m_prevTime = currentTime; + + if( m_active == false ) + { + SDL_Delay( 100 ); + + continue; + } - this->tickPlatform( frameTime, true, true, true ); + this->tickPlatform( frameTime ); + + if( this->renderPlatform() == false ) + { + SDL_Delay( 100 ); + + continue; + } } } ////////////////////////////////////////////////////////////////////////// @@ -1012,16 +1047,6 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit } } ////////////////////////////////////////////////////////////////////////// - void iOSPlatformService::setSleepMode( bool _sleepMode ) - { - m_sleepMode = _sleepMode; - } - ////////////////////////////////////////////////////////////////////////// - bool iOSPlatformService::getSleepMode() const - { - return m_sleepMode; - } - ////////////////////////////////////////////////////////////////////////// Timestamp iOSPlatformService::getPlatfomTime() const { Timestamp currentTime = Helper::getSystemTimestamp(); From 3af4994b0fd899516205d5dad596effb55f98fe6 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 1 Dec 2025 15:44:16 +0200 Subject: [PATCH 167/169] improve android sleeps --- gradle/plugins/AdMob/Core/build.gradle | 3 +-- src/Platforms/AndroidPlatform/AndroidPlatformService.cpp | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gradle/plugins/AdMob/Core/build.gradle b/gradle/plugins/AdMob/Core/build.gradle index 5d7431817f..d249ad9daf 100644 --- a/gradle/plugins/AdMob/Core/build.gradle +++ b/gradle/plugins/AdMob/Core/build.gradle @@ -7,5 +7,4 @@ android { dependencies { implementation api('com.google.android.gms:play-services-ads:24.7.0') -} - +} \ No newline at end of file diff --git a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp index bca7395d65..cc66718e01 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.cpp @@ -981,7 +981,7 @@ namespace Mengine if( m_active == false ) { - usleep( 100000 ); + usleep( 250000 ); continue; } @@ -990,7 +990,7 @@ namespace Mengine if( this->renderPlatform() == false ) { - usleep( 100000 ); + usleep( 250000 ); continue; } From 278c4cf51b62b12b59bd1899d6723ca3e9bd9a4f Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 1 Dec 2025 17:58:49 +0200 Subject: [PATCH 168/169] wip --- .../MetalRenderSystemExtensionInterface.h | 6 +- .../iOSPlatform/iOSPlatformService.mm | 353 +++++++----------- .../MetalRenderSystem/MetalRenderSystem.h | 3 + .../MetalRenderSystem/MetalRenderSystem.mm | 60 +-- 4 files changed, 187 insertions(+), 235 deletions(-) diff --git a/src/Environment/Metal/MetalRenderSystemExtensionInterface.h b/src/Environment/Metal/MetalRenderSystemExtensionInterface.h index ab21653fa3..1463e336a5 100644 --- a/src/Environment/Metal/MetalRenderSystemExtensionInterface.h +++ b/src/Environment/Metal/MetalRenderSystemExtensionInterface.h @@ -2,13 +2,15 @@ #include "Interface/UnknownInterface.h" +#import +#import + namespace Mengine { class MetalRenderSystemExtensionInterface : public UnknownInterface { public: - // Empty interface reserved for Metal specific extensions. + virtual void setMetalContext( id _device, CAMetalLayer * _layer ) = 0; }; } - diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.mm b/src/Platforms/iOSPlatform/iOSPlatformService.mm index 7f48257a7e..df7b7b34d6 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -24,6 +24,8 @@ #include "iOSAnalyticsEventProvider.h" +#include "Environment/Metal/MetalRenderSystemExtensionInterface.h" + #include "Kernel/FilePath.h" #include "Kernel/PathHelper.h" #include "Kernel/AssertionNotImplemented.h" @@ -836,11 +838,6 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit } SDL_ShowWindow( m_sdlWindow ); - - if( SDL_GetWindowFlags( m_sdlWindow ) & SDL_WINDOW_OPENGL ) - { - SDL_GL_SwapWindow( m_sdlWindow ); - } return true; } @@ -1113,133 +1110,9 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit ////////////////////////////////////////////////////////////////////////// bool iOSPlatformService::applyWindow_() { - SDL_GLContext glContext = SDL_GL_CreateContext( m_sdlWindow ); - - if( glContext == nullptr ) - { - LOGGER_ERROR( "invalid create GL context error: %s" - , SDL_GetError() - ); - - SDL_DestroyWindow( m_sdlWindow ); - m_sdlWindow = nullptr; - - return false; - } - - int attribute_GL_CONTEXT_PROFILE_MASK = 0; - if( SDL_GL_GetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, &attribute_GL_CONTEXT_PROFILE_MASK ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_CONTEXT_PROFILE_MASK error: %s" - , SDL_GetError() - ); - } - - int attribute_GL_CONTEXT_MAJOR_VERSION = 0; - if( SDL_GL_GetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, &attribute_GL_CONTEXT_MAJOR_VERSION ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_CONTEXT_MAJOR_VERSION error: %s" - , SDL_GetError() - ); - } - - int attribute_GL_CONTEXT_MINOR_VERSION = 0; - if( SDL_GL_GetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, &attribute_GL_CONTEXT_MINOR_VERSION ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_CONTEXT_MINOR_VERSION error: %s" - , SDL_GetError() - ); - } - - int attribute_SDL_GL_RED_SIZE = 0; - if( SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &attribute_SDL_GL_RED_SIZE ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_RED_SIZE error: %s" - , SDL_GetError() - ); - } - - int attribute_SDL_GL_GREEN_SIZE = 0; - if( SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &attribute_SDL_GL_GREEN_SIZE ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_GREEN_SIZE error: %s" - , SDL_GetError() - ); - } - - int attribute_SDL_GL_BLUE_SIZE = 0; - if( SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &attribute_SDL_GL_BLUE_SIZE ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_BLUE_SIZE error: %s" - , SDL_GetError() - ); - } - - int attribute_SDL_GL_ALPHA_SIZE = 0; - if( SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &attribute_SDL_GL_ALPHA_SIZE ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_ALPHA_SIZE error: %s" - , SDL_GetError() - ); - } - - int attribute_SDL_GL_DEPTH_SIZE = 0; - if( SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &attribute_SDL_GL_DEPTH_SIZE ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_DEPTH_SIZE error: %s" - , SDL_GetError() - ); - } - - int attribute_SDL_GL_DOUBLEBUFFER = 0; - if( SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &attribute_SDL_GL_DOUBLEBUFFER ) != 0 ) - { - LOGGER_WARNING( "get attribute SDL_GL_DOUBLEBUFFER error: %s" - , SDL_GetError() - ); - } - - LOGGER_INFO( "platform", "SDL_GL_CONTEXT_PROFILE_MASK: %d" - , attribute_GL_CONTEXT_PROFILE_MASK - ); - - LOGGER_INFO( "platform", "SDL_GL_CONTEXT_MAJOR_VERSION: %d" - , attribute_GL_CONTEXT_MAJOR_VERSION - ); - - LOGGER_INFO( "platform", "SDL_GL_CONTEXT_MINOR_VERSION: %d" - , attribute_GL_CONTEXT_MINOR_VERSION - ); - - LOGGER_INFO( "platform", "SDL_GL_RED_SIZE: %d" - , attribute_SDL_GL_RED_SIZE - ); - - LOGGER_INFO( "platform", "SDL_GL_GREEN_SIZE: %d" - , attribute_SDL_GL_GREEN_SIZE - ); - - LOGGER_INFO( "platform", "SDL_GL_BLUE_SIZE: %d" - , attribute_SDL_GL_BLUE_SIZE - ); - - LOGGER_INFO( "platform", "SDL_GL_ALPHA_SIZE: %d" - , attribute_SDL_GL_ALPHA_SIZE - ); - - LOGGER_INFO( "platform", "SDL_GL_DEPTH_SIZE: %d" - , attribute_SDL_GL_DEPTH_SIZE - ); - - LOGGER_INFO( "platform", "SDL_GL_DOUBLEBUFFER: %d" - , attribute_SDL_GL_DOUBLEBUFFER - ); - - m_glContext = glContext; - - int drawable_width; - int drawable_height; - SDL_GL_GetDrawableSize( m_sdlWindow, &drawable_width, &drawable_height ); + int drawable_width = 0; + int drawable_height = 0; + SDL_Metal_GetDrawableSize( m_sdlWindow, &drawable_width, &drawable_height ); LOGGER_INFO( "platform", "SDL drawable size [%d, %d]" , drawable_width @@ -1327,6 +1200,37 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit } } + ERenderPlatform renderPlatform = RENDER_SYSTEM() + ->getRenderPlatformType(); + + if( renderPlatform == RP_METAL ) + { + SDL_MetalView metalView = SDL_Metal_CreateView( m_sdlWindow ); + + if( metalView == nullptr ) + { + LOGGER_ERROR( "invalid create Metal view error: %s" + , SDL_GetError() + ); + + SDL_DestroyWindow( m_sdlWindow ); + m_sdlWindow = nullptr; + + return false; + } + + CAMetalLayer * metalLayer = (__bridge CAMetalLayer *)SDL_Metal_GetLayer( metalView ); + id device = metalLayer.device; + + MetalRenderSystemExtensionInterface * metalExtension = RENDER_SYSTEM() + ->getUnknown(); + + if( metalExtension != nullptr ) + { + metalExtension->setMetalContext( device, metalLayer ); + } + } + NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_ATACH_WINDOW ); return true; @@ -1429,7 +1333,17 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit int drawable_width; int drawable_height; - SDL_GL_GetDrawableSize( m_sdlWindow, &drawable_width, &drawable_height ); + + Uint32 flags = SDL_GetWindowFlags( m_sdlWindow ); + + if( (flags & SDL_WINDOW_METAL) == SDL_WINDOW_METAL ) + { + SDL_Metal_GetDrawableSize( m_sdlWindow, &drawable_width, &drawable_height ); + } + else + { + SDL_GL_GetDrawableSize( m_sdlWindow, &drawable_width, &drawable_height ); + } width = (uint32_t)drawable_width; height = (uint32_t)drawable_height; @@ -1767,96 +1681,106 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit ////////////////////////////////////////////////////////////////////////// void iOSPlatformService::setupWindow_() { - uint32_t Engine_SDL_GL_RED_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_RED_SIZE", 8U ); + ERenderPlatform renderPlatform = RENDER_SYSTEM() + ->getRenderPlatformType(); - if( SDL_GL_SetAttribute( SDL_GL_RED_SIZE, Engine_SDL_GL_RED_SIZE ) != 0 ) + if( renderPlatform == RP_METAL ) { - LOGGER_WARNING( "set attribute SDL_GL_RED_SIZE to [%u] error: %s" - , Engine_SDL_GL_RED_SIZE - , SDL_GetError() - ); + SDL_SetHint( SDL_HINT_RENDER_DRIVER, "metal" ); } + else + { + uint32_t Engine_SDL_GL_RED_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_RED_SIZE", 8U ); - uint32_t Engine_SDL_GL_GREEN_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_GREEN_SIZE", 8U ); + if( SDL_GL_SetAttribute( SDL_GL_RED_SIZE, Engine_SDL_GL_RED_SIZE ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_RED_SIZE to [%u] error: %s" + , Engine_SDL_GL_RED_SIZE + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, Engine_SDL_GL_GREEN_SIZE ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_GREEN_SIZE to [%u] error: %s" - , Engine_SDL_GL_GREEN_SIZE - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_GREEN_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_GREEN_SIZE", 8U ); - uint32_t Engine_SDL_GL_BLUE_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_BLUE_SIZE", 8U ); + if( SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, Engine_SDL_GL_GREEN_SIZE ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_GREEN_SIZE to [%u] error: %s" + , Engine_SDL_GL_GREEN_SIZE + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, Engine_SDL_GL_BLUE_SIZE ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_BLUE_SIZE to [%u] error: %s" - , Engine_SDL_GL_BLUE_SIZE - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_BLUE_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_BLUE_SIZE", 8U ); - uint32_t Engine_SDL_GL_ALPHA_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_ALPHA_SIZE", 0U ); + if( SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, Engine_SDL_GL_BLUE_SIZE ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_BLUE_SIZE to [%u] error: %s" + , Engine_SDL_GL_BLUE_SIZE + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, Engine_SDL_GL_ALPHA_SIZE ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_ALPHA_SIZE to [%u] error: %s" - , Engine_SDL_GL_ALPHA_SIZE - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_ALPHA_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_ALPHA_SIZE", 0U ); - uint32_t Engine_SDL_GL_DEPTH_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_DEPTH_SIZE", 24U ); + if( SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, Engine_SDL_GL_ALPHA_SIZE ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_ALPHA_SIZE to [%u] error: %s" + , Engine_SDL_GL_ALPHA_SIZE + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, Engine_SDL_GL_DEPTH_SIZE ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_DEPTH_SIZE to [%u] error: %s" - , Engine_SDL_GL_DEPTH_SIZE - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_DEPTH_SIZE = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_DEPTH_SIZE", 24U ); - uint32_t Engine_SDL_GL_DOUBLEBUFFER = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_DOUBLEBUFFER", 1U ); + if( SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, Engine_SDL_GL_DEPTH_SIZE ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_DEPTH_SIZE to [%u] error: %s" + , Engine_SDL_GL_DEPTH_SIZE + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, Engine_SDL_GL_DOUBLEBUFFER ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_DOUBLEBUFFER to [%u] error: %s" - , Engine_SDL_GL_DOUBLEBUFFER - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_DOUBLEBUFFER = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_DOUBLEBUFFER", 1U ); - SDL_SetHint( SDL_HINT_RENDER_DRIVER, "opengles2" ); + if( SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, Engine_SDL_GL_DOUBLEBUFFER ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_DOUBLEBUFFER to [%u] error: %s" + , Engine_SDL_GL_DOUBLEBUFFER + , SDL_GetError() + ); + } - uint32_t Engine_SDL_GL_CONTEXT_PROFILE_MASK = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_CONTEXT_PROFILE_MASK", (uint32_t)SDL_GL_CONTEXT_PROFILE_ES ); + SDL_SetHint( SDL_HINT_RENDER_DRIVER, "opengles2" ); - if( SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, Engine_SDL_GL_CONTEXT_PROFILE_MASK ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_CONTEXT_PROFILE_MASK to [%u] error: %s" - , Engine_SDL_GL_CONTEXT_PROFILE_MASK - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_CONTEXT_PROFILE_MASK = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_CONTEXT_PROFILE_MASK", (uint32_t)SDL_GL_CONTEXT_PROFILE_ES ); - uint32_t Engine_SDL_GL_CONTEXT_MAJOR_VERSION = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_CONTEXT_MAJOR_VERSION", 2U ); + if( SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, Engine_SDL_GL_CONTEXT_PROFILE_MASK ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_CONTEXT_PROFILE_MASK to [%u] error: %s" + , Engine_SDL_GL_CONTEXT_PROFILE_MASK + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, Engine_SDL_GL_CONTEXT_MAJOR_VERSION ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_CONTEXT_MAJOR_VERSION to [%u] error: %s" - , Engine_SDL_GL_CONTEXT_MAJOR_VERSION - , SDL_GetError() - ); - } + uint32_t Engine_SDL_GL_CONTEXT_MAJOR_VERSION = CONFIG_VALUE_INTEGER( "SDL", "SDL_GL_CONTEXT_MAJOR_VERSION", 2U ); - uint32_t Engine_SDL_GL_CONTEXT_MINOR_VERSION = CONFIG_VALUE_INTEGER( "SDL", "Engine_SDL_GL_CONTEXT_MINOR_VERSION", 0U ); + if( SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, Engine_SDL_GL_CONTEXT_MAJOR_VERSION ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_CONTEXT_MAJOR_VERSION to [%u] error: %s" + , Engine_SDL_GL_CONTEXT_MAJOR_VERSION + , SDL_GetError() + ); + } - if( SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, Engine_SDL_GL_CONTEXT_MINOR_VERSION ) != 0 ) - { - LOGGER_WARNING( "set attribute SDL_GL_CONTEXT_MINOR_VERSION to [%u] error: %s" - , Engine_SDL_GL_CONTEXT_MINOR_VERSION - , SDL_GetError() - ); + uint32_t Engine_SDL_GL_CONTEXT_MINOR_VERSION = CONFIG_VALUE_INTEGER( "SDL", "Engine_SDL_GL_CONTEXT_MINOR_VERSION", 0U ); + + if( SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, Engine_SDL_GL_CONTEXT_MINOR_VERSION ) != 0 ) + { + LOGGER_WARNING( "set attribute SDL_GL_CONTEXT_MINOR_VERSION to [%u] error: %s" + , Engine_SDL_GL_CONTEXT_MINOR_VERSION + , SDL_GetError() + ); + } } const Char * Engine_SDL_HINT_RENDER_SCALE_QUALITY = CONFIG_VALUE_STRING( "SDL", "SDL_HINT_RENDER_SCALE_QUALITY", "linear" ); @@ -1895,11 +1819,24 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit MENGINE_UNUSED( _windowResolution ); MENGINE_UNUSED( _fullscreen ); - SDL_GL_SetAttribute( SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1 ); + ERenderPlatform renderPlatform = RENDER_SYSTEM() + ->getRenderPlatformType(); + + if( renderPlatform != RP_METAL ) + { + SDL_GL_SetAttribute( SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1 ); + } Uint32 windowFlags = 0; - windowFlags |= SDL_WINDOW_OPENGL; + if( renderPlatform == RP_METAL ) + { + windowFlags |= SDL_WINDOW_METAL; + } + else + { + windowFlags |= SDL_WINDOW_OPENGL; + } windowFlags |= SDL_WINDOW_SHOWN; windowFlags |= SDL_WINDOW_RESIZABLE; windowFlags |= SDL_WINDOW_FULLSCREEN; @@ -1941,12 +1878,6 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit { NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_DETACH_WINDOW ); - if( m_glContext != nullptr ) - { - SDL_GL_DeleteContext( m_glContext ); - m_glContext = nullptr; - } - if( m_sdlWindow != nullptr ) { SDL_DestroyWindow( m_sdlWindow ); diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.h b/src/Systems/MetalRenderSystem/MetalRenderSystem.h index 6786fc1704..1323b4b0f5 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderSystem.h +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.h @@ -6,10 +6,13 @@ #import #import +#include "Environment/Metal/MetalRenderSystemExtensionInterface.h" + namespace Mengine { class MetalRenderSystem : public ServiceBase + , public MetalRenderSystemExtensionInterface { DECLARE_UNKNOWABLE(); diff --git a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm index e593e7e387..3f1743a909 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderSystem.mm +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm @@ -90,24 +90,6 @@ ////////////////////////////////////////////////////////////////////////// bool MetalRenderSystem::_initializeService() { - m_device = MTLCreateSystemDefaultDevice(); - - if( m_device == nil ) - { - LOGGER_ERROR( "MetalRenderSystem: failed to create device" ); - - return false; - } - - m_commandQueue = [m_device newCommandQueue]; - - if( m_commandQueue == nil ) - { - LOGGER_ERROR( "MetalRenderSystem: failed to create command queue" ); - - return false; - } - return true; } ////////////////////////////////////////////////////////////////////////// @@ -129,12 +111,46 @@ return m_renderSystemName; } ////////////////////////////////////////////////////////////////////////// + void MetalRenderSystem::setMetalContext( id _device, CAMetalLayer * _layer ) + { + m_device = _device; + m_metalLayer = _layer; + + if( m_device == nil ) + { + LOGGER_ERROR( "MetalRenderSystem: setMetalContext with nil device" ); + + return; + } + + if( m_commandQueue == nil ) + { + m_commandQueue = [m_device newCommandQueue]; + + if( m_commandQueue == nil ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to create command queue" ); + } + } + } + ////////////////////////////////////////////////////////////////////////// bool MetalRenderSystem::createRenderWindow( const RenderWindowDesc * _windowDesc ) { - m_metalLayer = [CAMetalLayer layer]; - [m_metalLayer setDevice:m_device]; + if( m_metalLayer == nil ) + { + m_metalLayer = [CAMetalLayer layer]; + + if( m_metalLayer == nil ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to create CAMetalLayer" ); - if( _windowDesc != nullptr ) + return false; + } + + [m_metalLayer setDevice:m_device]; + } + + if( _windowDesc != nullptr && m_metalLayer != nil ) { CGFloat drawableWidth = (CGFloat)_windowDesc->resolution.getWidth(); CGFloat drawableHeight = (CGFloat)_windowDesc->resolution.getHeight(); @@ -143,7 +159,7 @@ m_vsync = _windowDesc->waitForVSync; } - return true; + return m_metalLayer != nil; } ////////////////////////////////////////////////////////////////////////// void MetalRenderSystem::destroyRenderWindow() From cec40b64fb81e17046df7dfb9aa60dfcfe6e26e7 Mon Sep 17 00:00:00 2001 From: irov Date: Mon, 1 Dec 2025 18:20:48 +0200 Subject: [PATCH 169/169] wip --- src/Systems/MetalRenderSystem/MetalRenderImage.h | 2 +- src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h | 3 ++- src/Systems/MetalRenderSystem/MetalRenderVertexShader.h | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Systems/MetalRenderSystem/MetalRenderImage.h b/src/Systems/MetalRenderSystem/MetalRenderImage.h index fcda1f8c34..8aa7939c59 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderImage.h +++ b/src/Systems/MetalRenderSystem/MetalRenderImage.h @@ -19,7 +19,7 @@ namespace Mengine ~MetalRenderImage() override; bool initialize( uint32_t _mipmaps, uint32_t _width, uint32_t _height, EPixelFormat _format, bool _upscalePow2 ); bool initializeFromTexture( id _texture, uint32_t _width, uint32_t _height, EPixelFormat _format ); - void finalize() override; + void finalize(); public: void setRenderImageProvider( const RenderImageProviderInterfacePtr & _renderImageProvider ) override; diff --git a/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h index 8ac7076fa3..7377d0caac 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h +++ b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h @@ -1,6 +1,7 @@ #pragma once -#include "Interface/RenderMaterialStageCacheInterface.h" +#include "Interface/RenderMaterialInterface.h" + #include "Kernel/Factorable.h" namespace Mengine diff --git a/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h index 2d01a9227f..ab08956fad 100644 --- a/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h @@ -1,6 +1,8 @@ #pragma once #include "Interface/RenderVertexShaderInterface.h" +#include "Interface/MemoryInterface.h" + #include "Kernel/Factorable.h" namespace Mengine