react-native-nitro-modules 0.21.0 → 0.22.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/NitroModules.podspec +4 -1
- package/README.md +1 -1
- package/android/CMakeLists.txt +1 -0
- package/android/build.gradle +4 -2
- package/android/gradle.properties +2 -2
- package/android/src/main/cpp/platform/ThreadUtils.cpp +4 -4
- package/android/src/main/cpp/registry/JHybridObjectRegistry.hpp +2 -0
- package/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +10 -9
- package/android/src/main/java/com/margelo/nitro/core/HybridObjectInitializer.java +4 -0
- package/android/src/main/java/com/margelo/nitro/core/HybridObjectRegistry.java +2 -0
- package/android/src/main/java/com/margelo/nitro/views/HybridView.kt +23 -0
- package/cpp/core/ArrayBuffer.cpp +2 -2
- package/cpp/core/ArrayBuffer.hpp +3 -3
- package/cpp/core/HybridFunction.hpp +1 -1
- package/cpp/core/HybridObject.cpp +7 -6
- package/cpp/core/HybridObject.hpp +3 -3
- package/cpp/core/Promise.hpp +1 -1
- package/cpp/entrypoint/HybridNitroModulesProxy.cpp +8 -0
- package/cpp/entrypoint/HybridNitroModulesProxy.hpp +1 -0
- package/cpp/jsi/JSICache.cpp +5 -4
- package/cpp/jsi/JSICache.hpp +21 -15
- package/cpp/jsi/JSIConverter+Exception.hpp +1 -1
- package/cpp/jsi/JSIConverter+Function.hpp +3 -2
- package/cpp/jsi/JSIConverter+HostObject.hpp +1 -1
- package/cpp/jsi/JSIConverter+HybridObject.hpp +1 -1
- package/cpp/jsi/JSIConverter+Tuple.hpp +1 -1
- package/cpp/jsi/JSIConverter+Variant.hpp +1 -1
- package/cpp/jsi/JSIHelpers.hpp +1 -1
- package/cpp/prototype/HybridObjectPrototype.cpp +3 -3
- package/cpp/prototype/HybridObjectPrototype.hpp +2 -2
- package/cpp/registry/HybridObjectRegistry.cpp +25 -12
- package/cpp/registry/HybridObjectRegistry.hpp +1 -0
- package/cpp/utils/AssertPromiseState.hpp +1 -1
- package/cpp/utils/BorrowingReference.hpp +163 -54
- package/cpp/utils/NitroDefines.hpp +10 -1
- package/cpp/utils/NitroHash.hpp +17 -0
- package/cpp/utils/{TypeInfo.hpp → NitroTypeInfo.hpp} +1 -1
- package/cpp/utils/OwningLock.hpp +14 -14
- package/cpp/utils/ReferenceState.hpp +40 -0
- package/cpp/utils/WeakReference+Owning.hpp +33 -0
- package/cpp/utils/WeakReference.hpp +102 -0
- package/cpp/views/CachedProp.hpp +43 -0
- package/ios/core/AnyMapHolder.swift +8 -8
- package/ios/core/HybridContext.hpp +1 -1
- package/ios/core/{HybridObjectSpec.swift → HybridObject.swift} +10 -2
- package/ios/turbomodule/NativeNitroModules+NewArch.mm +1 -1
- package/ios/utils/RuntimeError.hpp +1 -1
- package/ios/views/HybridView.swift +41 -0
- package/lib/commonjs/index.js +11 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/views/HybridView.js +17 -0
- package/lib/commonjs/views/HybridView.js.map +1 -0
- package/lib/commonjs/views/getHostComponent.js +22 -0
- package/lib/commonjs/views/getHostComponent.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/views/HybridView.js +30 -0
- package/lib/module/views/HybridView.js.map +1 -0
- package/lib/module/views/getHostComponent.js +15 -0
- package/lib/module/views/getHostComponent.js.map +1 -0
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/typescript/NitroModulesProxy.d.ts +7 -0
- package/lib/typescript/NitroModulesProxy.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/views/HybridView.d.ts +35 -0
- package/lib/typescript/views/HybridView.d.ts.map +1 -0
- package/lib/typescript/views/getHostComponent.d.ts +13 -0
- package/lib/typescript/views/getHostComponent.d.ts.map +1 -0
- package/package.json +3 -2
- package/src/NitroModulesProxy.ts +8 -0
- package/src/index.ts +1 -0
- package/src/views/HybridView.ts +37 -0
- package/src/views/getHostComponent.ts +26 -0
- package/cpp/utils/BorrowingReference+Owning.hpp +0 -36
- package/cpp/utils/OwningReference.hpp +0 -237
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { HybridObject } from '../HybridObject';
|
|
2
|
+
/**
|
|
3
|
+
* Describes the languages this view will be implemented in.
|
|
4
|
+
*/
|
|
5
|
+
export interface ViewPlatformSpec {
|
|
6
|
+
ios?: 'swift';
|
|
7
|
+
android?: 'kotlin';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Represents a Nitro `HybridView` which is implemented in a native language
|
|
11
|
+
* like Swift or Kotlin.
|
|
12
|
+
*
|
|
13
|
+
* `HybridViews`s use the Nitro Tunnel for efficient, low-overhead JS <-> Native communication.
|
|
14
|
+
*
|
|
15
|
+
* All `HybridViews`s have a C++ Fabric View base with a backing Shadow Node.
|
|
16
|
+
*
|
|
17
|
+
* - TypeScript Properties (`name: Type`) will be React Props
|
|
18
|
+
* - TypeScript Methods (`name(): Type`) will be Ref Methods
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* export interface Camera extends HybridView {
|
|
23
|
+
* zoom: number
|
|
24
|
+
* flash: boolean
|
|
25
|
+
* takePhoto(): Image
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export interface HybridView<Platforms extends ViewPlatformSpec = {
|
|
30
|
+
ios: 'swift';
|
|
31
|
+
android: 'kotlin';
|
|
32
|
+
}> extends HybridObject<Platforms> {
|
|
33
|
+
}
|
|
34
|
+
export * from './getHostComponent';
|
|
35
|
+
//# sourceMappingURL=HybridView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HybridView.d.ts","sourceRoot":"","sources":["../../../src/views/HybridView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,OAAO,CAAC,EAAE,QAAQ,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU,CACzB,SAAS,SAAS,gBAAgB,GAAG;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CACxE,SAAQ,YAAY,CAAC,SAAS,CAAC;CAEhC;AAED,cAAc,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type HostComponent } from 'react-native';
|
|
2
|
+
export interface ViewConfig<Props> {
|
|
3
|
+
uiViewClassName: string;
|
|
4
|
+
supportsRawText?: boolean;
|
|
5
|
+
bubblingEventTypes: Record<string, unknown>;
|
|
6
|
+
directEventTypes: Record<string, unknown>;
|
|
7
|
+
validAttributes: Record<keyof Props, boolean>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Finds and returns a native view (aka {@linkcode HostComponent}) via the given {@linkcode name}.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getHostComponent<Props>(name: string, getViewConfig: () => ViewConfig<Props>): HostComponent<Props>;
|
|
13
|
+
//# sourceMappingURL=getHostComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getHostComponent.d.ts","sourceRoot":"","sources":["../../../src/views/getHostComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAI3D,MAAM,WAAW,UAAU,CAAC,KAAK;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC3C,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAC,MAAM,KAAK,EAAE,OAAO,CAAC,CAAA;CAC9C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,GACrC,aAAa,CAAC,KAAK,CAAC,CAOtB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-modules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.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",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"cpp/",
|
|
21
21
|
"app.plugin.js",
|
|
22
22
|
"*.podspec",
|
|
23
|
+
"nitro_pod_utils.rb",
|
|
23
24
|
"README.md"
|
|
24
25
|
],
|
|
25
26
|
"keywords": [
|
|
@@ -73,7 +74,7 @@
|
|
|
73
74
|
"@types/react": "*",
|
|
74
75
|
"jest": "*",
|
|
75
76
|
"react": "18.3.1",
|
|
76
|
-
"react-native": "0.
|
|
77
|
+
"react-native": "0.77.0",
|
|
77
78
|
"react-native-builder-bob": "^0.35.0"
|
|
78
79
|
},
|
|
79
80
|
"peerDependencies": {
|
package/src/NitroModulesProxy.ts
CHANGED
|
@@ -69,4 +69,12 @@ export interface NitroModulesProxy extends HybridObject {
|
|
|
69
69
|
* Returns whether the given {@linkcode object} has NativeState or not.
|
|
70
70
|
*/
|
|
71
71
|
hasNativeState(object: unknown): boolean
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Re-calculates `memorySize` of the given {@linkcode HybridObject} and notifies
|
|
75
|
+
* the JS VM about the newly updated memory footprint.
|
|
76
|
+
*
|
|
77
|
+
* This is achieved by just doing a round-trip from JS -> native -> JS.
|
|
78
|
+
*/
|
|
79
|
+
updateMemorySize(obj: HybridObject): HybridObject
|
|
72
80
|
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HybridObject } from '../HybridObject'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Describes the languages this view will be implemented in.
|
|
5
|
+
*/
|
|
6
|
+
export interface ViewPlatformSpec {
|
|
7
|
+
ios?: 'swift'
|
|
8
|
+
android?: 'kotlin'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents a Nitro `HybridView` which is implemented in a native language
|
|
13
|
+
* like Swift or Kotlin.
|
|
14
|
+
*
|
|
15
|
+
* `HybridViews`s use the Nitro Tunnel for efficient, low-overhead JS <-> Native communication.
|
|
16
|
+
*
|
|
17
|
+
* All `HybridViews`s have a C++ Fabric View base with a backing Shadow Node.
|
|
18
|
+
*
|
|
19
|
+
* - TypeScript Properties (`name: Type`) will be React Props
|
|
20
|
+
* - TypeScript Methods (`name(): Type`) will be Ref Methods
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* export interface Camera extends HybridView {
|
|
25
|
+
* zoom: number
|
|
26
|
+
* flash: boolean
|
|
27
|
+
* takePhoto(): Image
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export interface HybridView<
|
|
32
|
+
Platforms extends ViewPlatformSpec = { ios: 'swift'; android: 'kotlin' },
|
|
33
|
+
> extends HybridObject<Platforms> {
|
|
34
|
+
/* empty interface for now */
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export * from './getHostComponent'
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Platform, type HostComponent } from 'react-native'
|
|
2
|
+
// @ts-expect-error this unfortunately isn't typed or default-exported.
|
|
3
|
+
import * as NativeComponentRegistry from 'react-native/Libraries/NativeComponent/NativeComponentRegistry'
|
|
4
|
+
|
|
5
|
+
export interface ViewConfig<Props> {
|
|
6
|
+
uiViewClassName: string
|
|
7
|
+
supportsRawText?: boolean
|
|
8
|
+
bubblingEventTypes: Record<string, unknown>
|
|
9
|
+
directEventTypes: Record<string, unknown>
|
|
10
|
+
validAttributes: Record<keyof Props, boolean>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Finds and returns a native view (aka {@linkcode HostComponent}) via the given {@linkcode name}.
|
|
15
|
+
*/
|
|
16
|
+
export function getHostComponent<Props>(
|
|
17
|
+
name: string,
|
|
18
|
+
getViewConfig: () => ViewConfig<Props>
|
|
19
|
+
): HostComponent<Props> {
|
|
20
|
+
if (NativeComponentRegistry == null) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`NativeComponentRegistry is not available on ${Platform.OS}!`
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
return NativeComponentRegistry.get<Props>(name, getViewConfig)
|
|
26
|
+
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// BorrowingReference+Owning.hpp
|
|
3
|
-
// react-native-nitro
|
|
4
|
-
//
|
|
5
|
-
// Created by Marc Rousavy on 23.06.24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
#pragma once
|
|
9
|
-
|
|
10
|
-
#include "OwningReference.hpp"
|
|
11
|
-
|
|
12
|
-
namespace margelo::nitro {
|
|
13
|
-
|
|
14
|
-
template <typename T>
|
|
15
|
-
BorrowingReference<T>::BorrowingReference(const OwningReference<T>& ref) {
|
|
16
|
-
_value = ref._value;
|
|
17
|
-
_isDeleted = ref._isDeleted;
|
|
18
|
-
_strongRefCount = ref._strongRefCount;
|
|
19
|
-
_weakRefCount = ref._weakRefCount;
|
|
20
|
-
_mutex = ref._mutex;
|
|
21
|
-
(*_weakRefCount)++;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
template <typename T>
|
|
25
|
-
OwningReference<T> BorrowingReference<T>::lock() const {
|
|
26
|
-
std::unique_lock lock(*_mutex);
|
|
27
|
-
|
|
28
|
-
if (*_isDeleted) {
|
|
29
|
-
// return nullptr
|
|
30
|
-
return OwningReference<T>();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return OwningReference(*this);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
} // namespace margelo::nitro
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// OwningReference.hpp
|
|
3
|
-
// react-native-nitro
|
|
4
|
-
//
|
|
5
|
-
// Created by Marc Rousavy on 23.06.24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
#pragma once
|
|
9
|
-
|
|
10
|
-
#include "BorrowingReference.hpp"
|
|
11
|
-
#include "OwningLock.hpp"
|
|
12
|
-
#include <atomic>
|
|
13
|
-
#include <cstddef>
|
|
14
|
-
#include <mutex>
|
|
15
|
-
|
|
16
|
-
namespace margelo::nitro {
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
An `OwningReference<T>` is a smart-pointer that holds a strong reference to a pointer.
|
|
20
|
-
You can have multiple `OwningReference<T>` instances point to the same pointer, as they internally keep a ref-count.
|
|
21
|
-
As opposed to a `shared_ptr<T>`, an `OwningReference<T>` can also be imperatively manually deleted, even if there
|
|
22
|
-
are multiple strong references still holding onto the pointer.
|
|
23
|
-
|
|
24
|
-
An `OwningReference<T>` can be weakified, which gives the user a `BorrowingReference<T>`.
|
|
25
|
-
A `BorrowingReference<T>` can be locked to get an `OwningReference<T>` again, assuming it has not been deleted yet.
|
|
26
|
-
*/
|
|
27
|
-
template <typename T>
|
|
28
|
-
class OwningReference final {
|
|
29
|
-
public:
|
|
30
|
-
using Pointee = T;
|
|
31
|
-
|
|
32
|
-
public:
|
|
33
|
-
OwningReference() : _value(nullptr), _isDeleted(nullptr), _strongRefCount(nullptr), _weakRefCount(nullptr), _mutex(nullptr) {}
|
|
34
|
-
|
|
35
|
-
explicit OwningReference(T* value)
|
|
36
|
-
: _value(value), _isDeleted(new bool(false)), _strongRefCount(new std::atomic_size_t(1)), _weakRefCount(new std::atomic_size_t(0)),
|
|
37
|
-
_mutex(new std::recursive_mutex()) {}
|
|
38
|
-
|
|
39
|
-
OwningReference(const OwningReference& ref)
|
|
40
|
-
: _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
|
|
41
|
-
_mutex(ref._mutex) {
|
|
42
|
-
// increment ref count after copy
|
|
43
|
-
(*_strongRefCount)++;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
OwningReference(OwningReference&& ref)
|
|
47
|
-
: _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
|
|
48
|
-
_mutex(ref._mutex) {
|
|
49
|
-
ref._value = nullptr;
|
|
50
|
-
ref._isDeleted = nullptr;
|
|
51
|
-
ref._strongRefCount = nullptr;
|
|
52
|
-
ref._weakRefCount = nullptr;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
OwningReference& operator=(const OwningReference& ref) {
|
|
56
|
-
if (this == &ref)
|
|
57
|
-
return *this;
|
|
58
|
-
|
|
59
|
-
if (_strongRefCount != nullptr) {
|
|
60
|
-
// destroy previous pointer
|
|
61
|
-
(*_strongRefCount)--;
|
|
62
|
-
maybeDestroy();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
_value = ref._value;
|
|
66
|
-
_isDeleted = ref._isDeleted;
|
|
67
|
-
_strongRefCount = ref._strongRefCount;
|
|
68
|
-
_weakRefCount = ref._weakRefCount;
|
|
69
|
-
_mutex = ref._mutex;
|
|
70
|
-
if (_strongRefCount != nullptr) {
|
|
71
|
-
// increment new pointer
|
|
72
|
-
(*_strongRefCount)++;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return *this;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private:
|
|
79
|
-
// BorrowingReference<T> -> OwningReference<T> Lock-constructor
|
|
80
|
-
OwningReference(const BorrowingReference<T>& ref)
|
|
81
|
-
: _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
|
|
82
|
-
_mutex(ref._mutex) {
|
|
83
|
-
(*_strongRefCount)++;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private:
|
|
87
|
-
// OwningReference<C> -> OwningReference<T> Cast-constructor
|
|
88
|
-
template <typename OldT>
|
|
89
|
-
OwningReference(T* value, const OwningReference<OldT>& originalRef)
|
|
90
|
-
: _value(value), _isDeleted(originalRef._isDeleted), _strongRefCount(originalRef._strongRefCount),
|
|
91
|
-
_weakRefCount(originalRef._weakRefCount), _mutex(originalRef._mutex) {
|
|
92
|
-
(*_strongRefCount)++;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
template <typename C>
|
|
96
|
-
friend class OwningReference;
|
|
97
|
-
|
|
98
|
-
public:
|
|
99
|
-
~OwningReference() {
|
|
100
|
-
if (_strongRefCount == nullptr) {
|
|
101
|
-
// we are just a dangling nullptr.
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// decrement strong ref count on destroy
|
|
106
|
-
--(*_strongRefCount);
|
|
107
|
-
maybeDestroy();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
public:
|
|
111
|
-
/**
|
|
112
|
-
Casts this `OwningReference<T>` to a `OwningReference<C>`.
|
|
113
|
-
*/
|
|
114
|
-
template <typename C>
|
|
115
|
-
OwningReference<C> as() {
|
|
116
|
-
return OwningReference<C>(static_cast<C*>(_value), *this);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
public:
|
|
120
|
-
/**
|
|
121
|
-
Creates an `OwningLock<T>` for the given `OwningReference<T>` to guarantee safe
|
|
122
|
-
safe access to `OwningReference<T>`.
|
|
123
|
-
Other threads (e.g. the Hermes garbage collector) cannot delete the `OwningReference<T>`
|
|
124
|
-
as long as the `OwningLock<T>` is still alive.
|
|
125
|
-
*/
|
|
126
|
-
[[nodiscard]]
|
|
127
|
-
OwningLock<T> lock() const {
|
|
128
|
-
return OwningLock<T>(*this);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
Get whether the `OwningReference<T>` is still pointing to a valid value, or not.
|
|
133
|
-
*/
|
|
134
|
-
inline bool hasValue() const {
|
|
135
|
-
return _value != nullptr && !(*_isDeleted);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
Get a borrowing (or "weak") reference to this owning reference
|
|
140
|
-
*/
|
|
141
|
-
[[nodiscard]]
|
|
142
|
-
BorrowingReference<T> weak() const {
|
|
143
|
-
return BorrowingReference(*this);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
Delete and destroy the value this OwningReference is pointing to.
|
|
148
|
-
This can even be called if there are still multiple strong references to the value.
|
|
149
|
-
|
|
150
|
-
This will block as long as one or more `OwningLock<T>`s of this `OwningReference<T>` are still alive.
|
|
151
|
-
*/
|
|
152
|
-
void destroy() {
|
|
153
|
-
std::unique_lock lock(*_mutex);
|
|
154
|
-
|
|
155
|
-
forceDestroy();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
public:
|
|
159
|
-
explicit inline operator bool() const {
|
|
160
|
-
return hasValue();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
inline T& operator*() const {
|
|
164
|
-
return *_value;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
inline T* operator->() const {
|
|
168
|
-
return _value;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
inline bool operator==(T* other) const {
|
|
172
|
-
std::unique_lock lock(*_mutex);
|
|
173
|
-
|
|
174
|
-
if (*_isDeleted) {
|
|
175
|
-
return other == nullptr;
|
|
176
|
-
} else {
|
|
177
|
-
return other == _value;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
inline bool operator!=(T* other) const {
|
|
182
|
-
return !(this == other);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
inline bool operator==(const OwningReference<T>& other) const {
|
|
186
|
-
return _value == other._value;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
inline bool operator!=(const OwningReference<T>& other) const {
|
|
190
|
-
return !(this == other);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
private:
|
|
194
|
-
void maybeDestroy() {
|
|
195
|
-
_mutex->lock();
|
|
196
|
-
|
|
197
|
-
if (*_strongRefCount == 0) {
|
|
198
|
-
// after no strong references exist anymore
|
|
199
|
-
forceDestroy();
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (*_strongRefCount == 0 && *_weakRefCount == 0) {
|
|
203
|
-
// free the full memory if there are no more references at all
|
|
204
|
-
delete _isDeleted;
|
|
205
|
-
delete _strongRefCount;
|
|
206
|
-
delete _weakRefCount;
|
|
207
|
-
_mutex->unlock();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
_mutex->unlock();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
void forceDestroy() {
|
|
215
|
-
if (*_isDeleted) {
|
|
216
|
-
// it has already been destroyed.
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
delete _value;
|
|
220
|
-
*_isDeleted = true;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
public:
|
|
224
|
-
friend class BorrowingReference<T>;
|
|
225
|
-
friend class OwningLock<T>;
|
|
226
|
-
|
|
227
|
-
private:
|
|
228
|
-
T* _value;
|
|
229
|
-
bool* _isDeleted;
|
|
230
|
-
std::atomic_size_t* _strongRefCount;
|
|
231
|
-
std::atomic_size_t* _weakRefCount;
|
|
232
|
-
std::recursive_mutex* _mutex;
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
} // namespace margelo::nitro
|
|
236
|
-
|
|
237
|
-
#include "BorrowingReference+Owning.hpp"
|