Skip to content

Commit

Permalink
fix: Fix passing function inside object on Android (toCpp()) (#453)
Browse files Browse the repository at this point in the history
* chore: Add test for JS-style object as params

* Image specs

* Impl

* fix: Use `cthis()` for function conversions

* fix: Use `getFunction()`
  • Loading branch information
mrousavy authored Dec 30, 2024
1 parent 3a6d46d commit 57336f4
Show file tree
Hide file tree
Showing 35 changed files with 450 additions and 7 deletions.
15 changes: 15 additions & 0 deletions example/src/getTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,21 @@ export function getTests(
.didNotThrow()
.equals({ age: 24, name: 'marc' })
),
createTest('jsStyleObjectAsParameters()', async () =>
(
await it(() =>
timeoutedPromise<number>((complete) => {
testObject.jsStyleObjectAsParameters({
value: 55,
onChanged: (num) => complete(num),
})
})
)
)
.didNotThrow()
.didReturn('number')
.equals(55)
),

// Hybrid Object Tests
createTest('get self', () =>
Expand Down
11 changes: 9 additions & 2 deletions packages/nitrogen/src/syntax/kotlin/KotlinCxxBridgedType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,7 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
return parameterName
}
case 'struct':
case 'enum':
case 'function': {
case 'enum': {
switch (language) {
case 'c++':
return `${parameterName}->toCpp()`
Expand Down Expand Up @@ -662,6 +661,14 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
return parameterName
}
}
case 'function': {
switch (language) {
case 'c++':
return `${parameterName}->cthis()->getFunction()`
default:
return parameterName
}
}
case 'array-buffer': {
switch (language) {
case 'c++':
Expand Down
5 changes: 5 additions & 0 deletions packages/nitrogen/src/syntax/kotlin/KotlinFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ namespace ${cxxNamespace} {
${indent(callBody, ' ')}
}
public:
inline const ${typename}& getFunction() const {
return _func;
}
public:
static auto constexpr kJavaDescriptor = "L${jniClassDescriptor};";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ class HybridTestObjectKotlin: HybridTestObjectSwiftKotlinSpec() {
return car.driver
}

override fun jsStyleObjectAsParameters(params: JsStyleStruct): Unit {
params.onChanged(params.value)
}

override fun createArrayBuffer(): ArrayBuffer {
return ArrayBuffer.allocate(1024 * 1024 * 10) // 10 MB
}
Expand Down
4 changes: 4 additions & 0 deletions packages/react-native-nitro-image/cpp/HybridTestObjectCpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ std::optional<Person> HybridTestObjectCpp::getDriver(const Car& car) {
}
}

void HybridTestObjectCpp::jsStyleObjectAsParameters(const JsStyleStruct& params) {
params.onChanged(params.value);
}

std::shared_ptr<ArrayBuffer> HybridTestObjectCpp::createArrayBuffer() {
size_t size = 1024 * 1024 * 10; // 10MB
uint8_t* buffer = new uint8_t[size];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class HybridTestObjectCpp : public HybridTestObjectCppSpec {
Car getCar() override;
bool isCarElectric(const Car& car) override;
std::optional<Person> getDriver(const Car& car) override;
void jsStyleObjectAsParameters(const JsStyleStruct& params) override;
std::shared_ptr<ArrayBuffer> createArrayBuffer() override;
double getBufferLastItem(const std::shared_ptr<ArrayBuffer>& buffer) override;
void setAllValuesTo(const std::shared_ptr<ArrayBuffer>& buffer, double value) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ class HybridTestObjectSwift : HybridTestObjectSwiftKotlinSpec {
return car.driver
}

func jsStyleObjectAsParameters(params: JsStyleStruct) throws -> Void {
params.onChanged(params.value)
}

func createArrayBuffer() throws -> ArrayBufferHolder {
return .allocate(size: 1024 * 1024 * 10) // 10 MB
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_double____.hpp"
#include "JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__shared_ptr_ArrayBuffer_____.hpp"
#include "JFunc_std__shared_ptr_Promise_std__string__.hpp"
#include "JFunc_void_double.hpp"
#include "JHybridBaseSpec.hpp"
#include "JHybridChildSpec.hpp"
#include <NitroModules/JNISharedPtr.hpp>
Expand Down Expand Up @@ -53,6 +54,7 @@ int initialize(JavaVM* vm) {
margelo::nitro::image::JFunc_std__shared_ptr_Promise_double__::registerNatives();
margelo::nitro::image::JFunc_std__shared_ptr_Promise_std__string__::registerNatives();
margelo::nitro::image::JFunc_void_std__string::registerNatives();
margelo::nitro::image::JFunc_void_double::registerNatives();
margelo::nitro::image::JHybridBaseSpec::registerNatives();
margelo::nitro::image::JHybridChildSpec::registerNatives();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ namespace margelo::nitro::image {
}();
}

public:
inline const std::function<std::shared_ptr<Promise<double>>()>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_std__shared_ptr_Promise_double__;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ namespace margelo::nitro::image {
}();
}

public:
inline const std::function<std::shared_ptr<Promise<std::shared_ptr<Promise<double>>>>()>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_double____;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ namespace margelo::nitro::image {
}();
}

public:
inline const std::function<std::shared_ptr<Promise<std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>>>()>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__shared_ptr_ArrayBuffer_____;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ namespace margelo::nitro::image {
}();
}

public:
inline const std::function<std::shared_ptr<Promise<std::string>>()>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_std__shared_ptr_Promise_std__string__;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ namespace margelo::nitro::image {
_func();
}

public:
inline const std::function<void()>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_void;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
///
/// JFunc_void_double.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © 2024 Marc Rousavy @ Margelo
///

#pragma once

#include <fbjni/fbjni.h>
#include <functional>

#include <functional>

namespace margelo::nitro::image {

using namespace facebook;

/**
* C++ representation of the callback Func_void_double.
* This is a Kotlin `(num: Double) -> Unit`, backed by a `std::function<...>`.
*/
struct JFunc_void_double final: public jni::HybridClass<JFunc_void_double> {
public:
static jni::local_ref<JFunc_void_double::javaobject> fromCpp(const std::function<void(double /* num */)>& func) {
return JFunc_void_double::newObjectCxxArgs(func);
}

public:
void call(double num) {
_func(num);
}

public:
inline const std::function<void(double /* num */)>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_void_double;";
static void registerNatives() {
registerHybrid({makeNativeMethod("call", JFunc_void_double::call)});
}

private:
explicit JFunc_void_double(const std::function<void(double /* num */)>& func): _func(func) { }

private:
friend HybridBase;
std::function<void(double /* num */)> _func;
};

} // namespace margelo::nitro::image
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace margelo::nitro::image {
_func(maybe != nullptr ? std::make_optional(maybe->value()) : std::nullopt);
}

public:
inline const std::function<void(std::optional<double> /* maybe */)>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_void_std__optional_double_;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace margelo::nitro::image {
_func(valueFromJs->toStdString());
}

public:
inline const std::function<void(const std::string& /* valueFromJs */)>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_void_std__string;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ namespace margelo::nitro::image {
}());
}

public:
inline const std::function<void(const std::vector<Powertrain>& /* array */)>& getFunction() const {
return _func;
}

public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/Func_void_std__vector_Powertrain_;";
static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ namespace NitroModules { class ArrayBuffer; }
namespace margelo::nitro::image { class HybridChildSpec; }
// Forward declaration of `HybridBaseSpec` to properly resolve imports.
namespace margelo::nitro::image { class HybridBaseSpec; }
// Forward declaration of `JsStyleStruct` to properly resolve imports.
namespace margelo::nitro::image { struct JsStyleStruct; }

#include <memory>
#include "HybridTestObjectSwiftKotlinSpec.hpp"
Expand Down Expand Up @@ -64,6 +66,9 @@ namespace margelo::nitro::image { class HybridBaseSpec; }
#include "JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_std__shared_ptr_ArrayBuffer_____.hpp"
#include "JFunc_std__shared_ptr_Promise_std__string__.hpp"
#include "JFunc_void_std__string.hpp"
#include "JsStyleStruct.hpp"
#include "JJsStyleStruct.hpp"
#include "JFunc_void_double.hpp"

namespace margelo::nitro::image {

Expand Down Expand Up @@ -617,6 +622,10 @@ namespace margelo::nitro::image {
auto __result = method(_javaPart, JCar::fromCpp(car));
return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt;
}
void JHybridTestObjectSwiftKotlinSpec::jsStyleObjectAsParameters(const JsStyleStruct& params) {
static const auto method = _javaPart->getClass()->getMethod<void(jni::alias_ref<JJsStyleStruct> /* params */)>("jsStyleObjectAsParameters");
method(_javaPart, JJsStyleStruct::fromCpp(params));
}
std::shared_ptr<ArrayBuffer> JHybridTestObjectSwiftKotlinSpec::createArrayBuffer() {
static const auto method = _javaPart->getClass()->getMethod<jni::local_ref<JArrayBuffer::javaobject>()>("createArrayBuffer");
auto __result = method(_javaPart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ namespace margelo::nitro::image {
Car getCar() override;
bool isCarElectric(const Car& car) override;
std::optional<Person> getDriver(const Car& car) override;
void jsStyleObjectAsParameters(const JsStyleStruct& params) override;
std::shared_ptr<ArrayBuffer> createArrayBuffer() override;
double getBufferLastItem(const std::shared_ptr<ArrayBuffer>& buffer) override;
void setAllValuesTo(const std::shared_ptr<ArrayBuffer>& buffer, double value) override;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
///
/// JJsStyleStruct.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © 2024 Marc Rousavy @ Margelo
///

#pragma once

#include <fbjni/fbjni.h>
#include "JsStyleStruct.hpp"

#include "JFunc_void_double.hpp"
#include <functional>

namespace margelo::nitro::image {

using namespace facebook;

/**
* The C++ JNI bridge between the C++ struct "JsStyleStruct" and the the Kotlin data class "JsStyleStruct".
*/
struct JJsStyleStruct final: public jni::JavaClass<JJsStyleStruct> {
public:
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/image/JsStyleStruct;";

public:
/**
* Convert this Java/Kotlin-based struct to the C++ struct JsStyleStruct by copying all values to C++.
*/
[[maybe_unused]]
JsStyleStruct toCpp() const {
static const auto clazz = javaClassStatic();
static const auto fieldValue = clazz->getField<double>("value");
double value = this->getFieldValue(fieldValue);
static const auto fieldOnChanged = clazz->getField<JFunc_void_double::javaobject>("onChanged");
jni::local_ref<JFunc_void_double::javaobject> onChanged = this->getFieldValue(fieldOnChanged);
return JsStyleStruct(
value,
onChanged->cthis()->getFunction()
);
}

public:
/**
* Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
*/
[[maybe_unused]]
static jni::local_ref<JJsStyleStruct::javaobject> fromCpp(const JsStyleStruct& value) {
return newInstance(
value.value,
JFunc_void_double::fromCpp(value.onChanged)
);
}
};

} // namespace margelo::nitro::image
Loading

0 comments on commit 57336f4

Please sign in to comment.