Skip to content

Commit

Permalink
feat: Make initHybrid() static
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Jan 13, 2025
1 parent 67b707d commit 9b10dcf
Show file tree
Hide file tree
Showing 18 changed files with 225 additions and 146 deletions.
32 changes: 24 additions & 8 deletions packages/nitrogen/src/syntax/kotlin/FbjniHybridObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand Down Expand Up @@ -87,17 +87,19 @@ namespace ${cxxNamespace} {
${spaces} public virtual ${name.HybridTSpec} {
public:
static auto constexpr kJavaDescriptor = "L${jniClassDescriptor};";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaPart);
static void registerNatives();
protected:
// C++ constructor (called from Java via \`initHybrid()\`)
explicit ${name.JHybridTSpec}(jni::alias_ref<jhybridobject> jThis) :
${indent(cppConstructorCalls.join(',\n'), ' ')},
_javaPart(jni::make_global(jThis)) {}
explicit ${name.JHybridTSpec}(jni::alias_ref<jhybridobject> 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(); });
}
Expand Down Expand Up @@ -168,8 +170,22 @@ ${cppIncludes.join('\n')}
namespace ${cxxNamespace} {
jni::local_ref<${name.JHybridTSpec}::jhybriddata> ${name.JHybridTSpec}::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
${name.JHybridTSpec}::${name.JHybridTSpec}(jni::alias_ref<jhybridobject> 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<jhybridobject> javaPart) {
return makeCxxInstance(javaPart);
}
void ${name.JHybridTSpec}::registerNatives() {
Expand Down
28 changes: 13 additions & 15 deletions packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,33 +56,31 @@ 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, ' ')}
// 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...")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,22 @@

namespace margelo::nitro::image {

jni::local_ref<JHybridBaseSpec::jhybriddata> JHybridBaseSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
JHybridBaseSpec::JHybridBaseSpec(jni::alias_ref<jhybridobject> 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::jhybriddata> JHybridBaseSpec::initHybrid(jni::alias_ref<jhybridobject> javaPart) {
return makeCxxInstance(javaPart);
}

void JHybridBaseSpec::registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaPart);
static void registerNatives();

protected:
// C++ constructor (called from Java via `initHybrid()`)
explicit JHybridBaseSpec(jni::alias_ref<jhybridobject> jThis) :
HybridObject(HybridBaseSpec::TAG),
_javaPart(jni::make_global(jThis)) {}
explicit JHybridBaseSpec(jni::alias_ref<jhybridobject> 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(); });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,23 @@

namespace margelo::nitro::image {

jni::local_ref<JHybridChildSpec::jhybriddata> JHybridChildSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
JHybridChildSpec::JHybridChildSpec(jni::alias_ref<jhybridobject> 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::jhybriddata> JHybridChildSpec::initHybrid(jni::alias_ref<jhybridobject> javaPart) {
return makeCxxInstance(javaPart);
}

void JHybridChildSpec::registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaPart);
static void registerNatives();

protected:
// C++ constructor (called from Java via `initHybrid()`)
explicit JHybridChildSpec(jni::alias_ref<jhybridobject> jThis) :
HybridObject(HybridChildSpec::TAG),
HybridBase(jThis),
_javaPart(jni::make_global(jThis)) {}
explicit JHybridChildSpec(jni::alias_ref<jhybridobject> 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(); });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,22 @@ namespace margelo::nitro::image { class HybridImageSpec; }

namespace margelo::nitro::image {

jni::local_ref<JHybridImageFactorySpec::jhybriddata> JHybridImageFactorySpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
JHybridImageFactorySpec::JHybridImageFactorySpec(jni::alias_ref<jhybridobject> 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::jhybriddata> JHybridImageFactorySpec::initHybrid(jni::alias_ref<jhybridobject> javaPart) {
return makeCxxInstance(javaPart);
}

void JHybridImageFactorySpec::registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaPart);
static void registerNatives();

protected:
// C++ constructor (called from Java via `initHybrid()`)
explicit JHybridImageFactorySpec(jni::alias_ref<jhybridobject> jThis) :
HybridObject(HybridImageFactorySpec::TAG),
_javaPart(jni::make_global(jThis)) {}
explicit JHybridImageFactorySpec(jni::alias_ref<jhybridobject> 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(); });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,22 @@ namespace margelo::nitro::image { enum class ImageFormat; }

namespace margelo::nitro::image {

jni::local_ref<JHybridImageSpec::jhybriddata> JHybridImageSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
JHybridImageSpec::JHybridImageSpec(jni::alias_ref<jhybridobject> 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::jhybriddata> JHybridImageSpec::initHybrid(jni::alias_ref<jhybridobject> javaPart) {
return makeCxxInstance(javaPart);
}

void JHybridImageSpec::registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaPart);
static void registerNatives();

protected:
// C++ constructor (called from Java via `initHybrid()`)
explicit JHybridImageSpec(jni::alias_ref<jhybridobject> jThis) :
HybridObject(HybridImageSpec::TAG),
_javaPart(jni::make_global(jThis)) {}
explicit JHybridImageSpec(jni::alias_ref<jhybridobject> 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(); });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,22 @@ namespace margelo::nitro::image { struct JsStyleStruct; }

namespace margelo::nitro::image {

jni::local_ref<JHybridTestObjectSwiftKotlinSpec::jhybriddata> JHybridTestObjectSwiftKotlinSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
JHybridTestObjectSwiftKotlinSpec::JHybridTestObjectSwiftKotlinSpec(jni::alias_ref<jhybridobject> 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::jhybriddata> JHybridTestObjectSwiftKotlinSpec::initHybrid(jni::alias_ref<jhybridobject> javaPart) {
return makeCxxInstance(javaPart);
}

void JHybridTestObjectSwiftKotlinSpec::registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaPart);
static void registerNatives();

protected:
// C++ constructor (called from Java via `initHybrid()`)
explicit JHybridTestObjectSwiftKotlinSpec(jni::alias_ref<jhybridobject> jThis) :
HybridObject(HybridTestObjectSwiftKotlinSpec::TAG),
_javaPart(jni::make_global(jThis)) {}
explicit JHybridTestObjectSwiftKotlinSpec(jni::alias_ref<jhybridobject> 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(); });
}
Expand Down
Loading

0 comments on commit 9b10dcf

Please sign in to comment.