Skip to content

Commit

Permalink
Bridge to test swift object
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Jun 23, 2024
1 parent d0e7cfe commit bd630dd
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 86 deletions.
89 changes: 4 additions & 85 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,14 @@
import * as React from 'react';

import { StyleSheet, View, Text } from 'react-native';
import { createTestHybridObject } from 'react-native-nitro-modules';
import { runCppHybridObjectTests, runSwiftHybridObjectTests } from './runHybridObjectTests';

const FIBONACCI_N = 33
const FIBONACCI_COUNT = 5

async function runTests() {
try {
const testObject = createTestHybridObject()

console.log('---------- Beginning TestHybridObject Test:')
console.log('Keys:', Object.keys(testObject))
// Getters & Setters
console.log('get int:', testObject.int)
console.log('set int:', testObject.int = 5)
console.log('get string:', testObject.string)
console.log('set string:', testObject.string = "hello world!")
console.log('get nullable-string:', testObject.nullableString)
console.log('set nullable-string:', testObject.nullableString = "hello world!")
// Methods
console.log('call method:', testObject.multipleArguments(5, false, "hey!"))
// Functions/Lambdas
const getter = testObject.getIntGetter()
console.log('get getter:', getter)
console.log('call getter:', getter())
testObject.sayHelloCallback((name: string) => {
console.log('call with callback:', name)
})

// Promises/Threading
{
const start = performance.now()
let sum = 0n
for (let i = 0; i < FIBONACCI_COUNT; i++) {
sum += testObject.calculateFibonacci(FIBONACCI_N)
}
const end = performance.now()
console.log(`calculate fibonacci(${FIBONACCI_N}) ${FIBONACCI_COUNT}x sync/serially took ${(end - start).toFixed(2)}ms (result: ${sum})`)
}
{
const start = performance.now()
const promises: Promise<bigint>[] = []
for (let i = 0; i < FIBONACCI_COUNT; i++) {
const promise = testObject.calculateFibonacciAsync(FIBONACCI_N)
promises.push(promise)
}
const all = await Promise.all(promises)
const sum = all.reduce((prev, curr) => prev + curr, 0n)
const end = performance.now()
console.log(`calculate fibonacci(${FIBONACCI_N}) ${FIBONACCI_COUNT}x async/parallel took ${(end - start).toFixed(2)}ms (result: ${sum})`)
}
{
const start = performance.now()
for (let i = 0; i < 100; i++) {
testObject.syncVoidFunc()
}
const end = performance.now()
console.log(`Calling sync func 100 times took ${(end - start).toFixed(2)}ms`)
}
{
const start = performance.now()
for (let i = 0; i < 100; i++) {
await testObject.asyncVoidFunc()
}
const end = performance.now()
console.log(`Calling async func 100 times took ${(end - start).toFixed(2)}ms`)
}

// Create another TestHybridObject
const newTest = testObject.createNewHybridObject()
console.log('create new hybrid object:', newTest != testObject)

// Error throwing
try {
testObject.throwError()
console.error(`throw error didn't throw!!`)
} catch (e: any) {
console.log(`throw error: ${e.message}`)
}

console.log('---------- Finished TestHybridObject Test!')
} catch (e) {
console.error('---------- Failed TestHybridObject Test!', e)
}
}

