From 67b707d4a10cc6a46cdfc0219f04080e2a931f90 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Mon, 13 Jan 2025 15:15:09 +0100 Subject: [PATCH 1/3] fix: Move `ExtendableHybridClass` to it's own file with explanation --- .../com/margelo/nitro/core/HybridObject.kt | 4 --- .../nitro/utils/ExtendableHybridClass.kt | 29 +++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/utils/ExtendableHybridClass.kt diff --git a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt index 82998989a..a90518660 100644 --- a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +++ b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt @@ -4,10 +4,6 @@ import androidx.annotation.Keep import com.facebook.jni.HybridData import com.facebook.proguard.annotations.DoNotStrip -interface ExtendableHybridClass { - fun updateNative(hybridData: HybridData) -} - /** * A base class for all Kotlin-based HybridObjects. */ diff --git a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/utils/ExtendableHybridClass.kt b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/utils/ExtendableHybridClass.kt new file mode 100644 index 000000000..1529558ea --- /dev/null +++ b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/utils/ExtendableHybridClass.kt @@ -0,0 +1,29 @@ +package com.margelo.nitro.core + +import com.facebook.jni.HybridData + +/** + * Represents an fbjni Hybrid Class (aka a Java class with an accompanying C++ class) + * that supports inheritance. + * + * Each fbjni Hybrid Class initializes it's `mHybridData` using an `initHybrid()` method, + * which initializes the respective C++ class this was bound to. + + * Assuming we have Java class `B` which extends Java class `A`, and a C++ + * inheritance chain that reflects the Java inheritance chain (C++ class `B` which extends C++ class `A`), + * we would have two `initHybrid()` methods - one for `A` and one for `B`. + * - When you initialize an instance of `A`, it will initialize `A`'s C++ part. + * - When you initialize an instance of `B`, it will initialize `B`'s C++ part, as well as `A`'s C++ part, since + * the native `A.initHybrid()` method cannot be overridden in `B` - both have their own `initHybrid()` methods! + * + * To fix this issue, we have `ExtendableHybridClass`. In an extendable HybridClass, we initialize `mHybridData`, + * but we pass it upwards the inheritance chain after initializing self using `updateNative(mHybridData)`. + * This way the actual `mHybridData` instance is the lowest class in the chain - `B`. + */ +interface ExtendableHybridClass { + /** + * Update the `hybridData` (C++ part) this Hybrid Class is referencing. + * Call this with `hybridData` from a subclass to properly fill in the inheritance chain. + */ + fun updateNative(hybridData: HybridData) +} From 9b10dcfb09e4d90bb330eedeba441536a0a4f90c Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Mon, 13 Jan 2025 15:54:12 +0100 Subject: [PATCH 2/3] feat: Make `initHybrid()` static --- .../src/syntax/kotlin/FbjniHybridObject.ts | 32 ++++++++++++++----- .../src/syntax/kotlin/KotlinHybridObject.ts | 28 ++++++++-------- .../generated/android/c++/JHybridBaseSpec.cpp | 18 +++++++++-- .../generated/android/c++/JHybridBaseSpec.hpp | 12 ++++--- .../android/c++/JHybridChildSpec.cpp | 19 +++++++++-- .../android/c++/JHybridChildSpec.hpp | 13 ++++---- .../android/c++/JHybridImageFactorySpec.cpp | 18 +++++++++-- .../android/c++/JHybridImageFactorySpec.hpp | 12 ++++--- .../android/c++/JHybridImageSpec.cpp | 18 +++++++++-- .../android/c++/JHybridImageSpec.hpp | 12 ++++--- .../c++/JHybridTestObjectSwiftKotlinSpec.cpp | 18 +++++++++-- .../c++/JHybridTestObjectSwiftKotlinSpec.hpp | 12 ++++--- .../com/margelo/nitro/image/HybridBaseSpec.kt | 28 ++++++++-------- .../margelo/nitro/image/HybridChildSpec.kt | 28 ++++++++-------- .../nitro/image/HybridImageFactorySpec.kt | 28 ++++++++-------- .../margelo/nitro/image/HybridImageSpec.kt | 28 ++++++++-------- .../image/HybridTestObjectSwiftKotlinSpec.kt | 28 ++++++++-------- .../com/margelo/nitro/core/HybridObject.kt | 19 ++++------- 18 files changed, 225 insertions(+), 146 deletions(-) diff --git a/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts b/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts index 6e0a40a0d..6140b1d10 100644 --- a/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts +++ b/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts @@ -51,7 +51,7 @@ export function createFbjniHybridObject(spec: HybridObjectSpec): SourceFile[] { const cppConstructorCalls = [`HybridObject(${name.HybridTSpec}::TAG)`] for (const base of spec.baseTypes) { const { JHybridTSpec } = getHybridObjectName(base.name) - cppConstructorCalls.push('HybridBase(jThis)') + cppConstructorCalls.push('HybridBase(javaPart)') cppImports.push({ language: 'c++', name: `${JHybridTSpec}.hpp`, @@ -87,17 +87,19 @@ namespace ${cxxNamespace} { ${spaces} public virtual ${name.HybridTSpec} { public: static auto constexpr kJavaDescriptor = "L${jniClassDescriptor};"; - static jni::local_ref initHybrid(jni::alias_ref jThis); + static jni::local_ref initHybrid(jni::alias_ref javaPart); static void registerNatives(); protected: // C++ constructor (called from Java via \`initHybrid()\`) - explicit ${name.JHybridTSpec}(jni::alias_ref jThis) : - ${indent(cppConstructorCalls.join(',\n'), ' ')}, - _javaPart(jni::make_global(jThis)) {} + explicit ${name.JHybridTSpec}(jni::alias_ref javaPart); public: - virtual ~${name.JHybridTSpec}() { + // ${name.JHybridTSpec} cannot be default-constructed from C++. + ${name.JHybridTSpec}() = delete; + + public: + ~${name.JHybridTSpec}() override { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } @@ -168,8 +170,22 @@ ${cppIncludes.join('\n')} namespace ${cxxNamespace} { - jni::local_ref<${name.JHybridTSpec}::jhybriddata> ${name.JHybridTSpec}::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); + ${name.JHybridTSpec}::${name.JHybridTSpec}(jni::alias_ref javaPart): + ${indent(cppConstructorCalls.join(',\n'), ' ')}, + _javaPart(jni::make_global(javaPart)) { +#ifdef NITRO_DEBUG + if (javaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of \`${name.JHybridTSpec}\` from Java, " + "but \`javaPart\` was null!"); + } else if (!javaPart->isInstanceOf(${name.JHybridTSpec}::javaClassStatic())) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of \`${name.JHybridTSpec}\` from Java, " + "but \`javaPart\` is not an instance of \`${name.HybridTSpec}\`!"); + } +#endif + } + + jni::local_ref<${name.JHybridTSpec}::jhybriddata> ${name.JHybridTSpec}::initHybrid(jni::alias_ref javaPart) { + return makeCxxInstance(javaPart); } void ${name.JHybridTSpec}::registerNatives() { diff --git a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts index e082f7eed..2e67f835f 100644 --- a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts +++ b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts @@ -56,22 +56,19 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class ${name.HybridTSpec}: ${kotlinBase}() { - @DoNotStrip - private var mHybridData: HybridData = initHybrid() - - init { - // Pass this \`HybridData\` through to it's base class, - // to represent inheritance to JHybridObject on C++ side - super.updateNative(mHybridData) - } +abstract class ${name.HybridTSpec}: ${kotlinBase} { + /** + * Default-initialize this \`${name.HybridTSpec}\`. + * Use this constructor if \`${name.HybridTSpec}\` has no child-classes. + */ + constructor(): super(initHybrid()) { } /** - * Call from a child class to initialize HybridData with a child. + * Initialize this \`${name.HybridTSpec}\` from a child-class + * with a custom \`HybridData\` being passed upwards. + * Use this constructor if \`${name.HybridTSpec}\` is being initialized from a child-class. */ - override fun updateNative(hybridData: HybridData) { - mHybridData = hybridData - } + protected constructor(hybridData: HybridData): super(hybridData) { } // Properties ${indent(properties, ' ')} @@ -79,10 +76,11 @@ abstract class ${name.HybridTSpec}: ${kotlinBase}() { // Methods ${indent(methods, ' ')} - private external fun initHybrid(): HybridData - companion object { private const val TAG = "${name.HybridTSpec}" + @JvmStatic + private external fun initHybrid(): HybridData + init { try { Log.i(TAG, "Loading ${cppLibName} C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp index c75ea3fdf..8dda0a890 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp @@ -13,8 +13,22 @@ namespace margelo::nitro::image { - jni::local_ref JHybridBaseSpec::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); + JHybridBaseSpec::JHybridBaseSpec(jni::alias_ref javaPart): + HybridObject(HybridBaseSpec::TAG), + _javaPart(jni::make_global(javaPart)) { +#ifdef NITRO_DEBUG + if (javaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridBaseSpec` from Java, " + "but `javaPart` was null!"); + } else if (!javaPart->isInstanceOf(JHybridBaseSpec::javaClassStatic())) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridBaseSpec` from Java, " + "but `javaPart` is not an instance of `HybridBaseSpec`!"); + } +#endif + } + + jni::local_ref JHybridBaseSpec::initHybrid(jni::alias_ref javaPart) { + return makeCxxInstance(javaPart); } void JHybridBaseSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp index efd6246cd..d6b8d92c8 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp @@ -22,17 +22,19 @@ namespace margelo::nitro::image { public virtual HybridBaseSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridBaseSpec;"; - static jni::local_ref initHybrid(jni::alias_ref jThis); + static jni::local_ref initHybrid(jni::alias_ref javaPart); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridBaseSpec(jni::alias_ref jThis) : - HybridObject(HybridBaseSpec::TAG), - _javaPart(jni::make_global(jThis)) {} + explicit JHybridBaseSpec(jni::alias_ref javaPart); public: - virtual ~JHybridBaseSpec() { + // JHybridBaseSpec cannot be default-constructed from C++. + JHybridBaseSpec() = delete; + + public: + ~JHybridBaseSpec() override { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp index c8eba2ea4..f66b378f7 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp @@ -13,8 +13,23 @@ namespace margelo::nitro::image { - jni::local_ref JHybridChildSpec::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); + JHybridChildSpec::JHybridChildSpec(jni::alias_ref javaPart): + HybridObject(HybridChildSpec::TAG), + HybridBase(javaPart), + _javaPart(jni::make_global(javaPart)) { +#ifdef NITRO_DEBUG + if (javaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridChildSpec` from Java, " + "but `javaPart` was null!"); + } else if (!javaPart->isInstanceOf(JHybridChildSpec::javaClassStatic())) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridChildSpec` from Java, " + "but `javaPart` is not an instance of `HybridChildSpec`!"); + } +#endif + } + + jni::local_ref JHybridChildSpec::initHybrid(jni::alias_ref javaPart) { + return makeCxxInstance(javaPart); } void JHybridChildSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp index de565a74e..ade5d85f1 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp @@ -23,18 +23,19 @@ namespace margelo::nitro::image { public virtual HybridChildSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridChildSpec;"; - static jni::local_ref initHybrid(jni::alias_ref jThis); + static jni::local_ref initHybrid(jni::alias_ref javaPart); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridChildSpec(jni::alias_ref jThis) : - HybridObject(HybridChildSpec::TAG), - HybridBase(jThis), - _javaPart(jni::make_global(jThis)) {} + explicit JHybridChildSpec(jni::alias_ref javaPart); public: - virtual ~JHybridChildSpec() { + // JHybridChildSpec cannot be default-constructed from C++. + JHybridChildSpec() = delete; + + public: + ~JHybridChildSpec() override { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp index 24eb6d62c..bfb1a8143 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp @@ -18,8 +18,22 @@ namespace margelo::nitro::image { class HybridImageSpec; } namespace margelo::nitro::image { - jni::local_ref JHybridImageFactorySpec::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); + JHybridImageFactorySpec::JHybridImageFactorySpec(jni::alias_ref javaPart): + HybridObject(HybridImageFactorySpec::TAG), + _javaPart(jni::make_global(javaPart)) { +#ifdef NITRO_DEBUG + if (javaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageFactorySpec` from Java, " + "but `javaPart` was null!"); + } else if (!javaPart->isInstanceOf(JHybridImageFactorySpec::javaClassStatic())) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageFactorySpec` from Java, " + "but `javaPart` is not an instance of `HybridImageFactorySpec`!"); + } +#endif + } + + jni::local_ref JHybridImageFactorySpec::initHybrid(jni::alias_ref javaPart) { + return makeCxxInstance(javaPart); } void JHybridImageFactorySpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp index 2e6f00a32..acc8369d3 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp @@ -22,17 +22,19 @@ namespace margelo::nitro::image { public virtual HybridImageFactorySpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridImageFactorySpec;"; - static jni::local_ref initHybrid(jni::alias_ref jThis); + static jni::local_ref initHybrid(jni::alias_ref javaPart); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridImageFactorySpec(jni::alias_ref jThis) : - HybridObject(HybridImageFactorySpec::TAG), - _javaPart(jni::make_global(jThis)) {} + explicit JHybridImageFactorySpec(jni::alias_ref javaPart); public: - virtual ~JHybridImageFactorySpec() { + // JHybridImageFactorySpec cannot be default-constructed from C++. + JHybridImageFactorySpec() = delete; + + public: + ~JHybridImageFactorySpec() override { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp index 72d8827f4..00291309e 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp @@ -26,8 +26,22 @@ namespace margelo::nitro::image { enum class ImageFormat; } namespace margelo::nitro::image { - jni::local_ref JHybridImageSpec::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); + JHybridImageSpec::JHybridImageSpec(jni::alias_ref javaPart): + HybridObject(HybridImageSpec::TAG), + _javaPart(jni::make_global(javaPart)) { +#ifdef NITRO_DEBUG + if (javaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageSpec` from Java, " + "but `javaPart` was null!"); + } else if (!javaPart->isInstanceOf(JHybridImageSpec::javaClassStatic())) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageSpec` from Java, " + "but `javaPart` is not an instance of `HybridImageSpec`!"); + } +#endif + } + + jni::local_ref JHybridImageSpec::initHybrid(jni::alias_ref javaPart) { + return makeCxxInstance(javaPart); } void JHybridImageSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp index 8a3242baf..99f0ef24a 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp @@ -22,17 +22,19 @@ namespace margelo::nitro::image { public virtual HybridImageSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridImageSpec;"; - static jni::local_ref initHybrid(jni::alias_ref jThis); + static jni::local_ref initHybrid(jni::alias_ref javaPart); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridImageSpec(jni::alias_ref jThis) : - HybridObject(HybridImageSpec::TAG), - _javaPart(jni::make_global(jThis)) {} + explicit JHybridImageSpec(jni::alias_ref javaPart); public: - virtual ~JHybridImageSpec() { + // JHybridImageSpec cannot be default-constructed from C++. + JHybridImageSpec() = delete; + + public: + ~JHybridImageSpec() override { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp index 89b325faa..9d8928c3b 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp @@ -72,8 +72,22 @@ namespace margelo::nitro::image { struct JsStyleStruct; } namespace margelo::nitro::image { - jni::local_ref JHybridTestObjectSwiftKotlinSpec::initHybrid(jni::alias_ref jThis) { - return makeCxxInstance(jThis); + JHybridTestObjectSwiftKotlinSpec::JHybridTestObjectSwiftKotlinSpec(jni::alias_ref javaPart): + HybridObject(HybridTestObjectSwiftKotlinSpec::TAG), + _javaPart(jni::make_global(javaPart)) { +#ifdef NITRO_DEBUG + if (javaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridTestObjectSwiftKotlinSpec` from Java, " + "but `javaPart` was null!"); + } else if (!javaPart->isInstanceOf(JHybridTestObjectSwiftKotlinSpec::javaClassStatic())) [[unlikely]] { + throw std::runtime_error("Tried initializing a new C++ instance of `JHybridTestObjectSwiftKotlinSpec` from Java, " + "but `javaPart` is not an instance of `HybridTestObjectSwiftKotlinSpec`!"); + } +#endif + } + + jni::local_ref JHybridTestObjectSwiftKotlinSpec::initHybrid(jni::alias_ref javaPart) { + return makeCxxInstance(javaPart); } void JHybridTestObjectSwiftKotlinSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp index 161a15dff..07c630ee4 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp @@ -22,17 +22,19 @@ namespace margelo::nitro::image { public virtual HybridTestObjectSwiftKotlinSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec;"; - static jni::local_ref initHybrid(jni::alias_ref jThis); + static jni::local_ref initHybrid(jni::alias_ref javaPart); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridTestObjectSwiftKotlinSpec(jni::alias_ref jThis) : - HybridObject(HybridTestObjectSwiftKotlinSpec::TAG), - _javaPart(jni::make_global(jThis)) {} + explicit JHybridTestObjectSwiftKotlinSpec(jni::alias_ref javaPart); public: - virtual ~JHybridTestObjectSwiftKotlinSpec() { + // JHybridTestObjectSwiftKotlinSpec cannot be default-constructed from C++. + JHybridTestObjectSwiftKotlinSpec() = delete; + + public: + ~JHybridTestObjectSwiftKotlinSpec() override { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt index 15cf9bd72..2b20ba1f9 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt @@ -24,22 +24,19 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridBaseSpec: HybridObject() { - @DoNotStrip - private var mHybridData: HybridData = initHybrid() - - init { - // Pass this `HybridData` through to it's base class, - // to represent inheritance to JHybridObject on C++ side - super.updateNative(mHybridData) - } +abstract class HybridBaseSpec: HybridObject { + /** + * Default-initialize this `HybridBaseSpec`. + * Use this constructor if `HybridBaseSpec` has no child-classes. + */ + constructor(): super(initHybrid()) { } /** - * Call from a child class to initialize HybridData with a child. + * Initialize this `HybridBaseSpec` from a child-class + * with a custom `HybridData` being passed upwards. + * Use this constructor if `HybridBaseSpec` is being initialized from a child-class. */ - override fun updateNative(hybridData: HybridData) { - mHybridData = hybridData - } + protected constructor(hybridData: HybridData): super(hybridData) { } // Properties @get:DoNotStrip @@ -49,10 +46,11 @@ abstract class HybridBaseSpec: HybridObject() { // Methods - private external fun initHybrid(): HybridData - companion object { private const val TAG = "HybridBaseSpec" + @JvmStatic + private external fun initHybrid(): HybridData + init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt index ee68eeac3..c186c249a 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt @@ -24,22 +24,19 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridChildSpec: HybridBaseSpec() { - @DoNotStrip - private var mHybridData: HybridData = initHybrid() - - init { - // Pass this `HybridData` through to it's base class, - // to represent inheritance to JHybridObject on C++ side - super.updateNative(mHybridData) - } +abstract class HybridChildSpec: HybridBaseSpec { + /** + * Default-initialize this `HybridChildSpec`. + * Use this constructor if `HybridChildSpec` has no child-classes. + */ + constructor(): super(initHybrid()) { } /** - * Call from a child class to initialize HybridData with a child. + * Initialize this `HybridChildSpec` from a child-class + * with a custom `HybridData` being passed upwards. + * Use this constructor if `HybridChildSpec` is being initialized from a child-class. */ - override fun updateNative(hybridData: HybridData) { - mHybridData = hybridData - } + protected constructor(hybridData: HybridData): super(hybridData) { } // Properties @get:DoNotStrip @@ -49,10 +46,11 @@ abstract class HybridChildSpec: HybridBaseSpec() { // Methods - private external fun initHybrid(): HybridData - companion object { private const val TAG = "HybridChildSpec" + @JvmStatic + private external fun initHybrid(): HybridData + init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt index 89135dae1..403c49ff3 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt @@ -24,22 +24,19 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridImageFactorySpec: HybridObject() { - @DoNotStrip - private var mHybridData: HybridData = initHybrid() - - init { - // Pass this `HybridData` through to it's base class, - // to represent inheritance to JHybridObject on C++ side - super.updateNative(mHybridData) - } +abstract class HybridImageFactorySpec: HybridObject { + /** + * Default-initialize this `HybridImageFactorySpec`. + * Use this constructor if `HybridImageFactorySpec` has no child-classes. + */ + constructor(): super(initHybrid()) { } /** - * Call from a child class to initialize HybridData with a child. + * Initialize this `HybridImageFactorySpec` from a child-class + * with a custom `HybridData` being passed upwards. + * Use this constructor if `HybridImageFactorySpec` is being initialized from a child-class. */ - override fun updateNative(hybridData: HybridData) { - mHybridData = hybridData - } + protected constructor(hybridData: HybridData): super(hybridData) { } // Properties @@ -61,10 +58,11 @@ abstract class HybridImageFactorySpec: HybridObject() { @Keep abstract fun bounceBack(image: HybridImageSpec): HybridImageSpec - private external fun initHybrid(): HybridData - companion object { private const val TAG = "HybridImageFactorySpec" + @JvmStatic + private external fun initHybrid(): HybridData + init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt index f4b7013e9..9e751b5ea 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt @@ -24,22 +24,19 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridImageSpec: HybridObject() { - @DoNotStrip - private var mHybridData: HybridData = initHybrid() - - init { - // Pass this `HybridData` through to it's base class, - // to represent inheritance to JHybridObject on C++ side - super.updateNative(mHybridData) - } +abstract class HybridImageSpec: HybridObject { + /** + * Default-initialize this `HybridImageSpec`. + * Use this constructor if `HybridImageSpec` has no child-classes. + */ + constructor(): super(initHybrid()) { } /** - * Call from a child class to initialize HybridData with a child. + * Initialize this `HybridImageSpec` from a child-class + * with a custom `HybridData` being passed upwards. + * Use this constructor if `HybridImageSpec` is being initialized from a child-class. */ - override fun updateNative(hybridData: HybridData) { - mHybridData = hybridData - } + protected constructor(hybridData: HybridData): super(hybridData) { } // Properties @get:DoNotStrip @@ -70,10 +67,11 @@ abstract class HybridImageSpec: HybridObject() { return __result } - private external fun initHybrid(): HybridData - companion object { private const val TAG = "HybridImageSpec" + @JvmStatic + private external fun initHybrid(): HybridData + init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt index 8f1bd0b40..75cbecd96 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt @@ -24,22 +24,19 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { - @DoNotStrip - private var mHybridData: HybridData = initHybrid() - - init { - // Pass this `HybridData` through to it's base class, - // to represent inheritance to JHybridObject on C++ side - super.updateNative(mHybridData) - } +abstract class HybridTestObjectSwiftKotlinSpec: HybridObject { + /** + * Default-initialize this `HybridTestObjectSwiftKotlinSpec`. + * Use this constructor if `HybridTestObjectSwiftKotlinSpec` has no child-classes. + */ + constructor(): super(initHybrid()) { } /** - * Call from a child class to initialize HybridData with a child. + * Initialize this `HybridTestObjectSwiftKotlinSpec` from a child-class + * with a custom `HybridData` being passed upwards. + * Use this constructor if `HybridTestObjectSwiftKotlinSpec` is being initialized from a child-class. */ - override fun updateNative(hybridData: HybridData) { - mHybridData = hybridData - } + protected constructor(hybridData: HybridData): super(hybridData) { } // Properties @get:DoNotStrip @@ -384,10 +381,11 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { @Keep abstract fun castBase(base: HybridBaseSpec): HybridChildSpec - private external fun initHybrid(): HybridData - companion object { private const val TAG = "HybridTestObjectSwiftKotlinSpec" + @JvmStatic + private external fun initHybrid(): HybridData + init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt index a90518660..4214e0e52 100644 --- a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +++ b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt @@ -9,7 +9,7 @@ import com.facebook.proguard.annotations.DoNotStrip */ @Keep @DoNotStrip -abstract class HybridObject: ExtendableHybridClass { +open class HybridObject: ExtendableHybridClass { /** * Get the memory size of the Kotlin instance (plus any external heap allocations), * in bytes. @@ -31,18 +31,13 @@ abstract class HybridObject: ExtendableHybridClass { open val memorySize: Long get() = 0L - /** - * Holds the native C++ instance. - * In `HybridObject`, the C++ instance is a sub-class of `JHybridObject`, such as one of it's specs. - * This is `null`, until `updateNative(..)` is called. - */ - private var mHybridData: HybridData? = null + protected open var mHybridData: HybridData - /** - * Must be called in the constructor of a subclass of `HybridObject`, to initialize the C++ - * `JHybridObject` with a subclass of it. - */ - override fun updateNative(hybridData: HybridData) { + protected constructor(hybridData: HybridData) { mHybridData = hybridData } + + override fun updateNative(hybridData: HybridData) { + + } } From fef6b00eca8dd6bc76bdc8c3cb0b6a95c9748cee Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Mon, 13 Jan 2025 15:59:29 +0100 Subject: [PATCH 3/3] Revert "feat: Make `initHybrid()` static" This reverts commit 9b10dcfb09e4d90bb330eedeba441536a0a4f90c. --- .../src/syntax/kotlin/FbjniHybridObject.ts | 32 +++++-------------- .../src/syntax/kotlin/KotlinHybridObject.ts | 28 ++++++++-------- .../generated/android/c++/JHybridBaseSpec.cpp | 18 ++--------- .../generated/android/c++/JHybridBaseSpec.hpp | 12 +++---- .../android/c++/JHybridChildSpec.cpp | 19 ++--------- .../android/c++/JHybridChildSpec.hpp | 13 ++++---- .../android/c++/JHybridImageFactorySpec.cpp | 18 ++--------- .../android/c++/JHybridImageFactorySpec.hpp | 12 +++---- .../android/c++/JHybridImageSpec.cpp | 18 ++--------- .../android/c++/JHybridImageSpec.hpp | 12 +++---- .../c++/JHybridTestObjectSwiftKotlinSpec.cpp | 18 ++--------- .../c++/JHybridTestObjectSwiftKotlinSpec.hpp | 12 +++---- .../com/margelo/nitro/image/HybridBaseSpec.kt | 28 ++++++++-------- .../margelo/nitro/image/HybridChildSpec.kt | 28 ++++++++-------- .../nitro/image/HybridImageFactorySpec.kt | 28 ++++++++-------- .../margelo/nitro/image/HybridImageSpec.kt | 28 ++++++++-------- .../image/HybridTestObjectSwiftKotlinSpec.kt | 28 ++++++++-------- .../com/margelo/nitro/core/HybridObject.kt | 19 +++++++---- 18 files changed, 146 insertions(+), 225 deletions(-) diff --git a/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts b/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts index 6140b1d10..6e0a40a0d 100644 --- a/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts +++ b/packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts @@ -51,7 +51,7 @@ export function createFbjniHybridObject(spec: HybridObjectSpec): SourceFile[] { const cppConstructorCalls = [`HybridObject(${name.HybridTSpec}::TAG)`] for (const base of spec.baseTypes) { const { JHybridTSpec } = getHybridObjectName(base.name) - cppConstructorCalls.push('HybridBase(javaPart)') + cppConstructorCalls.push('HybridBase(jThis)') cppImports.push({ language: 'c++', name: `${JHybridTSpec}.hpp`, @@ -87,19 +87,17 @@ namespace ${cxxNamespace} { ${spaces} public virtual ${name.HybridTSpec} { public: static auto constexpr kJavaDescriptor = "L${jniClassDescriptor};"; - static jni::local_ref initHybrid(jni::alias_ref javaPart); + static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); protected: // C++ constructor (called from Java via \`initHybrid()\`) - explicit ${name.JHybridTSpec}(jni::alias_ref javaPart); + explicit ${name.JHybridTSpec}(jni::alias_ref jThis) : + ${indent(cppConstructorCalls.join(',\n'), ' ')}, + _javaPart(jni::make_global(jThis)) {} public: - // ${name.JHybridTSpec} cannot be default-constructed from C++. - ${name.JHybridTSpec}() = delete; - - public: - ~${name.JHybridTSpec}() override { + virtual ~${name.JHybridTSpec}() { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } @@ -170,22 +168,8 @@ ${cppIncludes.join('\n')} namespace ${cxxNamespace} { - ${name.JHybridTSpec}::${name.JHybridTSpec}(jni::alias_ref javaPart): - ${indent(cppConstructorCalls.join(',\n'), ' ')}, - _javaPart(jni::make_global(javaPart)) { -#ifdef NITRO_DEBUG - if (javaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of \`${name.JHybridTSpec}\` from Java, " - "but \`javaPart\` was null!"); - } else if (!javaPart->isInstanceOf(${name.JHybridTSpec}::javaClassStatic())) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of \`${name.JHybridTSpec}\` from Java, " - "but \`javaPart\` is not an instance of \`${name.HybridTSpec}\`!"); - } -#endif - } - - jni::local_ref<${name.JHybridTSpec}::jhybriddata> ${name.JHybridTSpec}::initHybrid(jni::alias_ref javaPart) { - return makeCxxInstance(javaPart); + jni::local_ref<${name.JHybridTSpec}::jhybriddata> ${name.JHybridTSpec}::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); } void ${name.JHybridTSpec}::registerNatives() { diff --git a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts index 2e67f835f..e082f7eed 100644 --- a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts +++ b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts @@ -56,19 +56,22 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class ${name.HybridTSpec}: ${kotlinBase} { - /** - * Default-initialize this \`${name.HybridTSpec}\`. - * Use this constructor if \`${name.HybridTSpec}\` has no child-classes. - */ - constructor(): super(initHybrid()) { } +abstract class ${name.HybridTSpec}: ${kotlinBase}() { + @DoNotStrip + private var mHybridData: HybridData = initHybrid() + + init { + // Pass this \`HybridData\` through to it's base class, + // to represent inheritance to JHybridObject on C++ side + super.updateNative(mHybridData) + } /** - * Initialize this \`${name.HybridTSpec}\` from a child-class - * with a custom \`HybridData\` being passed upwards. - * Use this constructor if \`${name.HybridTSpec}\` is being initialized from a child-class. + * Call from a child class to initialize HybridData with a child. */ - protected constructor(hybridData: HybridData): super(hybridData) { } + override fun updateNative(hybridData: HybridData) { + mHybridData = hybridData + } // Properties ${indent(properties, ' ')} @@ -76,11 +79,10 @@ abstract class ${name.HybridTSpec}: ${kotlinBase} { // Methods ${indent(methods, ' ')} + private external fun initHybrid(): HybridData + companion object { private const val TAG = "${name.HybridTSpec}" - @JvmStatic - private external fun initHybrid(): HybridData - init { try { Log.i(TAG, "Loading ${cppLibName} C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp index 8dda0a890..c75ea3fdf 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.cpp @@ -13,22 +13,8 @@ namespace margelo::nitro::image { - JHybridBaseSpec::JHybridBaseSpec(jni::alias_ref javaPart): - HybridObject(HybridBaseSpec::TAG), - _javaPart(jni::make_global(javaPart)) { -#ifdef NITRO_DEBUG - if (javaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridBaseSpec` from Java, " - "but `javaPart` was null!"); - } else if (!javaPart->isInstanceOf(JHybridBaseSpec::javaClassStatic())) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridBaseSpec` from Java, " - "but `javaPart` is not an instance of `HybridBaseSpec`!"); - } -#endif - } - - jni::local_ref JHybridBaseSpec::initHybrid(jni::alias_ref javaPart) { - return makeCxxInstance(javaPart); + jni::local_ref JHybridBaseSpec::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); } void JHybridBaseSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp index d6b8d92c8..efd6246cd 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridBaseSpec.hpp @@ -22,19 +22,17 @@ namespace margelo::nitro::image { public virtual HybridBaseSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridBaseSpec;"; - static jni::local_ref initHybrid(jni::alias_ref javaPart); + static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridBaseSpec(jni::alias_ref javaPart); + explicit JHybridBaseSpec(jni::alias_ref jThis) : + HybridObject(HybridBaseSpec::TAG), + _javaPart(jni::make_global(jThis)) {} public: - // JHybridBaseSpec cannot be default-constructed from C++. - JHybridBaseSpec() = delete; - - public: - ~JHybridBaseSpec() override { + virtual ~JHybridBaseSpec() { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp index f66b378f7..c8eba2ea4 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.cpp @@ -13,23 +13,8 @@ namespace margelo::nitro::image { - JHybridChildSpec::JHybridChildSpec(jni::alias_ref javaPart): - HybridObject(HybridChildSpec::TAG), - HybridBase(javaPart), - _javaPart(jni::make_global(javaPart)) { -#ifdef NITRO_DEBUG - if (javaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridChildSpec` from Java, " - "but `javaPart` was null!"); - } else if (!javaPart->isInstanceOf(JHybridChildSpec::javaClassStatic())) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridChildSpec` from Java, " - "but `javaPart` is not an instance of `HybridChildSpec`!"); - } -#endif - } - - jni::local_ref JHybridChildSpec::initHybrid(jni::alias_ref javaPart) { - return makeCxxInstance(javaPart); + jni::local_ref JHybridChildSpec::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); } void JHybridChildSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp index ade5d85f1..de565a74e 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridChildSpec.hpp @@ -23,19 +23,18 @@ namespace margelo::nitro::image { public virtual HybridChildSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridChildSpec;"; - static jni::local_ref initHybrid(jni::alias_ref javaPart); + static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridChildSpec(jni::alias_ref javaPart); + explicit JHybridChildSpec(jni::alias_ref jThis) : + HybridObject(HybridChildSpec::TAG), + HybridBase(jThis), + _javaPart(jni::make_global(jThis)) {} public: - // JHybridChildSpec cannot be default-constructed from C++. - JHybridChildSpec() = delete; - - public: - ~JHybridChildSpec() override { + virtual ~JHybridChildSpec() { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp index bfb1a8143..24eb6d62c 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.cpp @@ -18,22 +18,8 @@ namespace margelo::nitro::image { class HybridImageSpec; } namespace margelo::nitro::image { - JHybridImageFactorySpec::JHybridImageFactorySpec(jni::alias_ref javaPart): - HybridObject(HybridImageFactorySpec::TAG), - _javaPart(jni::make_global(javaPart)) { -#ifdef NITRO_DEBUG - if (javaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageFactorySpec` from Java, " - "but `javaPart` was null!"); - } else if (!javaPart->isInstanceOf(JHybridImageFactorySpec::javaClassStatic())) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageFactorySpec` from Java, " - "but `javaPart` is not an instance of `HybridImageFactorySpec`!"); - } -#endif - } - - jni::local_ref JHybridImageFactorySpec::initHybrid(jni::alias_ref javaPart) { - return makeCxxInstance(javaPart); + jni::local_ref JHybridImageFactorySpec::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); } void JHybridImageFactorySpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp index acc8369d3..2e6f00a32 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageFactorySpec.hpp @@ -22,19 +22,17 @@ namespace margelo::nitro::image { public virtual HybridImageFactorySpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridImageFactorySpec;"; - static jni::local_ref initHybrid(jni::alias_ref javaPart); + static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridImageFactorySpec(jni::alias_ref javaPart); + explicit JHybridImageFactorySpec(jni::alias_ref jThis) : + HybridObject(HybridImageFactorySpec::TAG), + _javaPart(jni::make_global(jThis)) {} public: - // JHybridImageFactorySpec cannot be default-constructed from C++. - JHybridImageFactorySpec() = delete; - - public: - ~JHybridImageFactorySpec() override { + virtual ~JHybridImageFactorySpec() { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp index 00291309e..72d8827f4 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.cpp @@ -26,22 +26,8 @@ namespace margelo::nitro::image { enum class ImageFormat; } namespace margelo::nitro::image { - JHybridImageSpec::JHybridImageSpec(jni::alias_ref javaPart): - HybridObject(HybridImageSpec::TAG), - _javaPart(jni::make_global(javaPart)) { -#ifdef NITRO_DEBUG - if (javaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageSpec` from Java, " - "but `javaPart` was null!"); - } else if (!javaPart->isInstanceOf(JHybridImageSpec::javaClassStatic())) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridImageSpec` from Java, " - "but `javaPart` is not an instance of `HybridImageSpec`!"); - } -#endif - } - - jni::local_ref JHybridImageSpec::initHybrid(jni::alias_ref javaPart) { - return makeCxxInstance(javaPart); + jni::local_ref JHybridImageSpec::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); } void JHybridImageSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp index 99f0ef24a..8a3242baf 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridImageSpec.hpp @@ -22,19 +22,17 @@ namespace margelo::nitro::image { public virtual HybridImageSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridImageSpec;"; - static jni::local_ref initHybrid(jni::alias_ref javaPart); + static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridImageSpec(jni::alias_ref javaPart); + explicit JHybridImageSpec(jni::alias_ref jThis) : + HybridObject(HybridImageSpec::TAG), + _javaPart(jni::make_global(jThis)) {} public: - // JHybridImageSpec cannot be default-constructed from C++. - JHybridImageSpec() = delete; - - public: - ~JHybridImageSpec() override { + virtual ~JHybridImageSpec() { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp index 9d8928c3b..89b325faa 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.cpp @@ -72,22 +72,8 @@ namespace margelo::nitro::image { struct JsStyleStruct; } namespace margelo::nitro::image { - JHybridTestObjectSwiftKotlinSpec::JHybridTestObjectSwiftKotlinSpec(jni::alias_ref javaPart): - HybridObject(HybridTestObjectSwiftKotlinSpec::TAG), - _javaPart(jni::make_global(javaPart)) { -#ifdef NITRO_DEBUG - if (javaPart == nullptr) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridTestObjectSwiftKotlinSpec` from Java, " - "but `javaPart` was null!"); - } else if (!javaPart->isInstanceOf(JHybridTestObjectSwiftKotlinSpec::javaClassStatic())) [[unlikely]] { - throw std::runtime_error("Tried initializing a new C++ instance of `JHybridTestObjectSwiftKotlinSpec` from Java, " - "but `javaPart` is not an instance of `HybridTestObjectSwiftKotlinSpec`!"); - } -#endif - } - - jni::local_ref JHybridTestObjectSwiftKotlinSpec::initHybrid(jni::alias_ref javaPart) { - return makeCxxInstance(javaPart); + jni::local_ref JHybridTestObjectSwiftKotlinSpec::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); } void JHybridTestObjectSwiftKotlinSpec::registerNatives() { diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp index 07c630ee4..161a15dff 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/android/c++/JHybridTestObjectSwiftKotlinSpec.hpp @@ -22,19 +22,17 @@ namespace margelo::nitro::image { public virtual HybridTestObjectSwiftKotlinSpec { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec;"; - static jni::local_ref initHybrid(jni::alias_ref javaPart); + static jni::local_ref initHybrid(jni::alias_ref jThis); static void registerNatives(); protected: // C++ constructor (called from Java via `initHybrid()`) - explicit JHybridTestObjectSwiftKotlinSpec(jni::alias_ref javaPart); + explicit JHybridTestObjectSwiftKotlinSpec(jni::alias_ref jThis) : + HybridObject(HybridTestObjectSwiftKotlinSpec::TAG), + _javaPart(jni::make_global(jThis)) {} public: - // JHybridTestObjectSwiftKotlinSpec cannot be default-constructed from C++. - JHybridTestObjectSwiftKotlinSpec() = delete; - - public: - ~JHybridTestObjectSwiftKotlinSpec() override { + virtual ~JHybridTestObjectSwiftKotlinSpec() { // Hermes GC can destroy JS objects on a non-JNI Thread. jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); } diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt index 2b20ba1f9..15cf9bd72 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridBaseSpec.kt @@ -24,19 +24,22 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridBaseSpec: HybridObject { - /** - * Default-initialize this `HybridBaseSpec`. - * Use this constructor if `HybridBaseSpec` has no child-classes. - */ - constructor(): super(initHybrid()) { } +abstract class HybridBaseSpec: HybridObject() { + @DoNotStrip + private var mHybridData: HybridData = initHybrid() + + init { + // Pass this `HybridData` through to it's base class, + // to represent inheritance to JHybridObject on C++ side + super.updateNative(mHybridData) + } /** - * Initialize this `HybridBaseSpec` from a child-class - * with a custom `HybridData` being passed upwards. - * Use this constructor if `HybridBaseSpec` is being initialized from a child-class. + * Call from a child class to initialize HybridData with a child. */ - protected constructor(hybridData: HybridData): super(hybridData) { } + override fun updateNative(hybridData: HybridData) { + mHybridData = hybridData + } // Properties @get:DoNotStrip @@ -46,11 +49,10 @@ abstract class HybridBaseSpec: HybridObject { // Methods + private external fun initHybrid(): HybridData + companion object { private const val TAG = "HybridBaseSpec" - @JvmStatic - private external fun initHybrid(): HybridData - init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt index c186c249a..ee68eeac3 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridChildSpec.kt @@ -24,19 +24,22 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridChildSpec: HybridBaseSpec { - /** - * Default-initialize this `HybridChildSpec`. - * Use this constructor if `HybridChildSpec` has no child-classes. - */ - constructor(): super(initHybrid()) { } +abstract class HybridChildSpec: HybridBaseSpec() { + @DoNotStrip + private var mHybridData: HybridData = initHybrid() + + init { + // Pass this `HybridData` through to it's base class, + // to represent inheritance to JHybridObject on C++ side + super.updateNative(mHybridData) + } /** - * Initialize this `HybridChildSpec` from a child-class - * with a custom `HybridData` being passed upwards. - * Use this constructor if `HybridChildSpec` is being initialized from a child-class. + * Call from a child class to initialize HybridData with a child. */ - protected constructor(hybridData: HybridData): super(hybridData) { } + override fun updateNative(hybridData: HybridData) { + mHybridData = hybridData + } // Properties @get:DoNotStrip @@ -46,11 +49,10 @@ abstract class HybridChildSpec: HybridBaseSpec { // Methods + private external fun initHybrid(): HybridData + companion object { private const val TAG = "HybridChildSpec" - @JvmStatic - private external fun initHybrid(): HybridData - init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt index 403c49ff3..89135dae1 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageFactorySpec.kt @@ -24,19 +24,22 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridImageFactorySpec: HybridObject { - /** - * Default-initialize this `HybridImageFactorySpec`. - * Use this constructor if `HybridImageFactorySpec` has no child-classes. - */ - constructor(): super(initHybrid()) { } +abstract class HybridImageFactorySpec: HybridObject() { + @DoNotStrip + private var mHybridData: HybridData = initHybrid() + + init { + // Pass this `HybridData` through to it's base class, + // to represent inheritance to JHybridObject on C++ side + super.updateNative(mHybridData) + } /** - * Initialize this `HybridImageFactorySpec` from a child-class - * with a custom `HybridData` being passed upwards. - * Use this constructor if `HybridImageFactorySpec` is being initialized from a child-class. + * Call from a child class to initialize HybridData with a child. */ - protected constructor(hybridData: HybridData): super(hybridData) { } + override fun updateNative(hybridData: HybridData) { + mHybridData = hybridData + } // Properties @@ -58,11 +61,10 @@ abstract class HybridImageFactorySpec: HybridObject { @Keep abstract fun bounceBack(image: HybridImageSpec): HybridImageSpec + private external fun initHybrid(): HybridData + companion object { private const val TAG = "HybridImageFactorySpec" - @JvmStatic - private external fun initHybrid(): HybridData - init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt index 9e751b5ea..f4b7013e9 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridImageSpec.kt @@ -24,19 +24,22 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridImageSpec: HybridObject { - /** - * Default-initialize this `HybridImageSpec`. - * Use this constructor if `HybridImageSpec` has no child-classes. - */ - constructor(): super(initHybrid()) { } +abstract class HybridImageSpec: HybridObject() { + @DoNotStrip + private var mHybridData: HybridData = initHybrid() + + init { + // Pass this `HybridData` through to it's base class, + // to represent inheritance to JHybridObject on C++ side + super.updateNative(mHybridData) + } /** - * Initialize this `HybridImageSpec` from a child-class - * with a custom `HybridData` being passed upwards. - * Use this constructor if `HybridImageSpec` is being initialized from a child-class. + * Call from a child class to initialize HybridData with a child. */ - protected constructor(hybridData: HybridData): super(hybridData) { } + override fun updateNative(hybridData: HybridData) { + mHybridData = hybridData + } // Properties @get:DoNotStrip @@ -67,11 +70,10 @@ abstract class HybridImageSpec: HybridObject { return __result } + private external fun initHybrid(): HybridData + companion object { private const val TAG = "HybridImageSpec" - @JvmStatic - private external fun initHybrid(): HybridData - init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt index 75cbecd96..8f1bd0b40 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt +++ b/packages/react-native-nitro-image/nitrogen/generated/android/kotlin/com/margelo/nitro/image/HybridTestObjectSwiftKotlinSpec.kt @@ -24,19 +24,22 @@ import com.margelo.nitro.core.* "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" ) -abstract class HybridTestObjectSwiftKotlinSpec: HybridObject { - /** - * Default-initialize this `HybridTestObjectSwiftKotlinSpec`. - * Use this constructor if `HybridTestObjectSwiftKotlinSpec` has no child-classes. - */ - constructor(): super(initHybrid()) { } +abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { + @DoNotStrip + private var mHybridData: HybridData = initHybrid() + + init { + // Pass this `HybridData` through to it's base class, + // to represent inheritance to JHybridObject on C++ side + super.updateNative(mHybridData) + } /** - * Initialize this `HybridTestObjectSwiftKotlinSpec` from a child-class - * with a custom `HybridData` being passed upwards. - * Use this constructor if `HybridTestObjectSwiftKotlinSpec` is being initialized from a child-class. + * Call from a child class to initialize HybridData with a child. */ - protected constructor(hybridData: HybridData): super(hybridData) { } + override fun updateNative(hybridData: HybridData) { + mHybridData = hybridData + } // Properties @get:DoNotStrip @@ -381,11 +384,10 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject { @Keep abstract fun castBase(base: HybridBaseSpec): HybridChildSpec + private external fun initHybrid(): HybridData + companion object { private const val TAG = "HybridTestObjectSwiftKotlinSpec" - @JvmStatic - private external fun initHybrid(): HybridData - init { try { Log.i(TAG, "Loading NitroImage C++ library...") diff --git a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt index 4214e0e52..a90518660 100644 --- a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +++ b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/HybridObject.kt @@ -9,7 +9,7 @@ import com.facebook.proguard.annotations.DoNotStrip */ @Keep @DoNotStrip -open class HybridObject: ExtendableHybridClass { +abstract class HybridObject: ExtendableHybridClass { /** * Get the memory size of the Kotlin instance (plus any external heap allocations), * in bytes. @@ -31,13 +31,18 @@ open class HybridObject: ExtendableHybridClass { open val memorySize: Long get() = 0L - protected open var mHybridData: HybridData - - protected constructor(hybridData: HybridData) { - mHybridData = hybridData - } + /** + * Holds the native C++ instance. + * In `HybridObject`, the C++ instance is a sub-class of `JHybridObject`, such as one of it's specs. + * This is `null`, until `updateNative(..)` is called. + */ + private var mHybridData: HybridData? = null + /** + * Must be called in the constructor of a subclass of `HybridObject`, to initialize the C++ + * `JHybridObject` with a subclass of it. + */ override fun updateNative(hybridData: HybridData) { - + mHybridData = hybridData } }