react-native-nitro-modules 0.29.5 → 0.29.7

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.
@@ -43,6 +43,7 @@ Pod::Spec.new do |s|
43
43
  "cpp/platform/NitroLogger.hpp",
44
44
  "cpp/threading/Dispatcher.hpp",
45
45
  "cpp/utils/JSCallback.hpp",
46
+ "cpp/utils/FastVectorCopy.hpp",
46
47
  "cpp/utils/NitroHash.hpp",
47
48
  "cpp/utils/NitroDefines.hpp",
48
49
  "cpp/views/CachedProp.hpp",
@@ -15,7 +15,7 @@ namespace margelo::nitro {
15
15
  using namespace facebook;
16
16
 
17
17
  template <typename T>
18
- class DefaultConstructableObject {
18
+ class DefaultConstructableObject final {
19
19
  public:
20
20
  explicit DefaultConstructableObject(const char* javaClassDescriptor) {
21
21
  try {
@@ -17,11 +17,11 @@ using namespace facebook;
17
17
 
18
18
  // 1. ArrayBuffer
19
19
 
20
- std::shared_ptr<ArrayBuffer> ArrayBuffer::wrap(uint8_t* data, size_t size, DeleteFn&& deleteFunc) {
20
+ std::shared_ptr<ArrayBuffer> ArrayBuffer::wrap(uint8_t* NON_NULL data, size_t size, DeleteFn&& deleteFunc) {
21
21
  return std::make_shared<NativeArrayBuffer>(data, size, std::move(deleteFunc));
22
22
  }
23
23
 
24
- std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(const uint8_t* data, size_t size) {
24
+ std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(const uint8_t* NON_NULL 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; });
@@ -42,7 +42,7 @@ std::shared_ptr<ArrayBuffer> ArrayBuffer::allocate(size_t size) {
42
42
 
43
43
  // 2. NativeArrayBuffer
44
44
 
45
- NativeArrayBuffer::NativeArrayBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc)
45
+ NativeArrayBuffer::NativeArrayBuffer(uint8_t* NON_NULL data, size_t size, DeleteFn&& deleteFunc)
46
46
  : ArrayBuffer(), _data(data), _size(size), _deleteFunc(std::move(deleteFunc)) {}
47
47
 
48
48
  NativeArrayBuffer::~NativeArrayBuffer() {
@@ -51,7 +51,7 @@ NativeArrayBuffer::~NativeArrayBuffer() {
51
51
  }
52
52
  }
53
53
 
54
- uint8_t* NativeArrayBuffer::data() {
54
+ uint8_t* NON_NULL NativeArrayBuffer::data() {
55
55
  return _data;
56
56
  }
57
57
 
@@ -70,7 +70,7 @@ JSArrayBuffer::JSArrayBuffer(jsi::Runtime& runtime, BorrowingReference<jsi::Arra
70
70
 
71
71
  JSArrayBuffer::~JSArrayBuffer() {}
72
72
 
73
- uint8_t* JSArrayBuffer::data() {
73
+ uint8_t* NULLABLE JSArrayBuffer::data() {
74
74
  if (_initialThreadId != std::this_thread::get_id()) [[unlikely]] {
75
75
  throw std::runtime_error("`data()` can only be accessed synchronously on the JS Thread! "
76
76
  "If you want to access it elsewhere, copy it first.");
@@ -8,6 +8,7 @@
8
8
  #pragma once
9
9
 
10
10
  #include "BorrowingReference.hpp"
11
+ #include "NitroDefines.hpp"
11
12
  #include <jsi/jsi.h>
12
13
  #include <thread>
13
14
  #include <vector>
@@ -53,12 +54,12 @@ public:
53
54
  * Create a new `NativeArrayBuffer` that wraps the given data (without copy) of the given size,
54
55
  * and calls `deleteFunc` in which `data` should be deleted.
55
56
  */
56
- static std::shared_ptr<ArrayBuffer> wrap(uint8_t* data, size_t size, DeleteFn&& deleteFunc);
57
+ static std::shared_ptr<ArrayBuffer> wrap(uint8_t* NON_NULL data, size_t size, DeleteFn&& deleteFunc);
57
58
  /**
58
59
  * Create a new `NativeArrayBuffer` that copies the given data of the given size
59
60
  * into a newly allocated buffer.
60
61
  */
61
- static std::shared_ptr<ArrayBuffer> copy(const uint8_t* data, size_t size);
62
+ static std::shared_ptr<ArrayBuffer> copy(const uint8_t* NON_NULL data, size_t size);
62
63
  /**
63
64
  * Create a new `NativeArrayBuffer` that copies the given `std::vector`.
64
65
  */
@@ -94,16 +95,16 @@ public:
94
95
  * Once this `ArrayBuffer` goes out of scope, `deleteFunc` will be called.
95
96
  * The caller is responsible for deleting the memory (`data`) here.
96
97
  */
97
- NativeArrayBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc);
98
+ NativeArrayBuffer(uint8_t* NON_NULL data, size_t size, DeleteFn&& deleteFunc);
98
99
  ~NativeArrayBuffer();
99
100
 
100
101
  public:
101
- uint8_t* data() override;
102
+ uint8_t* NON_NULL data() override;
102
103
  size_t size() const override;
103
104
  bool isOwner() const noexcept override;
104
105
 
105
106
  private:
106
- uint8_t* _data;
107
+ uint8_t* NON_NULL _data;
107
108
  size_t _size;
108
109
  DeleteFn _deleteFunc;
109
110
  };
@@ -128,7 +129,7 @@ public:
128
129
  /**
129
130
  * Gets the data this `ArrayBuffer` points to, or `nullptr` if it has already been deleted.
130
131
  */
131
- uint8_t* data() override;
132
+ uint8_t* NULLABLE data() override;
132
133
  /**
133
134
  * Gets the size of the data this `ArrayBuffer` points to, or `0` if it has already been deleted.
134
135
  */
@@ -21,7 +21,7 @@ using namespace facebook;
21
21
  *
22
22
  * Simply call `unbox()` on this `jsi::HostObject` from the new Runtime/context to get the `HybridObject` again.
23
23
  */
24
- class BoxedHybridObject : public jsi::HostObject {
24
+ class BoxedHybridObject final : public jsi::HostObject {
25
25
  public:
26
26
  explicit BoxedHybridObject(const std::shared_ptr<HybridObject>& hybridObject) : _hybridObject(hybridObject) {}
27
27
 
@@ -13,6 +13,7 @@ struct JSIConverter;
13
13
  } // namespace margelo::nitro
14
14
 
15
15
  #include "CountTrailingOptionals.hpp"
16
+ #include "InstanceMethod.hpp"
16
17
  #include "JSIConverter.hpp"
17
18
  #include "NitroDefines.hpp"
18
19
  #include "NitroTypeInfo.hpp"
@@ -33,6 +34,15 @@ using namespace facebook;
33
34
  */
34
35
  enum class FunctionKind { METHOD, GETTER, SETTER };
35
36
 
37
+ /**
38
+ * A helper for an `InstanceMethod` that doesn't have a typed return value or arguments, but instead uses raw JSI values.
39
+ */
40
+ template <typename T>
41
+ using RawInstanceMethod = InstanceMethod<
42
+ /* instance type */ T,
43
+ /* return value */ jsi::Value,
44
+ /* jsi::HostFunction arguments */ jsi::Runtime&, const jsi::Value&, const jsi::Value*, size_t>;
45
+
36
46
  /**
37
47
  * Represents a Hybrid Function.
38
48
  */
@@ -73,10 +83,12 @@ public:
73
83
  * The object's `this` needs to be a `NativeState`.
74
84
  */
75
85
  template <typename THybrid, typename ReturnType, typename... Args>
76
- static inline HybridFunction createHybridFunction(const std::string& name, ReturnType (THybrid::*method)(Args...), FunctionKind kind) {
86
+ static inline HybridFunction createHybridFunction(/* The name of the method */ const std::string& name,
87
+ /* The method on THybrid */ InstanceMethod<THybrid, ReturnType, Args...> method,
88
+ /* The type of the method */ FunctionKind kind) {
77
89
  jsi::HostFunctionType hostFunction = [name, method, kind](/* JS Runtime */ jsi::Runtime& runtime,
78
90
  /* HybridObject */ const jsi::Value& thisValue,
79
- /* JS arguments */ const jsi::Value* args,
91
+ /* JS arguments */ const jsi::Value* NON_NULL args,
80
92
  /* argument size */ size_t count) -> jsi::Value {
81
93
  // 1. Get actual `HybridObject` instance from `thisValue` (it's stored as `NativeState`)
82
94
  std::shared_ptr<THybrid> hybridInstance = getHybridObjectNativeState<THybrid>(runtime, thisValue, kind, name);
@@ -126,9 +138,9 @@ public:
126
138
  * It is a raw-, untyped JSI method, and the user is expected to manually handle arguments and return values.
127
139
  */
128
140
  template <typename Derived>
129
- static inline HybridFunction createRawHybridFunction(const std::string& name, size_t expectedArgumentsCount,
130
- jsi::Value (Derived::*method)(jsi::Runtime& runtime, const jsi::Value& thisArg,
131
- const jsi::Value* args, size_t count)) {
141
+ static inline HybridFunction createRawHybridFunction(/* The name of the raw method */ const std::string& name,
142
+ /* The number of expected arguments */ size_t expectedArgumentsCount,
143
+ /* The raw JSI method on the instance */ RawInstanceMethod<Derived> method) {
132
144
  jsi::HostFunctionType hostFunction = [name, method](/* JS Runtime */ jsi::Runtime& runtime,
133
145
  /* HybridObject */ const jsi::Value& thisValue,
134
146
  /* JS arguments */ const jsi::Value* args,
@@ -150,8 +162,11 @@ private:
150
162
  * The given method's return value will be converted to a `jsi::Value` again.
151
163
  */
152
164
  template <typename Derived, typename ReturnType, typename... Args, size_t... Is>
153
- static inline jsi::Value callMethod(Derived* obj, ReturnType (Derived::*method)(Args...), jsi::Runtime& runtime, const jsi::Value* args,
154
- size_t argsSize, std::index_sequence<Is...>) {
165
+ static inline jsi::Value callMethod(/* The instance to call the method on */ Derived* NON_NULL obj,
166
+ /* The method to call */ InstanceMethod<Derived, ReturnType, Args...> method,
167
+ /* JS Runtime */ jsi::Runtime& runtime,
168
+ /* JS Arguments */ const jsi::Value* NON_NULL args,
169
+ /* JS Arguments count */ size_t argsSize, std::index_sequence<Is...>) {
155
170
  static const jsi::Value defaultValue;
156
171
 
157
172
  if constexpr (std::is_void_v<ReturnType>) {
@@ -226,7 +241,7 @@ private:
226
241
  private:
227
242
  template <typename THybrid>
228
243
  static inline std::string getHybridFuncFullName(FunctionKind kind, const std::string& registrationName,
229
- THybrid* hybridInstance = nullptr) {
244
+ THybrid* NULLABLE hybridInstance = nullptr) {
230
245
  std::string typeName = hybridInstance != nullptr ? hybridInstance->getName() : TypeInfo::getFriendlyTypename<THybrid>(true);
231
246
  switch (kind) {
232
247
  case FunctionKind::METHOD:
@@ -238,7 +253,7 @@ private:
238
253
  }
239
254
  template <typename THybrid>
240
255
  static inline std::string getHybridFuncDebugInfo(FunctionKind kind, const std::string& registrationName,
241
- THybrid* hybridInstance = nullptr) {
256
+ THybrid* NULLABLE hybridInstance = nullptr) {
242
257
  auto funcName = getHybridFuncFullName<THybrid>(kind, registrationName, hybridInstance);
243
258
  switch (kind) {
244
259
  case FunctionKind::METHOD:
@@ -8,7 +8,7 @@
8
8
 
9
9
  namespace margelo::nitro {
10
10
 
11
- HybridObject::HybridObject(const char* name) : HybridObjectPrototype(), _name(name) {}
11
+ HybridObject::HybridObject(const char* NON_NULL name) : HybridObjectPrototype(), _name(name) {}
12
12
 
13
13
  std::string HybridObject::toString() {
14
14
  return "[HybridObject " + std::string(_name) + "]";
@@ -29,7 +29,7 @@ public:
29
29
  * Create a new instance of a `HybridObject`.
30
30
  * The given `name` will be used for logging and stringifying.
31
31
  */
32
- explicit HybridObject(const char* name);
32
+ explicit HybridObject(const char* NON_NULL name);
33
33
  /**
34
34
  * Called when no more references to the given `HybridObject` exist in both C++ and JS.
35
35
  * JS might keep references for longer, as it is a garbage collected language.
@@ -111,7 +111,7 @@ private:
111
111
  * The actual `dispose()` function from JS.
112
112
  * This needs to be a raw JSI function as we remove the NativeState here.
113
113
  */
114
- jsi::Value disposeRaw(jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* args, size_t count);
114
+ jsi::Value disposeRaw(jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* NON_NULL args, size_t count);
115
115
 
116
116
  protected:
117
117
  /**
@@ -144,7 +144,7 @@ protected:
144
144
 
145
145
  private:
146
146
  static constexpr auto TAG = "HybridObject";
147
- const char* _name = TAG;
147
+ const char* NON_NULL _name = TAG;
148
148
  std::unordered_map<jsi::Runtime*, BorrowingReference<jsi::WeakObject>> _objectCache;
149
149
  };
150
150
 
@@ -22,7 +22,7 @@ private:
22
22
 
23
23
  public:
24
24
  template <typename... Args>
25
- static void log([[maybe_unused]] LogLevel level, [[maybe_unused]] const char* tag, [[maybe_unused]] const char* format,
25
+ static void log([[maybe_unused]] LogLevel level, [[maybe_unused]] const char* NON_NULL tag, [[maybe_unused]] const char* NON_NULL format,
26
26
  [[maybe_unused]] Args... args) {
27
27
  #ifdef NITRO_DEBUG
28
28
  // 1. Make sure args can be passed to sprintf(..)
@@ -37,11 +37,11 @@ public:
37
37
  #endif
38
38
  }
39
39
 
40
- static void nativeLog(LogLevel level, const char* tag, const std::string& string);
40
+ static void nativeLog(LogLevel level, const char* NON_NULL tag, const std::string& string);
41
41
 
42
42
  private:
43
43
  template <typename... Args>
44
- static std::string formatString(const char* format, Args... args) {
44
+ static std::string formatString(const char* NON_NULL format, Args... args) {
45
45
  #pragma clang diagnostic push
46
46
  #pragma clang diagnostic ignored "-Wformat-security"
47
47
  int size = snprintf(nullptr, 0, format, args...) + 1; // Extra space for '\0'
@@ -47,7 +47,7 @@ public:
47
47
  private:
48
48
  static jsi::Value createPrototype(jsi::Runtime& runtime, const std::shared_ptr<Prototype>& prototype);
49
49
  using PrototypeCache = std::unordered_map<NativeInstanceId, BorrowingReference<jsi::Object>>;
50
- static std::unordered_map<jsi::Runtime*, PrototypeCache> _prototypeCache;
50
+ static std::unordered_map<jsi::Runtime * NON_NULL, PrototypeCache> _prototypeCache;
51
51
 
52
52
  protected:
53
53
  /**
@@ -70,7 +70,7 @@ private:
70
70
  }
71
71
 
72
72
  protected:
73
- using RegisterFn = void (*)(Prototype&);
73
+ using RegisterFn = void (*NON_NULL)(Prototype&);
74
74
  /**
75
75
  * Registers the given methods inside the Hybrid Object's prototype.
76
76
  *
@@ -79,7 +79,7 @@ protected:
79
79
  * **Do not conditionally register hybrid methods, getters or setter!**
80
80
  */
81
81
  template <typename Derived>
82
- inline void registerHybrids(Derived* /* this */, RegisterFn registerFunc) {
82
+ inline void registerHybrids(Derived* NON_NULL /* this */, RegisterFn registerFunc) {
83
83
  const std::shared_ptr<Prototype>& prototype = _prototypeChain.extendPrototype<Derived>();
84
84
 
85
85
  if (!prototype->hasHybrids()) {
@@ -110,7 +110,7 @@ public:
110
110
  * ```
111
111
  */
112
112
  template <typename Derived, typename ReturnType>
113
- inline void registerHybridGetter(std::string name, ReturnType (Derived::*method)()) {
113
+ inline void registerHybridGetter(std::string name, InstanceMethod<Derived, ReturnType> method) {
114
114
  if (_getters.contains(name)) [[unlikely]] {
115
115
  throw std::runtime_error("Cannot add Hybrid Property Getter \"" + name + "\" - a getter with that name already exists!");
116
116
  }
@@ -129,7 +129,7 @@ public:
129
129
  * ```
130
130
  */
131
131
  template <typename Derived, typename ValueType>
132
- inline void registerHybridSetter(std::string name, void (Derived::*method)(ValueType)) {
132
+ inline void registerHybridSetter(std::string name, InstanceMethod<Derived, void, ValueType> method) {
133
133
  if (_setters.contains(name)) [[unlikely]] {
134
134
  throw std::runtime_error("Cannot add Hybrid Property Setter \"" + name + "\" - a setter with that name already exists!");
135
135
  }
@@ -148,7 +148,7 @@ public:
148
148
  * ```
149
149
  */
150
150
  template <typename Derived, typename ReturnType, typename... Args>
151
- inline void registerHybridMethod(std::string name, ReturnType (Derived::*method)(Args...)) {
151
+ inline void registerHybridMethod(std::string name, InstanceMethod<Derived, ReturnType, Args...> method) {
152
152
  if (_getters.contains(name) || _setters.contains(name)) [[unlikely]] {
153
153
  throw std::runtime_error("Cannot add Hybrid Method \"" + name + "\" - a property with that name already exists!");
154
154
  }
@@ -167,9 +167,7 @@ public:
167
167
  * ```
168
168
  */
169
169
  template <typename Derived>
170
- inline void registerRawHybridMethod(std::string name, size_t expectedArgumentsCount,
171
- jsi::Value (Derived::*method)(jsi::Runtime& runtime, const jsi::Value& thisArg,
172
- const jsi::Value* args, size_t count)) {
170
+ inline void registerRawHybridMethod(std::string name, size_t expectedArgumentsCount, RawInstanceMethod<Derived> method) {
173
171
  if (_getters.contains(name) || _setters.contains(name)) [[unlikely]] {
174
172
  throw std::runtime_error("Cannot add Hybrid Method \"" + name + "\" - a property with that name already exists!");
175
173
  }
@@ -76,7 +76,7 @@ std::shared_ptr<HybridObject> HybridObjectRegistry::createHybridObject(const std
76
76
  "- If you use Nitrogen, make sure your `nitro.json` contains `" +
77
77
  hybridObjectName +
78
78
  "` on this platform.\n"
79
- "- If you use Nitrogen, make sure your library (*Package.java)/app (MainApplication.java) calls "
79
+ "- If you use Nitrogen, make sure your library (*Package.kt)/app (MainApplication.kt) calls "
80
80
  "`$$androidCxxLibName$$OnLoad.initializeNative()` somewhere on app-startup.\n"
81
81
  "- If you use Nitrogen, make sure your `cpp-adapter.cpp`/`OnLoad.cpp` calls `margelo::nitro::$$cxxNamespace$$::initialize(vm)`.\n"
82
82
  "- If you use Nitrogen, inspect the generated `$$androidCxxLibName$$OnLoad.cpp` file.\n"
@@ -0,0 +1,23 @@
1
+ //
2
+ // InstanceMethod.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 25.09.25.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include "NitroDefines.hpp"
11
+
12
+ namespace margelo::nitro {
13
+
14
+ /**
15
+ * Represents a Function pointer to an instance method of the given class.
16
+ * For example:
17
+ * `InstanceMethod<std::string, size_t>` could point to `size_t std::string::length()`
18
+ * `InstanceMethod<std::vector<int>, void, int>` could point to `void std::vector<int>::push_back(int)`
19
+ */
20
+ template <typename T, typename ReturnType, typename... Args>
21
+ using InstanceMethod = ReturnType (T::*NON_NULL)(Args...);
22
+
23
+ } // namespace margelo::nitro
@@ -16,7 +16,7 @@ using namespace facebook;
16
16
 
17
17
  static constexpr auto GLOBAL_DISPATCHER_HOLDER_NAME = "__nitroDispatcher";
18
18
 
19
- std::unordered_map<jsi::Runtime*, std::weak_ptr<Dispatcher>> Dispatcher::_globalCache;
19
+ std::unordered_map<jsi::Runtime * NON_NULL, std::weak_ptr<Dispatcher>> Dispatcher::_globalCache;
20
20
 
21
21
  void Dispatcher::installRuntimeGlobalDispatcher(jsi::Runtime& runtime, std::shared_ptr<Dispatcher> dispatcher) {
22
22
  Logger::log(LogLevel::Info, TAG, "Installing global Dispatcher Holder into Runtime \"%s\"...", getRuntimeId(runtime).c_str());
@@ -4,6 +4,7 @@
4
4
 
5
5
  #pragma once
6
6
 
7
+ #include "NitroDefines.hpp"
7
8
  #include "Promise.hpp"
8
9
  #include <functional>
9
10
  #include <jsi/jsi.h>
@@ -73,7 +74,7 @@ public:
73
74
  }
74
75
 
75
76
  private:
76
- static std::unordered_map<jsi::Runtime*, std::weak_ptr<Dispatcher>> _globalCache;
77
+ static std::unordered_map<jsi::Runtime * NON_NULL, std::weak_ptr<Dispatcher>> _globalCache;
77
78
 
78
79
  private:
79
80
  static constexpr auto TAG = "Dispatcher";
@@ -7,6 +7,7 @@
7
7
 
8
8
  #pragma once
9
9
 
10
+ #include "NitroDefines.hpp"
10
11
  #include <atomic>
11
12
  #include <condition_variable>
12
13
  #include <functional>
@@ -25,7 +26,7 @@ public:
25
26
  * Create a new ThreadPool with the given number of minimum workers/threads.
26
27
  * The Thread Pool can expand on the fly if it is busy.
27
28
  */
28
- explicit ThreadPool(const char* const name, size_t initialThreadsCount, size_t maxThreadsCount);
29
+ explicit ThreadPool(const char* NON_NULL const name, size_t initialThreadsCount, size_t maxThreadsCount);
29
30
  ~ThreadPool();
30
31
  ThreadPool(const ThreadPool&) = delete;
31
32
  ThreadPool(ThreadPool&&) = delete;
@@ -58,7 +59,7 @@ private:
58
59
  std::atomic<bool> _isAlive;
59
60
  std::atomic<size_t> _threadCount;
60
61
  size_t _threadCountLimit;
61
- const char* _name;
62
+ const char* NON_NULL _name;
62
63
  static constexpr auto TAG = "ThreadPool";
63
64
  };
64
65
 
@@ -33,7 +33,7 @@ class BorrowingReference final {
33
33
  public:
34
34
  BorrowingReference() : _value(nullptr), _state(nullptr) {}
35
35
 
36
- explicit BorrowingReference(T* value) : _value(value), _state(new ReferenceState()) {}
36
+ explicit BorrowingReference(T* NULLABLE value) : _value(value), _state(new ReferenceState()) {}
37
37
 
38
38
  BorrowingReference(const BorrowingReference& ref) : _value(ref._value), _state(ref._state) {
39
39
  if (_state != nullptr) {
@@ -79,7 +79,7 @@ private:
79
79
  private:
80
80
  // BorrowingReference<C> -> BorrowingReference<T> Cast-constructor
81
81
  template <typename OldT>
82
- BorrowingReference(T* value, const BorrowingReference<OldT>& originalRef) : _value(value), _state(originalRef._state) {
82
+ BorrowingReference(T* NULLABLE value, const BorrowingReference<OldT>& originalRef) : _value(value), _state(originalRef._state) {
83
83
  _state->strongRefCount++;
84
84
  }
85
85
 
@@ -150,7 +150,7 @@ public:
150
150
  }
151
151
 
152
152
  // Dereference (->)
153
- inline T* operator->() const {
153
+ inline T* NON_NULL operator->() const {
154
154
  #ifdef NITRO_DEBUG
155
155
  if (!hasValue()) [[unlikely]] {
156
156
  std::string typeName = TypeInfo::getFriendlyTypename<T>(true);
@@ -174,11 +174,11 @@ public:
174
174
  }
175
175
 
176
176
  // comparison (== *)
177
- inline bool operator==(T* other) const {
177
+ inline bool operator==(T* NULLABLE other) const {
178
178
  return _value == other;
179
179
  }
180
180
  // comparison (!= *)
181
- inline bool operator!=(T* other) const {
181
+ inline bool operator!=(T* NULLABLE other) const {
182
182
  return _value != other;
183
183
  }
184
184
 
@@ -214,8 +214,8 @@ public:
214
214
  friend class WeakReference<T>;
215
215
 
216
216
  private:
217
- T* _value;
218
- ReferenceState* _state;
217
+ T* NULLABLE _value;
218
+ ReferenceState* NON_NULL _state;
219
219
  };
220
220
 
221
221
  } // namespace margelo::nitro
@@ -0,0 +1,44 @@
1
+ //
2
+ // FastVectorCopy.hpp
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 22.09.25.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include "NitroDefines.hpp"
11
+ #include <span>
12
+ #include <type_traits>
13
+ #include <vector>
14
+
15
+ namespace margelo::nitro {
16
+
17
+ /**
18
+ * Copies `data` into an `std::vector` as fast as possible.
19
+ *
20
+ * If the type is trivially copyable (aka if it does not have a copy constructor),
21
+ * the data will be bulk-memcopied.
22
+ */
23
+ template <typename T>
24
+ std::vector<T> FastVectorCopy(const T* CONTIGUOUS_MEMORY NON_NULL data, size_t size) {
25
+ assert(data != nullptr && "FastVectoryCopy: data cannot be null!");
26
+
27
+ if (size == 0) [[unlikely]] {
28
+ // It's an empty vector.
29
+ return std::vector<T>();
30
+ }
31
+
32
+ if constexpr (std::is_trivially_copyable_v<T>) {
33
+ // FAST: Type does not have a copy constructor - simply memcpy it
34
+ std::vector<T> vector(size);
35
+ std::memcpy(vector.data(), data, size * sizeof(T));
36
+ return vector;
37
+ } else {
38
+ // SLOW: Type needs to be iterated to copy-construct it
39
+ std::span<const T> span(data, size);
40
+ return std::vector<T>(span.begin(), span.end());
41
+ }
42
+ }
43
+
44
+ } // namespace margelo::nitro
@@ -9,7 +9,7 @@
9
9
  #define NitroDefines_h
10
10
 
11
11
  // Sets the version of the native Nitro core library
12
- #define NITRO_VERSION "0.29.5"
12
+ #define NITRO_VERSION "0.29.7"
13
13
 
14
14
  // Sets whether to use debug or optimized production build flags
15
15
  #ifdef DEBUG
@@ -39,6 +39,24 @@
39
39
  #define CLOSED_ENUM
40
40
  #endif
41
41
 
42
+ // Nullability
43
+ #if defined(__clang__)
44
+ #define NON_NULL _Nonnull
45
+ #define NULLABLE _Nullable
46
+ #else
47
+ #define NON_NULL
48
+ #define NULLABLE
49
+ #endif
50
+
51
+ // Contiguous memory in pointers (__restrict)
52
+ #if defined(__clang__)
53
+ #define CONTIGUOUS_MEMORY __restrict__
54
+ #elif defined(_MSC_VER)
55
+ #define CONTIGUOUS_MEMORY __restrict
56
+ #else
57
+ #define CONTIGUOUS_MEMORY
58
+ #endif
59
+
42
60
  // Swift Support
43
61
  #if __has_include(<swift/bridging>)
44
62
  // Swift's bridging header defines those things
@@ -19,7 +19,7 @@ namespace margelo::nitro {
19
19
  * This function can be used at compile time as a constexpr to build
20
20
  * statically optimized switch statements.
21
21
  */
22
- constexpr uint64_t hashString(const char* str, size_t length) {
22
+ constexpr uint64_t hashString(const char* NON_NULL str, size_t length) {
23
23
  uint64_t hash = 14695981039346656037ull; // FNV offset basis
24
24
  const uint64_t fnv_prime = 1099511628211ull;
25
25
 
@@ -94,8 +94,8 @@ private:
94
94
  }
95
95
 
96
96
  private:
97
- T* _value;
98
- ReferenceState* _state;
97
+ T* NULLABLE _value;
98
+ ReferenceState* NON_NULL _state;
99
99
  };
100
100
 
101
101
  } // namespace margelo::nitro
@@ -14,10 +14,10 @@ namespace margelo::nitro {
14
14
  * Represents a Result from a function. It's either a value (`T`), or an error (`std::exception_ptr`).
15
15
  */
16
16
  template <typename T>
17
- class Result {
17
+ struct Result final {
18
18
  public:
19
19
  // Constructors
20
- Result(const Result& other) : _hasError(other._hasError) {
20
+ Result(const Result& other) noexcept(std::is_nothrow_copy_constructible<T>::value) : _hasError(other._hasError) {
21
21
  if (_hasError) {
22
22
  new (&_error) std::exception_ptr(other._error);
23
23
  } else {
@@ -33,11 +33,11 @@ public:
33
33
  }
34
34
  }
35
35
 
36
- ~Result() {
36
+ ~Result() noexcept(std::is_nothrow_destructible<T>::value) {
37
37
  destroy();
38
38
  }
39
39
 
40
- Result& operator=(const Result& other) {
40
+ Result& operator=(const Result& other) noexcept(std::is_nothrow_copy_constructible<T>::value && std::is_nothrow_destructible<T>::value) {
41
41
  if (this == &other)
42
42
  return *this;
43
43
  destroy();
@@ -50,7 +50,7 @@ public:
50
50
  return *this;
51
51
  }
52
52
 
53
- Result& operator=(Result&& other) noexcept(std::is_nothrow_move_constructible<T>::value) {
53
+ Result& operator=(Result&& other) noexcept(std::is_nothrow_move_constructible<T>::value && std::is_nothrow_destructible<T>::value) {
54
54
  if (this == &other)
55
55
  return *this;
56
56
  destroy();
@@ -64,15 +64,15 @@ public:
64
64
  }
65
65
 
66
66
  // Static factories
67
- static Result withValue(const T& value) {
67
+ static Result withValue(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value) {
68
68
  return Result(value);
69
69
  }
70
70
 
71
- static Result withValue(T&& value) {
71
+ static Result withValue(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value) {
72
72
  return Result(std::move(value));
73
73
  }
74
74
 
75
- static Result withError(std::exception_ptr eptr) {
75
+ static Result withError(std::exception_ptr eptr) noexcept {
76
76
  return Result(eptr);
77
77
  }
78
78
 
@@ -85,36 +85,36 @@ public:
85
85
  return _hasError;
86
86
  }
87
87
 
88
- const T& value() const {
88
+ const T& value() const noexcept {
89
89
  assert(!_hasError && "Result<T> does not hold a value!");
90
90
  return *reinterpret_cast<const T*>(&_storage);
91
91
  }
92
92
 
93
- T& value() {
93
+ T& value() noexcept {
94
94
  assert(!_hasError && "Result<T> does not hold a value!");
95
95
  return *reinterpret_cast<T*>(&_storage);
96
96
  }
97
97
 
98
- std::exception_ptr error() const {
98
+ std::exception_ptr error() const noexcept {
99
99
  assert(_hasError && "Result<T> does not hold an error!");
100
100
  return _error;
101
101
  }
102
102
 
103
103
  private:
104
104
  // Private constructors
105
- explicit Result(const T& value) : _hasError(false) {
105
+ explicit Result(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value) : _hasError(false) {
106
106
  new (&_storage) T(value);
107
107
  }
108
108
 
109
- explicit Result(T&& value) : _hasError(false) {
109
+ explicit Result(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value) : _hasError(false) {
110
110
  new (&_storage) T(std::move(value));
111
111
  }
112
112
 
113
- explicit Result(std::exception_ptr eptr) : _hasError(true) {
113
+ explicit Result(std::exception_ptr eptr) noexcept : _hasError(true) {
114
114
  new (&_error) std::exception_ptr(eptr);
115
115
  }
116
116
 
117
- void destroy() {
117
+ void destroy() noexcept(std::is_nothrow_destructible<T>::value) {
118
118
  if (_hasError) {
119
119
  reinterpret_cast<std::exception_ptr*>(&_error)->~exception_ptr();
120
120
  } else {
@@ -132,14 +132,14 @@ private:
132
132
 
133
133
  // Specialization for void
134
134
  template <>
135
- class Result<void> {
135
+ struct Result<void> final {
136
136
  public:
137
137
  // Constructors
138
- Result(const Result& other) : _hasError(other._hasError), _error(other._error) {}
138
+ Result(const Result& other) noexcept : _hasError(other._hasError), _error(other._error) {}
139
139
 
140
140
  Result(Result&& other) noexcept : _hasError(other._hasError), _error(std::move(other._error)) {}
141
141
 
142
- Result& operator=(const Result& other) {
142
+ Result& operator=(const Result& other) noexcept {
143
143
  if (this == &other)
144
144
  return *this;
145
145
  _hasError = other._hasError;
@@ -160,11 +160,11 @@ public:
160
160
  }
161
161
 
162
162
  // Static factories
163
- static Result withValue() {
163
+ static Result withValue() noexcept {
164
164
  return Result();
165
165
  }
166
166
 
167
- static Result withError(std::exception_ptr eptr) {
167
+ static Result withError(std::exception_ptr eptr) noexcept {
168
168
  return Result(eptr);
169
169
  }
170
170
 
@@ -176,14 +176,14 @@ public:
176
176
  return _hasError;
177
177
  }
178
178
 
179
- std::exception_ptr error() const {
179
+ std::exception_ptr error() const noexcept {
180
180
  assert(_hasError && "Result<void> does not hold an error!");
181
181
  return _error;
182
182
  }
183
183
 
184
184
  private:
185
- explicit Result() : _hasError(false), _error(nullptr) {}
186
- explicit Result(std::exception_ptr error) : _hasError(true), _error(error) {}
185
+ explicit Result() noexcept : _hasError(false), _error(nullptr) {}
186
+ explicit Result(std::exception_ptr error) noexcept : _hasError(true), _error(error) {}
187
187
 
188
188
  private:
189
189
  bool _hasError;
@@ -7,8 +7,7 @@ exports.callback = callback;
7
7
  exports.getHostComponent = getHostComponent;
8
8
  var _reactNative = require("react-native");
9
9
  var NativeComponentRegistry = _interopRequireWildcard(require("react-native/Libraries/NativeComponent/NativeComponentRegistry"));
10
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
10
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
11
  // @ts-expect-error this unfortunately isn't typed or default-exported.
13
12
  // eslint-disable-next-line @react-native/no-deep-imports
14
13
 
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","NativeComponentRegistry","_interopRequireWildcard","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","wrapValidAttributes","attributes","keys","key","diff","b","process","getHostComponent","name","getViewConfig","Error","Platform","OS","config","validAttributes","callback","func","f"],"sourceRoot":"../../../src","sources":["views/getHostComponent.ts"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,IAAAC,uBAAA,GAAAC,uBAAA,CAAAF,OAAA;AAAyG,SAAAG,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAF,wBAAAE,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAFzG;AACA;;AAyBA;AACA;AACA;;AAsBA;AACA;AACA;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA,SAASW,mBAAmBA,CAC1BC,UAAmC,EACV;EACzB,MAAMC,IAAI,GAAGV,MAAM,CAACU,IAAI,CAACD,UAAU,CAAsC;EACzE,KAAK,MAAME,GAAG,IAAID,IAAI,EAAE;IACtBD,UAAU,CAACE,GAAG,CAAC,GAAG;MAChBC,IAAI,EAAEA,CAACb,CAAC,EAAEc,CAAC,KAAKd,CAAC,KAAKc,CAAC;MACvBC,OAAO,EAAGR,CAAC,IAAKA;IAClB,CAAC;EACH;EACA,OAAOG,UAAU;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACO,SAASM,gBAAgBA,CAI9BC,IAAY,EACZC,aAAsC,EACL;EACjC,IAAI/B,uBAAuB,IAAI,IAAI,EAAE;IACnC,MAAM,IAAIgC,KAAK,CACb,+CAA+CC,qBAAQ,CAACC,EAAE,GAC5D,CAAC;EACH;EACA,OAAOlC,uBAAuB,CAACU,GAAG,CAACoB,IAAI,EAAE,MAAM;IAC7C,MAAMK,MAAM,GAAGJ,aAAa,CAAC,CAAC;IAC9BI,MAAM,CAACC,eAAe,GAAGd,mBAAmB,CAACa,MAAM,CAACC,eAAe,CAAC;IACpE,OAAOD,MAAM;EACf,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAIO,SAASE,QAAQA,CAACC,IAAa,EAAE;EACtC,IAAI,OAAOA,IAAI,KAAK,UAAU,EAAE;IAC9B,OAAO;MAAEC,CAAC,EAAED;IAAK,CAAC;EACpB;EACA,OAAOA,IAAI;AACb","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","NativeComponentRegistry","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","wrapValidAttributes","attributes","keys","key","diff","a","b","process","getHostComponent","name","getViewConfig","Error","Platform","OS","config","validAttributes","callback","func"],"sourceRoot":"../../../src","sources":["views/getHostComponent.ts"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,IAAAC,uBAAA,GAAAC,uBAAA,CAAAF,OAAA;AAAyG,SAAAE,wBAAAC,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAH,uBAAA,YAAAA,CAAAC,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAFzG;AACA;;AAyBA;AACA;AACA;;AAsBA;AACA;AACA;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA,SAASkB,mBAAmBA,CAC1BC,UAAmC,EACV;EACzB,MAAMC,IAAI,GAAGL,MAAM,CAACK,IAAI,CAACD,UAAU,CAAsC;EACzE,KAAK,MAAME,GAAG,IAAID,IAAI,EAAE;IACtBD,UAAU,CAACE,GAAG,CAAC,GAAG;MAChBC,IAAI,EAAEA,CAACC,CAAC,EAAEC,CAAC,KAAKD,CAAC,KAAKC,CAAC;MACvBC,OAAO,EAAGnB,CAAC,IAAKA;IAClB,CAAC;EACH;EACA,OAAOa,UAAU;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACO,SAASO,gBAAgBA,CAI9BC,IAAY,EACZC,aAAsC,EACL;EACjC,IAAI/B,uBAAuB,IAAI,IAAI,EAAE;IACnC,MAAM,IAAIgC,KAAK,CACb,+CAA+CC,qBAAQ,CAACC,EAAE,GAC5D,CAAC;EACH;EACA,OAAOlC,uBAAuB,CAACc,GAAG,CAACgB,IAAI,EAAE,MAAM;IAC7C,MAAMK,MAAM,GAAGJ,aAAa,CAAC,CAAC;IAC9BI,MAAM,CAACC,eAAe,GAAGf,mBAAmB,CAACc,MAAM,CAACC,eAAe,CAAC;IACpE,OAAOD,MAAM;EACf,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAIO,SAASE,QAAQA,CAACC,IAAa,EAAE;EACtC,IAAI,OAAOA,IAAI,KAAK,UAAU,EAAE;IAC9B,OAAO;MAAE5B,CAAC,EAAE4B;IAAK,CAAC;EACpB;EACA,OAAOA,IAAI;AACb","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-modules",
3
- "version": "0.29.5",
3
+ "version": "0.29.7",
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",