diff --git a/.circleci/config.yml b/.circleci/config.yml index ac6935e693..0434cb7409 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ jobs: build: executor: name: android/android-machine - tag: 2024.04.1 + tag: 2025.10.1 parallelism: 4 @@ -17,8 +17,8 @@ jobs: - android/accept-licenses - android/install-ndk: - version: 28.2.13676358 - + version: 29.0.14206865 + - run: name: install OpenJDK 17 command: | @@ -48,6 +48,9 @@ jobs: - run: name: sdkmanager cmake command: | + 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 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/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/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 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/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/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/cmake/Xcode_MacOS/CMakeLists.txt b/cmake/Xcode_MacOS/CMakeLists.txt index f7f28457ea..63997d301f 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") @@ -116,8 +117,10 @@ 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") 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 85af251af1..6db4f9129b 100644 --- a/cmake/Xcode_iOS/CMakeLists.txt +++ b/cmake/Xcode_iOS/CMakeLists.txt @@ -18,11 +18,11 @@ 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() -# platform +# platform ADD_PLATFORM(iOSPlatform "MENGINE_PLATFORM") # systems @@ -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") @@ -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") @@ -118,9 +119,11 @@ 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") +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 5ba141f9eb..639b1ed69f 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") @@ -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") @@ -111,9 +112,11 @@ 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") +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/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/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 5e0a888517..1962c331a3 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) @@ -96,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}) @@ -160,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}") @@ -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}") @@ -193,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}") @@ -222,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 ${MENGINE_SOLUTIONS_CONFIG_OUTPUT_BASE}/${MENGINE_OUTPUT_SUFFIX}) - - SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/solutions/${ANDROID_ABI}) + SET(CMAKE_TEMP_DIR ${CMAKE_BINARY_DIR}/mengine_solution_temp) elseif(MINGW) MESSAGE("Setup MINGW solution output directory") @@ -243,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 @@ -254,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() @@ -285,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") @@ -297,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) @@ -1038,7 +1019,19 @@ 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() + + 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/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 b8078a820a..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() @@ -111,10 +107,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/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/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/gradle/androidx.gradle b/gradle/androidx.gradle index ca0a3e84b2..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.2") +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 0bb2603b73..c2f4550839 100644 --- a/gradle/app.gradle +++ b/gradle/app.gradle @@ -7,60 +7,59 @@ 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_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) -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_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) -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) @@ -100,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)) { @@ -124,44 +123,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 @@ -177,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) { @@ -199,15 +160,61 @@ 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" + 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" + + 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") + } + + 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 + } + } + + 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" + + 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") + } + + 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 + } + } + } + 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 } } @@ -216,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 def buildDirectory = getLayout().getBuildDirectory() debug { firebaseCrashlytics { @@ -266,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 def PACKAGE_NAME = PACKAGE_DESC.split(";")[0] println "add delivery asset pack: $PACKAGE_NAME" @@ -290,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") @@ -306,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") @@ -339,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 @@ -381,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) { @@ -650,7 +663,15 @@ 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.") + } + + MENGINE_APP_ADMEDIATION_ADDED = true + android.ext.plugins += 'org.Mengine.Plugin.AdMob.MengineAdMobPlugin' dependencies { @@ -671,6 +692,12 @@ 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.") + } + + MENGINE_APP_ADMEDIATION_ADDED = true + android.ext.plugins += 'org.Mengine.Plugin.AppLovin.MengineAppLovinPlugin' dependencies { @@ -733,7 +760,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}\"" : "\"\"" } } } else { @@ -769,10 +796,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 def fname = f.getCanonicalPath() throw new GradleException("unstrippedNativeLibsDir not found folder: $fname") } @@ -785,10 +812,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 def fname = f.getCanonicalPath() throw new GradleException("unstrippedNativeLibsDir not found folder: $fname") } @@ -797,7 +824,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') { @@ -805,19 +832,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 29badb43c9..f794746c61 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -13,12 +13,12 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.12.1' + classpath 'com.android.tools.build:gradle:8.13.1' 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) { @@ -34,21 +34,21 @@ 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.10.1' } 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' } } } -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) { @@ -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/ci/res/mipmap/ic_launcher.png b/gradle/ci/res/mipmap/ic_launcher.png new file mode 100644 index 0000000000..309da340ac Binary files /dev/null and b/gradle/ci/res/mipmap/ic_launcher.png differ 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 0000000000..309da340ac Binary files /dev/null and b/gradle/ci/res/mipmap/ic_launcher_round.png differ 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 88% rename from gradle/ci/res/values/strings.xml rename to gradle/ci/res/values/app.xml index bc2ca582ef..b548641ccd 100644 --- a/gradle/ci/res/values/strings.xml +++ b/gradle/ci/res/values/app.xml @@ -1,7 +1,8 @@ + 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/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 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/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 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/gms.gradle b/gradle/gms.gradle index 38db08a71b..49cfd9e92e 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.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.properties.ci b/gradle/gradle.properties.ci index 6a5f6e5cd2..9037c71415 100644 --- a/gradle/gradle.properties.ci +++ b/gradle/gradle.properties.ci @@ -11,9 +11,20 @@ # 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.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 -ANDROID_APP_MAIN_PROJECT=ci \ No newline at end of file +# Configure daemon settings for CI +org.gradle.daemon=false \ No newline at end of file diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index f8bf34ad13..1c41947bf5 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.2.1-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/libraries/Mengine/build.gradle b/gradle/libraries/Mengine/build.gradle index 2e467f8bb8..94eada408b 100644 --- a/gradle/libraries/Mengine/build.gradle +++ b/gradle/libraries/Mengine/build.gradle @@ -1,78 +1,100 @@ 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 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") -def MENGINE_APP_BUILD_ASSERTION_DEBUG= Utils.getIntegerProperty("MENGINE_APP_BUILD_ASSERTION_DEBUG", -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 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") 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 { + 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_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER: ANDROID_APP_REQUIRED_HARDWARE_SENSOR_ACCELEROMETER + 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, + 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 { + 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}") + } - externalNativeBuild { - cmake { - path "../../../cmake/Android/Mengine/CMakeLists.txt" - buildStagingDirectory rootProject.projectDir.getAbsolutePath() + "/../outputs/gradle/.cxx/" + project.getName() + 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 { - 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_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}") - debug { externalNativeBuild { cmake { - for (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}"] - } } } } @@ -80,15 +102,7 @@ android { release { externalNativeBuild { cmake { - for (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}"] - } } } } @@ -121,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 @@ - - - - - + + + + + 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..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; @@ -21,6 +22,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; @@ -139,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" @@ -220,7 +236,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 +244,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/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/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/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 f02b7437ed..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(); @@ -494,6 +494,20 @@ public boolean showInterstitial(String placement) { 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) { @@ -521,12 +535,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 +562,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 +589,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; } @@ -605,6 +601,14 @@ public boolean showRewarded(String placement) { return true; } + public boolean isShowingRewarded() { + if (m_adProvider.isShowingRewarded() == false) { + return false; + } + + return true; + } + @Override public boolean hasAppOpen() { if (m_adProvider == null) { @@ -920,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/MengineAnalytics.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineAnalytics.java index ff7eef3b6f..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,71 @@ 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 addContextGetterParameterString(@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 addContextGetterParameterLong(@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 addContextGetterParameterDouble(@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 private void collapseGetter(Map parameters) { + static public void addContextGetterParameterDouble(@Size(min = 1L, max = 40L) String key, MengineAnalyticsGetter value) { + MengineAnalytics.assertContext(key); + MengineAnalytics.assertGetter(key); + + 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(); MengineAnalyticsGetter getter = (MengineAnalyticsGetter)entry.getValue(); @@ -95,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); @@ -105,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 37af581f64..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 @@ -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; @@ -250,7 +262,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 @@ -741,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); @@ -760,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) { @@ -805,6 +822,14 @@ public void onCreate() { return 8L; } + if (networkTransport == MengineNetworkTransport.NETWORKTRANSPORT_THREAD) { + return 9L; + } + + if (networkTransport == MengineNetworkTransport.NETWORKTRANSPORT_SATELLITE) { + return 10L; + } + return -1L; }); @@ -820,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) { @@ -899,6 +922,8 @@ public void onCreate() { } } + this.setState("application.init", "native_app_create"); + Object nativeApplication = this.createNativeApplication(); if (nativeApplication == null) { @@ -921,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(); @@ -1212,7 +1237,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/MengineFileLoggerService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java new file mode 100644 index 0000000000..7769dd3d79 --- /dev/null +++ b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFileLoggerService.java @@ -0,0 +1,111 @@ +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) { + if (message.MESSAGE_SOURCE != MengineLoggerMessageSource.MengineLoggerMessageSource_Java) { + return; + } + + 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/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/MengineFragmentAdvertisingId.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineFragmentAdvertisingId.java index 63c2fa9270..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,6 +3,19 @@ public class MengineFragmentAdvertisingId extends MengineFragment { public static MengineFragmentAdvertisingId INSTANCE = null; + 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; + } + + public boolean isLimitAdTracking() { + return m_limitAdTracking; + } + MengineFragmentAdvertisingId() { super(MengineListenerAdvertisingId.class); @@ -10,6 +23,9 @@ public class MengineFragmentAdvertisingId 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/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineLog.java index a20d19a336..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 @@ -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); @@ -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); } @@ -120,13 +120,11 @@ public static String logInfo(@NonNull MengineTag category, @NonNull String forma } public static String logMessage(@NonNull MengineTag category, @NonNull String format, Object ... args) { - String m = MengineLog.log(LM_MESSAGE, category, MengineLog.LFILTER_NONE, format, args); - - return m; - } + if (BuildConfig.DEBUG == false) { + return ""; + } - public static String logMessageProtected(@NonNull MengineTag category, @NonNull String format, Object ... args) { - String m = MengineLog.log(LM_MESSAGE, category, MengineLog.LFILTER_PROTECTED, format, args); + String m = MengineLog.log(LM_MESSAGE, category, MengineLog.LFILTER_NONE, format, args); return m; } @@ -172,6 +170,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/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/MengineMain.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineMain.java index e0a687fd80..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 @@ -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,15 @@ public void run() { } if (MengineNative.AndroidMain_main(m_nativeApplication) == false) { - MengineLog.logInfo(TAG, "main finish with failed" ); + 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 { + MengineLog.logInfo(TAG, "main finish with failed"); + } return; } 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..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 @@ -4,7 +4,9 @@ import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.os.Build; +import android.os.ext.SdkExtensions; import androidx.annotation.NonNull; @@ -13,122 +15,184 @@ 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; + } - MengineMonitorConnectivityStatusService.this.logInfo("network lost"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_WIFI_AWARE; + } + } - MengineNetwork.setNetworkAvailable(false); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) == true) { + return MengineNetworkTransport.NETWORKTRANSPORT_LOWPAN; } + } - private MengineNetworkTransport getNetworkTransport(@NonNull NetworkCapabilities networkCapabilities) { - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_CELLULAR; + 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_WIFI) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_WIFI; + 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 (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_BLUETOOTH; + 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; } + } + } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_ETHERNET; - } + return MengineNetworkTransport.NETWORKTRANSPORT_UNKNOWN; + } - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_VPN; - } + private void recomputeAndPublish(@NonNull ConnectivityManager cm) { + boolean available = false; + boolean unmetered = false; + MengineNetworkTransport transport = MengineNetworkTransport.NETWORKTRANSPORT_UNKNOWN; - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_WIFI_AWARE; - } + try { + Network[] networks = cm.getAllNetworks(); - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_LOWPAN; - } + for (Network network : networks) { + NetworkCapabilities nc = cm.getNetworkCapabilities(network); - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_USB; - } + if (nc != null && + nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true && + nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) == true ) { - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_THREAD) == true) { - return MengineNetworkTransport.NETWORKTRANSPORT_THREAD; + available = true; + unmetered = nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + transport = MengineMonitorConnectivityStatusService.getNetworkTransport(nc); + + break; } + } + } catch (SecurityException e) { + MengineMonitorConnectivityStatusService.this.logError("SecurityException ACCESS_NETWORK_STATE missing [exception: %s]" + , e.getMessage() + ); + } + + MengineNetwork.setNetworkAvailable(available); + MengineNetwork.setNetworkUnmetered(unmetered); + MengineNetwork.setNetworkTransport(transport); + } + + @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; + } + + ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { + @Override + public void onAvailable(@NonNull Network network) { + super.onAvailable(network); + + MengineMonitorConnectivityStatusService.this.logInfo("network %s available" + , network.toString() + ); - return MengineNetworkTransport.NETWORKTRANSPORT_UNKNOWN; + 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); } @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/MengineNative.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineNative.java index 3c45f6a177..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(); @@ -50,7 +52,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/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/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; 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/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..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); } @@ -219,7 +244,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/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineProcedureSendMail.java index af77c15329..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; @@ -227,6 +228,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"); @@ -249,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/MengineService.java b/gradle/libraries/Mengine/src/main/java/org/Mengine/Base/MengineService.java index dee13018ec..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 @@ -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,15 +231,7 @@ public String logMessage(String format, Object ... args) { } @Override - public String logMessageProtected(String format, Object ... args) { - MengineTag t = this.getServiceTag(); - String m = MengineLog.logMessageProtected(t, format, args); - - return m; - } - - @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 +239,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 +247,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 +261,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 +309,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 +324,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..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 @@ -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,50 @@ 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 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/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/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/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 49dcc4b79d..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 @@ -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 @@ -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; } @@ -967,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); @@ -1018,8 +1013,6 @@ public static void printCurrentStackTrace() { } public static void throwRuntimeException(String message, Throwable throwable) { - MengineUtils.debugBreak(); - throw new RuntimeException(message, throwable); } @@ -1409,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); @@ -1468,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/libraries/OpenAL32/build.gradle b/gradle/libraries/OpenAL32/build.gradle index 947f02f475..f9f2db54bf 100644 --- a/gradle/libraries/OpenAL32/build.gradle +++ b/gradle/libraries/OpenAL32/build.gradle @@ -8,22 +8,23 @@ android { } } - buildTypes { - 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 (String argument : cmake_arguments) { - arguments.add(argument) - } - arguments.add("-DCMAKE_BUILD_TYPE:STRING=Debug") } } @@ -32,10 +33,6 @@ android { release { externalNativeBuild { cmake { - for (String argument : cmake_arguments) { - arguments.add(argument) - } - arguments.add("-DCMAKE_BUILD_TYPE:STRING=Release") } } 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/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..d2e8a871de --- /dev/null +++ b/gradle/plugins/AdMob/BannerAd/src/main/java/org/Mengine/Plugin/AdMob/BannerAd/MengineAdMobBannerAd.java @@ -0,0 +1,373 @@ +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); + + ViewGroup viewGroup = activity.getContentViewGroup(); + viewGroup.addView(adView); + + 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(); + } + + @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..d249ad9daf --- /dev/null +++ b/gradle/plugins/AdMob/Core/build.gradle @@ -0,0 +1,10 @@ +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') +} \ No newline at end of file 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..cf7147db58 --- /dev/null +++ b/gradle/plugins/AdMob/Core/src/main/java/org/Mengine/Plugin/AdMob/Core/MengineAdMobBase.java @@ -0,0 +1,302 @@ +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); + } +} \ No newline at end of file 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..9ae81be56d --- /dev/null +++ b/gradle/plugins/AdMob/InterstitialAd/src/main/java/org/Mengine/Plugin/AdMob/InterstitialAd/MengineAdMobInterstitialAd.java @@ -0,0 +1,310 @@ +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); + + this.destroyInterstitialAd(); + } + + private void destroyInterstitialAd() { + 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) { + MengineAdMobInterstitialAd.this.destroyInterstitialAd(); + + 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) { + MengineAdMobInterstitialAd.this.destroyInterstitialAd(); + + 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 (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 (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; + + InterstitialAd show_interstitialAd = m_interstitialAd; + + MengineUtils.performOnMainThread(() -> { + show_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..a1a15d5cc1 --- /dev/null +++ b/gradle/plugins/AdMob/RewardedAd/src/main/java/org/Mengine/Plugin/AdMob/RewardedAd/MengineAdMobRewardedAd.java @@ -0,0 +1,348 @@ +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); + + this.destroyRewardedAd(); + } + + private void destroyRewardedAd() { + 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) { + MengineAdMobRewardedAd.this.destroyRewardedAd(); + + 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) { + MengineAdMobRewardedAd.this.destroyRewardedAd(); + + 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 (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 (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 (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; + + RewardedAd show_rewardedAd = m_rewardedAd; + + MengineUtils.performOnMainThread(() -> { + 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; + } + + @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/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..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 @@ -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/Amplitude/build.gradle b/gradle/plugins/Amplitude/build.gradle index 136fb407fa..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.1.0' + implementation 'com.squareup.okhttp3:okhttp:5.3.2' - implementation 'com.amplitude:analytics-android:1.21.5' + 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 7730ffe57d..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; @@ -23,6 +24,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Set; import okhttp3.OkHttpClient; @@ -36,13 +38,14 @@ 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); - 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); @@ -56,13 +59,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 +79,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); @@ -97,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; } @@ -129,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); @@ -142,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/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..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 @@ -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,25 +37,17 @@ 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); - - 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) ; @@ -233,7 +227,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 +281,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..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 @@ -21,7 +21,9 @@ import com.applovin.sdk.AppLovinSdkUtils; 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; @@ -42,19 +44,10 @@ 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); - - 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); @@ -67,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 acc66ac622..69168f5990 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]") @@ -89,38 +91,38 @@ 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' } 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.7.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.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) { - 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) { - 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.5.0.0' + implementation 'com.applovin.mediation:google-ad-manager-adapter:24.7.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_HYPRMX == true) { @@ -128,21 +130,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.0.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.0' + implementation 'com.applovin.mediation:line-adapter:2025.9.24.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_MAIO == true) { @@ -154,15 +156,15 @@ 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) { - 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.2.0.0' } if (MENGINE_APP_PLUGIN_APPLOVIN_MEDIATION_OGURY == true) { @@ -170,31 +172,31 @@ 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.7.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.10.0.0' } 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) { - 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.2.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.15.1.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 b60f12d34f..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; @@ -32,9 +34,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 +45,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; @@ -62,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; } @@ -230,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); @@ -517,7 +532,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/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/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/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 49ca981ff3..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 @@ -17,13 +17,17 @@ 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.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; @@ -32,22 +36,15 @@ public class MengineAppLovinInterstitialAd extends MengineAppLovinBase implement private MaxInterstitialAd m_interstitialAd; - public MengineAppLovinInterstitialAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.INTERSTITIAL); + private boolean m_showing = false; - String MengineAppLovinPlugin_Interstitial_AdUnitId = plugin.getResourceString(METADATA_INTERSTITIAL_ADUNITID); + public MengineAppLovinInterstitialAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.INTERSTITIAL); - if (MengineAppLovinPlugin_Interstitial_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , plugin.getResourceName(METADATA_INTERSTITIAL_ADUNITID) - , MengineAppLovinPlugin_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; @@ -177,11 +174,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"); @@ -217,6 +221,8 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setInterstitialState("displayed." + placement + "." + ad.getNetworkName()); + + MengineNative.AndroidPlatform_freezeEvent( true, true ); } @Override @@ -232,8 +238,14 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setInterstitialState("hidden." + placement + "." + ad.getNetworkName()); + MengineNative.AndroidPlatform_unfreezeEvent( true, true ); + + m_showing = 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 +298,12 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setInterstitialState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); + m_showing = 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/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..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 @@ -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,25 +43,17 @@ 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); - - 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); @@ -283,7 +277,7 @@ public boolean canYouShow() { } public void show(int leftMargin, int topMargin) { - MengineUtils.performOnMainThread("show", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == true) { return; } @@ -302,7 +296,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/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/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..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 @@ -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,25 +44,17 @@ 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); - - 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); @@ -312,7 +306,7 @@ public boolean canYouShow() { } public void show() { - MengineUtils.performOnMainThread("show", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == true) { return; } @@ -324,7 +318,7 @@ public void show() { } public void hide() { - MengineUtils.performOnMainThread("hide", () -> { + MengineUtils.performOnMainThread(() -> { if (m_visible == false) { return; } 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..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 @@ -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; } @@ -56,7 +56,7 @@ static 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; @@ -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/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..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 @@ -18,7 +18,10 @@ 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; @@ -34,21 +37,15 @@ public class MengineAppLovinRewardedAd extends MengineAppLovinBase implements Me private MaxRewardedAd m_rewardedAd; - public MengineAppLovinRewardedAd(@NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { - super(plugin, MaxAdFormat.REWARDED); + private boolean m_showing = false; - String MengineAppLovinPlugin_Rewarded_AdUnitId = plugin.getResourceString(METADATA_REWARDED_ADUNITID); + public MengineAppLovinRewardedAd(@NonNull MengineAdService adService, @NonNull MengineAppLovinPluginInterface plugin) throws MengineServiceInvalidInitializeException { + super(adService, plugin, MaxAdFormat.REWARDED); - if (MengineAppLovinPlugin_Rewarded_AdUnitId.isEmpty() == true) { - this.invalidInitialize("meta %s is empty" - , 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; @@ -201,11 +198,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"); @@ -232,7 +236,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 +266,8 @@ public void onAdDisplayed(@NonNull MaxAd ad) { .log(); this.setRewardedState("displayed." + placement + "." + ad.getNetworkName()); + + MengineNative.AndroidPlatform_freezeEvent( true, true ); } @Override @@ -275,8 +283,14 @@ public void onAdHidden(@NonNull MaxAd ad) { this.setRewardedState("hidden." + placement + "." + ad.getNetworkName()); + MengineNative.AndroidPlatform_unfreezeEvent( true, true ); + + m_showing = 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 +343,12 @@ public void onAdDisplayFailed(@NonNull MaxAd ad, @NonNull MaxError error) { this.setRewardedState("display_failed." + placement + "." + ad.getNetworkName() + "." + errorCode); + m_showing = 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/build.gradle b/gradle/plugins/AppLovin/build.gradle index 00a376fec2..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) @@ -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}\"" : "\"\"" 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/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..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 @@ -21,6 +21,7 @@ import org.Mengine.Base.MengineAdProviderInterface; import org.Mengine.Base.MengineAdService; import org.Mengine.Base.MengineConsentFlowUserGeography; +import org.Mengine.Base.MengineFragmentAdvertisingId; import org.Mengine.Base.MengineListenerApplication; import org.Mengine.Base.MengineListenerRemoteConfig; import org.Mengine.Base.MengineApplication; @@ -85,8 +86,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 +127,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); } @@ -256,9 +257,21 @@ public void onAppCreate(@NonNull MengineApplication application) throws MengineS builder.setPluginVersion("Mengine-v" + engineVersion); if (BuildConfig.MENGINE_APP_PLUGIN_APPLOVIN_TEST_DEVICE_ADVERTISING_ID != null) { - List 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(); @@ -394,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) { @@ -404,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); } } @@ -552,6 +565,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 +638,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) { 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/build.gradle b/gradle/plugins/DataDog/build.gradle index 68264b2f66..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:2.25.0' + implementation 'com.datadoghq:dd-sdk-android-logs:3.3.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 be0a8b4e04..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 @@ -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; @@ -77,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) ); @@ -104,14 +105,16 @@ 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) ); boolean crashReportsEnabled = false; + boolean is_publish = application.isBuildPublish(); + String clientToken = MengineDataDogPlugin_ClientToken; - String envName = (BuildConfig.DEBUG == true) ? "dev" : "prod"; + String envName = (is_publish == true) ? "dev" : "prod"; String variant = ""; Configuration config = new Configuration.Builder(clientToken, envName, variant) @@ -138,7 +141,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)); } @@ -183,6 +186,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); @@ -191,6 +206,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; } @@ -201,6 +222,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 +237,7 @@ public void onMengineChangeUserId(@NonNull MengineApplication application, Strin @Override public void onMengineRemoveUserData(@NonNull MengineApplication application) { - Datadog.setUserInfo(null, null, null, null); + Datadog.clearAllData(); } @Override @@ -271,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) { @@ -287,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/DevToDev/build.gradle b/gradle/plugins/DevToDev/build.gradle index fc17b13b7c..2eb102c178 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" @@ -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.2' } android { 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/Firebase/build.gradle b/gradle/plugins/Firebase/build.gradle index db1e6f1c2a..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.1.0') + api enforcedPlatform('com.google.firebase:firebase-bom:34.6.0') - implementation 'com.google.firebase:firebase-common:22.0.0' + implementation 'com.google.firebase:firebase-common:22.0.1' } 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..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 @@ -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); @@ -72,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); } @@ -125,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); @@ -139,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); @@ -176,15 +168,15 @@ private static String getAdMediation(MengineAdMediation adMediation) { return "appLovin"; } + if (adMediation == MengineAdMediation.ADMEDIATION_ADMOB) { + return "adMob"; + } + return "unknown"; } @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; @@ -207,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(); @@ -234,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); @@ -246,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/gradle/plugins/FirebaseCrashlytics/build.gradle b/gradle/plugins/FirebaseCrashlytics/build.gradle index a070a35cb8..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.0' - implementation 'com.google.firebase:firebase-crashlytics-ndk:20.0.0' + 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/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..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 @@ -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); } } @@ -141,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/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 277a80def3..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.0' + implementation 'com.google.firebase:firebase-perf:22.0.4' } \ 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/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..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 ); @@ -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/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/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..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 @@ -25,13 +25,11 @@ 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; - protected final Object m_syncronizationAdvertising = new Object(); + protected final Object m_synchronizationAdvertising = new Object(); private Thread m_advertisingThread; @@ -50,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); @@ -63,8 +61,8 @@ public Bundle onSave(@NonNull MengineApplication application) { public void onLoad(@NonNull MengineApplication application, @NonNull Bundle bundle) { int version = bundle.getInt("version", 0); - synchronized (m_syncronizationAdvertising) { - m_advertisingId = bundle.getString("advertisingId", LIMIT_ADVERTISING_ID); + synchronized (m_synchronizationAdvertising) { + m_advertisingId = bundle.getString("advertisingId", MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID); m_advertisingLimitTrackingEnabled = bundle.getBoolean("advertisingLimitTrackingEnabled", true); m_advertisingLimitTrackingFetch = bundle.getBoolean("advertisingLimitTrackingFetch", false); } @@ -77,15 +75,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_synchronizationAdvertising) { + m_advertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; + m_advertisingLimitTrackingEnabled = true; + m_advertisingLimitTrackingFetch = true; + } MengineFragmentAdvertisingId.INSTANCE.setAdvertisingId(m_advertisingId, m_advertisingLimitTrackingEnabled); return; } + synchronized (m_synchronizationAdvertising) { + 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(); @@ -114,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(); } @@ -122,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; @@ -131,39 +142,47 @@ public void onAppTerminate(@NonNull MengineApplication application) { } private void postAdInfo(AdvertisingIdClient.Info adInfo) { - synchronized (m_syncronizationAdvertising) { + synchronized (m_synchronizationAdvertising) { + String newAdvertisingId; + boolean newAdvertisingLimitTrackingEnabled; + if (adInfo == null) { - m_advertisingId = LIMIT_ADVERTISING_ID; - m_advertisingLimitTrackingEnabled = true; + newAdvertisingId = MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID; + newAdvertisingLimitTrackingEnabled = true; } else if (adInfo.isLimitAdTrackingEnabled() == true) { - m_advertisingId = LIMIT_ADVERTISING_ID; - m_advertisingLimitTrackingEnabled = true; + newAdvertisingId = MengineFragmentAdvertisingId.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; + if (Objects.equals(adInfoAdvertisingId, MengineFragmentAdvertisingId.LIMIT_ADVERTISING_ID) == true) { + newAdvertisingId = MengineFragmentAdvertisingId.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; - } } } diff --git a/gradle/plugins/GoogleConsent/build.gradle b/gradle/plugins/GoogleConsent/build.gradle index e698452b19..97ad2e2dcc 100644 --- a/gradle/plugins/GoogleConsent/build.gradle +++ b/gradle/plugins/GoogleConsent/build.gradle @@ -1,7 +1,9 @@ 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) android { namespace "org.Mengine.Plugin.GoogleConsent" @@ -10,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}" + 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/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..f8fdd31936 --- /dev/null +++ b/gradle/plugins/GoogleGameSocial/src/main/java/org/Mengine/Plugin/GoogleGameSocial/MengineGoogleGameSocialAchievement.java @@ -0,0 +1,126 @@ +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() == true) { + 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(); + + boolean unlocked = this.isUnlocked(); + boolean incremental = this.isIncremental(); + + 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", 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 ae47e28d83..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 @@ -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; @@ -14,26 +19,35 @@ 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; 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.JSONException; +import org.json.JSONObject; +import java.util.HashMap; import java.util.Map; public class MengineGoogleGameSocialPlugin extends MengineService implements MengineListenerApplication, MengineListenerActivity { 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; private GamesSignInClient m_gamesSignInClient; private AchievementsClient m_achievementsClient; @@ -41,6 +55,8 @@ public class MengineGoogleGameSocialPlugin extends MengineService implements Men private EventsClient m_eventsClient; private boolean m_isAuthenticated = false; + private Map m_cachedAchievements = new HashMap<>(); + private final Object m_cachedAchievementsLock = new Object(); @Override public boolean onAvailable(@NonNull MengineApplication application) { @@ -58,7 +74,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 +88,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 +97,37 @@ 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) { + 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; + m_gamesSignInClient = PlayGames.getGamesSignInClient(activity); m_achievementsClient = PlayGames.getAchievementsClient(activity); m_leaderboardsClient = PlayGames.getLeaderboardsClient(activity); @@ -106,10 +148,20 @@ 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; m_eventsClient = null; + + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } } @Override @@ -122,14 +174,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; } @@ -148,22 +200,42 @@ private void signInSilently() { m_isAuthenticated = false; + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } + return; } 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; + synchronized (m_cachedAchievementsLock) { + 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"); }); } @@ -171,8 +243,6 @@ public void signInIntent() { if (MengineNetwork.isNetworkAvailable() == false) { this.logInfo("signInIntent network not available"); - this.nativeCall("onGoogleGameSocialSignInIntentError", new RuntimeException("network not available")); - return; } @@ -182,14 +252,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"); + + 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"); + } + } catch (Exception ex) { + this.logException(ex, Map.of()); + } + + return; + } + if (e != null) { this.logException(e, Map.of()); } else { this.logError("[ERROR] signInIntent failed: null exception"); } - this.nativeCall("onGoogleGameSocialSignInIntentError", e); - return; } @@ -200,7 +296,9 @@ public void signInIntent() { m_isAuthenticated = false; - this.nativeCall("onGoogleGameSocialSignInIntentFailed"); + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements.clear(); + } return; } @@ -209,10 +307,102 @@ public void signInIntent() { m_isAuthenticated = true; - this.nativeCall("onGoogleGameSocialSignInIntentSuccess"); + MenginePreferences.setPreferenceBoolean(PREFERENCE_KEY_TRYING_SIGN_IN_INTENT, false); + + 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 { + Map cachedAchievements = new HashMap<>(); + + int count = achievementBuffer.getCount(); + + for (int index = 0; index < count; ++index) { + Achievement achievement = achievementBuffer.get(index).freeze(); + + MengineGoogleGameSocialAchievement achievementInfo = new MengineGoogleGameSocialAchievement(achievement); + + String id = achievementInfo.getId(); + + cachedAchievements.put(id, achievementInfo); + } + + synchronized (m_cachedAchievementsLock) { + m_cachedAchievements = cachedAchievements; + } + + JSONObject achievementsJSON = new JSONObject(); + + 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); + + 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"); @@ -222,6 +412,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() @@ -240,6 +438,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" @@ -261,6 +487,14 @@ public void unlockAchievement(String achievementId) { return; } + if (this.hasAchievementUnlock(achievementId) == true) { + this.logInfo("unlockAchievement achievementId: %s already unlocked", achievementId); + + this.nativeCall("onGoogleGameSocialUnlockAchievementError", achievementId, new RuntimeException("already unlocked")); + + return; + } + this.logInfo("unlockAchievement achievementId: %s" , achievementId ); @@ -271,6 +505,14 @@ public void unlockAchievement(String achievementId) { , achievementId ); + long timestamp = System.currentTimeMillis(); + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement cachedAchievement = this.getCachedAchievement(achievementId); + + cachedAchievement.markUnlocked(timestamp); + } + MengineFragmentGame.INSTANCE.unlockAchievement(achievementId); this.nativeCall("onGoogleGameSocialUnlockAchievementSuccess", achievementId); @@ -318,12 +560,24 @@ 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 ); + long timestamp = System.currentTimeMillis(); + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement cachedAchievement = this.getCachedAchievement(achievementId); + + cachedAchievement.incrementSteps(numSteps, timestamp); + + if (Boolean.TRUE.equals(unlock)) { + cachedAchievement.markUnlocked(timestamp); + } + } + MengineFragmentGame.INSTANCE.incrementAchievement(achievementId, numSteps); this.nativeCall("onGoogleGameSocialIncrementAchievementSuccess", achievementId, numSteps); @@ -375,6 +629,14 @@ public void revealAchievement(String achievementId) { , achievementId ); + long timestamp = System.currentTimeMillis(); + + synchronized (m_cachedAchievementsLock) { + MengineGoogleGameSocialAchievement cachedAchievement = this.getCachedAchievement(achievementId); + + cachedAchievement.markRevealed(timestamp); + } + MengineFragmentGame.INSTANCE.revealAchievement(achievementId); this.nativeCall("onGoogleGameSocialRevealAchievementSuccess", achievementId); 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..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 @@ -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; } @@ -717,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/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/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/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/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/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 682ad5f17a..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 @@ -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; @@ -40,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 ); @@ -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); } 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/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 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 b0a7b67e85..87ba49dd6b 100644 --- a/gradle/settings.gradle.kts +++ b/gradle/settings.gradle.kts @@ -1,70 +1,95 @@ +import java.util.Properties + fun getBooleanProperty(name: String, d: Boolean): Boolean { if (extra.has(name) == false) { 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 { +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('"')) { + return s.substring(1, s.length - 1) + } + + if (s.startsWith("'") && s.endsWith("'")) { + return s.substring(1, s.length - 1) + } + + 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 (file(ANDROID_APP_MAIN_PROJECT).exists() == false) { - println("\u001b[31m" + "[-] Not found $ANDROID_APP_MAIN_PROJECT" + "\u001b[0m") +if (ANDROID_APP_MAIN_PROJECT == null || file(ANDROID_APP_MAIN_PROJECT).exists() == false) { + 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) } @@ -78,23 +103,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") @@ -166,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") @@ -189,4 +218,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/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 992d0aa574..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 @@ -11,33 +11,53 @@ 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}'") } -Utils.getStringProperty = { String name, String d -> - def p = project.findProperty(name) +Utils.getStringProperty = { final String name, final String d -> + final 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 -> - def p = project.findProperty(name) +Utils.getIntegerProperty = { final String name, final Integer d -> + final def p = project.findProperty(name) if (p == null) { return d } - def v = p as Integer + try { + final def v = p as Integer - return v + return v + } catch (final ClassCastException e) { + throw new IllegalArgumentException("Property '${name}' must be integer, but got '${p}' [exception: ${e}]") + } } -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 @@ -46,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 @@ -66,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/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/Applications/iOSApplication/iOSUIApplicationDelegate.h b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h index b041aa97d7..ab93d62461 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.h +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.h @@ -8,10 +8,13 @@ #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 +typedef void (^iOSDidBecomeActiveOperationBlock)(void (^completion)(void)); + @interface iOSUIApplicationDelegate : NSObject @property (nonatomic, strong) UIWindow * m_window; @@ -23,6 +26,10 @@ @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; +@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 0f24ae51e6..4a5b85bec6 100644 --- a/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm +++ b/src/Applications/iOSApplication/iOSUIApplicationDelegate.mm @@ -27,8 +27,12 @@ - (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]; + self.m_didBecomeActiveOperations = [NSMutableArray array]; + self.m_isProcessingDidBecomeActiveOperation = NO; + NSArray * proxysClassed = [iOSApplicationDelegates getApplicationDelegates]; for (id className in proxysClassed) { @@ -66,6 +70,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 +109,10 @@ - (instancetype)init { return self.m_pluginAdRevenueDelegates; } +- (NSArray *)getPluginAppTrackingTransparencyDelegates { + return self.m_pluginAppTrackingTransparencyDelegates; +} + - (NSArray *)getPluginTransparencyConsentDelegates { return self.m_pluginTransparencyConsentDelegates; } @@ -162,18 +174,18 @@ - (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]; } } } -- (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]; } } } @@ -218,6 +230,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) { @@ -226,6 +246,57 @@ - (void)eventTransparencyConsent:(iOSTransparencyConsentParam *)consent { } } +- (void)addDidBecomeActiveOperationWithCompletion:(iOSDidBecomeActiveOperationBlock)block { + @synchronized(self.m_didBecomeActiveOperations) { + [self.m_didBecomeActiveOperations addObject:block]; + } + + [self processNextOperation]; +} + +- (void)processNextOperation { + [AppleDetail addMainQueueOperation:^{ + UIApplicationState appState = [[UIApplication sharedApplication] applicationState]; + + if (appState != UIApplicationStateActive) { + return; + } + + iOSDidBecomeActiveOperationBlock operation = nil; + + @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]; + } + }]; +} + +- (void)processOperation:(iOSDidBecomeActiveOperationBlock)block { + [AppleDetail addMainQueueOperation:^{ + block(^{ + @synchronized(self.m_didBecomeActiveOperations) { + self.m_isProcessingDidBecomeActiveOperation = NO; + } + + [self processNextOperation]; + }); + }]; +} + #pragma mark - UIApplicationDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions API_AVAILABLE(ios(3.0)) { @@ -311,6 +382,8 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N - (void)applicationDidBecomeActive:(UIApplication *)application { [AppleLog withFormat:@"Mengine application applicationDidBecomeActive"]; + [self processNextOperation]; + @autoreleasepool { for (id delegate in self.m_pluginApplicationDelegates) { if ([delegate respondsToSelector:@selector(applicationDidBecomeActive:)] == NO) { @@ -436,7 +509,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 +527,7 @@ - (void)postFinishLaunch { if( application.initialize() == false ) { [AppleLog withFormat:@"🔴 [ERROR] Mengine application initialize [Failed]"]; - [[NSOperationQueue mainQueue] cancelAllOperations]; + [AppleDetail cancelAllQueueOperations]; application.finalize(); @@ -471,7 +544,7 @@ - (void)postFinishLaunch { application.loop(); - [[NSOperationQueue mainQueue] cancelAllOperations]; + [AppleDetail cancelAllQueueOperations]; application.finalize(); diff --git a/src/Bootstrapper/Bootstrapper.cpp b/src/Bootstrapper/Bootstrapper.cpp index 9361fb306f..a747054c5e 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 @@ -413,8 +414,8 @@ PLUGIN_EXPORT( AppleMARSDK ); PLUGIN_EXPORT( AppleAppLovin ); #endif ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS_STATIC) -PLUGIN_EXPORT( AppleFirebaseAnalytics ); +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_STATIC) +PLUGIN_EXPORT( AppleAdMob ); #endif ////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_PLUGIN_APPLE_FIREBASE_CRASHLYTICS_STATIC) @@ -453,10 +454,6 @@ PLUGIN_EXPORT( AppleStoreInAppPurchase ); PLUGIN_EXPORT( AppleAdjust ); #endif ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLUGIN_APPLE_DEVTODEV_STATIC) -PLUGIN_EXPORT( AppleDevToDev ); -#endif -////////////////////////////////////////////////////////////////////////// #if defined(MENGINE_PLUGIN_APPLE_SENTRY_STATIC) PLUGIN_EXPORT( AppleSentry ); #endif @@ -900,31 +897,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; } @@ -937,19 +934,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 )\ @@ -1052,6 +1049,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" ); @@ -1329,11 +1330,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) @@ -1405,7 +1406,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) @@ -1468,8 +1469,8 @@ namespace Mengine MENGINE_ADD_PLUGIN( AppleAppLovin, "plugin AppleAppLovin...", MENGINE_DOCUMENT_FACTORABLE ); #endif -#if defined(MENGINE_PLUGIN_APPLE_FIREBASE_ANALYTICS_STATIC) - MENGINE_ADD_PLUGIN( AppleFirebaseAnalytics, "plugin AppleFirebaseAnalytics...", MENGINE_DOCUMENT_FACTORABLE ); +#if defined(MENGINE_PLUGIN_APPLE_ADMOB_STATIC) + MENGINE_ADD_PLUGIN( AppleAdMob, "plugin AppleAdMob...", MENGINE_DOCUMENT_FACTORABLE ); #endif #if defined(MENGINE_PLUGIN_APPLE_FIREBASE_MESSAGING_STATIC) @@ -1500,10 +1501,6 @@ namespace Mengine MENGINE_ADD_PLUGIN( AppleAdjust, "plugin AppleAdjust...", 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 @@ -1748,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 ) @@ -1759,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/Config/CMakeLists.txt b/src/Config/CMakeLists.txt index 3f4359c594..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 @@ -156,6 +160,7 @@ src StdUtility.h StdThread.h StdAssert.h + StdRandom.h Limits.h UInt32ToPointer.h Metaprogramming.h diff --git a/src/Config/Config.h b/src/Config/Config.h index d9c418fef8..444c2e5497 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 @@ -345,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/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/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/Application.cpp b/src/Engine/Application.cpp index 812a4f61a2..6f8d6ed650 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" @@ -306,10 +308,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 ) { @@ -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 ); @@ -1815,10 +1821,10 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool Application::render() { + m_renderPipeline->clear(); + if( m_nopause == false && m_focus == false ) { - m_renderPipeline->clear(); - return false; } @@ -1832,9 +1838,7 @@ namespace Mengine ->render( m_renderPipeline ); RENDER_SERVICE() - ->endScene( m_renderPipeline ); - - m_renderPipeline->clear(); + ->endScene( m_renderPipeline ); return true; } @@ -1955,30 +1959,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 @@ -2058,11 +2062,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; @@ -2132,10 +2138,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; @@ -2270,7 +2277,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 +2285,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/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/Engine/TextField.cpp b/src/Engine/TextField.cpp index 80b81aea91..86beadd751 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 ) @@ -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 ); @@ -1125,7 +1120,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 +1366,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/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..28bccbd5e2 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" ); @@ -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/AndroidEnv.cpp b/src/Environment/Android/AndroidEnv.cpp index 1cee862bff..7fbe4c5839 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 ) { @@ -56,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 ); @@ -161,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 ) { @@ -212,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; } ////////////////////////////////////////////////////////////////////////// @@ -235,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; } @@ -243,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 ) @@ -261,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 ) { @@ -271,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" ); @@ -281,7 +225,7 @@ namespace Mengine return nullptr; } - return new_envThread; + return new_jenv; } ////////////////////////////////////////////////////////////////////////// int Mengine_JNI_SetupThread() @@ -303,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" ); @@ -317,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 ); @@ -675,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 ); @@ -701,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 ); @@ -731,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 ); @@ -761,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 ); @@ -791,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 ); @@ -821,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 ); @@ -851,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 ); @@ -881,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 ); @@ -909,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 ); @@ -935,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 ); @@ -965,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 ); @@ -995,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 ); @@ -1007,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 ); @@ -1055,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 ); @@ -1188,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 ); @@ -1220,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 ); @@ -1248,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 ); @@ -1278,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 ); @@ -1294,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 ); @@ -1306,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..17a4c7b799 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,12 +361,14 @@ 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 ); 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 ); @@ -356,12 +376,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 +391,14 @@ 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 ); + 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..f63e5fe661 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; } @@ -156,4 +158,4 @@ namespace Mengine Mengine_JNI_DeleteLocalRef( jenv, jclass_UtilLog ); } ////////////////////////////////////////////////////////////////////////// -} +} \ No newline at end of file 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/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/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/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/Environment/Apple/AppleDetail.h b/src/Environment/Apple/AppleDetail.h index feca99cbe2..8c94a3e864 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; @@ -43,4 +51,20 @@ + (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:(id _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 a5f2ca29e5..6ec6db7071 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; +} -+ (void)addMainQueueOperation:(dispatch_block_t)block { ++ (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 _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 { @@ -136,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); @@ -171,38 +313,142 @@ + (void)getParamsFromNSDictionary:(NSDictionary *) _in outParams:(Mengine::Param 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 { - const Mengine::Char * value_str = [[NSString stringWithFormat:@"%@", value] UTF8String]; + forUnknown(key, value); + } + } +} + ++ (void)visitValues:(id _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/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/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/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..1463e336a5 --- /dev/null +++ b/src/Environment/Metal/MetalRenderSystemExtensionInterface.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Interface/UnknownInterface.h" + +#import +#import + +namespace Mengine +{ + class MetalRenderSystemExtensionInterface + : public UnknownInterface + { + public: + virtual void setMetalContext( id _device, CAMetalLayer * _layer ) = 0; + }; +} 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..c064b2fce8 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 @@ -18,6 +20,10 @@ src iOSEnvironmentService.mm iOSConsentFlowUserGeography.h + + iOSAppTrackingAuthorization.h + iOSAppTrackingTransparencyParam.h + iOSAppTrackingTransparencyParam.mm iOSTransparencyConsentParam.h iOSTransparencyConsentParam.mm @@ -34,6 +40,8 @@ src iOSAnalytics.h iOSAnalytics.mm + iOSAnalyticsEventCategory.h + iOSNetwork.h iOSNetwork.mm @@ -42,6 +50,7 @@ src iOSPluginUserIdDelegateInterface.h iOSPluginAdRevenueDelegateInterface.h iOSPluginApplicationDelegateInterface.h + iOSPluginAppTrackingTransparencyDelegateInterface.h iOSPluginTransparencyConsentDelegateInterface.h iOSPluginLoggerDelegateInterface.h iOSPluginConfigDelegateInterface.h diff --git a/src/Environment/iOS/iOSAnalytics.h b/src/Environment/iOS/iOSAnalytics.h index 93b34d4e0c..b4dba1f627 100644 --- a/src/Environment/iOS/iOSAnalytics.h +++ b/src/Environment/iOS/iOSAnalytics.h @@ -1,10 +1,13 @@ #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)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; diff --git a/src/Environment/iOS/iOSAnalytics.mm b/src/Environment/iOS/iOSAnalytics.mm index 050d3ec0f2..441ff4f177 100644 --- a/src/Environment/iOS/iOSAnalytics.mm +++ b/src/Environment/iOS/iOSAnalytics.mm @@ -3,17 +3,26 @@ #import "Environment/Apple/AppleDetail.h" #import "Environment/iOS/iOSDetail.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" @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]; }]; } ++(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/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/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..0f3a4769a9 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,9 +40,14 @@ + (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; ++ (void)config:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids; + ++ (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 de6bd5c33a..7b5d7ed4ab 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; @@ -166,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]; @@ -184,14 +186,62 @@ + (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]; }]; } ++ (void) addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block { + NSObject *delegate = [iOSDetail getUIMainApplicationDelegate]; + + [delegate addDidBecomeActiveOperationWithCompletion:block]; +} + ++ (BOOL)hasSystemWindows { + UIApplication * application = [UIApplication sharedApplication]; + + NSMutableArray * all_windows = [NSMutableArray array]; + + 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; + } + + UIViewController * view = [iOSDetail getRootViewController]; + + if (view == nil) { + return NO; + } + + if (view.presentedViewController == nil) { + return NO; + } + + return YES; +} + + (NSString *) pathForTemporaryFileWithPrefix:(NSString *)prefix ext:(NSString *)ext { NSString * result; CFUUIDRef uuid = CFUUIDCreate(NULL); @@ -224,16 +274,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 +317,7 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController UIAlertAction * yesAction = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ yes(); }]; }]; @@ -275,7 +325,7 @@ + (void) showAreYouSureAlertDialogWithContext:(UIViewController *)viewController UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"CANCEL" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ cancel(); }]; }]; @@ -293,9 +343,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/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/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/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/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/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 6d785bc285..091c679083 100644 --- a/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/iOSUIMainApplicationDelegateInterface.h @@ -6,7 +6,9 @@ #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" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" @protocol iOSUIMainApplicationDelegateInterface @@ -15,6 +17,7 @@ - (NSArray * _Nonnull)getPluginConfigDelegates; - (NSArray * _Nonnull)getPluginUserIdDelegates; - (NSArray * _Nonnull)getPluginAdRevenueDelegates; +- (NSArray *_Nonnull)getPluginAppTrackingTransparencyDelegates; - (NSArray * _Nonnull)getPluginTransparencyConsentDelegates; - (id _Nullable)getPluginDelegateOfClass:(Class _Nonnull)delegateClass; @@ -25,9 +28,9 @@ - (void)eventLog:(AppleLogRecordParam * _Nonnull)record; -- (void)eventConfig:(NSDictionary * _Nonnull)config; +- (void)eventConfig:(NSDictionary * _Nonnull)config ids:(NSDictionary * _Nonnull)ids; -- (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; @@ -35,6 +38,9 @@ - (void)eventRemoveUserData; - (void)eventAdRevenue:(iOSAdRevenueParam * _Nonnull)revenue; +- (void)eventAppTrackingTransparency:(iOSAppTrackingTransparencyParam * _Nonnull)tracking; - (void)eventTransparencyConsent:(iOSTransparencyConsentParam * _Nonnull)consent; +- (void)addDidBecomeActiveOperationWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull completion)(void)))block; + @end 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/EngineScriptEmbedding.cpp b/src/Frameworks/PythonFramework/EngineScriptEmbedding.cpp index d0e951f7be..bc73624aa6 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" @@ -130,6 +127,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" @@ -412,7 +410,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 ); @@ -431,12 +429,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(); @@ -444,7 +442,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; } @@ -548,7 +546,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(); @@ -558,7 +556,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; } @@ -1463,7 +1486,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 +1501,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 { @@ -1664,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; @@ -1791,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 ); @@ -2219,6 +2246,8 @@ namespace Mengine return false; } + content->closeInputStreamFile( stream ); + resource->release(); return true; @@ -4195,6 +4224,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 ) { @@ -4211,6 +4244,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 ) { @@ -4220,6 +4257,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 ) { @@ -4236,6 +4277,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 ) { @@ -4342,6 +4387,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 ); @@ -4710,7 +4756,7 @@ namespace Mengine return false; } - pybind::interface_>( _kernel, "Randomizer" ) + pybind::interface_>( _kernel, "RandomizerInterface" ) .def( "setSeed", &RandomizerInterface::setSeed ) .def( "getRandom", &RandomizerInterface::getRandom32 ) .def( "getRandomRange", &RandomizerInterface::getRandomRange32 ) diff --git a/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp b/src/Frameworks/PythonFramework/GameScriptEmbedding.cpp index fe05f22a73..6f93beaad0 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 ); @@ -105,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/Frameworks/PythonFramework/HelperScriptEmbedding.cpp b/src/Frameworks/PythonFramework/HelperScriptEmbedding.cpp index 6fe679d9e2..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" @@ -1022,6 +1023,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 +1056,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 ) @@ -1782,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; } @@ -1812,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; } @@ -1842,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; } @@ -1872,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; } @@ -2977,31 +2996,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 ) { @@ -3028,17 +3051,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/Frameworks/PythonFramework/KernelScriptEmbedding.cpp b/src/Frameworks/PythonFramework/KernelScriptEmbedding.cpp index 8ad1d45898..88ef4909ea 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" @@ -124,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 ); @@ -369,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 ); @@ -2488,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" ) @@ -2860,7 +2857,6 @@ namespace Mengine pybind::interface_>( _kernel, "RenderResolutionInterface" ) .def( "getContentResolution", &RenderResolutionInterface::getContentResolution ) - .def( "getGameViewport", &RenderResolutionInterface::getGameViewport ) ; pybind::interface_>( _kernel, "RenderViewportInterface" ) @@ -2891,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/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/PythonGameEventReceiver.cpp b/src/Frameworks/PythonFramework/PythonGameEventReceiver.cpp index c24b65d0cc..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 { @@ -282,9 +283,7 @@ namespace Mengine void PythonGameEventReceiver::onGameFrameEnd() { m_cb.call(); - } - ////////////////////////////////////////////////////////////////////////// -#if defined(MENGINE_PLATFORM_IOS) || defined(MENGINE_PLATFORM_ANDROID) + } ////////////////////////////////////////////////////////////////////////// void PythonGameEventReceiver::onGameApplicationDidBecomeActive() { @@ -311,8 +310,6 @@ namespace Mengine m_cb.call(); } ////////////////////////////////////////////////////////////////////////// -#endif - ////////////////////////////////////////////////////////////////////////// void PythonGameEventReceiver::onGameAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) { pybind::kernel_interface * kernel = pybind::get_kernel(); @@ -321,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/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/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; diff --git a/src/Frameworks/PythonFramework/PythonScriptService.cpp b/src/Frameworks/PythonFramework/PythonScriptService.cpp index 1861c07ee7..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,27 +311,30 @@ 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(); + 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(); @@ -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/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/Frameworks/PythonFramework/SoundScriptEmbedding.cpp b/src/Frameworks/PythonFramework/SoundScriptEmbedding.cpp index 63bef05c2b..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" @@ -90,6 +91,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 ); @@ -161,7 +167,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 +194,10 @@ namespace Mengine if( soundBuffer == nullptr ) { + LOGGER_ERROR( "resource sound '%s' invalid create sound buffer" + , _resourceName.c_str() + ); + resource->release(); return nullptr; @@ -196,9 +206,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 ) { @@ -224,6 +232,9 @@ namespace Mengine , volume ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + resource->release(); return nullptr; @@ -243,7 +254,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 +273,9 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -275,7 +289,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 +308,9 @@ namespace Mengine , Helper::getResourceFilePathByName( _resourceName ).c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -324,9 +341,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 +353,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 +375,13 @@ namespace Mengine , _position ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } - return sourceEmitter; + return soundIdentity; } ////////////////////////////////////////////////////////////////////////// float soundGetPosition( const SoundIdentityInterfacePtr & _identity ) @@ -443,11 +466,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; } @@ -474,14 +497,14 @@ 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() ); - 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 ) { @@ -495,10 +518,13 @@ 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() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -528,15 +554,21 @@ 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; } + 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 ); @@ -562,19 +594,20 @@ 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() ); - 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 ) { - 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; @@ -583,10 +616,14 @@ namespace Mengine if( SOUND_SERVICE() ->playEmitter( soundIdentity ) == false ) { - LOGGER_ERROR( "resource sound '%s' invalid play" + LOGGER_WARNING( "invalid play emitter resource '%s' file '%s'" , _resourceName.c_str() + , Helper::getResourceFilePathByName( _resourceName ).c_str() ); + SOUND_SERVICE() + ->releaseSoundIdentity( soundIdentity ); + return nullptr; } @@ -643,30 +680,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" ); @@ -760,7 +773,7 @@ namespace Mengine } }; ////////////////////////////////////////////////////////////////////////// - typedef IntrusivePtr< SoundScriptMethod> SoundScriptMethodPtr; + typedef IntrusivePtr SoundScriptMethodPtr; ////////////////////////////////////////////////////////////////////////// } SoundScriptEmbedding::SoundScriptEmbedding() @@ -780,10 +793,28 @@ 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_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" ) .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 ); @@ -799,20 +830,17 @@ 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 ); 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/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/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/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/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/Interface/CMakeLists.txt b/src/Interface/CMakeLists.txt index d0b1e54168..5c4ed7a941 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 @@ -139,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/Interface/ContentInterface.h b/src/Interface/ContentInterface.h index 1a8a74d9d8..e635596f8a 100644 --- a/src/Interface/ContentInterface.h +++ b/src/Interface/ContentInterface.h @@ -47,9 +47,12 @@ 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 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/DebugFileInterface.h b/src/Interface/DebugFileInterface.h index 68a797524c..e69de29bb2 100644 --- a/src/Interface/DebugFileInterface.h +++ b/src/Interface/DebugFileInterface.h @@ -1,22 +0,0 @@ -#pragma once - -#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; - ////////////////////////////////////////////////////////////////////////// -} - - 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/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/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/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/Interface/FileServiceInterface.h b/src/Interface/FileServiceInterface.h index a5478f8f17..1a4277943b 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, const DocumentInterfacePtr & _doc ) = 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/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/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/Interface/PlatformServiceInterface.h b/src/Interface/PlatformServiceInterface.h index 233fb7e5ed..f56752e926 100644 --- a/src/Interface/PlatformServiceInterface.h +++ b/src/Interface/PlatformServiceInterface.h @@ -40,12 +40,11 @@ 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 void tickPlatform( float _frameTime ) = 0; + virtual bool renderPlatform() = 0; virtual void stopPlatform() = 0; - - public: - virtual void setSleepMode( bool _sleepMode ) = 0; - virtual bool getSleepMode() const = 0; + virtual void freezePlatform( bool _tick, bool _render, bool _sound ) = 0; + virtual void unfreezePlatform( bool _tick, bool _render, bool _sound ) = 0; public: virtual Timestamp getPlatfomTime() const = 0; 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/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/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/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/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/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/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/SoundIdentityInterface.h b/src/Interface/SoundIdentityInterface.h index ffb79bd46e..5078c008c4 100644 --- a/src/Interface/SoundIdentityInterface.h +++ b/src/Interface/SoundIdentityInterface.h @@ -21,10 +21,11 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// enum ESoundSourceState { - ESS_STOP = 0, + ESS_INIT = 0, ESS_PLAY = 1, ESS_PAUSE = 2, - ESS_CANCEL = 3, + ESS_STOP = 3, + ESS_END = 4, }; ////////////////////////////////////////////////////////////////////////// typedef IntrusivePtr SoundIdentityInterfacePtr; @@ -33,6 +34,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/Interface/SoundServiceInterface.h b/src/Interface/SoundServiceInterface.h index c65a87e9d6..049d3a5fe0 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: @@ -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; @@ -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/Interface/SoundSystemInterface.h b/src/Interface/SoundSystemInterface.h index 45e36947a9..0951232df0 100644 --- a/src/Interface/SoundSystemInterface.h +++ b/src/Interface/SoundSystemInterface.h @@ -29,10 +29,7 @@ namespace Mengine virtual bool isSilent() const = 0; public: - 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/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/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/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/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/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/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/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/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/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/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/BaseDebugFile.cpp b/src/Kernel/BaseDebugFile.cpp deleted file mode 100644 index 910d48e063..0000000000 --- a/src/Kernel/BaseDebugFile.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "BaseDebugFile.h" - -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; - } - ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file diff --git a/src/Kernel/BaseDebugFile.h b/src/Kernel/BaseDebugFile.h deleted file mode 100644 index 7cf94f914b..0000000000 --- a/src/Kernel/BaseDebugFile.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "Interface/DebugFileInterface.h" - -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; - }; -} \ No newline at end of file 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.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/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..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,22 +74,12 @@ namespace Mengine } UPDATE_SERVICE() - ->removeUpdatater( UpdationInterfacePtr::from( this ) ); + ->removeUpdatater( this ); m_deep = mode_deep; UPDATE_SERVICE() - ->placeUpdatater( UpdationInterfacePtr::from( this ) ); - } - ////////////////////////////////////////////////////////////////////////// - EUpdateMode BaseUpdation::getUpdationMode() const - { - return m_mode; - } - ////////////////////////////////////////////////////////////////////////// - uint32_t BaseUpdation::getUpdationDeep() const - { - return m_deep; + ->placeUpdatater( this ); } ////////////////////////////////////////////////////////////////////////// } \ 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/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/CMakeLists.txt b/src/Kernel/CMakeLists.txt index 553e498ed6..50eddf044f 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 @@ -717,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 @@ -879,9 +883,6 @@ Core BaseDebuggerBoundingBox.h - BaseDebugFile.h - BaseDebugFile.cpp - DebugFileHelper.h Event.h 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/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/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/Kernel/DebugFileHelper.h b/src/Kernel/DebugFileHelper.h index 85e22b1b02..5af0131dc0 100644 --- a/src/Kernel/DebugFileHelper.h +++ b/src/Kernel/DebugFileHelper.h @@ -1,11 +1,12 @@ #pragma once -#include "Interface/DebugFileInterface.h" +#include "Interface/FileServiceInterface.h" +#include "Interface/DocumentInterface.h" #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 @@ -14,21 +15,65 @@ namespace Mengine { namespace Helper { + ////////////////////////////////////////////////////////////////////////// + template + 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 ); + + UniqueId id = factorable->getUniqueIdentity(); + + FILE_SERVICE() + ->addDebugFilePath( id, _relationPath, _folderPath, _filePath, _doc ); +#endif + } + ////////////////////////////////////////////////////////////////////////// + template + 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, _doc ); + } + ////////////////////////////////////////////////////////////////////////// + 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 ) { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) - const DebugFileInterface * debug = Helper::dynamicCast( _ptr ); +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + 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 @@ -41,15 +86,13 @@ namespace Mengine { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) - const DebugFileInterface * base = Helper::dynamicCast( _ptr ); +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + 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 @@ -62,15 +105,13 @@ namespace Mengine { MENGINE_UNUSED( _ptr ); -#if defined(MENGINE_DEBUG) - const DebugFileInterface * base = Helper::dynamicCast( _ptr ); +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + 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 @@ -83,7 +124,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/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/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/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/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/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/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/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/Kernel/FileContent.cpp b/src/Kernel/FileContent.cpp index d551be40e5..a49d4be46f 100644 --- a/src/Kernel/FileContent.cpp +++ b/src/Kernel/FileContent.cpp @@ -42,6 +42,11 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// + void FileContent::closeInputStreamFile( const InputStreamInterfacePtr & _stream ) + { + Helper::closeInputStreamFile( m_fileGroup, _stream ); + } + ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr FileContent::openOutputStreamFile( bool _withTemp, const DocumentInterfacePtr & _doc ) { OutputStreamInterfacePtr stream = Helper::openOutputStreamFile( m_fileGroup, m_filePath, _withTemp, _doc ); @@ -49,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 ea6eea4fd6..1c2691792e 100644 --- a/src/Kernel/FileContent.h +++ b/src/Kernel/FileContent.h @@ -21,9 +21,12 @@ 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; + 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/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/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/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/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/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/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/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/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/MT19937Randomizer.cpp b/src/Kernel/MT19937Randomizer.cpp index b4b5ede89e..27b5ac3a6c 100644 --- a/src/Kernel/MT19937Randomizer.cpp +++ b/src/Kernel/MT19937Randomizer.cpp @@ -8,13 +8,20 @@ namespace Mengine { ////////////////////////////////////////////////////////////////////////// MT19937Randomizer::MT19937Randomizer() + : m_engineRandomize( Helper::generateRandomDeviceMT19937() ) { - uint64_t seed = Helper::generateRandomLocaleSeed(); + StdRandom::mt19937_64::result_type min_value = (m_engineRandomize.min)(); + StdRandom::mt19937_64::result_type max_value = (m_engineRandomize.max)(); - 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)(); + m_epsilonf = 1.f / float( max_value - min_value ); + m_epsilond = 1.0 / double( max_value - min_value ); + } + ////////////////////////////////////////////////////////////////////////// + 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 ); @@ -36,7 +43,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 +62,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 +71,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 +85,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 +99,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 +118,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 +127,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 +141,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 +159,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 +186,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 +204,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 +231,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..970b6574d7 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,6 +13,7 @@ namespace Mengine public: MT19937Randomizer(); + MT19937Randomizer( uint64_t _seed ); ~MT19937Randomizer() override; protected: @@ -38,7 +39,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/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..439d6f8702 100644 --- a/src/Kernel/MixerMultiplicative.cpp +++ b/src/Kernel/MixerMultiplicative.cpp @@ -83,11 +83,12 @@ namespace Mengine for( Element & m : m_mixer ) { float used = 0.f; - if( m.follower.update( _context, &used ) == false ) { - process = true; + continue; } + + process = true; } return process; 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..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 @@ -61,6 +61,9 @@ namespace Mengine Node(); ~Node() override; + public: + HashType getHierarchyHash() const; + public: NodePtr findUniqueChild( UniqueId _uniqueIdentity ) const; 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/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/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/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/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..f58df62b2d --- /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/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/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/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/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/SpinLockScope.cpp b/src/Kernel/SpinLockScope.cpp new file mode 100644 index 0000000000..d779ca80ab --- /dev/null +++ b/src/Kernel/SpinLockScope.cpp @@ -0,0 +1,17 @@ +#include "SpinLockScope.h" + +namespace Mengine +{ + ////////////////////////////////////////////////////////////////////////// + SpinLockScope::SpinLockScope( SpinLock & _futex ) + : m_spinlock( _futex ) + { + m_spinlock.lock(); + } + ////////////////////////////////////////////////////////////////////////// + SpinLockScope::~SpinLockScope() + { + 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/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/Kernel/SurfaceSound.cpp b/src/Kernel/SurfaceSound.cpp index 327149ef5e..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() @@ -235,10 +235,26 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_restart( UniqueId _enumerator, float _time ) { - MENGINE_UNUSED( _time ); MENGINE_UNUSED( _enumerator ); + MENGINE_UNUSED( _time ); + + if( this->isCompile() == false ) + { + LOGGER_ERROR( "surface sound '%s' not compile" + , this->getName().c_str() + ); - //ToDo + 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 ); return false; } @@ -256,14 +272,20 @@ 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 ); } ////////////////////////////////////////////////////////////////////////// void SurfaceSound::_resume( UniqueId _enumerator, float _time ) { - MENGINE_UNUSED( _time ); MENGINE_UNUSED( _enumerator ); + MENGINE_UNUSED( _time ); if( this->isCompile() == false ) { @@ -274,23 +296,40 @@ 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 ); } ////////////////////////////////////////////////////////////////////////// bool SurfaceSound::_stop( UniqueId _enumerator ) { + if( this->isCompile() == false ) + { + LOGGER_ERROR( "surface sound '%s' not compile" + , this->getName().c_str() + ); + + 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 ) { - if( SOUND_SERVICE() - ->isEmitterStop( m_soundIdentity ) == false ) - { - SOUND_SERVICE() - ->stopEmitter( m_soundIdentity ); - } + SOUND_SERVICE() + ->stopEmitter( m_soundIdentity ); } - EVENTABLE_METHOD( EVENT_ANIMATION_END ) + EVENTABLE_METHOD( EVENT_ANIMATION_STOP ) ->onAnimationStop( _enumerator ); return true; @@ -304,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 ); } @@ -433,6 +478,17 @@ namespace Mengine return nullptr; } ////////////////////////////////////////////////////////////////////////// + void SurfaceSound::onSoundPlay( const SoundIdentityInterfacePtr & _identity ) + { + MENGINE_UNUSED( _identity ); + + uint32_t id = this->getPlayId(); + float playTime = this->getPlayTime(); + + EVENTABLE_METHOD( EVENT_ANIMATION_PLAY ) + ->onAnimationPlay( id, playTime ); + } + ////////////////////////////////////////////////////////////////////////// void SurfaceSound::onSoundPause( const SoundIdentityInterfacePtr & _identity ) { MENGINE_UNUSED( _identity ); @@ -448,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/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/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/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/Kernel/ValueFollower.h b/src/Kernel/ValueFollower.h index b7f200b5de..142bf0698b 100644 --- a/src/Kernel/ValueFollower.h +++ b/src/Kernel/ValueFollower.h @@ -75,9 +75,9 @@ namespace Mengine bool update( const UpdateContext * _context, float * const _used ) { - bool successful = this->_update( _context, _used ); + bool process = this->_update( _context, _used ); - return successful; + return process; } protected: diff --git a/src/Kernel/ValueFollowerAcceleration.h b/src/Kernel/ValueFollowerAcceleration.h index c2010566df..e0e844c314 100644 --- a/src/Kernel/ValueFollowerAcceleration.h +++ b/src/Kernel/ValueFollowerAcceleration.h @@ -52,43 +52,31 @@ namespace Mengine { *_used = _context->time; + m_speed += m_acceleration * _context->time; + 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; } - m_speed += m_acceleration * _context->time; + 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 ) { - T offset = this->getDistance(); - - T add = offset * ((value_length - m_minimalDistance) / value_length); - - this->step( add ); - - 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 9993230ca7..a6e5e6f75b 100644 --- a/src/Kernel/ValueFollowerLinear.h +++ b/src/Kernel/ValueFollowerLinear.h @@ -43,39 +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 ) { - T offset = this->getDistance(); - - T add = offset * ((value_length - m_minimalDistance) / value_length); - - this->step( add ); - - 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/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/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp index ef719edc4a..c338165216 100644 --- a/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp +++ b/src/Platforms/AndroidPlatform/AndroidAnalyticsEventProvider.cpp @@ -5,9 +5,24 @@ #include "Environment/Android/AndroidFragmentHelper.h" #include "Kernel/AssertionMemoryPanic.h" +#include "Kernel/AnalyticsHelper.h" namespace Mengine { + namespace Detail + { + static const Char * getAndroidAnalyticsCategoryEnumName( EAnalyticsEventCategory _category ) + { + switch( _category ) + { + case AEEC_SYSTEM: + return "MengineAnalyticsEventCategory_System"; + default: + return "MengineAnalyticsEventCategory_Custom"; + } + } + } + ////////////////////////////////////////////////////////////////////////// AndroidAnalyticsEventProvider::AndroidAnalyticsEventProvider() { @@ -19,7 +34,7 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// void AndroidAnalyticsEventProvider::onAnalyticsEvent( const AnalyticsEventInterfacePtr & _event ) { - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); if( jenv == nullptr ) { @@ -42,48 +57,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 ); @@ -91,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" ); @@ -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..cc66718e01 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" @@ -69,6 +70,7 @@ #include #include +#include ////////////////////////////////////////////////////////////////////////// #ifndef MENGINE_SETLOCALE_ENABLE @@ -86,7 +88,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 +433,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 +581,9 @@ namespace Mengine , m_prevTime( 0.0 ) , m_pauseUpdatingTime( -1.f ) , m_active( false ) + , m_freezedTick( 0 ) + , m_freezedRender( 0 ) + , m_freezedSound( 0 ) , m_desktop( false ) , m_touchpad( false ) { @@ -576,7 +607,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 +648,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" ); @@ -702,12 +733,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() @@ -754,6 +779,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; } ////////////////////////////////////////////////////////////////////////// @@ -843,11 +870,11 @@ namespace Mengine return false; } - this->tickPlatform( 0.f, false, false, false ); + this->tickPlatform( 0.f ); NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_RUN ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -856,15 +883,12 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - void 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 ); - if( updating == true ) + if( m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { @@ -879,19 +903,25 @@ namespace Mengine APPLICATION_SERVICE() ->endUpdate(); - if( m_active == false ) + if( updating == false ) { - return; + if( m_pauseUpdatingTime < 0.f ) + { + m_pauseUpdatingTime = _frameTime; + } } - + } + ////////////////////////////////////////////////////////////////////////// + bool AndroidPlatformService::renderPlatform() + { if( m_activityState != EAS_RESUME && m_activityState != EAS_START ) { - return; + return false; } - if( _render == false ) + if( m_freezedRender != 0 ) { - return; + return false; } MENGINE_THREAD_MUTEX_SCOPE( m_nativeWindowMutex ); @@ -899,13 +929,13 @@ namespace Mengine if( m_nativeWindow == nullptr || m_eglSurface == EGL_NO_SURFACE || m_eglContext == EGL_NO_CONTEXT ) { - return; + return false; } bool sucessful = APPLICATION_SERVICE() ->render(); - if( sucessful == true && _flush == true ) + if( sucessful == true ) { APPLICATION_SERVICE() ->flush(); @@ -917,7 +947,7 @@ namespace Mengine , ::eglGetError() ); - return; + return false; } if( ::eglSwapBuffers( m_eglDisplay, m_eglSurface ) == EGL_FALSE ) @@ -926,8 +956,10 @@ namespace Mengine , ::eglGetError() ); - return; + return false; } + + return true; } ////////////////////////////////////////////////////////////////////////// void AndroidPlatformService::loopPlatform() @@ -947,7 +979,21 @@ namespace Mengine m_prevTime = currentTime; - this->tickPlatform( frameTime, true, true, true ); + if( m_active == false ) + { + usleep( 250000 ); + + continue; + } + + this->tickPlatform( frameTime ); + + if( this->renderPlatform() == false ) + { + usleep( 250000 ); + + continue; + } } } ////////////////////////////////////////////////////////////////////////// @@ -969,7 +1015,7 @@ namespace Mengine , _url ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -990,7 +1036,7 @@ namespace Mengine , _body ); - MengineJNIEnvThread * jenv = Mengine_JNI_GetEnvThread(); + JNIEnv * jenv = Mengine_JNI_GetEnv(); MENGINE_ASSERTION_MEMORY_PANIC( jenv, "invalid get jenv" ); @@ -1011,7 +1057,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 +1068,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 +1077,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 +1088,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" ); @@ -1051,16 +1097,52 @@ namespace Mengine this->pushQuitEvent_(); } ////////////////////////////////////////////////////////////////////////// - void AndroidPlatformService::setSleepMode( bool _sleepMode ) + void AndroidPlatformService::freezePlatform( bool _tick, bool _render, bool _sound ) { - MENGINE_UNUSED( _sleepMode ); + if( _tick == true ) + { + ++m_freezedTick; + } - //Empty + if( _render == true ) + { + ++m_freezedRender; + } + + if( _sound == true ) + { + ++m_freezedSound; + } + + if( m_freezedSound == 1 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), true ); + } } ////////////////////////////////////////////////////////////////////////// - bool AndroidPlatformService::getSleepMode() const + void AndroidPlatformService::unfreezePlatform( bool _tick, bool _render, bool _sound ) { - return true; + if( _tick == true ) + { + --m_freezedTick; + } + + if( _render == true ) + { + --m_freezedRender; + } + + if( _sound == true ) + { + --m_freezedSound; + } + + if( m_freezedSound == 0 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), false ); + } } ////////////////////////////////////////////////////////////////////////// Timestamp AndroidPlatformService::getPlatfomTime() const @@ -1239,7 +1321,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 +1383,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 +1392,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 +1401,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 +1482,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 +1515,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 +1530,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" ); @@ -1535,6 +1617,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 ); @@ -1681,7 +1771,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" ); @@ -2331,6 +2421,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 +2568,24 @@ namespace Mengine //ToDo } ////////////////////////////////////////////////////////////////////////// + void AndroidPlatformService::freezeEvent_( const PlatformUnionEvent::PlatformFreezeEvent & _event ) + { + bool tick = _event.tick; + bool render = _event.render; + bool sound = _event.sound; + + 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, sound ); + } + ////////////////////////////////////////////////////////////////////////// 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..9ca105ab21 100644 --- a/src/Platforms/AndroidPlatform/AndroidPlatformService.h +++ b/src/Platforms/AndroidPlatform/AndroidPlatformService.h @@ -58,12 +58,11 @@ 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 setSleepMode( bool _sleepMode ) override; - bool getSleepMode() const override; + void freezePlatform( bool _tick, bool _render, bool _sound ) override; + void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; public: Timestamp getPlatfomTime() const override; @@ -182,6 +181,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 +216,8 @@ namespace Mengine PET_START, PET_RESTART, PET_DESTROY, + PET_FREEZE, + PET_UNFREEZE, PET_SURFACE_CREATE, PET_SURFACE_DESTROY, PET_SURFACE_CHANGED, @@ -262,6 +265,20 @@ namespace Mengine int32_t dummy; }; + struct PlatformFreezeEvent + { + bool tick; + bool render; + bool sound; + }; + + struct PlatformUnfreezeEvent + { + bool tick; + bool render; + bool sound; + }; + struct PlatformSurfaceCreateEvent { ANativeWindow * nativeWindow; @@ -316,6 +333,8 @@ namespace Mengine PlatformStartEvent start; PlatformRestartEvent restart; PlatformDestroyEvent destroy; + PlatformFreezeEvent freeze; + PlatformUnfreezeEvent unfreeze; PlatformSurfaceCreateEvent surfaceCreate; PlatformSurfaceDestroyEvent surfaceDestroy; PlatformSurfaceChangedEvent surfaceChanged; @@ -334,6 +353,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 +390,7 @@ namespace Mengine EAS_PAUSE, EAS_STOP, EAS_RESTART, + EAS_FREEZE, EAS_DESTROY }; @@ -399,6 +421,10 @@ namespace Mengine float m_pauseUpdatingTime; bool m_active; + + AtomicInt32 m_freezedTick; + AtomicInt32 m_freezedRender; + AtomicInt32 m_freezedSound; bool m_desktop; bool m_touchpad; diff --git a/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp b/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp index f14f225c32..fbb4d76d38 100644 --- a/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp +++ b/src/Platforms/AndroidPlatform/AndroidProxyLogger.cpp @@ -43,13 +43,13 @@ 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" ); 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 ); diff --git a/src/Platforms/Win32Platform/Win32PlatformService.cpp b/src/Platforms/Win32Platform/Win32PlatformService.cpp index 0bf88fc8d8..345e80562d 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 @@ -100,16 +101,17 @@ namespace Mengine ////////////////////////////////////////////////////////////////////////// Win32PlatformService::Win32PlatformService() : m_beginTime( 0 ) - , m_hInstance( NULL ) , m_hWnd( NULL ) , m_xDpi( ~0U ) , m_yDpi( ~0U ) , m_performanceFrequency{0} , m_performanceSupport( false ) , m_active( false ) - , m_hIcon( NULL ) , m_close( false ) - , m_sleepMode( true ) + , m_freezedTick( 0 ) + , m_freezedRender( 0 ) + , m_freezedSound( 0 ) + , m_hIcon( NULL ) , m_windowExposed( false ) , m_pauseUpdatingTime( -1.f ) , m_prevTime( 0.0 ) @@ -141,9 +143,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 ) { @@ -340,14 +340,6 @@ namespace Mengine } #endif - uint64_t deviceSeed = Helper::generateRandomDeviceSeed(); - - MENGINE_UNUSED( deviceSeed ); - - LOGGER_INFO_PROTECTED( "platform", "device seed: %" MENGINE_PRIu64 - , deviceSeed - ); - return true; } ////////////////////////////////////////////////////////////////////////// @@ -394,21 +386,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; @@ -607,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(); @@ -640,7 +607,7 @@ namespace Mengine return false; } - this->tickPlatform( 0.f, false, false, false ); + this->tickPlatform( 0.f ); NOTIFICATION_NOTIFY( NOTIFICATOR_PLATFORM_RUN ); @@ -663,23 +630,14 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void 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; - } -#endif - bool updating = APPLICATION_SERVICE() ->beginUpdate( _frameTime ); - if( updating == true ) + if( m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { @@ -694,49 +652,41 @@ namespace Mengine APPLICATION_SERVICE() ->endUpdate(); - if( 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_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; } ////////////////////////////////////////////////////////////////////////// void Win32PlatformService::loopPlatform() @@ -760,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 ); + } } } ////////////////////////////////////////////////////////////////////////// @@ -795,9 +776,59 @@ namespace Mengine MENGINE_PROFILER_END_APPLICATION(); } ////////////////////////////////////////////////////////////////////////// + void Win32PlatformService::freezePlatform( bool _tick, bool _render, bool _sound ) + { + if( _tick == true ) + { + ++m_freezedTick; + } + + if( _render == true ) + { + ++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, bool _sound ) + { + if( _tick == true ) + { + --m_freezedTick; + } + + if( _render == true ) + { + --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 ) { - HICON hIcon = ::LoadIcon( m_hInstance, _iconResource ); + HINSTANCE hInstance = ::GetModuleHandle( NULL ); + + HICON hIcon = ::LoadIcon( hInstance, _iconResource ); if( hIcon == NULL ) { @@ -1465,6 +1496,8 @@ namespace Mengine LOGGER_MESSAGE( "quit application" ); + NOTIFICATION_NOTIFY( NOTIFICATOR_APPLICATION_WILL_TERMINATE ); + m_close = true; ::PostQuitMessage( 0 ); @@ -2165,6 +2198,8 @@ namespace Mengine return true; } + HINSTANCE hInstance = ::GetModuleHandle( NULL ); + WNDCLASSEX wc; ::ZeroMemory( &wc, sizeof( WNDCLASSEX ) ); wc.cbSize = sizeof( WNDCLASSEX ); @@ -2172,7 +2207,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 +2242,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 ) { @@ -2292,6 +2330,7 @@ namespace Mengine if( shcoreModule != NULL ) { FGetDpiForMonitor GetDpiForMonitor = (FGetDpiForMonitor)::GetProcAddress( shcoreModule, "GetDpiForMonitor" ); + if( GetDpiForMonitor != NULL ) { HMONITOR monitor = ::MonitorFromWindow( (HWND)m_hWnd, MONITOR_DEFAULTTONEAREST ); @@ -2368,6 +2407,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; @@ -2648,10 +2699,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; @@ -3474,6 +3525,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(); @@ -3522,6 +3582,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/Platforms/Win32Platform/Win32PlatformService.h b/src/Platforms/Win32Platform/Win32PlatformService.h index cebc65272e..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,8 +43,11 @@ 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; + 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; @@ -197,9 +196,7 @@ namespace Mengine protected: Timestamp m_beginTime; - StaticWString m_windowClassName; - - HINSTANCE m_hInstance; + StaticWString m_windowClassName; HWND m_hWnd; @@ -240,6 +237,10 @@ namespace Mengine bool m_active; bool m_close; + AtomicInt32 m_freezedTick; + AtomicInt32 m_freezedRender; + AtomicInt32 m_freezedSound; + bool m_sleepMode; bool m_windowExposed; diff --git a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm index 2a9e6f8fe6..6dcf28ad10 100644 --- a/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm +++ b/src/Platforms/iOSPlatform/iOSAnalyticsEventProvider.mm @@ -2,11 +2,27 @@ #import "Environment/Apple/AppleIncluder.h" #import "Environment/iOS/iOSAnalytics.h" +#import "Environment/iOS/iOSAnalyticsEventCategory.h" #include "Kernel/AssertionMemoryPanic.h" +#include "Kernel/AnalyticsHelper.h" namespace Mengine { + ////////////////////////////////////////////////////////////////////////// + namespace Detail + { + static iOSAnalyticsEventCategory getIOSAnalyticsCategory( EAnalyticsEventCategory _category ) + { + switch( _category ) + { + case AEEC_SYSTEM: + return iOSAnalyticsEventCategory_System; + default: + return iOSAnalyticsEventCategory_Custom; + } + } + } ////////////////////////////////////////////////////////////////////////// iOSAnalyticsEventProvider::iOSAnalyticsEventProvider() { @@ -21,8 +37,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 ) @@ -30,57 +44,40 @@ 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:@(_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) forKey:@(name_str)]; - }break; - case EAEPT_DOUBLE: - { - AnalyticsEventParameterDoubleInterfacePtr parameter_double = AnalyticsEventParameterDoubleInterfacePtr::from( _parameter ); - double parameter_value = parameter_double->resolveValue(); + [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) 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)]; + } ); + } ); - [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(); + EAnalyticsEventCategory eventCategory = _event->getCategory(); - [parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - }break; - } - } ); + iOSAnalyticsEventCategory iosCategory = Detail::getIOSAnalyticsCategory( eventCategory ); - [iOSAnalytics event:@(eventName_str) params:parameters]; + [iOSAnalytics event:@(eventName_str) category:iosCategory params:parameters]; } ////////////////////////////////////////////////////////////////////////// void iOSAnalyticsEventProvider::onAnalyticsScreenView( const ConstString & _screenType, const ConstString & _screenName ) diff --git a/src/Platforms/iOSPlatform/iOSPlatformService.h b/src/Platforms/iOSPlatform/iOSPlatformService.h index d25d7f5fbc..9fc3c48edf 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.h +++ b/src/Platforms/iOSPlatform/iOSPlatformService.h @@ -59,12 +59,13 @@ 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 setSleepMode( bool _sleepMode ) override; - bool getSleepMode() const override; + void freezePlatform( bool _tick, bool _render, bool _sound ) override; + void unfreezePlatform( bool _tick, bool _render, bool _sound ) override; public: Timestamp getPlatfomTime() const override; @@ -221,7 +222,10 @@ namespace Mengine float m_pauseUpdatingTime; bool m_active; - bool m_sleepMode; + + 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 dc2c75ce88..df7b7b34d6 100644 --- a/src/Platforms/iOSPlatform/iOSPlatformService.mm +++ b/src/Platforms/iOSPlatform/iOSPlatformService.mm @@ -11,8 +11,8 @@ #include "Interface/PluginServiceInterface.h" #include "Interface/DateTimeSystemInterface.h" #include "Interface/ThreadServiceInterface.h" +#include "Interface/SoundServiceInterface.h" #include "Interface/EnvironmentServiceInterface.h" -#include "Interface/iOSKernelServiceInterface.h" #include "Interface/AccountServiceInterface.h" #include "Interface/AnalyticsServiceInterface.h" @@ -20,9 +20,12 @@ #import "Environment/iOS/iOSApplication.h" #import "Environment/iOS/iOSDetail.h" #import "Environment/iOS/iOSLog.h" +#import "Environment/iOS/iOSKernelServiceInterface.h" #include "iOSAnalyticsEventProvider.h" +#include "Environment/Metal/MetalRenderSystemExtensionInterface.h" + #include "Kernel/FilePath.h" #include "Kernel/PathHelper.h" #include "Kernel/AssertionNotImplemented.h" @@ -89,7 +92,9 @@ , m_prevTime( 0.0 ) , m_pauseUpdatingTime( -1.f ) , m_active( false ) - , m_sleepMode( true ) + , m_freezedTick( 0 ) + , m_freezedRender( 0 ) + , m_freezedSound( 0 ) , m_desktop( false ) , m_touchpad( false ) , m_glContext( nullptr ) @@ -572,14 +577,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 ); @@ -776,21 +773,19 @@ 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 ); - if( updating == true ) + if( m_freezedTick == 0 && updating == true ) { if( m_pauseUpdatingTime >= 0.f ) { @@ -801,31 +796,50 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit APPLICATION_SERVICE() ->tick( _frameTime ); } + + APPLICATION_SERVICE() + ->endUpdate(); - if( 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() - ->endUpdate(); + ->flush(); + + if( m_sdlWindow == nullptr ) + { + return false; + } + + SDL_ShowWindow( m_sdlWindow ); + + return true; } ////////////////////////////////////////////////////////////////////////// void iOSPlatformService::loopPlatform() @@ -844,8 +858,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; + } } } ////////////////////////////////////////////////////////////////////////// @@ -968,14 +996,52 @@ static void SDL_LogOutputFunction( void * userdata, int category, SDL_LogPriorit this->pushQuitEvent_(); } ////////////////////////////////////////////////////////////////////////// - void iOSPlatformService::setSleepMode( bool _sleepMode ) + void iOSPlatformService::freezePlatform( bool _tick, bool _render, bool _sound ) { - m_sleepMode = _sleepMode; + if( _tick == true ) + { + ++m_freezedTick; + } + + if( _render == true ) + { + ++m_freezedRender; + } + + if( _sound == true ) + { + ++m_freezedSound; + } + + if( m_freezedSound == 1 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), true ); + } } ////////////////////////////////////////////////////////////////////////// - bool iOSPlatformService::getSleepMode() const + void iOSPlatformService::unfreezePlatform( bool _tick, bool _render, bool _sound ) { - return m_sleepMode; + if( _tick == true ) + { + --m_freezedTick; + } + + if( _render == true ) + { + --m_freezedRender; + } + + if( _sound == true ) + { + --m_freezedSound; + } + + if( m_freezedSound == 0 ) + { + SOUND_SERVICE() + ->setMute( STRINGIZE_STRING_LOCAL( "FreezePlatform" ), false ); + } } ////////////////////////////////////////////////////////////////////////// Timestamp iOSPlatformService::getPlatfomTime() const @@ -1044,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 @@ -1258,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; @@ -1360,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; @@ -1698,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" ); @@ -1826,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; @@ -1872,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/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..8b524796f8 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; @@ -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 ) { @@ -210,10 +212,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(); @@ -223,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 ); @@ -235,7 +255,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(); @@ -245,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(); @@ -262,7 +284,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..1e3f31dc58 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" ); @@ -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; } ////////////////////////////////////////////////////////////////////////// @@ -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" ); @@ -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; @@ -352,7 +354,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" ); @@ -373,14 +375,16 @@ 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; } ////////////////////////////////////////////////////////////////////////// - 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/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h new file mode 100644 index 0000000000..e0ca16f7ee --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.h @@ -0,0 +1,34 @@ +#pragma once + +#import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" +#import "Environment/iOS/iOSPluginAppTrackingTransparencyDelegateInterface.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; +@property (nonatomic, assign) BOOL m_initialized; + +@end + diff --git a/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm new file mode 100644 index 0000000000..b5f4c00131 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobApplicationDelegate.mm @@ -0,0 +1,367 @@ +#import "AppleAdMobApplicationDelegate.h" + +#import "Environment/Apple/AppleBundle.h" +#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" +#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; + self.m_initialized = NO; + } + + 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 - 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 { + if ([AppleBundle hasPluginConfig:@PLUGIN_BUNDLE_NAME] == NO) { + 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]; + NSString * versionString = [NSString stringWithFormat:@"%lu.%lu.%lu", version.majorVersion, version.minorVersion, version.patchVersion]; + + 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 ([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) { + AppleAdMobApplicationDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + return; + } + + [AppleDetail addMainQueueOperation:^{ + IOS_LOGGER_MESSAGE(@"[AdMob] plugin initialize complete"); + +#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]; + }]; + }]; +} + +#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..392ff628a7 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBannerDelegate.mm @@ -0,0 +1,194 @@ +#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; + + 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 { + 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 = adSize.size; + + 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 = [self createAdRequest]; + [self.m_bannerView loadRequest:request]; +} + +- (CGSize) getSize { + if (self.m_bannerView == nil) { + return CGSizeZero; + } + + 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..ce6554c2e3 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.h @@ -0,0 +1,41 @@ +#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; + +- (GADRequest * _Nonnull) createAdRequest; + +@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..db2b9eb619 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobBaseDelegate.mm @@ -0,0 +1,153 @@ +#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.responseIdentifier != nil) { + [params setObject:responseInfo.responseIdentifier forKey:@"responseIdentifier"]; + } + if (responseInfo.loadedAdNetworkResponseInfo != nil) { + GADAdNetworkResponseInfo * loadedInfo = responseInfo.loadedAdNetworkResponseInfo; + if (loadedInfo.adNetworkClassName != nil) { + [params setObject:loadedInfo.adNetworkClassName forKey:@"adNetworkClassName"]; + } + NSDictionary * dictionaryRepresentation = loadedInfo.dictionaryRepresentation; + if (dictionaryRepresentation != nil) { + [params setObject:dictionaryRepresentation forKey:@"dictionaryRepresentation"]; + } + } + } + + 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:^{ + [self loadAd]; + } afterSeconds:delaySec]; +} + +- (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 eventSystem:name params:total_params]; +} + +- (GADRequest *) createAdRequest { + GADRequest * request = [GADRequest request]; + request.requestAgent = @"Mengine"; + + return request; +} + +@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..dfdd8ddf4e --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobInterstitialDelegate.mm @@ -0,0 +1,206 @@ +#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 { + [self destroyInterstitialAd]; +} + +- (void) destroyInterstitialAd { + 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 { + 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 { + 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 = [self createAdRequest]; + + __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, 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; + + [self destroyInterstitialAd]; + + 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, true ); + + self.m_showing = NO; + + [self destroyInterstitialAd]; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; + + if (callback != nil) { + [callback onAppleAdvertisementShowSuccess:@"unknown"]; + } + + [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..2ce021daa3 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/AppleAdMobRewardedDelegate.mm @@ -0,0 +1,252 @@ +#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 { + [self destroyRewardedAd]; +} + +- (void) destroyRewardedAd { + 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 { + 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 { + 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 { + 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 = [self createAdRequest]; + + __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, 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 destroyRewardedAd]; + + 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, true ); + + [self destroyRewardedAd]; + + self.m_showing = NO; + + id callback = [[AppleAdMobApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; + + if (callback != nil) { + [callback onAppleAdvertisementShowSuccess:@"unknown"]; + } + + [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/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 new file mode 100644 index 0000000000..d2c0abd858 --- /dev/null +++ b/src/Plugins/AppleAdMobPlugin/CMakeLists.txt @@ -0,0 +1,54 @@ +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 +) + +if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) + ADD_FILTER( + embedding + AppleAdMobScriptEmbedding.h + AppleAdMobScriptEmbedding.mm + ) + + 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.14.0") + +ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleAdMobApplicationDelegate") + +ADD_MENGINE_SKADNETWORKITEMS_PLIST_FILE("${CMAKE_CURRENT_SOURCE_DIR}/SKAdNetworkItems.plist") + +if(MENGINE_BUILD_MENGINE_SCRIPT_EMBEDDED) + TARGET_LINK_LIBRARIES(${PROJECT_NAME} Python) +endif() + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleAdvertisementPlugin) + 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 + + + + diff --git a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm index 23a20fe087..9e5d58cdf0 100644 --- a/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm +++ b/src/Plugins/AppleAdvertisementPlugin/AppleAdvertisementApplicationDelegate.mm @@ -235,13 +235,13 @@ - (BOOL)showInterstitial:(NSString *)placement { self.m_lastShowInterstitial = [AppleDetail getTimestamp]; self.m_countShowInterstitial += 1; - + [adPoint showAd]; return YES; } -- (BOOL)hasRewarded { +- (BOOL)isShowingInterstitial { if (self.m_provider == nil) { return NO; } @@ -252,6 +252,18 @@ - (BOOL)hasRewarded { return NO; } + if ([self.m_provider isShowingInterstitial] == NO) { + return NO; + } + + return YES; +} + +- (BOOL)hasRewarded { + if (self.m_provider == nil) { + return NO; + } + if ([self.m_provider hasRewarded] == NO) { return NO; } @@ -332,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 { @@ -410,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/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/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/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/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h new file mode 100644 index 0000000000..6c1dd0c73c --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.h @@ -0,0 +1,11 @@ +#pragma once + +#import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" +#import "Environment/iOS/iOSPluginUserIdDelegateInterface.h" +#import "Environment/iOS/iOSPluginAdRevenueDelegateInterface.h" +#import "Environment/iOS/iOSPluginAnalyticDelegateInterface.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..009abf4aa0 --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/AppleAmplitudeApplicationDelegate.mm @@ -0,0 +1,161 @@ +#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 "Environment/iOS/iOSAnalyticsEventCategory.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; + } + + NSString * userId = [iOSApplication.sharedInstance getUserId]; + + [[Amplitude instance] initializeApiKey:apiKey userId:userId]; + + NSString * installId = [iOSApplication.sharedInstance getInstallId]; + + [[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]; + + [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]; +} + +#pragma mark - iOSPluginAnalyticDelegateInterface + +- (void)onAnalyticEvent:(NSString *)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary *)params { + if (category == iOSAnalyticsEventCategory_System) { + return; + } + + [[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/CMakeLists.txt b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt new file mode 100644 index 0000000000..212901d22b --- /dev/null +++ b/src/Plugins/AppleAmplitudePlugin/CMakeLists.txt @@ -0,0 +1,14 @@ +MENGINE_PROJECT(AppleAmplitudePlugin) + +ADD_FILTER( +src + 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/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinApplicationDelegate.mm index 1016b8e30a..ce590d4e5e 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 @@ -116,7 +120,7 @@ - (BOOL)loadAndShowCMPFlow:(id)provid , error.cmpMessage ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [provider onAppleAppLovinConsentFlowShowFailed]; }]; @@ -125,7 +129,7 @@ - (BOOL)loadAndShowCMPFlow:(id)provid IOS_LOGGER_MESSAGE( @"AppLovin CMP show success" ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ [provider onAppleAppLovinConsentFlowShowSuccess]; }]; }]; @@ -150,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]; @@ -207,17 +197,72 @@ - (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]; + 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 + + 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) + if ([AppleDetail hasOption:@"applovin.test_device_advertising"] == YES) { + builder.testDeviceAdvertisingIdentifiers = @[[ASIdentifierManager sharedManager].advertisingIdentifier.UUIDString]; + } +#endif }]; [[ALSdk shared] initializeWithConfiguration:initializationConfiguration completionHandler:^(ALSdkConfiguration *configuration) { @@ -255,34 +300,28 @@ - (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"]; 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; } #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]; + AppleAppLovinInterstitialDelegate * interstitialAd = [[AppleAppLovinInterstitialDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_InterstitialAdUnitId advertisement:advertisement]; self.m_interstitialAd = interstitialAd; } #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]; + AppleAppLovinRewardedDelegate * rewardedAd = [[AppleAppLovinRewardedDelegate alloc] initWithAdUnitIdentifier:MengineAppleAppLovinPlugin_RewardedAdUnitId advertisement:advertisement]; self.m_rewardedAd = rewardedAd; } @@ -379,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; @@ -435,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..85f17e0328 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; @@ -145,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/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..4c09415974 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinInterstitialDelegate.mm @@ -1,18 +1,18 @@ #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 -- (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; @@ -164,6 +172,9 @@ - (void) didDisplayAd:(MAAd *)ad { @"placement": ad.placement, @"ad": [self getMAAdParams:ad] }]; + + PLATFORM_SERVICE() + ->freezePlatform( true, true, true ); } - (void) didClickAd:(MAAd *)ad { @@ -183,6 +194,11 @@ - (void) didHideAd:(MAAd *)ad { @"ad": [self getMAAdParams:ad] }]; + PLATFORM_SERVICE() + ->unfreezePlatform( true, true, true ); + + self.m_showing = NO; + id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementInterstitialCallback]; if (callback != nil) { @@ -202,6 +218,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..98ff6efb0c 100644 --- a/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm +++ b/src/Plugins/AppleAppLovinPlugin/AppleAppLovinRewardedDelegate.mm @@ -1,17 +1,19 @@ #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 -- (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 +37,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 +127,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; @@ -185,6 +191,9 @@ - (void) didDisplayAd:(MAAd *)ad { @"placement": ad.placement, @"ad": [self getMAAdParams:ad] }]; + + PLATFORM_SERVICE() + ->freezePlatform( true, true, true ); } - (void) didClickAd:(MAAd *)ad { @@ -203,6 +212,11 @@ - (void) didHideAd:(MAAd *)ad { @"placement": ad.placement, @"ad": [self getMAAdParams:ad] }]; + + PLATFORM_SERVICE() + ->unfreezePlatform( true, true, true ); + + self.m_showing = NO; id callback = [[AppleAppLovinApplicationDelegate sharedInstance] getAdvertisementRewardedCallback]; @@ -222,6 +236,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]; diff --git a/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt b/src/Plugins/AppleAppLovinPlugin/CMakeLists.txt index 59b6d4f2ff..2f8678650c 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,33 +98,33 @@ macro(ADD_APPLOVIN_MEDIATION MEDIATION POD VERSION) endif() endmacro() -ADD_APPLOVIN_MEDIATION(ADMOB "AppLovinMediationGoogleAdapter" "12.8.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(ADMOB "AppLovinMediationGoogleAdapter" "12.11.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(GOOGLEADMANAGER "AppLovinMediationGoogleAdManagerAdapter" "12.8.0.0") +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.15.1.1") -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(UNITYADS "AppLovinMediationUnityAdsAdapter" "4.16.1.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") 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 c368f09c2b..bb3fde2a94 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_NOT_DETERMINED; + }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_NOT_DETERMINED; + }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 { @@ -29,57 +60,61 @@ + (instancetype) sharedInstance { return sharedInstance; } -- (void)makeIDFA { ++ (NSString *)makeIDFA { NSUUID * idfa_uuid = [iOSDetail getAdIdentifier]; if (idfa_uuid == nil) { - return; + return IDFA_NOT_DETERMINED; } NSString * idfa = [idfa_uuid UUIDString]; - self.m_idfa = idfa; + return idfa; } -- (void)authorization:(void (^)(EAppleAppTrackingAuthorization status, NSString *idfa))response { - if (@available(iOS 14.5, *)) { - 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; - } - - IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); - - [AppleDetail dispatchMainQueue:^{ - response( self.m_status, self.m_idfa ); - }]; - }]; +- (void)authorization { + IOS_LOGGER_MESSAGE( @"request app tracking authorization" ); + + ATTrackingManagerAuthorizationStatus currentStatus = [ATTrackingManager trackingAuthorizationStatus]; + + if (currentStatus != ATTrackingManagerAuthorizationStatusNotDetermined) { + [self updateTrackingStatus:currentStatus]; return; } - self.m_status = EAATA_AUTHORIZED; + __weak AppleAppTrackingApplicationDelegate * weakSelf = self; + + [iOSDetail addDidBecomeActiveOperationWithCompletion:^(void (^ _Nonnull completion)(void)) { + AppleAppTrackingApplicationDelegate * strongSelf = weakSelf; + + if (strongSelf == nil) { + completion(); + return; + } + + ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus]; + + if (status != ATTrackingManagerAuthorizationStatusNotDetermined) { + [strongSelf updateTrackingStatus:status]; + completion(); + return; + } + + [strongSelf requestAuthorizationWithCompletion:completion]; + }]; +} - [self makeIDFA]; +- (void)requestAuthorizationWithCompletion:(void (^ _Nonnull)(void))completion { + IOS_LOGGER_MESSAGE( @"requesting ATT authorization dialog" ); - IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", self.m_status ); + [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { + IOS_LOGGER_MESSAGE( @"app tracking authorization status: %lu", status ); - response( self.m_status, self.m_idfa ); + [self updateTrackingStatus:status]; + + completion(); + }]; } - (EAppleAppTrackingAuthorization)getAuthorizationStatus { @@ -91,30 +126,38 @@ - (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; + 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; +} + +#pragma mark - iOSPluginTransparencyConsentDelegateInterface - if ([iOSDetail isValidIDFA] == NO) { - return NO; +- (void)onTransparencyConsent:(iOSTransparencyConsentParam *)consent { + IOS_LOGGER_MESSAGE(@"UMP consent received, requesting ATT authorization"); + + ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus]; + + if (status != ATTrackingManagerAuthorizationStatusNotDetermined) { + [self updateTrackingStatus:status]; + + return; } - return YES; + [self authorization]; } #pragma mark - iOSPluginApplicationDelegateInterface 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/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/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..63fc2646e0 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 @@ -211,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; + } - self.m_enableInfoMessage = [[config objectForKey:@"datadog_info_message"] boolValue]; + NSDictionary * datadog_info_message = [config objectForKey:@"datadog_info_message"]; + + 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/AppleDatadogPlugin/CMakeLists.txt b/src/Plugins/AppleDatadogPlugin/CMakeLists.txt index d378a63203..5fa03b4f91 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.3.0") +ADD_MENGINE_COCOAPOD("DatadogLogs" "NO-GIT" "3.3.0") target_compile_options(${PROJECT_NAME} PRIVATE -fcxx-modules) 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 ad6e30d683..0000000000 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevAnalyticsEventProvider.mm +++ /dev/null @@ -1,95 +0,0 @@ -#include "AppleDevToDevAnalyticsEventProvider.h" - -#include "Kernel/Logger.h" -#include "Kernel/ConfigHelper.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(); - - EAnalyticsEventParameterType parameterType = _parameter->getType(); - - switch( parameterType ) - { - 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 addString:@(name_str) value:@(parameter_value_str)]; - }break; - } - } ); - - [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..d5cb20b821 100644 --- a/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm +++ b/src/Plugins/AppleDevToDevPlugin/AppleDevToDevApplicationDelegate.mm @@ -2,9 +2,11 @@ #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" #import @@ -18,12 +20,19 @@ - (void)sendEvent:(NSString *)eventName parameters:(NSDictionary DTDCustomEventParameters * devtodev_parameters = [[DTDCustomEventParameters alloc] init]; - for (NSString * key in parameters) - { - id value = parameters[key]; - + [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]; + } 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]; } @@ -72,4 +81,27 @@ - (void)onRemoveUserData { //Empty } +#pragma mark - iOSPluginAnalyticDelegateInterface + +- (void)onAnalyticEvent:(NSString *)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary *)params { + if (category == iOSAnalyticsEventCategory_System) { + return; + } + + [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..99e848fec0 100644 --- a/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt +++ b/src/Plugins/AppleDevToDevPlugin/CMakeLists.txt @@ -2,12 +2,6 @@ MENGINE_PROJECT(AppleDevToDevPlugin) ADD_FILTER( src - AppleDevToDevPlugin.h - AppleDevToDevPlugin.mm - - AppleDevToDevAnalyticsEventProvider.h - AppleDevToDevAnalyticsEventProvider.mm - AppleDevToDevApplicationDelegate.h AppleDevToDevApplicationDelegate.mm ) 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 72723dfb02..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 @@ -39,7 +40,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_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"]; [FIRAnalytics setUserPropertyString:intstallVersion forName:@"install_version"]; @@ -93,4 +95,26 @@ - (void)onTransparencyConsent:(iOSTransparencyConsentParam *)consent { }]; } +#pragma mark - iOSPluginAnalyticDelegateInterface + +- (void)onAnalyticEvent:(NSString *)event category:(iOSAnalyticsEventCategory)category params:(NSDictionary *)params { + if (category == iOSAnalyticsEventCategory_System) { + return; + } + + [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 d2ad3c0636..0000000000 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/AppleFirebaseAnalyticsEventProvider.mm +++ /dev/null @@ -1,124 +0,0 @@ -#include "AppleFirebaseAnalyticsEventProvider.h" - -#import "Environment/Apple/AppleString.h" - -#include "Kernel/Logger.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(); - - EAnalyticsEventParameterType parameterType = _parameter->getType(); - - switch( parameterType ) - { - 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: - { - 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(); - - [firebase_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(); - - if( parameter_value_size > 100 ) - { - return; - } - - const Char * parameter_value_str = parameter_value.c_str(); - - [firebase_parameters setValue:@(parameter_value_str) forKey:@(name_str)]; - }break; - } - } ); - - [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 a15ac30e43..b37b717e99 100644 --- a/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt +++ b/src/Plugins/AppleFirebaseAnalyticsPlugin/CMakeLists.txt @@ -2,12 +2,6 @@ MENGINE_PROJECT(AppleFirebaseAnalyticsPlugin) ADD_FILTER( src - AppleFirebaseAnalyticsPlugin.h - AppleFirebaseAnalyticsPlugin.mm - - AppleFirebaseAnalyticsEventProvider.h - AppleFirebaseAnalyticsEventProvider.mm - AppleFirebaseAnalyticsApplicationDelegate.h AppleFirebaseAnalyticsApplicationDelegate.mm ) @@ -17,6 +11,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.6.0") -TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} AppleFirebasePlugin) \ No newline at end of file diff --git a/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm b/src/Plugins/AppleFirebaseCrashlyticsPlugin/AppleFirebaseCrashlyticsANRMonitor.mm index 17102a2cd3..9a2b93582e 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" @@ -8,6 +9,7 @@ #import #import +#import #if defined(MENGINE_DEBUG) # import @@ -34,11 +36,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 +72,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,14 +87,35 @@ - (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 ) { +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; } @@ -101,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; @@ -109,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; } @@ -132,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; diff --git a/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseCrashlyticsPlugin/CMakeLists.txt index 6a9eca60ec..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" "11.15.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 1877aef422..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" "11.15.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 574f8b3d51..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" "11.15.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 30befd828c..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" "11.15.0") +ADD_MENGINE_COCOAPOD("FirebaseCore" "NO-GIT" "12.6.0") ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleFirebaseApplicationDelegate") 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 { diff --git a/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt b/src/Plugins/AppleFirebaseRemoteConfigPlugin/CMakeLists.txt index 355c87269b..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" "11.15.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 6ae1934aa4..18f115829e 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 ); }]; }]; @@ -179,7 +179,7 @@ - (BOOL)resetAchievements { IOS_LOGGER_MESSAGE( @"reset achievement success" ); }] ; - return YES; + return result; } - (BOOL)login:(void(^)(NSError *))handler { @@ -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 ); }]; }]; @@ -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,20 +291,29 @@ - (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; + } + + GKPlayer * player = [GKLocalPlayer localPlayer]; - NSArray * scores = @[scoreReporter]; - [GKScore reportScores:scores withCompletionHandler:^(NSError * error) { + [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 dispatchMainQueue:^{ + , [AppleDetail getMessageFromNSError:error]); + + [AppleDetail addMainQueueOperation:^{ handler(error); }]; @@ -316,7 +325,7 @@ - (BOOL)reportScore:(NSString *)identifier score:(int64_t)score response:(void(^ , score ); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ handler(nil); }]; }]; @@ -334,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 5453df98d0..af7b94dc18 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 ); @@ -120,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; @@ -203,8 +166,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 ); @@ -251,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; @@ -329,7 +254,7 @@ void invoke() override { PythonCallbackProviderPtr keep = PythonCallbackProviderPtr::from(this); - [AppleDetail dispatchMainQueue:^{ + [AppleDetail addMainQueueOperation:^{ keep->call_cb(); }]; } 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, 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/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h new file mode 100644 index 0000000000..13650357a0 --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.h @@ -0,0 +1,9 @@ +#import "Environment/iOS/iOSPluginApplicationDelegateInterface.h" + +@interface AppleUserMessagingPlatformApplicationDelegate : NSObject + +@property (atomic, assign) BOOL m_completed; + +@end + + diff --git a/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm new file mode 100644 index 0000000000..c37ba176e2 --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/AppleUserMessagingPlatformApplicationDelegate.mm @@ -0,0 +1,123 @@ +#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 + +- (instancetype)init { + self = [super init]; + + if (self) { + self.m_completed = NO; + } + + return self; +} + +#pragma mark - Details + +- (void)completedConsent { + self.m_completed = YES; + + iOSTransparencyConsentParam * consent = [[iOSTransparencyConsentParam alloc] initFromUserDefaults]; + + [iOSDetail transparencyConsent:consent]; +} + +#pragma mark - iOSPluginApplicationDelegateInterface + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + UMPRequestParameters * parameters = [[UMPRequestParameters alloc] init]; + 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 = @[@"DB1869F9-B9D0-4D84-B2CB-F63F249E58C9"]; + 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); + + [strongSelf completedConsent]; + + return; + } + + UMPPrivacyOptionsRequirementStatus privacyOptionsRequirementStatus = UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus; + + if (privacyOptionsRequirementStatus == UMPPrivacyOptionsRequirementStatusNotRequired) { + IOS_LOGGER_MESSAGE(@"[UMP] privacyOptionsRequirementStatus not required"); + + [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyOther]; + + [strongSelf completedConsent]; + + return; + } + + [iOSTransparencyConsentParam setConsentFlowUserGeography:iOSConsentFlowUserGeographyGDPR]; + + UMPFormStatus formStatus = UMPConsentInformation.sharedInstance.formStatus; + + if (formStatus != UMPFormStatusAvailable) { + IOS_LOGGER_MESSAGE(@"[UMP] formStatus not available: %ld", (long)formStatus); + + [strongSelf completedConsent]; + + return; + } + + [iOSDetail addDidBecomeActiveOperationWithCompletion:^(void (^ _Nonnull completion)(void)) { + AppleUserMessagingPlatformApplicationDelegate * strongSelf2 = weakSelf; + + if (strongSelf2 == nil) { + completion(); + return; + } + + 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(); + }]; + }]; + }]; + + 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 new file mode 100644 index 0000000000..5e78d64d2d --- /dev/null +++ b/src/Plugins/AppleUserMessagingPlatformPlugin/CMakeLists.txt @@ -0,0 +1,17 @@ +MENGINE_PROJECT(AppleUserMessagingPlatformPlugin) + +ADD_FILTER( +src + AppleUserMessagingPlatformInterface.h + + AppleUserMessagingPlatformApplicationDelegate.h + AppleUserMessagingPlatformApplicationDelegate.mm +) + +ADD_MENGINE_PLUGIN(MENGINE_PLUGIN_APPLE_USERMESSAGINGPLATFORM) + +ADD_MENGINE_APPLE_APPLICATION_DELEGATE("AppleUserMessagingPlatformApplicationDelegate") + +ADD_MENGINE_COCOAPOD("GoogleUserMessagingPlatform" "NO-GIT" "3.1.0") + + 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..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 @@ -16,12 +17,14 @@ + (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; + content.interruptionLevel = UNNotificationInterruptionLevelTimeSensitive; + content.relevanceScore = relevanceScore; // от 0.0 до 1.0 UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:delay repeats:NO]; @@ -53,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; @@ -81,7 +99,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/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/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/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/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/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/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/CMakeLists.txt b/src/Plugins/CMakeLists.txt index 27ee4388be..d8d676acdc 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() @@ -322,6 +326,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() @@ -330,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() 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/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/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/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp b/src/Plugins/DevelopmentConverterPlugin/HotspotImageConverterPNGToHIT.cpp index b349600c4b..eca34cff39 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,14 +175,7 @@ namespace Mengine encoder->finalize(); - if( m_options.outputContent->closeOutputStreamFile( output_stream ) == 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 db33750869..3a3e5cce9b 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,15 +164,7 @@ namespace Mengine encoder->finalize(); - if( Helper::closeOutputStreamFile( m_fileGroupDev, 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 ec30b542f5..4048680beb 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,15 +146,7 @@ namespace Mengine encoder->finalize(); - if( Helper::closeOutputStreamFile( m_fileGroupDev, 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 d1fd2d16b5..c9675c7347 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,14 +163,7 @@ namespace Mengine encoder->finalize(); - if( Helper::closeOutputStreamFile( m_fileGroupDev, 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/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/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/ImGUIPlugin/ImGUIService.cpp b/src/Plugins/ImGUIPlugin/ImGUIService.cpp index 032f060b1e..879d4901de 100644 --- a/src/Plugins/ImGUIPlugin/ImGUIService.cpp +++ b/src/Plugins/ImGUIPlugin/ImGUIService.cpp @@ -189,18 +189,28 @@ 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 + { + 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) ImGui_ImplSDL2_Shutdown(); 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) 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/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/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/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/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/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/ModuleNodeDebugger.cpp b/src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.cpp similarity index 95% rename from src/Plugins/NodeDebuggerPlugin/ModuleNodeDebugger.cpp rename to src/Plugins/NodeDebuggerPlugin/NodeDebuggerModule.cpp index 5664de14aa..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() ); @@ -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,12 +1967,16 @@ 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 ); } } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::receiveChangedNode( const pugi::xml_node & _xmlNode ) + void NodeDebuggerModule::receiveChangedNode( const pugi::xml_node & _xmlNode ) { String pathStr = _xmlNode.attribute( "path" ).value(); @@ -2301,7 +2302,7 @@ namespace Mengine } } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::receiveGameControlCommand( const String & _command ) + void NodeDebuggerModule::receiveGameControlCommand( const String & _command ) { if( _command == "pause" ) { @@ -2325,18 +2326,18 @@ 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 ); - 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 ) + void NodeDebuggerModule::receiveSetting( const Char * _setting, const Char * _key, const Char * _value ) { ConstString setting_cstr = Helper::stringizeString( _setting ); @@ -2406,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] != '-' ) { @@ -2431,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, "/" ) ); @@ -2439,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; @@ -2478,7 +2479,7 @@ namespace Mengine this->clearRequestDatas_(); } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::notifyHttpResponse( const HttpResponseInterfacePtr & _response ) + void NodeDebuggerModule::notifyHttpResponse( const HttpResponseInterfacePtr & _response ) { NodeDebuggerRequestData responseData; @@ -2493,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 ) { @@ -2501,7 +2502,7 @@ namespace Mengine }; } ////////////////////////////////////////////////////////////////////////// - void ModuleNodeDebugger::clearRequestDatas_() + void NodeDebuggerModule::clearRequestDatas_() { if( m_requestDatas.size() <= 128 ) { @@ -2511,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(); @@ -2631,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(); @@ -2687,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 @@ -2774,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 ); @@ -2793,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; 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/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/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 ) ); 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/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/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 ); 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/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/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 be1e57ba24..ead5e7a309 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,6 +21,8 @@ #include "Kernel/StringFormat.h" #include "Kernel/ConfigHelper.h" #include "Kernel/ThreadMutexHelper.h" +#include "Kernel/FactoryPool.h" +#include "Kernel/AssertionFactory.h" #include "Config/StdIO.h" #include "Config/Path.h" @@ -160,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 ); @@ -186,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_() @@ -627,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 ); @@ -699,92 +718,98 @@ 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 ) { - MemoryInputInterface * memory = _stream.getT(); + if( fi.file_size < m_mappedThreshold || fi.zip->mappedFile == nullptr ) + { + 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() - , _filePath.c_str() - , 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 + ); - 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 ) + fi.zip->mutex->lock(); + 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 { - return false; + if( fi.zip->mappedFile->openInputStream( _stream, file_offset, fi.file_size ) == false ) + { + 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 - ); + else + { + ZipMemoryInputStream * zip_memory = _stream.getT(); - MemoryInterfacePtr compress_buffer = Helper::createMemoryCacheBuffer( fi.file_size, MENGINE_DOCUMENT_FACTORABLE ); + void * buffer = zip_memory->newBuffer( fi.unz_size ); - 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 - ); + MENGINE_ASSERTION_MEMORY_PANIC( buffer, "zip '%s' file '%s' failed new memory %zu" + , fi.zip->folderPath.c_str() + , _filePath.c_str() + , fi.unz_size + ); - void * compress_memory = compress_buffer->getBuffer(); + MemoryInterfacePtr compress_buffer = Helper::createMemoryCacheBuffer( fi.file_size, MENGINE_DOCUMENT_FACTORABLE ); - 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 - ); + 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 + ); - fi.zip->mutex->lock(); - fi.zip->stream->seek( file_offset ); - fi.zip->stream->read( compress_memory, fi.file_size ); - fi.zip->mutex->unlock(); + void * compress_memory = compress_buffer->getBuffer(); - 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() + 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 ); - return false; + 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; + } + + const FilePath & relationPath = this->getRelationPath(); + + zip_memory->open( relationPath, fi.zip->folderPath, _filePath ); } } 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 ) @@ -812,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 ) @@ -841,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 @@ -877,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 18a680c58f..efc70266aa 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" @@ -46,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; @@ -64,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_(); @@ -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..21840ca5f8 --- /dev/null +++ b/src/Plugins/ZipPlugin/ZipMemoryInputStream.cpp @@ -0,0 +1,114 @@ +#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 ) + { + 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 + + return true; + } + ////////////////////////////////////////////////////////////////////////// + void ZipMemoryInputStream::close() + { + m_stream = nullptr; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif + } + ////////////////////////////////////////////////////////////////////////// + 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 ); + } + ////////////////////////////////////////////////////////////////////////// +} diff --git a/src/Plugins/ZipPlugin/ZipMemoryInputStream.h b/src/Plugins/ZipPlugin/ZipMemoryInputStream.h new file mode 100644 index 0000000000..72144c9ccb --- /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 ); + void 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; + ////////////////////////////////////////////////////////////////////////// +} diff --git a/src/Services/AccountService/Account.cpp b/src/Services/AccountService/Account.cpp index d05ee97c5b..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; @@ -146,6 +144,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 ); @@ -252,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; } @@ -309,7 +310,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() @@ -321,20 +321,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(); @@ -366,13 +352,15 @@ namespace Mengine j_root.set( "ACCOUNT", j_account ); j_root.set( "SETTINGS", j_settings ); - if( Helper::writeJSONStream( j_root, file ) == false ) - { - return false; - } + const FilePath & settingsJSONPath = m_settingsJSONContent->getFilePath(); - if( m_fileGroup->closeOutputFile( file ) == 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() + , Helper::getContentFullPath( m_settingsJSONContent ).c_str() + ); + return false; } @@ -417,6 +405,11 @@ namespace Mengine return stream; } ////////////////////////////////////////////////////////////////////////// + void Account::closeReadBinaryFile( const InputStreamInterfacePtr & _stream ) + { + m_fileGroup->closeInputFile( _stream ); + } + ////////////////////////////////////////////////////////////////////////// OutputStreamInterfacePtr Account::openWriteBinaryFile( const FilePath & _filePath ) { PathString path; @@ -440,18 +433,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 ) @@ -470,6 +454,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'" @@ -510,7 +496,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() @@ -520,11 +510,6 @@ namespace Mengine return false; } - if( m_fileGroup->closeOutputFile( stream ) == false ) - { - return false; - } - return true; } ////////////////////////////////////////////////////////////////////////// @@ -541,4 +526,4 @@ namespace Mengine return exist; } ////////////////////////////////////////////////////////////////////////// -} +} \ No newline at end of file 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 d62ecee8fb..95d465290f 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(); } ////////////////////////////////////////////////////////////////////////// @@ -170,22 +172,29 @@ 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; + return newAccount; } ////////////////////////////////////////////////////////////////////////// @@ -210,12 +219,24 @@ 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; + return newAccount; } ////////////////////////////////////////////////////////////////////////// @@ -793,14 +814,15 @@ namespace Mengine if( Helper::writeJSONStream( j_root, stream ) == false ) { - return false; - } + LOGGER_ERROR( "invalid write accounts '%s'" + , Game_AccountsPath.c_str() + ); - if( Helper::closeOutputStreamFile( m_fileGroup, stream ) == false ) - { return false; } + Helper::closeOutputStreamFile( m_fileGroup, stream ); + for( const HashtableAccounts::value_type & value : m_accounts ) { const AccountInterfacePtr & account = value.element; diff --git a/src/Services/AmplifierService/AmplifierService.cpp b/src/Services/AmplifierService/AmplifierService.cpp index f1e200c143..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,9 +69,9 @@ namespace Mengine SOUND_SERVICE() ->releaseSoundIdentity( keep_soundIdentity ); }break; - case ESS_CANCEL: + case ESS_STOP: break; - default: + case ESS_END: break; } } @@ -191,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/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/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; 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 3dba9c6cb9..809fdc3e89 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,93 @@ 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, const DocumentInterfacePtr & _doc ) + { + MENGINE_THREAD_MUTEX_SCOPE( m_debugFilePathsMutex ); + + DebugFilePath dfp; + 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 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 ) + ); + } + ////////////////////////////////////////////////////////////////////////// + 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..329e64637b 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,34 @@ 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, const DocumentInterfacePtr & _doc ) 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; + DocumentInterfacePtr doc; + }; + + typedef UnorderedMap UnorderedMapDebugFilePaths; + UnorderedMapDebugFilePaths m_debugFilePaths; +#endif }; } 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; 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/LoggerService/LoggerService.cpp b/src/Services/LoggerService/LoggerService.cpp index ac61dd850f..cb5dc57464 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 @@ -54,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 ) @@ -126,18 +118,14 @@ namespace Mengine logLevel = LM_VERBOSE; } -#if defined(MENGINE_LOGGER_LEVEL_FORCE_VERBOSE_ENABLE) - logLevel = LM_VERBOSE; -#endif - this->setVerboseLevel( logLevel ); uint32_t verboseFilter = 0xFFFFFFFF; 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 ) { @@ -170,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 @@ -180,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/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/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/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 437e1ad1d5..f52958aa38 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 ); @@ -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(); @@ -560,6 +560,10 @@ namespace Mengine if( package->enable() == false ) { + LOGGER_ERROR( "invalid enable package '%s'" + , package->getPackageDesc().name.c_str() + ); + return false; } } @@ -581,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(); @@ -602,10 +606,14 @@ namespace Mengine packages.emplace_back( package ); } - for( const PackagePtr & package : packages ) + for( const PackageInterfacePtr & package : packages ) { if( package->enable() == false ) { + LOGGER_ERROR( "invalid enable package '%s'" + , package->getPackageDesc().name.c_str() + ); + return false; } } @@ -613,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(); @@ -634,10 +642,55 @@ 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 ) { + LOGGER_ERROR( "invalid disable package '%s'" + , package->getPackageDesc().name.c_str() + ); + return false; } } @@ -645,25 +698,30 @@ 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(); - 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() @@ -672,6 +730,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..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 ); + void notifyChangeLocale_( const ConstString & _prevLocale, const ConstString & _currentlocale ); protected: - typedef Vector VectorPackages; + typedef Vector VectorPackages; VectorPackages m_packages; FactoryInterfacePtr m_factoryPackage; diff --git a/src/Services/PlayerService/PlayerService.cpp b/src/Services/PlayerService/PlayerService.cpp index 5b1efe1cb8..535f75537f 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" @@ -94,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 ); @@ -324,45 +324,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 +543,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; 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..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" @@ -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 @@ -64,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 ); @@ -342,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++; @@ -361,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 ) { @@ -405,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++; @@ -469,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(); @@ -500,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(); @@ -600,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 ) { @@ -639,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 ) { @@ -678,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; 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/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/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/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/Services/RenderService/RenderTextureService.cpp b/src/Services/RenderService/RenderTextureService.cpp index 455ca9af52..7f4c8bf7e2 100644 --- a/src/Services/RenderService/RenderTextureService.cpp +++ b/src/Services/RenderService/RenderTextureService.cpp @@ -150,12 +150,14 @@ 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() ); + _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/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 f4843a0b19..623469a9f0 100644 --- a/src/Services/SoundService/SoundService.cpp +++ b/src/Services/SoundService/SoundService.cpp @@ -249,7 +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_STOP ); continue; } @@ -265,7 +269,16 @@ namespace Mengine continue; } - this->playSoundBufferUpdate_( identity ); + if( this->playSoundBufferUpdate_( identity ) == false ) + { + LOGGER_MESSAGE( "invalid play sound buffer update identity [%u]" + , identity->getUniqueIdentity() + ); + + identity->setState( ESS_STOP ); + + continue; + } } } } @@ -278,7 +291,7 @@ namespace Mengine ESoundSourceState state = identity->getState(); - if( state == ESS_STOP ) + if( state == ESS_INIT || state == ESS_STOP || state == ESS_END ) { continue; } @@ -322,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 ) @@ -452,7 +464,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() @@ -482,16 +494,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() @@ -503,10 +515,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() @@ -518,7 +530,7 @@ namespace Mengine } SoundBufferInterfacePtr buffer = SOUND_SYSTEM() - ->createSoundBuffer( soundDecoder, _streamable, _doc ); + ->createSoundBuffer( decoder, _streamable, _doc ); if( buffer == nullptr ) { @@ -673,11 +685,23 @@ namespace Mengine { ESoundSourceState state = identity->getState(); - if( state != ESS_PLAY ) + if( state == ESS_INIT ) { continue; } + if( state == ESS_PAUSE ) + { + continue; + } + + if( state == ESS_STOP || state == ESS_END ) + { + m_soundIdentitiesEndAux.emplace_back( identity ); + + continue; + } + bool source_process = process; const MixerMultiplicativeInterfacePtr & mixerVolume = identity->getMixerVolume(); @@ -702,64 +726,24 @@ 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 ); - - const SoundSourceInterfacePtr & soundSource = identity->getSoundSource(); - - if( soundSource != nullptr ) - { - soundSource->stop(); - } - - identity->setTimeLeft( 0.f ); + identity->setState( ESS_STOP ); - m_soundIdentitiesEndAux.emplace_back( identity ); - } - else - { - if( time_new <= 0.f ) - { - identity->setTimeLeft( 0.f ); - } - else - { - identity->setTimeLeft( time_new ); - } - } + 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 +751,19 @@ namespace Mengine } } } + else + { + if( time_new <= 0.f ) + { + identity->setState( ESS_STOP ); + + m_soundIdentitiesEndAux.emplace_back( identity ); + } + else + { + identity->setTimeLeft( time_new ); + } + } } if( process == true ) @@ -776,6 +773,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 ) @@ -823,19 +831,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_CANCEL ); - - return false; - } - this->updateSourceVolume_( _identity ); const SoundSourceInterfacePtr & source = _identity->getSoundSource(); @@ -869,18 +876,26 @@ namespace Mengine return false; } - this->playSoundBufferUpdate_( _identity ); + if( this->playSoundBufferUpdate_( _identity ) == false ) + { + LOGGER_ASSERTION( "invalid play sound buffer update" ); + + _identity->setState( ESS_STOP ); + + return false; + } + } + + const SoundListenerInterfacePtr & listener = _identity->getSoundListener(); + + if( listener != nullptr ) + { + SoundListenerInterfacePtr keep_listener = listener; + keep_listener->onSoundPlay( _identity ); } }break; case ESS_PAUSE: { - if( this->checkMaxSoundPlay_() == false ) - { - _identity->setState( ESS_CANCEL ); - - return false; - } - this->updateSourceVolume_( _identity ); const SoundSourceInterfacePtr & source = _identity->getSoundSource(); @@ -902,6 +917,8 @@ namespace Mengine , _identity->getUniqueIdentity() ); + _identity->setState( ESS_STOP ); + return false; } @@ -1006,17 +1023,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(); @@ -1037,6 +1054,8 @@ namespace Mengine , _identity->getUniqueIdentity() ); + _identity->setState( ESS_STOP ); + return false; } @@ -1071,13 +1090,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(); @@ -1107,17 +1127,25 @@ 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; + case ESS_STOP: + { + //Empty + }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 @@ -1129,48 +1157,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 ); @@ -1364,7 +1350,9 @@ namespace Mengine if( source->setPosition( _position ) == false ) { - return false; + LOGGER_ASSERTION( "invalid set position identity: %u" + , _identity->getUniqueIdentity() + ); } if( hasBufferUpdate == true && playing == true && pausing == false ) @@ -1375,6 +1363,8 @@ namespace Mengine , _identity->getUniqueIdentity() ); + _identity->setState( ESS_STOP ); + return false; } } @@ -1387,16 +1377,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 ) @@ -1408,15 +1398,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 ) @@ -1444,9 +1432,14 @@ namespace Mengine { LOGGER_ERROR( "identity worker invalid add worker" ); + worker->finalize(); + + _identity->setWorkerUpdateBuffer( nullptr ); + return false; } + _identity->setWorkerUpdateBuffer( worker ); _identity->setWorkerId( workerId ); } else @@ -1458,16 +1451,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 ) @@ -1476,20 +1469,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 ) @@ -1498,8 +1489,6 @@ namespace Mengine m_threadJobSoundBufferUpdate->resumeWorker( workerId ); } - - return true; } ////////////////////////////////////////////////////////////////////////// bool SoundService::checkMaxSoundPlay_() const @@ -1513,12 +1502,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) +#if defined(MENGINE_LOGGER_INFO) + Timestamp timestamp = Helper::getSystemTimestamp(); + for( const SoundIdentityInterfacePtr & identity : m_soundIdentities ) { ss << "\n" @@ -1526,11 +1515,13 @@ 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() ) << ")"; } #endif + LOGGER_ASSERTION( "%s", ss.str().c_str() ); return false; diff --git a/src/Services/SoundService/SoundService.h b/src/Services/SoundService/SoundService.h index c493c0a5d8..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; @@ -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; @@ -110,7 +105,7 @@ namespace Mengine bool getMute( const ConstString & _type ) const override; bool mixMute() const override; - public: + protected: void updateVolume() override; protected: @@ -127,9 +122,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; 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/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 efc28991b6..41a1460e8b 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 + { + ////////////////////////////////////////////////////////////////////////// + static 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; } @@ -185,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; @@ -198,13 +212,8 @@ 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 ) - { - continue; - } - uint32_t updation_deep = updation->getUpdationDeep(); if( updation_deep != _deep ) 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 ); }; diff --git a/src/Services/UserdataService/UserdataService.cpp b/src/Services/UserdataService/UserdataService.cpp index e717b518a8..6a616009b2 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; } ////////////////////////////////////////////////////////////////////////// @@ -173,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..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" @@ -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 84a510879f..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" @@ -40,12 +41,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; @@ -58,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 ) { @@ -102,6 +97,10 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -135,30 +134,27 @@ 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 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) 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,7 +165,9 @@ namespace Mengine m_asset = nullptr; - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// 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 e0f9bca767..99abbd8d8f 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 ); @@ -30,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 1a57d73d4b..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 { @@ -40,12 +41,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; @@ -55,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 ) { @@ -88,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 @@ -102,6 +117,10 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// @@ -135,28 +154,25 @@ 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 return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileInputStream::close() + void AndroidFileInputStream::close() { if( m_file == 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 ); } @@ -165,7 +181,11 @@ namespace Mengine ::fclose( m_file ); m_file = nullptr; - return true; + m_size = 0; + +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// size_t AndroidFileInputStream::read( void * const _buf, size_t _count ) @@ -255,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; @@ -300,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 ) { @@ -317,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; @@ -361,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; @@ -378,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 ) @@ -394,4 +444,4 @@ namespace Mengine return m_file; } ////////////////////////////////////////////////////////////////////////// -} +} \ No newline at end of file diff --git a/src/Systems/AndroidFileSystem/AndroidFileInputStream.h b/src/Systems/AndroidFileSystem/AndroidFileInputStream.h index 1f87f505c0..ba094a9f26 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 ); @@ -31,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 2f6fa85cca..235209e61e 100644 --- a/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidFileOutputStream.cpp @@ -1,12 +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" @@ -16,6 +20,7 @@ namespace Mengine AndroidFileOutputStream::AndroidFileOutputStream() : m_file( nullptr ) , m_size( 0 ) + , m_withTemp( false ) { } ////////////////////////////////////////////////////////////////////////// @@ -26,25 +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 ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif + 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" ); @@ -65,32 +83,35 @@ 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, m_relationPath, m_folderPath, m_filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// - bool AndroidFileOutputStream::close() + void AndroidFileOutputStream::close() { MENGINE_THREAD_GUARD_SCOPE( AndroidFileOutputStream, this ); if( m_file == nullptr ) { - return false; + 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 = 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 @@ -99,7 +120,27 @@ namespace Mengine m_size = 0; - return true; + 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 } ////////////////////////////////////////////////////////////////////////// size_t AndroidFileOutputStream::write( const void * _data, size_t _size ) @@ -108,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 853ecf2a4f..c9f8be3f3a 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 ); @@ -27,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; @@ -41,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 dc276a8427..234f48d764 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexAssetInputStream.cpp @@ -2,10 +2,13 @@ #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" +#include "Kernel/DebugFileHelper.h" +#include "Kernel/DocumentHelper.h" #include "stdex/memorycopy.h" @@ -42,15 +45,9 @@ 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 ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { @@ -81,15 +78,21 @@ namespace Mengine 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 AndroidMutexAssetInputStream::close() + void AndroidMutexAssetInputStream::close() { m_stream = nullptr; m_mutex = nullptr; - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// 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 2f216e8b64..bcc72cdb9c 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 ); @@ -33,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 2e0d3089a0..ffd5802662 100644 --- a/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp +++ b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.cpp @@ -4,6 +4,8 @@ #include "Kernel/Logger.h" #include "Kernel/ThreadMutexScope.h" +#include "Kernel/DebugFileHelper.h" +#include "Kernel/DocumentHelper.h" #include "stdex/memorycopy.h" @@ -40,15 +42,9 @@ 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 ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { @@ -79,15 +75,21 @@ namespace Mengine 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 AndroidMutexFileInputStream::close() + void AndroidMutexFileInputStream::close() { m_stream = nullptr; m_mutex = nullptr; - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// size_t AndroidMutexFileInputStream::read( void * const _buf, size_t _count ) @@ -177,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/AndroidFileSystem/AndroidMutexFileInputStream.h b/src/Systems/AndroidFileSystem/AndroidMutexFileInputStream.h index eab7cca234..4799b3bc61 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 ); @@ -33,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/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; 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 6085099bea..e1bd64c9df 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 ); @@ -30,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..125e7f2243 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; @@ -73,7 +67,7 @@ size_t size = attribute_filesize.unsignedLongLongValue; - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > (size_t)size ) { @@ -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 ) @@ -261,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 ) @@ -396,9 +396,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 899c16efe5..afb4eb3412 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 ); @@ -28,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..9ed572806f 100644 --- a/src/Systems/AppleFileSystem/AppleFileOutputStream.mm +++ b/src/Systems/AppleFileSystem/AppleFileOutputStream.mm @@ -1,12 +1,14 @@ #include "AppleFileOutputStream.h" #include "Interface/PlatformServiceInterface.h" +#include "Interface/FileSystemInterface.h" #import "Environment/Apple/AppleDetail.h" #include "Kernel/Logger.h" #include "Kernel/PathHelper.h" #include "Kernel/FilePathHelper.h" +#include "Kernel/DebugFileHelper.h" #include "Config/Path.h" @@ -35,7 +37,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 +61,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,23 +83,52 @@ 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; } ////////////////////////////////////////////////////////////////////////// - bool AppleFileOutputStream::close() + void AppleFileOutputStream::close() { if( m_fileHandle == nullptr ) { 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" )}, fullPathTemp ); - return true; + 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.h b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.h index f9f31aeb58..8ca1a1a71f 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 ); @@ -29,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..0906acb5a1 100644 --- a/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm +++ b/src/Systems/AppleFileSystem/AppleMutexFileInputStream.mm @@ -43,18 +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 ); -#if defined(MENGINE_DEBUG) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - size_t size = m_stream->size(); - if( _size != ~0U ) + if( _size != MENGINE_UNKNOWN_SIZE ) { if( _offset + _size > size ) { @@ -84,16 +81,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 ) @@ -168,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 ) @@ -301,9 +306,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 ) 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) 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; 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..8aa7939c59 --- /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(); + + 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..b5c3619b18 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderImage.mm @@ -0,0 +1,166 @@ +#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 ); + + 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; + } + ////////////////////////////////////////////////////////////////////////// + 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..9e44a20573 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.h @@ -0,0 +1,55 @@ +#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; + MTLIndexType getIndexType() 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; + MTLIndexType m_indexType; + 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..6004ca41f8 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderIndexBuffer.mm @@ -0,0 +1,130 @@ +#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_indexType( MTLIndexTypeUInt16 ) + , m_indexCount( 0 ) + , m_lockOffset( 0 ) + { + } + ////////////////////////////////////////////////////////////////////////// + MetalRenderIndexBuffer::~MetalRenderIndexBuffer() = default; + ////////////////////////////////////////////////////////////////////////// + bool MetalRenderIndexBuffer::initialize( uint32_t _indexSize, EBufferType _bufferType ) + { + 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" ); + + 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 ) + { + 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(); + + return true; + } + ////////////////////////////////////////////////////////////////////////// + MetalBufferId MetalRenderIndexBuffer::getBuffer() const + { + 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 ) + { + LOGGER_ASSERTION( "offset %u count %u more max size %u", _offset, _count, m_indexCount ); + + return false; + } + + if( m_buffer == nil ) + { + return false; + } + + void * bufferContents = [m_buffer contents]; + memcpy( ((uint8_t *)bufferContents) + _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..7377d0caac --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Interface/RenderMaterialInterface.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/Kernel/FutexScope.cpp b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm similarity index 58% rename from src/Kernel/FutexScope.cpp rename to src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm index 2c905d5405..05e446be8d 100644 --- a/src/Kernel/FutexScope.cpp +++ b/src/Systems/MetalRenderSystem/MetalRenderMaterialStageCache.mm @@ -1,17 +1,13 @@ -#include "FutexScope.h" +#include "MetalRenderMaterialStageCache.h" namespace Mengine { ////////////////////////////////////////////////////////////////////////// - FutexScope::FutexScope( Futex & _futex ) - : m_futex( _futex ) + MetalRenderMaterialStageCache::MetalRenderMaterialStageCache() { - m_futex.lock(); } ////////////////////////////////////////////////////////////////////////// - FutexScope::~FutexScope() - { - m_futex.unlock(); - } + MetalRenderMaterialStageCache::~MetalRenderMaterialStageCache() = default; ////////////////////////////////////////////////////////////////////////// -} \ No newline at end of file +} + 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..1323b4b0f5 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.h @@ -0,0 +1,179 @@ +#pragma once + +#include "Interface/RenderSystemInterface.h" +#include "Kernel/ServiceBase.h" + +#import +#import + +#include "Environment/Metal/MetalRenderSystemExtensionInterface.h" + +namespace Mengine +{ + class MetalRenderSystem + : public ServiceBase + , public MetalRenderSystemExtensionInterface + { + 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..3f1743a909 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderSystem.mm @@ -0,0 +1,677 @@ +#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() + { + 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; + } + ////////////////////////////////////////////////////////////////////////// + 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 ) + { + if( m_metalLayer == nil ) + { + m_metalLayer = [CAMetalLayer layer]; + + if( m_metalLayer == nil ) + { + LOGGER_ERROR( "MetalRenderSystem: failed to create CAMetalLayer" ); + + 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(); + + m_metalLayer.drawableSize = CGSizeMake( drawableWidth, drawableHeight ); + m_vsync = _windowDesc->waitForVSync; + } + + return m_metalLayer != nil; + } + ////////////////////////////////////////////////////////////////////////// + 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 ) + { + 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(); + 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]; + + [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(); + + 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( texture, hwWidth, hwHeight, hwPixelFormat ) == 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; + 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]; + + [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..5e237344fe --- /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; + + public: + 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..1ede3162d4 --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexBuffer.mm @@ -0,0 +1,123 @@ +#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 ) + { + 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(); + + 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; + } + + void * bufferContents = [m_buffer contents]; + memcpy( ((uint8_t *)bufferContents) + _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..ab08956fad --- /dev/null +++ b/src/Systems/MetalRenderSystem/MetalRenderVertexShader.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Interface/RenderVertexShaderInterface.h" +#include "Interface/MemoryInterface.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; + } + ////////////////////////////////////////////////////////////////////////// +} + 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 1c424392f0..d6c4713e2c 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; @@ -251,7 +255,7 @@ namespace Mengine return true; } ////////////////////////////////////////////////////////////////////////// - bool OpenALSoundBufferStream::resumeSource( ALuint _sourceId ) + void OpenALSoundBufferStream::stopSource( ALuint _sourceId ) { MENGINE_UNUSED( _sourceId ); @@ -259,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 ) @@ -272,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 ); @@ -283,7 +304,11 @@ namespace Mengine , _sourceId ); - this->setUpdating_( false ); + this->setUpdating_( true ); + + MENGINE_OPENAL_CALL( alSourcePlay, (_sourceId) ); + + return true; } ////////////////////////////////////////////////////////////////////////// void OpenALSoundBufferStream::setUpdating_( bool _updating ) @@ -377,10 +402,6 @@ namespace Mengine switch( state ) { - case AL_INITIAL: - { - //Empty - }break; case AL_PLAYING: { //Empty @@ -389,6 +410,7 @@ namespace Mengine { //Empty }break; + case AL_INITIAL: case AL_STOPPED: { if( m_looped == false ) @@ -422,7 +444,7 @@ namespace Mengine 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 ) { @@ -441,7 +463,8 @@ namespace Mengine bytesWritten += bytesWritten2; } - else if( bytesWritten == 0 ) + + 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) ); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.cpp index 61f0da0c6a..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 ); @@ -203,7 +196,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 +217,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..4fae32052e 100644 --- a/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h +++ b/src/Systems/OpenALSoundSystem/OpenALSoundSystem.h @@ -35,12 +35,9 @@ 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 _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/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; } 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..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; } ////////////////////////////////////////////////////////////////////////// @@ -143,17 +144,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 ); @@ -208,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; }; 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/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.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/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/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; diff --git a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp index 3c7103d462..82d90d5ce0 100644 --- a/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp +++ b/src/Systems/Win32FileSystem/Win32FileGroupDirectory.cpp @@ -234,19 +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(); - - MENGINE_ASSERTION( result == true, "failed close file '%s'" - , 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 ) @@ -293,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 ) @@ -335,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 @@ -399,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 9296378d5f..4a5a6ba562 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) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_streaming = _streaming; m_share = _share; @@ -124,21 +118,25 @@ namespace Mengine } } +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::addDebugFilePath( this, _relationPath, _folderPath, _filePath, MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileInputStream::close() + void Win32FileInputStream::close() { if( m_hFile == INVALID_HANDLE_VALUE ) { - 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 ); } @@ -155,7 +153,9 @@ namespace Mengine ); } - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// bool Win32FileInputStream::openFile_( const FilePath & _relationPath, const FilePath & _folderPath, const FilePath & _filePath, WChar * const _fullPath ) @@ -200,10 +200,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 8a84112216..119fc65384 100644 --- a/src/Systems/Win32FileSystem/Win32FileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileInputStream.h @@ -7,10 +7,6 @@ #include "Kernel/Factorable.h" #include "Kernel/ThreadGuardScope.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - #ifndef MENGINE_WIN32_FILE_STREAM_BUFFER_SIZE #define MENGINE_WIN32_FILE_STREAM_BUFFER_SIZE 4096 #endif @@ -21,9 +17,6 @@ namespace Mengine class Win32FileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( Win32FileInputStream ); @@ -33,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 0d94e32b53..efa28099c0 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,10 +104,14 @@ 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; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileMapped::close() + void Win32FileMapped::close() { if( m_hMapping != INVALID_HANDLE_VALUE ) { @@ -124,7 +129,9 @@ namespace Mengine m_factoryFileMappedInputStream = nullptr; - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// 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 fee8c5e2de..bd7597a516 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) - this->setDebugRelationPath( _relationPath ); - this->setDebugFolderPath( _folderPath ); - this->setDebugFilePath( _filePath ); -#endif - m_relationPath = _relationPath; m_folderPath = _folderPath; m_filePath = _filePath; @@ -96,34 +91,37 @@ 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, MENGINE_DOCUMENT_FACTORABLE ); +#endif + return true; } ////////////////////////////////////////////////////////////////////////// - bool Win32FileOutputStream::close() + void Win32FileOutputStream::close() { if( m_hFile == INVALID_HANDLE_VALUE ) { - return true; + return; } #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 - bool successful = this->flush(); + MENGINE_ASSERTION_FATAL( m_size != 0, "file '%s:%s' is empty" + , m_folderPath.c_str() + , m_filePath.c_str() + ); + + this->flush(); ::CloseHandle( m_hFile ); m_hFile = INVALID_HANDLE_VALUE; @@ -159,12 +157,12 @@ namespace Mengine , fullPathTemp , fullPath ); - - return false; } } - return successful; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// 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 94e78304ca..08a6c50520 100644 --- a/src/Systems/Win32FileSystem/Win32FileOutputStream.h +++ b/src/Systems/Win32FileSystem/Win32FileOutputStream.h @@ -6,18 +6,11 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { class Win32FileOutputStream : public FileOutputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( Win32FileOutputStream ); @@ -27,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 4e0c33ee20..6cf8ec1230 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,19 +53,15 @@ 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 != MENGINE_UNKNOWN_SIZE ) { 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 @@ -89,15 +86,21 @@ namespace Mengine 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 Win32MutexFileInputStream::close() + void Win32MutexFileInputStream::close() { m_stream = nullptr; m_mutex = nullptr; - return true; +#if defined(MENGINE_DEBUG_FILE_PATH_ENABLE) + Helper::removeDebugFilePath( this ); +#endif } ////////////////////////////////////////////////////////////////////////// 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 4e5de62643..8688b1be34 100644 --- a/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h +++ b/src/Systems/Win32FileSystem/Win32MutexFileInputStream.h @@ -7,19 +7,12 @@ #include "Kernel/Factorable.h" -#if defined(MENGINE_DEBUG) -# include "Kernel/BaseDebugFile.h" -#endif - namespace Mengine { ////////////////////////////////////////////////////////////////////////// class Win32MutexFileInputStream : public FileInputStreamInterface , public Factorable -#if defined(MENGINE_DEBUG) - , public BaseDebugFile -#endif { DECLARE_FACTORABLE( Win32MutexFileInputStream ); @@ -33,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/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 " ); 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; }; ////////////////////////////////////////////////////////////////////////// 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 ) { 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; }