react-native-nitro-modules 0.24.1 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +1 -1
- package/android/src/main/cpp/utils/JNISharedPtr.hpp +25 -7
- package/cpp/core/ArrayBuffer.cpp +2 -2
- package/cpp/core/ArrayBuffer.hpp +2 -2
- package/cpp/core/HybridObject.cpp +9 -3
- package/cpp/jsi/JSICache.cpp +1 -1
- package/cpp/prototype/HybridObjectPrototype.cpp +2 -1
- package/cpp/threading/Dispatcher.cpp +4 -3
- package/cpp/utils/NitroDefines.hpp +1 -1
- package/ios/platform/ThreadUtils.mm +46 -0
- package/package.json +1 -1
- package/ios/platform/ThreadUtils.cpp +0 -33
package/android/build.gradle
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
#pragma once
|
|
6
6
|
|
|
7
|
+
#include "NitroDefines.hpp"
|
|
8
|
+
#include "NitroTypeInfo.hpp"
|
|
7
9
|
#include <fbjni/fbjni.h>
|
|
8
10
|
#include <memory>
|
|
9
11
|
|
|
@@ -13,19 +15,21 @@ using namespace facebook;
|
|
|
13
15
|
|
|
14
16
|
template <typename T>
|
|
15
17
|
struct GlobalRefDeleter {
|
|
16
|
-
explicit GlobalRefDeleter(jni::global_ref<typename T::javaobject
|
|
18
|
+
explicit GlobalRefDeleter(const jni::global_ref<typename T::javaobject>& ref) : _ref(ref) {}
|
|
19
|
+
|
|
20
|
+
GlobalRefDeleter(const GlobalRefDeleter& copy) = delete;
|
|
21
|
+
GlobalRefDeleter(GlobalRefDeleter&& move) = default;
|
|
17
22
|
|
|
18
23
|
void operator()(T* /* cthis */) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
24
|
+
// It's RAII - once `GlobalRefDeleter` goes out of scope, `jni::global_ref` will too.
|
|
25
|
+
_ref = nullptr;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
private:
|
|
25
29
|
jni::global_ref<typename T::javaobject> _ref;
|
|
26
30
|
};
|
|
27
31
|
|
|
28
|
-
class JNISharedPtr {
|
|
32
|
+
class JNISharedPtr final {
|
|
29
33
|
private:
|
|
30
34
|
template <typename T, template <typename, typename...> class Base>
|
|
31
35
|
struct is_base_template_of {
|
|
@@ -39,9 +43,23 @@ private:
|
|
|
39
43
|
};
|
|
40
44
|
|
|
41
45
|
public:
|
|
46
|
+
JNISharedPtr() = delete;
|
|
47
|
+
~JNISharedPtr() = delete;
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new `std::shared_ptr<T>` from the given `jni::global_ref<T::javaobject>`.
|
|
52
|
+
*/
|
|
42
53
|
template <typename T, typename std::enable_if<is_base_template_of<T, jni::HybridClass>::value, int>::type = 0>
|
|
43
|
-
static std::shared_ptr<T> make_shared_from_jni(jni::global_ref<typename T::javaobject
|
|
44
|
-
|
|
54
|
+
static std::shared_ptr<T> make_shared_from_jni(const jni::global_ref<typename T::javaobject>& ref) {
|
|
55
|
+
#ifdef NITRO_DEBUG
|
|
56
|
+
if (ref == nullptr || ref->cthis() == nullptr) [[unlikely]] {
|
|
57
|
+
std::string typeName = TypeInfo::getFriendlyTypename<T>(true);
|
|
58
|
+
throw std::runtime_error("Failed to wrap jni::global_ref<" + typeName + "::javaobject> in std::shared_ptr<" + typeName +
|
|
59
|
+
"> - it's null!");
|
|
60
|
+
}
|
|
61
|
+
#endif
|
|
62
|
+
return std::shared_ptr<T>(ref->cthis(), GlobalRefDeleter<T>(ref));
|
|
45
63
|
}
|
|
46
64
|
};
|
|
47
65
|
|
package/cpp/core/ArrayBuffer.cpp
CHANGED
|
@@ -21,13 +21,13 @@ std::shared_ptr<ArrayBuffer> ArrayBuffer::wrap(uint8_t* data, size_t size, Delet
|
|
|
21
21
|
return std::make_shared<NativeArrayBuffer>(data, size, std::move(deleteFunc));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(uint8_t* data, size_t size) {
|
|
24
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(const uint8_t* data, size_t size) {
|
|
25
25
|
uint8_t* copy = new uint8_t[size];
|
|
26
26
|
std::memcpy(copy, data, size);
|
|
27
27
|
return ArrayBuffer::wrap(copy, size, [=]() { delete[] copy; });
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(std::vector<uint8_t>& data) {
|
|
30
|
+
std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(const std::vector<uint8_t>& data) {
|
|
31
31
|
return ArrayBuffer::copy(data.data(), data.size());
|
|
32
32
|
}
|
|
33
33
|
|
package/cpp/core/ArrayBuffer.hpp
CHANGED
|
@@ -58,11 +58,11 @@ public:
|
|
|
58
58
|
* Create a new `NativeArrayBuffer` that copies the given data of the given size
|
|
59
59
|
* into a newly allocated buffer.
|
|
60
60
|
*/
|
|
61
|
-
static std::shared_ptr<ArrayBuffer> copy(uint8_t* data, size_t size);
|
|
61
|
+
static std::shared_ptr<ArrayBuffer> copy(const uint8_t* data, size_t size);
|
|
62
62
|
/**
|
|
63
63
|
* Create a new `NativeArrayBuffer` that copies the given `std::vector`.
|
|
64
64
|
*/
|
|
65
|
-
static std::shared_ptr<ArrayBuffer> copy(std::vector<uint8_t>& data);
|
|
65
|
+
static std::shared_ptr<ArrayBuffer> copy(const std::vector<uint8_t>& data);
|
|
66
66
|
/**
|
|
67
67
|
* Create a new `NativeArrayBuffer` that allocates a new buffer of the given size.
|
|
68
68
|
*/
|
|
@@ -79,11 +79,17 @@ jsi::Value HybridObject::toObject(jsi::Runtime& runtime) {
|
|
|
79
79
|
object.setProperty(runtime, "__type", jsi::String::createFromUtf8(runtime, "NativeState<" + std::string(_name) + ">"));
|
|
80
80
|
#endif
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
#ifdef NITRO_DEBUG
|
|
83
|
+
// 8. Freeze the object to prevent accidentally setting wrong props on it that do nothing.
|
|
84
|
+
jsi::Function freeze = objectConstructor.getPropertyAsFunction(runtime, "freeze");
|
|
85
|
+
freeze.call(runtime, object);
|
|
86
|
+
#endif
|
|
87
|
+
|
|
88
|
+
// 9. Throw a jsi::WeakObject pointing to our object into cache so subsequent calls can use it from cache
|
|
83
89
|
JSICacheReference cache = JSICache::getOrCreateCache(runtime);
|
|
84
|
-
_objectCache
|
|
90
|
+
_objectCache[&runtime] = cache.makeShared(jsi::WeakObject(runtime, object));
|
|
85
91
|
|
|
86
|
-
//
|
|
92
|
+
// 10. Return it!
|
|
87
93
|
return object;
|
|
88
94
|
}
|
|
89
95
|
|
package/cpp/jsi/JSICache.cpp
CHANGED
|
@@ -57,7 +57,7 @@ JSICacheReference JSICache::getOrCreateCache(jsi::Runtime& runtime) {
|
|
|
57
57
|
// Cache doesn't exist yet.
|
|
58
58
|
Logger::log(LogLevel::Info, TAG, "Creating new JSICache<T> for runtime %s..", getRuntimeId(runtime).c_str());
|
|
59
59
|
// Create new cache
|
|
60
|
-
|
|
60
|
+
std::shared_ptr<JSICache> nativeState(new JSICache());
|
|
61
61
|
// Wrap it in a jsi::Value using NativeState
|
|
62
62
|
jsi::Object cache(runtime);
|
|
63
63
|
cache.setNativeState(runtime, nativeState);
|
|
@@ -78,7 +78,8 @@ jsi::Value HybridObjectPrototype::createPrototype(jsi::Runtime& runtime, const s
|
|
|
78
78
|
// 7. Throw it into our cache so the next lookup can be cached and therefore faster
|
|
79
79
|
JSICacheReference jsiCache = JSICache::getOrCreateCache(runtime);
|
|
80
80
|
BorrowingReference<jsi::Object> sharedObject = jsiCache.makeShared(std::move(object));
|
|
81
|
-
|
|
81
|
+
auto instanceId = prototype->getNativeInstanceId();
|
|
82
|
+
prototypeCache[instanceId] = sharedObject;
|
|
82
83
|
|
|
83
84
|
// 8. Return it!
|
|
84
85
|
return jsi::Value(runtime, *sharedObject);
|
|
@@ -22,7 +22,7 @@ void Dispatcher::installRuntimeGlobalDispatcher(jsi::Runtime& runtime, std::shar
|
|
|
22
22
|
Logger::log(LogLevel::Info, TAG, "Installing global Dispatcher Holder into Runtime \"%s\"...", getRuntimeId(runtime).c_str());
|
|
23
23
|
|
|
24
24
|
// Store a weak reference in global cache
|
|
25
|
-
_globalCache[&runtime] =
|
|
25
|
+
_globalCache[&runtime] = dispatcher;
|
|
26
26
|
|
|
27
27
|
// Inject the dispatcher into Runtime global (runtime will hold a strong reference)
|
|
28
28
|
jsi::Object dispatcherHolder(runtime);
|
|
@@ -31,9 +31,10 @@ void Dispatcher::installRuntimeGlobalDispatcher(jsi::Runtime& runtime, std::shar
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
std::shared_ptr<Dispatcher> Dispatcher::getRuntimeGlobalDispatcher(jsi::Runtime& runtime) {
|
|
34
|
-
|
|
34
|
+
auto found = _globalCache.find(&runtime);
|
|
35
|
+
if (found != _globalCache.end()) [[likely]] {
|
|
35
36
|
// the runtime is known - we have something in cache
|
|
36
|
-
std::weak_ptr<Dispatcher> weakDispatcher =
|
|
37
|
+
std::weak_ptr<Dispatcher> weakDispatcher = found->second;
|
|
37
38
|
std::shared_ptr<Dispatcher> strongDispatcher = weakDispatcher.lock();
|
|
38
39
|
if (strongDispatcher) {
|
|
39
40
|
// the weak reference we cached is still valid - return it!
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ThreadUtils.mm
|
|
3
|
+
// react-native-nitro
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 14.07.24.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#include "ThreadUtils.hpp"
|
|
9
|
+
#include <pthread.h>
|
|
10
|
+
#include <sstream>
|
|
11
|
+
#include <thread>
|
|
12
|
+
|
|
13
|
+
// ObjC import
|
|
14
|
+
#import <Foundation/Foundation.h>
|
|
15
|
+
|
|
16
|
+
namespace margelo::nitro {
|
|
17
|
+
|
|
18
|
+
std::string ThreadUtils::getThreadName() {
|
|
19
|
+
// Try using NSThread APIs
|
|
20
|
+
NSString* threadName = NSThread.currentThread.name;
|
|
21
|
+
if (threadName != nil && threadName.length > 0) {
|
|
22
|
+
return threadName.UTF8String;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Try using DispatchQueue APIs as fallback
|
|
26
|
+
#pragma clang diagnostic push
|
|
27
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
28
|
+
dispatch_queue_t queue = dispatch_get_current_queue();
|
|
29
|
+
#pragma clang diagnostic pop
|
|
30
|
+
const char* label = dispatch_queue_get_label(queue);
|
|
31
|
+
if (label != nullptr) {
|
|
32
|
+
return label;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Fall back to this_thread ID
|
|
36
|
+
std::stringstream stream;
|
|
37
|
+
stream << std::this_thread::get_id();
|
|
38
|
+
std::string threadId = stream.str();
|
|
39
|
+
return "Thread #" + threadId;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void ThreadUtils::setThreadName(const std::string& name) {
|
|
43
|
+
pthread_setname_np(name.c_str());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-modules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.1",
|
|
4
4
|
"description": "Insanely fast native C++, Swift or Kotlin modules with a statically compiled binding layer to JSI.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ThreadUtils.cpp
|
|
3
|
-
// react-native-nitro
|
|
4
|
-
//
|
|
5
|
-
// Created by Marc Rousavy on 14.07.24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
#include "ThreadUtils.hpp"
|
|
9
|
-
#include <pthread.h>
|
|
10
|
-
#include <sstream>
|
|
11
|
-
#include <thread>
|
|
12
|
-
|
|
13
|
-
namespace margelo::nitro {
|
|
14
|
-
|
|
15
|
-
std::string ThreadUtils::getThreadName() {
|
|
16
|
-
// Try using pthread APIs
|
|
17
|
-
char name[256];
|
|
18
|
-
if (pthread_getname_np(pthread_self(), name, sizeof(name)) == 0) {
|
|
19
|
-
return std::string(name);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Fall back to this_thread ID
|
|
23
|
-
std::stringstream stream;
|
|
24
|
-
stream << std::this_thread::get_id();
|
|
25
|
-
std::string threadId = stream.str();
|
|
26
|
-
return "Thread #" + threadId;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
void ThreadUtils::setThreadName(const std::string& name) {
|
|
30
|
-
pthread_setname_np(name.c_str());
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
} // namespace margelo::nitro
|