export default function App() {
React.useEffect(() => {
const timeout = setTimeout(() => {
runTests()
const timeout = setTimeout(async () => {
await runCppHybridObjectTests()
await runSwiftHybridObjectTests()
}, 1000)
return () => {
clearTimeout(timeout)
Expand Down
103 changes: 103 additions & 0 deletions example/src/runHybridObjectTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { createCppTestHybridObject, createSwiftTestHybridObject, TestHybridObject } from 'react-native-nitro-modules';

const FIBONACCI_N = 33
const FIBONACCI_COUNT = 5

async function runHybridObjectTests(testObject: TestHybridObject): Promise<void> {
try {
console.log('---------- Beginning TestHybridObject Test:')
console.log('Keys:', Object.keys(testObject))
// Getters & Setters
console.log('get int:', testObject.int)
console.log('set int:', testObject.int = 5)
console.log('get string:', testObject.string)
console.log('set string:', testObject.string = "hello world!")
console.log('get nullable-string:', testObject.nullableString)
console.log('set nullable-string:', testObject.nullableString = "hello world!")
// Methods
console.log('call method:', testObject.multipleArguments(5, false, "hey!"))
// Functions/Lambdas
const getter = testObject.getIntGetter()
console.log('get getter:', getter)
console.log('call getter:', getter())
testObject.sayHelloCallback((name: string) => {
console.log('call with callback:', name)
})

// Promises/Threading
{
const start = performance.now()
let sum = 0n
for (let i = 0; i < FIBONACCI_COUNT; i++) {
sum += testObject.calculateFibonacci(FIBONACCI_N)
}
const end = performance.now()
console.log(`calculate fibonacci(${FIBONACCI_N}) ${FIBONACCI_COUNT}x sync/serially took ${(end - start).toFixed(2)}ms (result: ${sum})`)
}
{
const start = performance.now()
const promises: Promise<bigint>[] = []
for (let i = 0; i < FIBONACCI_COUNT; i++) {
const promise = testObject.calculateFibonacciAsync(FIBONACCI_N)
promises.push(promise)
}
const all = await Promise.all(promises)
const sum = all.reduce((prev, curr) => prev + curr, 0n)
const end = performance.now()
console.log(`calculate fibonacci(${FIBONACCI_N}) ${FIBONACCI_COUNT}x async/parallel took ${(end - start).toFixed(2)}ms (result: ${sum})`)
}
{
const start = performance.now()
for (let i = 0; i < 100; i++) {
testObject.syncVoidFunc()
}
const end = performance.now()
console.log(`Calling sync func 100 times took ${(end - start).toFixed(2)}ms`)
}
{
const start = performance.now()
for (let i = 0; i < 100; i++) {
await testObject.asyncVoidFunc()
}
const end = performance.now()
console.log(`Calling async func 100 times took ${(end - start).toFixed(2)}ms`)
}

// Create another TestHybridObject
const newTest = testObject.createNewHybridObject()
console.log('create new hybrid object:', newTest != testObject)

// Error throwing
try {
testObject.throwError()
console.error(`throw error didn't throw!!`)
} catch (e: any) {
console.log(`throw error: ${e.message}`)
}

console.log('---------- Finished TestHybridObject Test!')
} catch (e) {
console.error('---------- Failed TestHybridObject Test!', e)
}
}

// Tests the C++ object
export async function runCppHybridObjectTests(): Promise<void> {
try {
const cppTestObject = createCppTestHybridObject()
await runHybridObjectTests(cppTestObject)
} catch (e) {
console.error(`Failed to create C++ TestHybridObject!`, e)
}
}

// Tests the Swift object
export async function runSwiftHybridObjectTests(): Promise<void> {
try {
const swiftTestObject = createSwiftTestHybridObject()
await runHybridObjectTests(swiftTestObject)
} catch (e) {
console.error(`Failed to create Swift TestHybridObject!`, e)
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// SwiftTestHybridObject.cpp
// NitroModules
//
// Created by Marc Rousavy on 23.06.24.
//

#include "SwiftTestHybridObject.hpp"

namespace margelo {

SwiftTestHybridObject::SwiftTestHybridObject(): HybridObject("SwiftTestHybridObject"), _swiftPart(NitroModules::SwiftTestHybridObjectSwift::init()) {
}

int SwiftTestHybridObject::getInt() {
return _swiftPart.getInt();
}

void SwiftTestHybridObject::setInt(int value) {
_swiftPart.setInt(value);
}

void SwiftTestHybridObject::loadHybridMethods() {
registerHybridGetter("int", &SwiftTestHybridObject::getInt, this);
registerHybridSetter("int", &SwiftTestHybridObject::setInt, this);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// SwiftTestHybridObject.hpp
// NitroModules
//
// Created by Marc Rousavy on 23.06.24.
//

#pragma once

#include "HybridObject.hpp"
#include "NitroModules-Swift.h"

namespace margelo {

class SwiftTestHybridObject: public HybridObject {
public:
explicit SwiftTestHybridObject();

int getInt();
void setInt(int value);

void loadHybridMethods() override;

private:
NitroModules::SwiftTestHybridObjectSwift _swiftPart;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "NativeNitroModules.hpp"
#include "TestHybridObject.hpp"
#include "SwiftTestHybridObject.hpp"
#include "Dispatcher.hpp"
#include "CallInvokerDispatcher.hpp"

Expand All @@ -31,4 +32,9 @@ jsi::Object NativeNitroModules::createTestHybridObject(jsi::Runtime &runtime) {
return jsi::Object::createFromHostObject(runtime, hybrid);
}

jsi::Object NativeNitroModules::createSwiftTestHybridObject(jsi::Runtime &runtime) {
auto hybrid = std::make_shared<SwiftTestHybridObject>();
return jsi::Object::createFromHostObject(runtime, hybrid);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class NativeNitroModules : public NativeNitroCxxSpec<NativeNitroModules> {

void install(jsi::Runtime& runtime);
jsi::Object createTestHybridObject(jsi::Runtime& runtime);
jsi::Object createSwiftTestHybridObject(jsi::Runtime& runtime);

private:
std::shared_ptr<CallInvoker> _callInvoker;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// SwiftTestHybridObject.swift
// NitroModules
//
// Created by Marc Rousavy on 23.06.24.
//

import Foundation

public class SwiftTestHybridObjectSwift {
private var _int: Int = 5
public var int: Int {
get {
return _int
}
set {
_int = newValue
}
}

public init() {

}
}
1 change: 1 addition & 0 deletions packages/react-native-nitro-modules/src/NativeNitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
export interface Spec extends TurboModule {
install(): void;
createTestHybridObject(): UnsafeObject;
createSwiftTestHybridObject(): UnsafeObject;
}

export const NitroModules =
Expand Down
6 changes: 5 additions & 1 deletion packages/react-native-nitro-modules/src/createTestObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ interface TestHybridObject {
throwError(): void;
}

export function createTestHybridObject(): TestHybridObject {
export function createCppTestHybridObject(): TestHybridObject {
return NitroModules.createTestHybridObject() as TestHybridObject;
}

export function createSwiftTestHybridObject(): TestHybridObject {
return NitroModules.createSwiftTestHybridObject() as TestHybridObject;
}

0 comments on commit bd630dd

Please sign in to comment.